blob: 0299df5f5b48dc9f34d0a462d90f0eab241216dc [file] [log] [blame]
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001" Test the :disassemble command, and compilation as a side effect
2
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01003source check.vim
4
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01005func NotCompiled()
6 echo "not"
7endfunc
8
9let s:scriptvar = 4
10let g:globalvar = 'g'
11
12def s:ScriptFuncLoad(arg: string)
13 let local = 1
14 buffers
15 echo arg
16 echo local
17 echo v:version
18 echo s:scriptvar
19 echo g:globalvar
20 echo &tabstop
21 echo $ENVVAR
22 echo @z
23enddef
24
Bram Moolenaarf2460a32020-02-07 22:09:54 +010025def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010026 assert_fails('disass NoFunc', 'E1061:')
27 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010028 assert_fails('disass', 'E471:')
29 assert_fails('disass [', 'E475:')
30 assert_fails('disass 234', 'E475:')
31 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010032
33 let res = execute('disass s:ScriptFuncLoad')
34 assert_match('<SNR>\d*_ScriptFuncLoad.*'
35 \ .. 'buffers.*'
36 \ .. ' EXEC \+buffers.*'
37 \ .. ' LOAD arg\[-1\].*'
38 \ .. ' LOAD $0.*'
39 \ .. ' LOADV v:version.*'
40 \ .. ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*'
41 \ .. ' LOADG g:globalvar.*'
42 \ .. ' LOADENV $ENVVAR.*'
43 \ .. ' LOADREG @z.*'
44 \, res)
45enddef
46
47def s:ScriptFuncPush()
48 let localbool = true
49 let localspec = v:none
50 let localblob = 0z1234
51 if has('float')
52 let localfloat = 1.234
53 endif
54enddef
55
Bram Moolenaarf2460a32020-02-07 22:09:54 +010056def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010057 let res = execute('disass s:ScriptFuncPush')
58 assert_match('<SNR>\d*_ScriptFuncPush.*'
59 \ .. 'localbool = true.*'
60 \ .. ' PUSH v:true.*'
61 \ .. 'localspec = v:none.*'
62 \ .. ' PUSH v:none.*'
63 \ .. 'localblob = 0z1234.*'
64 \ .. ' PUSHBLOB 0z1234.*'
65 \, res)
66 if has('float')
67 assert_match('<SNR>\d*_ScriptFuncPush.*'
68 \ .. 'localfloat = 1.234.*'
69 \ .. ' PUSHF 1.234.*'
70 \, res)
71 endif
72enddef
73
74def s:ScriptFuncStore()
75 let localnr = 1
76 localnr = 2
77 let localstr = 'abc'
78 localstr = 'xyz'
79 v:char = 'abc'
80 s:scriptvar = 'sv'
81 g:globalvar = 'gv'
82 &tabstop = 8
83 $ENVVAR = 'ev'
84 @z = 'rv'
85enddef
86
Bram Moolenaarf2460a32020-02-07 22:09:54 +010087def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010088 let res = execute('disass s:ScriptFuncStore')
89 assert_match('<SNR>\d*_ScriptFuncStore.*'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020090 \ .. 'let localnr = 1.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010091 \ .. 'localnr = 2.*'
92 \ .. ' STORE 2 in $0.*'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020093 \ .. 'let localstr = ''abc''.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010094 \ .. 'localstr = ''xyz''.*'
95 \ .. ' STORE $1.*'
96 \ .. 'v:char = ''abc''.*'
97 \ .. 'STOREV v:char.*'
98 \ .. 's:scriptvar = ''sv''.*'
99 \ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*'
100 \ .. 'g:globalvar = ''gv''.*'
101 \ .. ' STOREG g:globalvar.*'
102 \ .. '&tabstop = 8.*'
103 \ .. ' STOREOPT &tabstop.*'
104 \ .. '$ENVVAR = ''ev''.*'
105 \ .. ' STOREENV $ENVVAR.*'
106 \ .. '@z = ''rv''.*'
107 \ .. ' STOREREG @z.*'
108 \, res)
109enddef
110
111def s:ScriptFuncTry()
112 try
113 echo 'yes'
114 catch /fail/
115 echo 'no'
116 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100117 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100118 endtry
119enddef
120
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100121def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100122 let res = execute('disass s:ScriptFuncTry')
123 assert_match('<SNR>\d*_ScriptFuncTry.*'
124 \ .. 'try.*'
125 \ .. 'TRY catch -> \d\+, finally -> \d\+.*'
126 \ .. 'catch /fail/.*'
127 \ .. ' JUMP -> \d\+.*'
128 \ .. ' PUSH v:exception.*'
129 \ .. ' PUSHS "fail".*'
130 \ .. ' COMPARESTRING =\~.*'
131 \ .. ' JUMP_IF_FALSE -> \d\+.*'
132 \ .. ' CATCH.*'
133 \ .. 'finally.*'
134 \ .. ' PUSHS "end".*'
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100135 \ .. ' THROW.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100136 \ .. 'endtry.*'
137 \ .. ' ENDTRY.*'
138 \, res)
139enddef
140
141def s:ScriptFuncNew()
142 let ll = [1, "two", 333]
143 let dd = #{one: 1, two: "val"}
144enddef
145
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100146def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100147 let res = execute('disass s:ScriptFuncNew')
148 assert_match('<SNR>\d*_ScriptFuncNew.*'
149 \ .. 'let ll = \[1, "two", 333].*'
150 \ .. 'PUSHNR 1.*'
151 \ .. 'PUSHS "two".*'
152 \ .. 'PUSHNR 333.*'
153 \ .. 'NEWLIST size 3.*'
154 \ .. 'let dd = #{one: 1, two: "val"}.*'
155 \ .. 'PUSHS "one".*'
156 \ .. 'PUSHNR 1.*'
157 \ .. 'PUSHS "two".*'
158 \ .. 'PUSHS "val".*'
159 \ .. 'NEWDICT size 2.*'
160 \, res)
161enddef
162
163def FuncWithArg(arg)
164 echo arg
165enddef
166
167func UserFunc()
168 echo 'nothing'
169endfunc
170
171func UserFuncWithArg(arg)
172 echo a:arg
173endfunc
174
175def s:ScriptFuncCall(): string
176 changenr()
177 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100178 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100179 FuncWithArg(343)
180 ScriptFuncNew()
181 s:ScriptFuncNew()
182 UserFunc()
183 UserFuncWithArg("foo")
184 let FuncRef = function("UserFunc")
185 FuncRef()
186 let FuncRefWithArg = function("UserFuncWithArg")
187 FuncRefWithArg("bar")
188 return "yes"
189enddef
190
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100191def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100192 let res = execute('disass s:ScriptFuncCall')
193 assert_match('<SNR>\d\+_ScriptFuncCall.*'
194 \ .. 'changenr().*'
195 \ .. ' BCALL changenr(argc 0).*'
196 \ .. 'char2nr("abc").*'
197 \ .. ' PUSHS "abc".*'
198 \ .. ' BCALL char2nr(argc 1).*'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100199 \ .. 'Test_disassemble_new().*'
200 \ .. ' DCALL Test_disassemble_new(argc 0).*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100201 \ .. 'FuncWithArg(343).*'
202 \ .. ' PUSHNR 343.*'
203 \ .. ' DCALL FuncWithArg(argc 1).*'
204 \ .. 'ScriptFuncNew().*'
205 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
206 \ .. 's:ScriptFuncNew().*'
207 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
208 \ .. 'UserFunc().*'
209 \ .. ' UCALL UserFunc(argc 0).*'
210 \ .. 'UserFuncWithArg("foo").*'
211 \ .. ' PUSHS "foo".*'
212 \ .. ' UCALL UserFuncWithArg(argc 1).*'
213 \ .. 'let FuncRef = function("UserFunc").*'
214 \ .. 'FuncRef().*'
215 \ .. ' LOAD $\d.*'
216 \ .. ' PCALL (argc 0).*'
217 \ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
218 \ .. 'FuncRefWithArg("bar").*'
219 \ .. ' PUSHS "bar".*'
220 \ .. ' LOAD $\d.*'
221 \ .. ' PCALL (argc 1).*'
222 \ .. 'return "yes".*'
223 \ .. ' PUSHS "yes".*'
224 \ .. ' RETURN.*'
225 \, res)
226enddef
227
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100228
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200229def EchoArg(arg: string): string
230 return arg
231enddef
232def RefThis(): func
233 return function('EchoArg')
234enddef
235def s:ScriptPCall()
236 RefThis()("text")
237enddef
238
239def Test_disassemble_pcall()
240 let res = execute('disass s:ScriptPCall')
241 assert_match('<SNR>\d\+_ScriptPCall.*'
242 \ .. 'RefThis()("text").*'
243 \ .. '\d DCALL RefThis(argc 0).*'
244 \ .. '\d PUSHS "text".*'
245 \ .. '\d PCALL top (argc 1).*'
246 \ .. '\d PCALL end.*'
247 \ .. '\d DROP.*'
248 \ .. '\d PUSHNR 0.*'
249 \ .. '\d RETURN.*'
250 \, res)
251enddef
252
253
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100254def FuncWithForwardCall(): string
255 return DefinedLater("yes")
256enddef
257
258def DefinedLater(arg: string): string
259 return arg
260enddef
261
262def Test_disassemble_update_instr()
263 let res = execute('disass FuncWithForwardCall')
264 assert_match('FuncWithForwardCall.*'
265 \ .. 'return DefinedLater("yes").*'
266 \ .. '\d PUSHS "yes".*'
267 \ .. '\d UCALL DefinedLater(argc 1).*'
268 \ .. '\d CHECKTYPE string stack\[-1].*'
269 \ .. '\d RETURN.*'
270 \, res)
271
272 " Calling the function will change UCALL into the faster DCALL
273 assert_equal('yes', FuncWithForwardCall())
274
275 res = execute('disass FuncWithForwardCall')
276 assert_match('FuncWithForwardCall.*'
277 \ .. 'return DefinedLater("yes").*'
278 \ .. '\d PUSHS "yes".*'
279 \ .. '\d DCALL DefinedLater(argc 1).*'
280 \ .. '\d CHECKTYPE string stack\[-1].*'
281 \ .. '\d RETURN.*'
282 \, res)
283enddef
284
285
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100286def FuncWithDefault(arg: string = 'default'): string
287 return arg
288enddef
289
290def Test_disassemble_call_default()
291 let res = execute('disass FuncWithDefault')
292 assert_match('FuncWithDefault.*'
293 \ .. '\d PUSHS "default".*'
294 \ .. '\d STORE arg\[-1].*'
295 \ .. 'return arg.*'
296 \ .. '\d LOAD arg\[-1].*'
297 \ .. '\d RETURN.*'
298 \, res)
299enddef
300
301
Bram Moolenaar158906c2020-02-06 20:39:45 +0100302def HasEval()
303 if has("eval")
304 echo "yes"
305 else
306 echo "no"
307 endif
308enddef
309
310def HasNothing()
311 if has("nothing")
312 echo "yes"
313 else
314 echo "no"
315 endif
316enddef
317
318def HasSomething()
319 if has("nothing")
320 echo "nothing"
321 elseif has("something")
322 echo "something"
323 elseif has("eval")
324 echo "eval"
325 elseif has("less")
326 echo "less"
327 endif
328enddef
329
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100330def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100331 assert_equal("\nyes", execute('call HasEval()'))
332 let instr = execute('disassemble HasEval')
333 assert_match('HasEval.*'
334 \ .. 'if has("eval").*'
335 \ .. ' PUSHS "yes".*'
336 \, instr)
337 assert_notmatch('JUMP', instr)
338
339 assert_equal("\nno", execute('call HasNothing()'))
340 instr = execute('disassemble HasNothing')
341 assert_match('HasNothing.*'
342 \ .. 'if has("nothing").*'
343 \ .. 'else.*'
344 \ .. ' PUSHS "no".*'
345 \, instr)
346 assert_notmatch('PUSHS "yes"', instr)
347 assert_notmatch('JUMP', instr)
348
349 assert_equal("\neval", execute('call HasSomething()'))
350 instr = execute('disassemble HasSomething')
351 assert_match('HasSomething.*'
352 \ .. 'if has("nothing").*'
353 \ .. 'elseif has("something").*'
354 \ .. 'elseif has("eval").*'
355 \ .. ' PUSHS "eval".*'
356 \ .. 'elseif has("less").*'
357 \, instr)
358 assert_notmatch('PUSHS "nothing"', instr)
359 assert_notmatch('PUSHS "something"', instr)
360 assert_notmatch('PUSHS "less"', instr)
361 assert_notmatch('JUMP', instr)
362enddef
363
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100364def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200365 let Funky1: func
366 let Funky2: func = function("len")
367 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100368enddef
369
370def Test_disassemble_function()
371 let instr = execute('disassemble WithFunc')
372 assert_match('WithFunc.*'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200373 \ .. 'let Funky1: func.*'
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100374 \ .. '0 PUSHFUNC "\[none]".*'
375 \ .. '1 STORE $0.*'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200376 \ .. 'let Funky2: func = function("len").*'
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100377 \ .. '2 PUSHS "len".*'
378 \ .. '3 BCALL function(argc 1).*'
379 \ .. '4 STORE $1.*'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200380 \ .. 'let Party2: func = funcref("UserFunc").*'
Bram Moolenaard77a8522020-04-03 21:59:57 +0200381 \ .. '\d PUSHS "UserFunc".*'
382 \ .. '\d BCALL funcref(argc 1).*'
383 \ .. '\d STORE $2.*'
384 \ .. '\d PUSHNR 0.*'
385 \ .. '\d RETURN.*'
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100386 \, instr)
387enddef
388
389if has('channel')
390 def WithChannel()
391 let job1: job
392 let job2: job = job_start("donothing")
393 let chan1: channel
394 enddef
395endif
396
397def Test_disassemble_channel()
398 CheckFeature channel
399
400 let instr = execute('disassemble WithChannel')
401 assert_match('WithChannel.*'
402 \ .. 'let job1: job.*'
403 \ .. '\d PUSHJOB "no process".*'
404 \ .. '\d STORE $0.*'
405 \ .. 'let job2: job = job_start("donothing").*'
406 \ .. '\d PUSHS "donothing".*'
407 \ .. '\d BCALL job_start(argc 1).*'
408 \ .. '\d STORE $1.*'
409 \ .. 'let chan1: channel.*'
410 \ .. '\d PUSHCHANNEL 0.*'
411 \ .. '\d STORE $2.*'
412 \ .. '\d PUSHNR 0.*'
413 \ .. '\d RETURN.*'
414 \, instr)
415enddef
416
Bram Moolenaar777770f2020-02-06 21:27:08 +0100417def WithLambda(): string
418 let F = {a -> "X" .. a .. "X"}
419 return F("x")
420enddef
421
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100422def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100423 assert_equal("XxX", WithLambda())
424 let instr = execute('disassemble WithLambda')
425 assert_match('WithLambda.*'
426 \ .. 'let F = {a -> "X" .. a .. "X"}.*'
427 \ .. ' FUNCREF <lambda>\d\+.*'
428 \ .. 'PUSHS "x".*'
429 \ .. ' LOAD $0.*'
430 \ .. ' PCALL (argc 1).*'
431 \ .. ' CHECKTYPE string stack\[-1].*'
432 \, instr)
433enddef
434
435def AndOr(arg): string
436 if arg == 1 && arg != 2 || arg == 4
437 return 'yes'
438 endif
439 return 'no'
440enddef
441
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100442def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100443 assert_equal("yes", AndOr(1))
444 assert_equal("no", AndOr(2))
445 assert_equal("yes", AndOr(4))
446 let instr = execute('disassemble AndOr')
447 assert_match('AndOr.*'
448 \ .. 'if arg == 1 && arg != 2 || arg == 4.*'
449 \ .. '\d LOAD arg\[-1].*'
450 \ .. '\d PUSHNR 1.*'
451 \ .. '\d COMPAREANY ==.*'
452 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*'
453 \ .. '\d LOAD arg\[-1].*'
454 \ .. '\d PUSHNR 2.*'
455 \ .. '\d COMPAREANY !=.*'
456 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*'
457 \ .. '\d LOAD arg\[-1].*'
458 \ .. '\d PUSHNR 4.*'
459 \ .. '\d COMPAREANY ==.*'
460 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
461 \, instr)
462enddef
463
Bram Moolenaar04d05222020-02-06 22:06:54 +0100464def ForLoop(): list<number>
465 let res: list<number>
466 for i in range(3)
467 res->add(i)
468 endfor
469 return res
470enddef
471
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100472def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100473 assert_equal([0, 1, 2], ForLoop())
474 let instr = execute('disassemble ForLoop')
475 assert_match('ForLoop.*'
476 \ .. 'let res: list<number>.*'
477 \ .. ' NEWLIST size 0.*'
478 \ .. '\d STORE $0.*'
479 \ .. 'for i in range(3).*'
480 \ .. '\d STORE -1 in $1.*'
481 \ .. '\d PUSHNR 3.*'
482 \ .. '\d BCALL range(argc 1).*'
483 \ .. '\d FOR $1 -> \d\+.*'
484 \ .. '\d STORE $2.*'
485 \ .. 'res->add(i).*'
486 \ .. '\d LOAD $0.*'
487 \ .. '\d LOAD $2.*'
488 \ .. '\d BCALL add(argc 2).*'
489 \ .. '\d DROP.*'
490 \ .. 'endfor.*'
491 \ .. '\d JUMP -> \d\+.*'
492 \ .. '\d DROP.*'
493 \, instr)
494enddef
495
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100496let g:number = 42
497
498def Computing()
499 let nr = 3
500 let nrres = nr + 7
501 nrres = nr - 7
502 nrres = nr * 7
503 nrres = nr / 7
504 nrres = nr % 7
505
506 let anyres = g:number + 7
507 anyres = g:number - 7
508 anyres = g:number * 7
509 anyres = g:number / 7
510 anyres = g:number % 7
511
512 if has('float')
513 let fl = 3.0
514 let flres = fl + 7.0
515 flres = fl - 7.0
516 flres = fl * 7.0
517 flres = fl / 7.0
518 endif
519enddef
520
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100521def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100522 let instr = execute('disassemble Computing')
523 assert_match('Computing.*'
524 \ .. 'let nr = 3.*'
525 \ .. '\d STORE 3 in $0.*'
526 \ .. 'let nrres = nr + 7.*'
527 \ .. '\d LOAD $0.*'
528 \ .. '\d PUSHNR 7.*'
529 \ .. '\d OPNR +.*'
530 \ .. '\d STORE $1.*'
531 \ .. 'nrres = nr - 7.*'
532 \ .. '\d OPNR -.*'
533 \ .. 'nrres = nr \* 7.*'
534 \ .. '\d OPNR \*.*'
535 \ .. 'nrres = nr / 7.*'
536 \ .. '\d OPNR /.*'
537 \ .. 'nrres = nr % 7.*'
538 \ .. '\d OPNR %.*'
539 \ .. 'let anyres = g:number + 7.*'
540 \ .. '\d LOADG g:number.*'
541 \ .. '\d PUSHNR 7.*'
542 \ .. '\d OPANY +.*'
543 \ .. '\d STORE $2.*'
544 \ .. 'anyres = g:number - 7.*'
545 \ .. '\d OPANY -.*'
546 \ .. 'anyres = g:number \* 7.*'
547 \ .. '\d OPANY \*.*'
548 \ .. 'anyres = g:number / 7.*'
549 \ .. '\d OPANY /.*'
550 \ .. 'anyres = g:number % 7.*'
551 \ .. '\d OPANY %.*'
552 \, instr)
553 if has('float')
554 assert_match('Computing.*'
555 \ .. 'let fl = 3.0.*'
556 \ .. '\d PUSHF 3.0.*'
557 \ .. '\d STORE $3.*'
558 \ .. 'let flres = fl + 7.0.*'
559 \ .. '\d LOAD $3.*'
560 \ .. '\d PUSHF 7.0.*'
561 \ .. '\d OPFLOAT +.*'
562 \ .. '\d STORE $4.*'
563 \ .. 'flres = fl - 7.0.*'
564 \ .. '\d OPFLOAT -.*'
565 \ .. 'flres = fl \* 7.0.*'
566 \ .. '\d OPFLOAT \*.*'
567 \ .. 'flres = fl / 7.0.*'
568 \ .. '\d OPFLOAT /.*'
569 \, instr)
570 endif
571enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100572
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100573def AddListBlob()
574 let reslist = [1, 2] + [3, 4]
575 let resblob = 0z1122 + 0z3344
576enddef
577
578def Test_disassemble_add_list_blob()
579 let instr = execute('disassemble AddListBlob')
580 assert_match('AddListBlob.*'
581 \ .. 'let reslist = \[1, 2] + \[3, 4].*'
582 \ .. '\d PUSHNR 1.*'
583 \ .. '\d PUSHNR 2.*'
584 \ .. '\d NEWLIST size 2.*'
585 \ .. '\d PUSHNR 3.*'
586 \ .. '\d PUSHNR 4.*'
587 \ .. '\d NEWLIST size 2.*'
588 \ .. '\d ADDLIST.*'
589 \ .. '\d STORE $.*.*'
590 \ .. 'let resblob = 0z1122 + 0z3344.*'
591 \ .. '\d PUSHBLOB 0z1122.*'
592 \ .. '\d PUSHBLOB 0z3344.*'
593 \ .. '\d ADDBLOB.*'
594 \ .. '\d STORE $.*'
595 \, instr)
596enddef
597
598let g:aa = 'aa'
599def ConcatString(): string
600 let res = g:aa .. "bb"
601 return res
602enddef
603
604def Test_disassemble_concat()
605 let instr = execute('disassemble ConcatString')
606 assert_match('ConcatString.*'
607 \ .. 'let res = g:aa .. "bb".*'
608 \ .. '\d LOADG g:aa.*'
609 \ .. '\d PUSHS "bb".*'
610 \ .. '\d 2STRING stack\[-2].*'
611 \ .. '\d CONCAT.*'
612 \ .. '\d STORE $.*'
613 \, instr)
614 assert_equal('aabb', ConcatString())
615enddef
616
617def ListIndex(): number
618 let l = [1, 2, 3]
619 let res = l[1]
620 return res
621enddef
622
623def Test_disassemble_list_index()
624 let instr = execute('disassemble ListIndex')
625 assert_match('ListIndex.*'
626 \ .. 'let l = \[1, 2, 3].*'
627 \ .. '\d PUSHNR 1.*'
628 \ .. '\d PUSHNR 2.*'
629 \ .. '\d PUSHNR 3.*'
630 \ .. '\d NEWLIST size 3.*'
631 \ .. '\d STORE $0.*'
632 \ .. 'let res = l\[1].*'
633 \ .. '\d LOAD $0.*'
634 \ .. '\d PUSHNR 1.*'
635 \ .. '\d INDEX.*'
636 \ .. '\d STORE $1.*'
637 \, instr)
638 assert_equal(2, ListIndex())
639enddef
640
641def DictMember(): number
642 let d = #{item: 1}
643 let res = d.item
644 return res
645enddef
646
647def Test_disassemble_dict_member()
648 let instr = execute('disassemble DictMember')
649 assert_match('DictMember.*'
650 \ .. 'let d = #{item: 1}.*'
651 \ .. '\d PUSHS "item".*'
652 \ .. '\d PUSHNR 1.*'
653 \ .. '\d NEWDICT size 1.*'
654 \ .. '\d STORE $0.*'
655 \ .. 'let res = d.item.*'
656 \ .. '\d LOAD $0.*'
657 \ .. '\d MEMBER item.*'
658 \ .. '\d STORE $1.*'
659 \, instr)
660 call assert_equal(1, DictMember())
661enddef
662
663def NegateNumber(): number
664 let nr = 9
665 let plus = +nr
666 let res = -nr
667 return res
668enddef
669
670def Test_disassemble_negate_number()
671 let instr = execute('disassemble NegateNumber')
672 assert_match('NegateNumber.*'
673 \ .. 'let nr = 9.*'
674 \ .. '\d STORE 9 in $0.*'
675 \ .. 'let plus = +nr.*'
676 \ .. '\d LOAD $0.*'
677 \ .. '\d CHECKNR.*'
678 \ .. '\d STORE $1.*'
679 \ .. 'let res = -nr.*'
680 \ .. '\d LOAD $0.*'
681 \ .. '\d NEGATENR.*'
682 \ .. '\d STORE $2.*'
683 \, instr)
684 call assert_equal(-9, NegateNumber())
685enddef
686
687def InvertBool(): bool
688 let flag = true
689 let invert = !flag
690 let res = !!flag
691 return res
692enddef
693
694def Test_disassemble_invert_bool()
695 let instr = execute('disassemble InvertBool')
696 assert_match('InvertBool.*'
697 \ .. 'let flag = true.*'
698 \ .. '\d PUSH v:true.*'
699 \ .. '\d STORE $0.*'
700 \ .. 'let invert = !flag.*'
701 \ .. '\d LOAD $0.*'
702 \ .. '\d INVERT (!val).*'
703 \ .. '\d STORE $1.*'
704 \ .. 'let res = !!flag.*'
705 \ .. '\d LOAD $0.*'
706 \ .. '\d 2BOOL (!!val).*'
707 \ .. '\d STORE $2.*'
708 \, instr)
709 call assert_equal(true, InvertBool())
710enddef
711
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100712def Test_disassemble_compare()
713 " TODO: COMPAREFUNC
714 let cases = [
715 \ ['true == false', 'COMPAREBOOL =='],
716 \ ['true != false', 'COMPAREBOOL !='],
717 \ ['v:none == v:null', 'COMPARESPECIAL =='],
718 \ ['v:none != v:null', 'COMPARESPECIAL !='],
719 \
720 \ ['111 == 222', 'COMPARENR =='],
721 \ ['111 != 222', 'COMPARENR !='],
722 \ ['111 > 222', 'COMPARENR >'],
723 \ ['111 < 222', 'COMPARENR <'],
724 \ ['111 >= 222', 'COMPARENR >='],
725 \ ['111 <= 222', 'COMPARENR <='],
726 \ ['111 =~ 222', 'COMPARENR =\~'],
727 \ ['111 !~ 222', 'COMPARENR !\~'],
728 \
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100729 \ ['"xx" != "yy"', 'COMPARESTRING !='],
730 \ ['"xx" > "yy"', 'COMPARESTRING >'],
731 \ ['"xx" < "yy"', 'COMPARESTRING <'],
732 \ ['"xx" >= "yy"', 'COMPARESTRING >='],
733 \ ['"xx" <= "yy"', 'COMPARESTRING <='],
734 \ ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
735 \ ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
736 \ ['"xx" is "yy"', 'COMPARESTRING is'],
737 \ ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
738 \
739 \ ['0z11 == 0z22', 'COMPAREBLOB =='],
740 \ ['0z11 != 0z22', 'COMPAREBLOB !='],
741 \ ['0z11 is 0z22', 'COMPAREBLOB is'],
742 \ ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
743 \
744 \ ['[1,2] == [3,4]', 'COMPARELIST =='],
745 \ ['[1,2] != [3,4]', 'COMPARELIST !='],
746 \ ['[1,2] is [3,4]', 'COMPARELIST is'],
747 \ ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
748 \
749 \ ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
750 \ ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
751 \ ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
752 \ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
753 \
Bram Moolenaard77a8522020-04-03 21:59:57 +0200754 \ ['{->33} == {->44}', 'COMPAREFUNC =='],
755 \ ['{->33} != {->44}', 'COMPAREFUNC !='],
756 \ ['{->33} is {->44}', 'COMPAREFUNC is'],
757 \ ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100758 \
759 \ ['77 == g:xx', 'COMPAREANY =='],
760 \ ['77 != g:xx', 'COMPAREANY !='],
761 \ ['77 > g:xx', 'COMPAREANY >'],
762 \ ['77 < g:xx', 'COMPAREANY <'],
763 \ ['77 >= g:xx', 'COMPAREANY >='],
764 \ ['77 <= g:xx', 'COMPAREANY <='],
765 \ ['77 =~ g:xx', 'COMPAREANY =\~'],
766 \ ['77 !~ g:xx', 'COMPAREANY !\~'],
767 \ ['77 is g:xx', 'COMPAREANY is'],
768 \ ['77 isnot g:xx', 'COMPAREANY isnot'],
769 \ ]
770 if has('float')
771 cases->extend([
772 \ ['1.1 == 2.2', 'COMPAREFLOAT =='],
773 \ ['1.1 != 2.2', 'COMPAREFLOAT !='],
774 \ ['1.1 > 2.2', 'COMPAREFLOAT >'],
775 \ ['1.1 < 2.2', 'COMPAREFLOAT <'],
776 \ ['1.1 >= 2.2', 'COMPAREFLOAT >='],
777 \ ['1.1 <= 2.2', 'COMPAREFLOAT <='],
778 \ ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
779 \ ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
780 \ ])
781 endif
782
783 let nr = 1
784 for case in cases
785 writefile(['def TestCase' .. nr .. '()',
786 \ ' if ' .. case[0],
787 \ ' echo 42'
788 \ ' endif',
789 \ 'enddef'], 'Xdisassemble')
790 source Xdisassemble
791 let instr = execute('disassemble TestCase' .. nr)
792 assert_match('TestCase' .. nr .. '.*'
793 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
794 \ .. '\d \(PUSH\|FUNCREF\).*'
795 \ .. '\d \(PUSH\|FUNCREF\|LOADG\).*'
796 \ .. '\d ' .. case[1] .. '.*'
797 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
798 \, instr)
799
800 nr += 1
801 endfor
802
Bram Moolenaar22da5592020-03-19 14:52:20 +0100803 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100804enddef
805
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200806def Test_disassemble_compare_const()
807 let cases = [
808 \ ['"xx" == "yy"', false],
809 \ ['"aa" == "aa"', true],
Bram Moolenaare8c4abb2020-04-02 21:13:25 +0200810 \ ['has("eval") ? true : false', true],
811 \ ['has("asdf") ? true : false', false],
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200812 \ ]
813
814 let nr = 1
815 for case in cases
816 writefile(['def TestCase' .. nr .. '()',
817 \ ' if ' .. case[0],
818 \ ' echo 42'
819 \ ' endif',
820 \ 'enddef'], 'Xdisassemble')
821 source Xdisassemble
822 let instr = execute('disassemble TestCase' .. nr)
823 if case[1]
824 " condition true, "echo 42" executed
825 assert_match('TestCase' .. nr .. '.*'
826 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
827 \ .. '\d PUSHNR 42.*'
828 \ .. '\d ECHO 1.*'
829 \ .. '\d PUSHNR 0.*'
830 \ .. '\d RETURN.*'
831 \, instr)
832 else
833 " condition false, function just returns
834 assert_match('TestCase' .. nr .. '.*'
835 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*'
836 \ .. 'echo 42[ \n]*'
837 \ .. 'endif[ \n]*'
838 \ .. '\s*\d PUSHNR 0.*'
839 \ .. '\d RETURN.*'
840 \, instr)
841 endif
842
843 nr += 1
844 endfor
845
846 delete('Xdisassemble')
847enddef
848
Bram Moolenaarad39c092020-02-26 18:23:43 +0100849def s:Execute()
850 execute 'help vim9.txt'
851 let cmd = 'help vim9.txt'
852 execute cmd
853 let tag = 'vim9.txt'
854 execute 'help ' .. tag
855enddef
856
857def Test_disassemble_execute()
858 let res = execute('disass s:Execute')
859 assert_match('\<SNR>\d*_Execute.*'
860 \ .. "execute 'help vim9.txt'.*"
861 \ .. '\d PUSHS "help vim9.txt".*'
862 \ .. '\d EXECUTE 1.*'
863 \ .. "let cmd = 'help vim9.txt'.*"
864 \ .. '\d PUSHS "help vim9.txt".*'
865 \ .. '\d STORE $0.*'
866 \ .. 'execute cmd.*'
867 \ .. '\d LOAD $0.*'
868 \ .. '\d EXECUTE 1.*'
869 \ .. "let tag = 'vim9.txt'.*"
870 \ .. '\d PUSHS "vim9.txt".*'
871 \ .. '\d STORE $1.*'
872 \ .. "execute 'help ' .. tag.*"
873 \ .. '\d PUSHS "help ".*'
874 \ .. '\d LOAD $1.*'
875 \ .. '\d CONCAT.*'
876 \ .. '\d EXECUTE 1.*'
877 \ .. '\d PUSHNR 0.*'
878 \ .. '\d RETURN'
879 \, res)
880enddef
881
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100882def SomeStringArg(arg: string)
883 echo arg
884enddef
885
886def SomeAnyArg(arg: any)
887 echo arg
888enddef
889
890def SomeStringArgAndReturn(arg: string): string
891 return arg
892enddef
893
894def Test_display_func()
895 let res1 = execute('function SomeStringArg')
896 assert_match('.* def SomeStringArg(arg: string).*'
897 \ .. ' echo arg.*'
898 \ .. ' enddef'
899 \, res1)
900
901 let res2 = execute('function SomeAnyArg')
902 assert_match('.* def SomeAnyArg(arg: any).*'
903 \ .. ' echo arg.*'
904 \ .. ' enddef'
905 \, res2)
906
907 let res3 = execute('function SomeStringArgAndReturn')
908 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*'
909 \ .. ' return arg.*'
910 \ .. ' enddef'
911 \, res3)
912enddef
913
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100914" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker