blob: 7875e847e7b4fb6e21bafe7fe7afbb1445e0cf86 [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.*'
90 \ .. 'localnr = 2.*'
91 \ .. ' STORE 2 in $0.*'
92 \ .. 'localstr = ''xyz''.*'
93 \ .. ' STORE $1.*'
94 \ .. 'v:char = ''abc''.*'
95 \ .. 'STOREV v:char.*'
96 \ .. 's:scriptvar = ''sv''.*'
97 \ .. ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*'
98 \ .. 'g:globalvar = ''gv''.*'
99 \ .. ' STOREG g:globalvar.*'
100 \ .. '&tabstop = 8.*'
101 \ .. ' STOREOPT &tabstop.*'
102 \ .. '$ENVVAR = ''ev''.*'
103 \ .. ' STOREENV $ENVVAR.*'
104 \ .. '@z = ''rv''.*'
105 \ .. ' STOREREG @z.*'
106 \, res)
107enddef
108
109def s:ScriptFuncTry()
110 try
111 echo 'yes'
112 catch /fail/
113 echo 'no'
114 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100115 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100116 endtry
117enddef
118
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100119def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100120 let res = execute('disass s:ScriptFuncTry')
121 assert_match('<SNR>\d*_ScriptFuncTry.*'
122 \ .. 'try.*'
123 \ .. 'TRY catch -> \d\+, finally -> \d\+.*'
124 \ .. 'catch /fail/.*'
125 \ .. ' JUMP -> \d\+.*'
126 \ .. ' PUSH v:exception.*'
127 \ .. ' PUSHS "fail".*'
128 \ .. ' COMPARESTRING =\~.*'
129 \ .. ' JUMP_IF_FALSE -> \d\+.*'
130 \ .. ' CATCH.*'
131 \ .. 'finally.*'
132 \ .. ' PUSHS "end".*'
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100133 \ .. ' THROW.*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100134 \ .. 'endtry.*'
135 \ .. ' ENDTRY.*'
136 \, res)
137enddef
138
139def s:ScriptFuncNew()
140 let ll = [1, "two", 333]
141 let dd = #{one: 1, two: "val"}
142enddef
143
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100144def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100145 let res = execute('disass s:ScriptFuncNew')
146 assert_match('<SNR>\d*_ScriptFuncNew.*'
147 \ .. 'let ll = \[1, "two", 333].*'
148 \ .. 'PUSHNR 1.*'
149 \ .. 'PUSHS "two".*'
150 \ .. 'PUSHNR 333.*'
151 \ .. 'NEWLIST size 3.*'
152 \ .. 'let dd = #{one: 1, two: "val"}.*'
153 \ .. 'PUSHS "one".*'
154 \ .. 'PUSHNR 1.*'
155 \ .. 'PUSHS "two".*'
156 \ .. 'PUSHS "val".*'
157 \ .. 'NEWDICT size 2.*'
158 \, res)
159enddef
160
161def FuncWithArg(arg)
162 echo arg
163enddef
164
165func UserFunc()
166 echo 'nothing'
167endfunc
168
169func UserFuncWithArg(arg)
170 echo a:arg
171endfunc
172
173def s:ScriptFuncCall(): string
174 changenr()
175 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100176 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100177 FuncWithArg(343)
178 ScriptFuncNew()
179 s:ScriptFuncNew()
180 UserFunc()
181 UserFuncWithArg("foo")
182 let FuncRef = function("UserFunc")
183 FuncRef()
184 let FuncRefWithArg = function("UserFuncWithArg")
185 FuncRefWithArg("bar")
186 return "yes"
187enddef
188
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100189def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100190 let res = execute('disass s:ScriptFuncCall')
191 assert_match('<SNR>\d\+_ScriptFuncCall.*'
192 \ .. 'changenr().*'
193 \ .. ' BCALL changenr(argc 0).*'
194 \ .. 'char2nr("abc").*'
195 \ .. ' PUSHS "abc".*'
196 \ .. ' BCALL char2nr(argc 1).*'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100197 \ .. 'Test_disassemble_new().*'
198 \ .. ' DCALL Test_disassemble_new(argc 0).*'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100199 \ .. 'FuncWithArg(343).*'
200 \ .. ' PUSHNR 343.*'
201 \ .. ' DCALL FuncWithArg(argc 1).*'
202 \ .. 'ScriptFuncNew().*'
203 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
204 \ .. 's:ScriptFuncNew().*'
205 \ .. ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*'
206 \ .. 'UserFunc().*'
207 \ .. ' UCALL UserFunc(argc 0).*'
208 \ .. 'UserFuncWithArg("foo").*'
209 \ .. ' PUSHS "foo".*'
210 \ .. ' UCALL UserFuncWithArg(argc 1).*'
211 \ .. 'let FuncRef = function("UserFunc").*'
212 \ .. 'FuncRef().*'
213 \ .. ' LOAD $\d.*'
214 \ .. ' PCALL (argc 0).*'
215 \ .. 'let FuncRefWithArg = function("UserFuncWithArg").*'
216 \ .. 'FuncRefWithArg("bar").*'
217 \ .. ' PUSHS "bar".*'
218 \ .. ' LOAD $\d.*'
219 \ .. ' PCALL (argc 1).*'
220 \ .. 'return "yes".*'
221 \ .. ' PUSHS "yes".*'
222 \ .. ' RETURN.*'
223 \, res)
224enddef
225
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100226
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100227def FuncWithForwardCall(): string
228 return DefinedLater("yes")
229enddef
230
231def DefinedLater(arg: string): string
232 return arg
233enddef
234
235def Test_disassemble_update_instr()
236 let res = execute('disass FuncWithForwardCall')
237 assert_match('FuncWithForwardCall.*'
238 \ .. 'return DefinedLater("yes").*'
239 \ .. '\d PUSHS "yes".*'
240 \ .. '\d UCALL DefinedLater(argc 1).*'
241 \ .. '\d CHECKTYPE string stack\[-1].*'
242 \ .. '\d RETURN.*'
243 \, res)
244
245 " Calling the function will change UCALL into the faster DCALL
246 assert_equal('yes', FuncWithForwardCall())
247
248 res = execute('disass FuncWithForwardCall')
249 assert_match('FuncWithForwardCall.*'
250 \ .. 'return DefinedLater("yes").*'
251 \ .. '\d PUSHS "yes".*'
252 \ .. '\d DCALL DefinedLater(argc 1).*'
253 \ .. '\d CHECKTYPE string stack\[-1].*'
254 \ .. '\d RETURN.*'
255 \, res)
256enddef
257
258
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100259def FuncWithDefault(arg: string = 'default'): string
260 return arg
261enddef
262
263def Test_disassemble_call_default()
264 let res = execute('disass FuncWithDefault')
265 assert_match('FuncWithDefault.*'
266 \ .. '\d PUSHS "default".*'
267 \ .. '\d STORE arg\[-1].*'
268 \ .. 'return arg.*'
269 \ .. '\d LOAD arg\[-1].*'
270 \ .. '\d RETURN.*'
271 \, res)
272enddef
273
274
Bram Moolenaar158906c2020-02-06 20:39:45 +0100275def HasEval()
276 if has("eval")
277 echo "yes"
278 else
279 echo "no"
280 endif
281enddef
282
283def HasNothing()
284 if has("nothing")
285 echo "yes"
286 else
287 echo "no"
288 endif
289enddef
290
291def HasSomething()
292 if has("nothing")
293 echo "nothing"
294 elseif has("something")
295 echo "something"
296 elseif has("eval")
297 echo "eval"
298 elseif has("less")
299 echo "less"
300 endif
301enddef
302
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100303def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100304 assert_equal("\nyes", execute('call HasEval()'))
305 let instr = execute('disassemble HasEval')
306 assert_match('HasEval.*'
307 \ .. 'if has("eval").*'
308 \ .. ' PUSHS "yes".*'
309 \, instr)
310 assert_notmatch('JUMP', instr)
311
312 assert_equal("\nno", execute('call HasNothing()'))
313 instr = execute('disassemble HasNothing')
314 assert_match('HasNothing.*'
315 \ .. 'if has("nothing").*'
316 \ .. 'else.*'
317 \ .. ' PUSHS "no".*'
318 \, instr)
319 assert_notmatch('PUSHS "yes"', instr)
320 assert_notmatch('JUMP', instr)
321
322 assert_equal("\neval", execute('call HasSomething()'))
323 instr = execute('disassemble HasSomething')
324 assert_match('HasSomething.*'
325 \ .. 'if has("nothing").*'
326 \ .. 'elseif has("something").*'
327 \ .. 'elseif has("eval").*'
328 \ .. ' PUSHS "eval".*'
329 \ .. 'elseif has("less").*'
330 \, instr)
331 assert_notmatch('PUSHS "nothing"', instr)
332 assert_notmatch('PUSHS "something"', instr)
333 assert_notmatch('PUSHS "less"', instr)
334 assert_notmatch('JUMP', instr)
335enddef
336
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100337def WithFunc()
338 let funky1: func
339 let funky2: func = function("len")
340 let party1: partial
341 let party2: partial = funcref("UserFunc")
342enddef
343
344def Test_disassemble_function()
345 let instr = execute('disassemble WithFunc')
346 assert_match('WithFunc.*'
347 \ .. 'let funky1: func.*'
348 \ .. '0 PUSHFUNC "\[none]".*'
349 \ .. '1 STORE $0.*'
350 \ .. 'let funky2: func = function("len").*'
351 \ .. '2 PUSHS "len".*'
352 \ .. '3 BCALL function(argc 1).*'
353 \ .. '4 STORE $1.*'
354 \ .. 'let party1: partial.*'
355 \ .. '5 PUSHPARTIAL "\[none]".*'
356 \ .. '6 STORE $2.*'
357 \ .. 'let party2: partial = funcref("UserFunc").*'
358 \ .. '7 PUSHS "UserFunc".*'
359 \ .. '8 BCALL funcref(argc 1).*'
360 \ .. '9 STORE $3.*'
361 \ .. '10 PUSHNR 0.*'
362 \ .. '11 RETURN.*'
363 \, instr)
364enddef
365
366if has('channel')
367 def WithChannel()
368 let job1: job
369 let job2: job = job_start("donothing")
370 let chan1: channel
371 enddef
372endif
373
374def Test_disassemble_channel()
375 CheckFeature channel
376
377 let instr = execute('disassemble WithChannel')
378 assert_match('WithChannel.*'
379 \ .. 'let job1: job.*'
380 \ .. '\d PUSHJOB "no process".*'
381 \ .. '\d STORE $0.*'
382 \ .. 'let job2: job = job_start("donothing").*'
383 \ .. '\d PUSHS "donothing".*'
384 \ .. '\d BCALL job_start(argc 1).*'
385 \ .. '\d STORE $1.*'
386 \ .. 'let chan1: channel.*'
387 \ .. '\d PUSHCHANNEL 0.*'
388 \ .. '\d STORE $2.*'
389 \ .. '\d PUSHNR 0.*'
390 \ .. '\d RETURN.*'
391 \, instr)
392enddef
393
Bram Moolenaar777770f2020-02-06 21:27:08 +0100394def WithLambda(): string
395 let F = {a -> "X" .. a .. "X"}
396 return F("x")
397enddef
398
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100399def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100400 assert_equal("XxX", WithLambda())
401 let instr = execute('disassemble WithLambda')
402 assert_match('WithLambda.*'
403 \ .. 'let F = {a -> "X" .. a .. "X"}.*'
404 \ .. ' FUNCREF <lambda>\d\+.*'
405 \ .. 'PUSHS "x".*'
406 \ .. ' LOAD $0.*'
407 \ .. ' PCALL (argc 1).*'
408 \ .. ' CHECKTYPE string stack\[-1].*'
409 \, instr)
410enddef
411
412def AndOr(arg): string
413 if arg == 1 && arg != 2 || arg == 4
414 return 'yes'
415 endif
416 return 'no'
417enddef
418
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100419def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100420 assert_equal("yes", AndOr(1))
421 assert_equal("no", AndOr(2))
422 assert_equal("yes", AndOr(4))
423 let instr = execute('disassemble AndOr')
424 assert_match('AndOr.*'
425 \ .. 'if arg == 1 && arg != 2 || arg == 4.*'
426 \ .. '\d LOAD arg\[-1].*'
427 \ .. '\d PUSHNR 1.*'
428 \ .. '\d COMPAREANY ==.*'
429 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*'
430 \ .. '\d LOAD arg\[-1].*'
431 \ .. '\d PUSHNR 2.*'
432 \ .. '\d COMPAREANY !=.*'
433 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*'
434 \ .. '\d LOAD arg\[-1].*'
435 \ .. '\d PUSHNR 4.*'
436 \ .. '\d COMPAREANY ==.*'
437 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
438 \, instr)
439enddef
440
Bram Moolenaar04d05222020-02-06 22:06:54 +0100441def ForLoop(): list<number>
442 let res: list<number>
443 for i in range(3)
444 res->add(i)
445 endfor
446 return res
447enddef
448
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100449def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100450 assert_equal([0, 1, 2], ForLoop())
451 let instr = execute('disassemble ForLoop')
452 assert_match('ForLoop.*'
453 \ .. 'let res: list<number>.*'
454 \ .. ' NEWLIST size 0.*'
455 \ .. '\d STORE $0.*'
456 \ .. 'for i in range(3).*'
457 \ .. '\d STORE -1 in $1.*'
458 \ .. '\d PUSHNR 3.*'
459 \ .. '\d BCALL range(argc 1).*'
460 \ .. '\d FOR $1 -> \d\+.*'
461 \ .. '\d STORE $2.*'
462 \ .. 'res->add(i).*'
463 \ .. '\d LOAD $0.*'
464 \ .. '\d LOAD $2.*'
465 \ .. '\d BCALL add(argc 2).*'
466 \ .. '\d DROP.*'
467 \ .. 'endfor.*'
468 \ .. '\d JUMP -> \d\+.*'
469 \ .. '\d DROP.*'
470 \, instr)
471enddef
472
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100473let g:number = 42
474
475def Computing()
476 let nr = 3
477 let nrres = nr + 7
478 nrres = nr - 7
479 nrres = nr * 7
480 nrres = nr / 7
481 nrres = nr % 7
482
483 let anyres = g:number + 7
484 anyres = g:number - 7
485 anyres = g:number * 7
486 anyres = g:number / 7
487 anyres = g:number % 7
488
489 if has('float')
490 let fl = 3.0
491 let flres = fl + 7.0
492 flres = fl - 7.0
493 flres = fl * 7.0
494 flres = fl / 7.0
495 endif
496enddef
497
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100498def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100499 let instr = execute('disassemble Computing')
500 assert_match('Computing.*'
501 \ .. 'let nr = 3.*'
502 \ .. '\d STORE 3 in $0.*'
503 \ .. 'let nrres = nr + 7.*'
504 \ .. '\d LOAD $0.*'
505 \ .. '\d PUSHNR 7.*'
506 \ .. '\d OPNR +.*'
507 \ .. '\d STORE $1.*'
508 \ .. 'nrres = nr - 7.*'
509 \ .. '\d OPNR -.*'
510 \ .. 'nrres = nr \* 7.*'
511 \ .. '\d OPNR \*.*'
512 \ .. 'nrres = nr / 7.*'
513 \ .. '\d OPNR /.*'
514 \ .. 'nrres = nr % 7.*'
515 \ .. '\d OPNR %.*'
516 \ .. 'let anyres = g:number + 7.*'
517 \ .. '\d LOADG g:number.*'
518 \ .. '\d PUSHNR 7.*'
519 \ .. '\d OPANY +.*'
520 \ .. '\d STORE $2.*'
521 \ .. 'anyres = g:number - 7.*'
522 \ .. '\d OPANY -.*'
523 \ .. 'anyres = g:number \* 7.*'
524 \ .. '\d OPANY \*.*'
525 \ .. 'anyres = g:number / 7.*'
526 \ .. '\d OPANY /.*'
527 \ .. 'anyres = g:number % 7.*'
528 \ .. '\d OPANY %.*'
529 \, instr)
530 if has('float')
531 assert_match('Computing.*'
532 \ .. 'let fl = 3.0.*'
533 \ .. '\d PUSHF 3.0.*'
534 \ .. '\d STORE $3.*'
535 \ .. 'let flres = fl + 7.0.*'
536 \ .. '\d LOAD $3.*'
537 \ .. '\d PUSHF 7.0.*'
538 \ .. '\d OPFLOAT +.*'
539 \ .. '\d STORE $4.*'
540 \ .. 'flres = fl - 7.0.*'
541 \ .. '\d OPFLOAT -.*'
542 \ .. 'flres = fl \* 7.0.*'
543 \ .. '\d OPFLOAT \*.*'
544 \ .. 'flres = fl / 7.0.*'
545 \ .. '\d OPFLOAT /.*'
546 \, instr)
547 endif
548enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100549
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100550def AddListBlob()
551 let reslist = [1, 2] + [3, 4]
552 let resblob = 0z1122 + 0z3344
553enddef
554
555def Test_disassemble_add_list_blob()
556 let instr = execute('disassemble AddListBlob')
557 assert_match('AddListBlob.*'
558 \ .. 'let reslist = \[1, 2] + \[3, 4].*'
559 \ .. '\d PUSHNR 1.*'
560 \ .. '\d PUSHNR 2.*'
561 \ .. '\d NEWLIST size 2.*'
562 \ .. '\d PUSHNR 3.*'
563 \ .. '\d PUSHNR 4.*'
564 \ .. '\d NEWLIST size 2.*'
565 \ .. '\d ADDLIST.*'
566 \ .. '\d STORE $.*.*'
567 \ .. 'let resblob = 0z1122 + 0z3344.*'
568 \ .. '\d PUSHBLOB 0z1122.*'
569 \ .. '\d PUSHBLOB 0z3344.*'
570 \ .. '\d ADDBLOB.*'
571 \ .. '\d STORE $.*'
572 \, instr)
573enddef
574
575let g:aa = 'aa'
576def ConcatString(): string
577 let res = g:aa .. "bb"
578 return res
579enddef
580
581def Test_disassemble_concat()
582 let instr = execute('disassemble ConcatString')
583 assert_match('ConcatString.*'
584 \ .. 'let res = g:aa .. "bb".*'
585 \ .. '\d LOADG g:aa.*'
586 \ .. '\d PUSHS "bb".*'
587 \ .. '\d 2STRING stack\[-2].*'
588 \ .. '\d CONCAT.*'
589 \ .. '\d STORE $.*'
590 \, instr)
591 assert_equal('aabb', ConcatString())
592enddef
593
594def ListIndex(): number
595 let l = [1, 2, 3]
596 let res = l[1]
597 return res
598enddef
599
600def Test_disassemble_list_index()
601 let instr = execute('disassemble ListIndex')
602 assert_match('ListIndex.*'
603 \ .. 'let l = \[1, 2, 3].*'
604 \ .. '\d PUSHNR 1.*'
605 \ .. '\d PUSHNR 2.*'
606 \ .. '\d PUSHNR 3.*'
607 \ .. '\d NEWLIST size 3.*'
608 \ .. '\d STORE $0.*'
609 \ .. 'let res = l\[1].*'
610 \ .. '\d LOAD $0.*'
611 \ .. '\d PUSHNR 1.*'
612 \ .. '\d INDEX.*'
613 \ .. '\d STORE $1.*'
614 \, instr)
615 assert_equal(2, ListIndex())
616enddef
617
618def DictMember(): number
619 let d = #{item: 1}
620 let res = d.item
621 return res
622enddef
623
624def Test_disassemble_dict_member()
625 let instr = execute('disassemble DictMember')
626 assert_match('DictMember.*'
627 \ .. 'let d = #{item: 1}.*'
628 \ .. '\d PUSHS "item".*'
629 \ .. '\d PUSHNR 1.*'
630 \ .. '\d NEWDICT size 1.*'
631 \ .. '\d STORE $0.*'
632 \ .. 'let res = d.item.*'
633 \ .. '\d LOAD $0.*'
634 \ .. '\d MEMBER item.*'
635 \ .. '\d STORE $1.*'
636 \, instr)
637 call assert_equal(1, DictMember())
638enddef
639
640def NegateNumber(): number
641 let nr = 9
642 let plus = +nr
643 let res = -nr
644 return res
645enddef
646
647def Test_disassemble_negate_number()
648 let instr = execute('disassemble NegateNumber')
649 assert_match('NegateNumber.*'
650 \ .. 'let nr = 9.*'
651 \ .. '\d STORE 9 in $0.*'
652 \ .. 'let plus = +nr.*'
653 \ .. '\d LOAD $0.*'
654 \ .. '\d CHECKNR.*'
655 \ .. '\d STORE $1.*'
656 \ .. 'let res = -nr.*'
657 \ .. '\d LOAD $0.*'
658 \ .. '\d NEGATENR.*'
659 \ .. '\d STORE $2.*'
660 \, instr)
661 call assert_equal(-9, NegateNumber())
662enddef
663
664def InvertBool(): bool
665 let flag = true
666 let invert = !flag
667 let res = !!flag
668 return res
669enddef
670
671def Test_disassemble_invert_bool()
672 let instr = execute('disassemble InvertBool')
673 assert_match('InvertBool.*'
674 \ .. 'let flag = true.*'
675 \ .. '\d PUSH v:true.*'
676 \ .. '\d STORE $0.*'
677 \ .. 'let invert = !flag.*'
678 \ .. '\d LOAD $0.*'
679 \ .. '\d INVERT (!val).*'
680 \ .. '\d STORE $1.*'
681 \ .. 'let res = !!flag.*'
682 \ .. '\d LOAD $0.*'
683 \ .. '\d 2BOOL (!!val).*'
684 \ .. '\d STORE $2.*'
685 \, instr)
686 call assert_equal(true, InvertBool())
687enddef
688
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100689def Test_disassemble_compare()
690 " TODO: COMPAREFUNC
691 let cases = [
692 \ ['true == false', 'COMPAREBOOL =='],
693 \ ['true != false', 'COMPAREBOOL !='],
694 \ ['v:none == v:null', 'COMPARESPECIAL =='],
695 \ ['v:none != v:null', 'COMPARESPECIAL !='],
696 \
697 \ ['111 == 222', 'COMPARENR =='],
698 \ ['111 != 222', 'COMPARENR !='],
699 \ ['111 > 222', 'COMPARENR >'],
700 \ ['111 < 222', 'COMPARENR <'],
701 \ ['111 >= 222', 'COMPARENR >='],
702 \ ['111 <= 222', 'COMPARENR <='],
703 \ ['111 =~ 222', 'COMPARENR =\~'],
704 \ ['111 !~ 222', 'COMPARENR !\~'],
705 \
706 \ ['"xx" == "yy"', 'COMPARESTRING =='],
707 \ ['"xx" != "yy"', 'COMPARESTRING !='],
708 \ ['"xx" > "yy"', 'COMPARESTRING >'],
709 \ ['"xx" < "yy"', 'COMPARESTRING <'],
710 \ ['"xx" >= "yy"', 'COMPARESTRING >='],
711 \ ['"xx" <= "yy"', 'COMPARESTRING <='],
712 \ ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
713 \ ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
714 \ ['"xx" is "yy"', 'COMPARESTRING is'],
715 \ ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
716 \
717 \ ['0z11 == 0z22', 'COMPAREBLOB =='],
718 \ ['0z11 != 0z22', 'COMPAREBLOB !='],
719 \ ['0z11 is 0z22', 'COMPAREBLOB is'],
720 \ ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
721 \
722 \ ['[1,2] == [3,4]', 'COMPARELIST =='],
723 \ ['[1,2] != [3,4]', 'COMPARELIST !='],
724 \ ['[1,2] is [3,4]', 'COMPARELIST is'],
725 \ ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
726 \
727 \ ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
728 \ ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
729 \ ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
730 \ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
731 \
732 \ ['{->33} == {->44}', 'COMPAREPARTIAL =='],
733 \ ['{->33} != {->44}', 'COMPAREPARTIAL !='],
734 \ ['{->33} is {->44}', 'COMPAREPARTIAL is'],
735 \ ['{->33} isnot {->44}', 'COMPAREPARTIAL isnot'],
736 \
737 \ ['77 == g:xx', 'COMPAREANY =='],
738 \ ['77 != g:xx', 'COMPAREANY !='],
739 \ ['77 > g:xx', 'COMPAREANY >'],
740 \ ['77 < g:xx', 'COMPAREANY <'],
741 \ ['77 >= g:xx', 'COMPAREANY >='],
742 \ ['77 <= g:xx', 'COMPAREANY <='],
743 \ ['77 =~ g:xx', 'COMPAREANY =\~'],
744 \ ['77 !~ g:xx', 'COMPAREANY !\~'],
745 \ ['77 is g:xx', 'COMPAREANY is'],
746 \ ['77 isnot g:xx', 'COMPAREANY isnot'],
747 \ ]
748 if has('float')
749 cases->extend([
750 \ ['1.1 == 2.2', 'COMPAREFLOAT =='],
751 \ ['1.1 != 2.2', 'COMPAREFLOAT !='],
752 \ ['1.1 > 2.2', 'COMPAREFLOAT >'],
753 \ ['1.1 < 2.2', 'COMPAREFLOAT <'],
754 \ ['1.1 >= 2.2', 'COMPAREFLOAT >='],
755 \ ['1.1 <= 2.2', 'COMPAREFLOAT <='],
756 \ ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
757 \ ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
758 \ ])
759 endif
760
761 let nr = 1
762 for case in cases
763 writefile(['def TestCase' .. nr .. '()',
764 \ ' if ' .. case[0],
765 \ ' echo 42'
766 \ ' endif',
767 \ 'enddef'], 'Xdisassemble')
768 source Xdisassemble
769 let instr = execute('disassemble TestCase' .. nr)
770 assert_match('TestCase' .. nr .. '.*'
771 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
772 \ .. '\d \(PUSH\|FUNCREF\).*'
773 \ .. '\d \(PUSH\|FUNCREF\|LOADG\).*'
774 \ .. '\d ' .. case[1] .. '.*'
775 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
776 \, instr)
777
778 nr += 1
779 endfor
780
781 " delete('Xdisassemble')
782enddef
783
Bram Moolenaarad39c092020-02-26 18:23:43 +0100784def s:Execute()
785 execute 'help vim9.txt'
786 let cmd = 'help vim9.txt'
787 execute cmd
788 let tag = 'vim9.txt'
789 execute 'help ' .. tag
790enddef
791
792def Test_disassemble_execute()
793 let res = execute('disass s:Execute')
794 assert_match('\<SNR>\d*_Execute.*'
795 \ .. "execute 'help vim9.txt'.*"
796 \ .. '\d PUSHS "help vim9.txt".*'
797 \ .. '\d EXECUTE 1.*'
798 \ .. "let cmd = 'help vim9.txt'.*"
799 \ .. '\d PUSHS "help vim9.txt".*'
800 \ .. '\d STORE $0.*'
801 \ .. 'execute cmd.*'
802 \ .. '\d LOAD $0.*'
803 \ .. '\d EXECUTE 1.*'
804 \ .. "let tag = 'vim9.txt'.*"
805 \ .. '\d PUSHS "vim9.txt".*'
806 \ .. '\d STORE $1.*'
807 \ .. "execute 'help ' .. tag.*"
808 \ .. '\d PUSHS "help ".*'
809 \ .. '\d LOAD $1.*'
810 \ .. '\d CONCAT.*'
811 \ .. '\d EXECUTE 1.*'
812 \ .. '\d PUSHNR 0.*'
813 \ .. '\d RETURN'
814 \, res)
815enddef
816
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100817" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker