blob: e71782b970559b0e78fda552ba07f1e822d056c0 [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 Moolenaarbd5da372020-03-31 23:13:10 +0200227def EchoArg(arg: string): string
228 return arg
229enddef
230def RefThis(): func
231 return function('EchoArg')
232enddef
233def s:ScriptPCall()
234 RefThis()("text")
235enddef
236
237def Test_disassemble_pcall()
238 let res = execute('disass s:ScriptPCall')
239 assert_match('<SNR>\d\+_ScriptPCall.*'
240 \ .. 'RefThis()("text").*'
241 \ .. '\d DCALL RefThis(argc 0).*'
242 \ .. '\d PUSHS "text".*'
243 \ .. '\d PCALL top (argc 1).*'
244 \ .. '\d PCALL end.*'
245 \ .. '\d DROP.*'
246 \ .. '\d PUSHNR 0.*'
247 \ .. '\d RETURN.*'
248 \, res)
249enddef
250
251
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100252def FuncWithForwardCall(): string
253 return DefinedLater("yes")
254enddef
255
256def DefinedLater(arg: string): string
257 return arg
258enddef
259
260def Test_disassemble_update_instr()
261 let res = execute('disass FuncWithForwardCall')
262 assert_match('FuncWithForwardCall.*'
263 \ .. 'return DefinedLater("yes").*'
264 \ .. '\d PUSHS "yes".*'
265 \ .. '\d UCALL DefinedLater(argc 1).*'
266 \ .. '\d CHECKTYPE string stack\[-1].*'
267 \ .. '\d RETURN.*'
268 \, res)
269
270 " Calling the function will change UCALL into the faster DCALL
271 assert_equal('yes', FuncWithForwardCall())
272
273 res = execute('disass FuncWithForwardCall')
274 assert_match('FuncWithForwardCall.*'
275 \ .. 'return DefinedLater("yes").*'
276 \ .. '\d PUSHS "yes".*'
277 \ .. '\d DCALL DefinedLater(argc 1).*'
278 \ .. '\d CHECKTYPE string stack\[-1].*'
279 \ .. '\d RETURN.*'
280 \, res)
281enddef
282
283
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100284def FuncWithDefault(arg: string = 'default'): string
285 return arg
286enddef
287
288def Test_disassemble_call_default()
289 let res = execute('disass FuncWithDefault')
290 assert_match('FuncWithDefault.*'
291 \ .. '\d PUSHS "default".*'
292 \ .. '\d STORE arg\[-1].*'
293 \ .. 'return arg.*'
294 \ .. '\d LOAD arg\[-1].*'
295 \ .. '\d RETURN.*'
296 \, res)
297enddef
298
299
Bram Moolenaar158906c2020-02-06 20:39:45 +0100300def HasEval()
301 if has("eval")
302 echo "yes"
303 else
304 echo "no"
305 endif
306enddef
307
308def HasNothing()
309 if has("nothing")
310 echo "yes"
311 else
312 echo "no"
313 endif
314enddef
315
316def HasSomething()
317 if has("nothing")
318 echo "nothing"
319 elseif has("something")
320 echo "something"
321 elseif has("eval")
322 echo "eval"
323 elseif has("less")
324 echo "less"
325 endif
326enddef
327
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100328def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100329 assert_equal("\nyes", execute('call HasEval()'))
330 let instr = execute('disassemble HasEval')
331 assert_match('HasEval.*'
332 \ .. 'if has("eval").*'
333 \ .. ' PUSHS "yes".*'
334 \, instr)
335 assert_notmatch('JUMP', instr)
336
337 assert_equal("\nno", execute('call HasNothing()'))
338 instr = execute('disassemble HasNothing')
339 assert_match('HasNothing.*'
340 \ .. 'if has("nothing").*'
341 \ .. 'else.*'
342 \ .. ' PUSHS "no".*'
343 \, instr)
344 assert_notmatch('PUSHS "yes"', instr)
345 assert_notmatch('JUMP', instr)
346
347 assert_equal("\neval", execute('call HasSomething()'))
348 instr = execute('disassemble HasSomething')
349 assert_match('HasSomething.*'
350 \ .. 'if has("nothing").*'
351 \ .. 'elseif has("something").*'
352 \ .. 'elseif has("eval").*'
353 \ .. ' PUSHS "eval".*'
354 \ .. 'elseif has("less").*'
355 \, instr)
356 assert_notmatch('PUSHS "nothing"', instr)
357 assert_notmatch('PUSHS "something"', instr)
358 assert_notmatch('PUSHS "less"', instr)
359 assert_notmatch('JUMP', instr)
360enddef
361
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100362def WithFunc()
363 let funky1: func
364 let funky2: func = function("len")
Bram Moolenaard77a8522020-04-03 21:59:57 +0200365 let party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100366enddef
367
368def Test_disassemble_function()
369 let instr = execute('disassemble WithFunc')
370 assert_match('WithFunc.*'
371 \ .. 'let funky1: func.*'
372 \ .. '0 PUSHFUNC "\[none]".*'
373 \ .. '1 STORE $0.*'
374 \ .. 'let funky2: func = function("len").*'
375 \ .. '2 PUSHS "len".*'
376 \ .. '3 BCALL function(argc 1).*'
377 \ .. '4 STORE $1.*'
Bram Moolenaard77a8522020-04-03 21:59:57 +0200378 \ .. 'let party2: func = funcref("UserFunc").*'
379 \ .. '\d PUSHS "UserFunc".*'
380 \ .. '\d BCALL funcref(argc 1).*'
381 \ .. '\d STORE $2.*'
382 \ .. '\d PUSHNR 0.*'
383 \ .. '\d RETURN.*'
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100384 \, instr)
385enddef
386
387if has('channel')
388 def WithChannel()
389 let job1: job
390 let job2: job = job_start("donothing")
391 let chan1: channel
392 enddef
393endif
394
395def Test_disassemble_channel()
396 CheckFeature channel
397
398 let instr = execute('disassemble WithChannel')
399 assert_match('WithChannel.*'
400 \ .. 'let job1: job.*'
401 \ .. '\d PUSHJOB "no process".*'
402 \ .. '\d STORE $0.*'
403 \ .. 'let job2: job = job_start("donothing").*'
404 \ .. '\d PUSHS "donothing".*'
405 \ .. '\d BCALL job_start(argc 1).*'
406 \ .. '\d STORE $1.*'
407 \ .. 'let chan1: channel.*'
408 \ .. '\d PUSHCHANNEL 0.*'
409 \ .. '\d STORE $2.*'
410 \ .. '\d PUSHNR 0.*'
411 \ .. '\d RETURN.*'
412 \, instr)
413enddef
414
Bram Moolenaar777770f2020-02-06 21:27:08 +0100415def WithLambda(): string
416 let F = {a -> "X" .. a .. "X"}
417 return F("x")
418enddef
419
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100420def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100421 assert_equal("XxX", WithLambda())
422 let instr = execute('disassemble WithLambda')
423 assert_match('WithLambda.*'
424 \ .. 'let F = {a -> "X" .. a .. "X"}.*'
425 \ .. ' FUNCREF <lambda>\d\+.*'
426 \ .. 'PUSHS "x".*'
427 \ .. ' LOAD $0.*'
428 \ .. ' PCALL (argc 1).*'
429 \ .. ' CHECKTYPE string stack\[-1].*'
430 \, instr)
431enddef
432
433def AndOr(arg): string
434 if arg == 1 && arg != 2 || arg == 4
435 return 'yes'
436 endif
437 return 'no'
438enddef
439
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100440def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100441 assert_equal("yes", AndOr(1))
442 assert_equal("no", AndOr(2))
443 assert_equal("yes", AndOr(4))
444 let instr = execute('disassemble AndOr')
445 assert_match('AndOr.*'
446 \ .. 'if arg == 1 && arg != 2 || arg == 4.*'
447 \ .. '\d LOAD arg\[-1].*'
448 \ .. '\d PUSHNR 1.*'
449 \ .. '\d COMPAREANY ==.*'
450 \ .. '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*'
451 \ .. '\d LOAD arg\[-1].*'
452 \ .. '\d PUSHNR 2.*'
453 \ .. '\d COMPAREANY !=.*'
454 \ .. '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*'
455 \ .. '\d LOAD arg\[-1].*'
456 \ .. '\d PUSHNR 4.*'
457 \ .. '\d COMPAREANY ==.*'
458 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
459 \, instr)
460enddef
461
Bram Moolenaar04d05222020-02-06 22:06:54 +0100462def ForLoop(): list<number>
463 let res: list<number>
464 for i in range(3)
465 res->add(i)
466 endfor
467 return res
468enddef
469
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100470def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100471 assert_equal([0, 1, 2], ForLoop())
472 let instr = execute('disassemble ForLoop')
473 assert_match('ForLoop.*'
474 \ .. 'let res: list<number>.*'
475 \ .. ' NEWLIST size 0.*'
476 \ .. '\d STORE $0.*'
477 \ .. 'for i in range(3).*'
478 \ .. '\d STORE -1 in $1.*'
479 \ .. '\d PUSHNR 3.*'
480 \ .. '\d BCALL range(argc 1).*'
481 \ .. '\d FOR $1 -> \d\+.*'
482 \ .. '\d STORE $2.*'
483 \ .. 'res->add(i).*'
484 \ .. '\d LOAD $0.*'
485 \ .. '\d LOAD $2.*'
486 \ .. '\d BCALL add(argc 2).*'
487 \ .. '\d DROP.*'
488 \ .. 'endfor.*'
489 \ .. '\d JUMP -> \d\+.*'
490 \ .. '\d DROP.*'
491 \, instr)
492enddef
493
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100494let g:number = 42
495
496def Computing()
497 let nr = 3
498 let nrres = nr + 7
499 nrres = nr - 7
500 nrres = nr * 7
501 nrres = nr / 7
502 nrres = nr % 7
503
504 let anyres = g:number + 7
505 anyres = g:number - 7
506 anyres = g:number * 7
507 anyres = g:number / 7
508 anyres = g:number % 7
509
510 if has('float')
511 let fl = 3.0
512 let flres = fl + 7.0
513 flres = fl - 7.0
514 flres = fl * 7.0
515 flres = fl / 7.0
516 endif
517enddef
518
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100519def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100520 let instr = execute('disassemble Computing')
521 assert_match('Computing.*'
522 \ .. 'let nr = 3.*'
523 \ .. '\d STORE 3 in $0.*'
524 \ .. 'let nrres = nr + 7.*'
525 \ .. '\d LOAD $0.*'
526 \ .. '\d PUSHNR 7.*'
527 \ .. '\d OPNR +.*'
528 \ .. '\d STORE $1.*'
529 \ .. 'nrres = nr - 7.*'
530 \ .. '\d OPNR -.*'
531 \ .. 'nrres = nr \* 7.*'
532 \ .. '\d OPNR \*.*'
533 \ .. 'nrres = nr / 7.*'
534 \ .. '\d OPNR /.*'
535 \ .. 'nrres = nr % 7.*'
536 \ .. '\d OPNR %.*'
537 \ .. 'let anyres = g:number + 7.*'
538 \ .. '\d LOADG g:number.*'
539 \ .. '\d PUSHNR 7.*'
540 \ .. '\d OPANY +.*'
541 \ .. '\d STORE $2.*'
542 \ .. 'anyres = g:number - 7.*'
543 \ .. '\d OPANY -.*'
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 \, instr)
551 if has('float')
552 assert_match('Computing.*'
553 \ .. 'let fl = 3.0.*'
554 \ .. '\d PUSHF 3.0.*'
555 \ .. '\d STORE $3.*'
556 \ .. 'let flres = fl + 7.0.*'
557 \ .. '\d LOAD $3.*'
558 \ .. '\d PUSHF 7.0.*'
559 \ .. '\d OPFLOAT +.*'
560 \ .. '\d STORE $4.*'
561 \ .. 'flres = fl - 7.0.*'
562 \ .. '\d OPFLOAT -.*'
563 \ .. 'flres = fl \* 7.0.*'
564 \ .. '\d OPFLOAT \*.*'
565 \ .. 'flres = fl / 7.0.*'
566 \ .. '\d OPFLOAT /.*'
567 \, instr)
568 endif
569enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100570
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100571def AddListBlob()
572 let reslist = [1, 2] + [3, 4]
573 let resblob = 0z1122 + 0z3344
574enddef
575
576def Test_disassemble_add_list_blob()
577 let instr = execute('disassemble AddListBlob')
578 assert_match('AddListBlob.*'
579 \ .. 'let reslist = \[1, 2] + \[3, 4].*'
580 \ .. '\d PUSHNR 1.*'
581 \ .. '\d PUSHNR 2.*'
582 \ .. '\d NEWLIST size 2.*'
583 \ .. '\d PUSHNR 3.*'
584 \ .. '\d PUSHNR 4.*'
585 \ .. '\d NEWLIST size 2.*'
586 \ .. '\d ADDLIST.*'
587 \ .. '\d STORE $.*.*'
588 \ .. 'let resblob = 0z1122 + 0z3344.*'
589 \ .. '\d PUSHBLOB 0z1122.*'
590 \ .. '\d PUSHBLOB 0z3344.*'
591 \ .. '\d ADDBLOB.*'
592 \ .. '\d STORE $.*'
593 \, instr)
594enddef
595
596let g:aa = 'aa'
597def ConcatString(): string
598 let res = g:aa .. "bb"
599 return res
600enddef
601
602def Test_disassemble_concat()
603 let instr = execute('disassemble ConcatString')
604 assert_match('ConcatString.*'
605 \ .. 'let res = g:aa .. "bb".*'
606 \ .. '\d LOADG g:aa.*'
607 \ .. '\d PUSHS "bb".*'
608 \ .. '\d 2STRING stack\[-2].*'
609 \ .. '\d CONCAT.*'
610 \ .. '\d STORE $.*'
611 \, instr)
612 assert_equal('aabb', ConcatString())
613enddef
614
615def ListIndex(): number
616 let l = [1, 2, 3]
617 let res = l[1]
618 return res
619enddef
620
621def Test_disassemble_list_index()
622 let instr = execute('disassemble ListIndex')
623 assert_match('ListIndex.*'
624 \ .. 'let l = \[1, 2, 3].*'
625 \ .. '\d PUSHNR 1.*'
626 \ .. '\d PUSHNR 2.*'
627 \ .. '\d PUSHNR 3.*'
628 \ .. '\d NEWLIST size 3.*'
629 \ .. '\d STORE $0.*'
630 \ .. 'let res = l\[1].*'
631 \ .. '\d LOAD $0.*'
632 \ .. '\d PUSHNR 1.*'
633 \ .. '\d INDEX.*'
634 \ .. '\d STORE $1.*'
635 \, instr)
636 assert_equal(2, ListIndex())
637enddef
638
639def DictMember(): number
640 let d = #{item: 1}
641 let res = d.item
642 return res
643enddef
644
645def Test_disassemble_dict_member()
646 let instr = execute('disassemble DictMember')
647 assert_match('DictMember.*'
648 \ .. 'let d = #{item: 1}.*'
649 \ .. '\d PUSHS "item".*'
650 \ .. '\d PUSHNR 1.*'
651 \ .. '\d NEWDICT size 1.*'
652 \ .. '\d STORE $0.*'
653 \ .. 'let res = d.item.*'
654 \ .. '\d LOAD $0.*'
655 \ .. '\d MEMBER item.*'
656 \ .. '\d STORE $1.*'
657 \, instr)
658 call assert_equal(1, DictMember())
659enddef
660
661def NegateNumber(): number
662 let nr = 9
663 let plus = +nr
664 let res = -nr
665 return res
666enddef
667
668def Test_disassemble_negate_number()
669 let instr = execute('disassemble NegateNumber')
670 assert_match('NegateNumber.*'
671 \ .. 'let nr = 9.*'
672 \ .. '\d STORE 9 in $0.*'
673 \ .. 'let plus = +nr.*'
674 \ .. '\d LOAD $0.*'
675 \ .. '\d CHECKNR.*'
676 \ .. '\d STORE $1.*'
677 \ .. 'let res = -nr.*'
678 \ .. '\d LOAD $0.*'
679 \ .. '\d NEGATENR.*'
680 \ .. '\d STORE $2.*'
681 \, instr)
682 call assert_equal(-9, NegateNumber())
683enddef
684
685def InvertBool(): bool
686 let flag = true
687 let invert = !flag
688 let res = !!flag
689 return res
690enddef
691
692def Test_disassemble_invert_bool()
693 let instr = execute('disassemble InvertBool')
694 assert_match('InvertBool.*'
695 \ .. 'let flag = true.*'
696 \ .. '\d PUSH v:true.*'
697 \ .. '\d STORE $0.*'
698 \ .. 'let invert = !flag.*'
699 \ .. '\d LOAD $0.*'
700 \ .. '\d INVERT (!val).*'
701 \ .. '\d STORE $1.*'
702 \ .. 'let res = !!flag.*'
703 \ .. '\d LOAD $0.*'
704 \ .. '\d 2BOOL (!!val).*'
705 \ .. '\d STORE $2.*'
706 \, instr)
707 call assert_equal(true, InvertBool())
708enddef
709
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100710def Test_disassemble_compare()
711 " TODO: COMPAREFUNC
712 let cases = [
713 \ ['true == false', 'COMPAREBOOL =='],
714 \ ['true != false', 'COMPAREBOOL !='],
715 \ ['v:none == v:null', 'COMPARESPECIAL =='],
716 \ ['v:none != v:null', 'COMPARESPECIAL !='],
717 \
718 \ ['111 == 222', 'COMPARENR =='],
719 \ ['111 != 222', 'COMPARENR !='],
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 \
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100727 \ ['"xx" != "yy"', 'COMPARESTRING !='],
728 \ ['"xx" > "yy"', 'COMPARESTRING >'],
729 \ ['"xx" < "yy"', 'COMPARESTRING <'],
730 \ ['"xx" >= "yy"', 'COMPARESTRING >='],
731 \ ['"xx" <= "yy"', 'COMPARESTRING <='],
732 \ ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
733 \ ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
734 \ ['"xx" is "yy"', 'COMPARESTRING is'],
735 \ ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
736 \
737 \ ['0z11 == 0z22', 'COMPAREBLOB =='],
738 \ ['0z11 != 0z22', 'COMPAREBLOB !='],
739 \ ['0z11 is 0z22', 'COMPAREBLOB is'],
740 \ ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
741 \
742 \ ['[1,2] == [3,4]', 'COMPARELIST =='],
743 \ ['[1,2] != [3,4]', 'COMPARELIST !='],
744 \ ['[1,2] is [3,4]', 'COMPARELIST is'],
745 \ ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
746 \
747 \ ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
748 \ ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
749 \ ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
750 \ ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
751 \
Bram Moolenaard77a8522020-04-03 21:59:57 +0200752 \ ['{->33} == {->44}', 'COMPAREFUNC =='],
753 \ ['{->33} != {->44}', 'COMPAREFUNC !='],
754 \ ['{->33} is {->44}', 'COMPAREFUNC is'],
755 \ ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100756 \
757 \ ['77 == g:xx', 'COMPAREANY =='],
758 \ ['77 != g:xx', 'COMPAREANY !='],
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 is g:xx', 'COMPAREANY is'],
766 \ ['77 isnot g:xx', 'COMPAREANY isnot'],
767 \ ]
768 if has('float')
769 cases->extend([
770 \ ['1.1 == 2.2', 'COMPAREFLOAT =='],
771 \ ['1.1 != 2.2', 'COMPAREFLOAT !='],
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 \ ])
779 endif
780
781 let nr = 1
782 for case in cases
783 writefile(['def TestCase' .. nr .. '()',
784 \ ' if ' .. case[0],
785 \ ' echo 42'
786 \ ' endif',
787 \ 'enddef'], 'Xdisassemble')
788 source Xdisassemble
789 let instr = execute('disassemble TestCase' .. nr)
790 assert_match('TestCase' .. nr .. '.*'
791 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
792 \ .. '\d \(PUSH\|FUNCREF\).*'
793 \ .. '\d \(PUSH\|FUNCREF\|LOADG\).*'
794 \ .. '\d ' .. case[1] .. '.*'
795 \ .. '\d JUMP_IF_FALSE -> \d\+.*'
796 \, instr)
797
798 nr += 1
799 endfor
800
Bram Moolenaar22da5592020-03-19 14:52:20 +0100801 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100802enddef
803
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200804def Test_disassemble_compare_const()
805 let cases = [
806 \ ['"xx" == "yy"', false],
807 \ ['"aa" == "aa"', true],
Bram Moolenaare8c4abb2020-04-02 21:13:25 +0200808 \ ['has("eval") ? true : false', true],
809 \ ['has("asdf") ? true : false', false],
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200810 \ ]
811
812 let nr = 1
813 for case in cases
814 writefile(['def TestCase' .. nr .. '()',
815 \ ' if ' .. case[0],
816 \ ' echo 42'
817 \ ' endif',
818 \ 'enddef'], 'Xdisassemble')
819 source Xdisassemble
820 let instr = execute('disassemble TestCase' .. nr)
821 if case[1]
822 " condition true, "echo 42" executed
823 assert_match('TestCase' .. nr .. '.*'
824 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*'
825 \ .. '\d PUSHNR 42.*'
826 \ .. '\d ECHO 1.*'
827 \ .. '\d PUSHNR 0.*'
828 \ .. '\d RETURN.*'
829 \, instr)
830 else
831 " condition false, function just returns
832 assert_match('TestCase' .. nr .. '.*'
833 \ .. 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*'
834 \ .. 'echo 42[ \n]*'
835 \ .. 'endif[ \n]*'
836 \ .. '\s*\d PUSHNR 0.*'
837 \ .. '\d RETURN.*'
838 \, instr)
839 endif
840
841 nr += 1
842 endfor
843
844 delete('Xdisassemble')
845enddef
846
Bram Moolenaarad39c092020-02-26 18:23:43 +0100847def s:Execute()
848 execute 'help vim9.txt'
849 let cmd = 'help vim9.txt'
850 execute cmd
851 let tag = 'vim9.txt'
852 execute 'help ' .. tag
853enddef
854
855def Test_disassemble_execute()
856 let res = execute('disass s:Execute')
857 assert_match('\<SNR>\d*_Execute.*'
858 \ .. "execute 'help vim9.txt'.*"
859 \ .. '\d PUSHS "help vim9.txt".*'
860 \ .. '\d EXECUTE 1.*'
861 \ .. "let cmd = 'help vim9.txt'.*"
862 \ .. '\d PUSHS "help vim9.txt".*'
863 \ .. '\d STORE $0.*'
864 \ .. 'execute cmd.*'
865 \ .. '\d LOAD $0.*'
866 \ .. '\d EXECUTE 1.*'
867 \ .. "let tag = 'vim9.txt'.*"
868 \ .. '\d PUSHS "vim9.txt".*'
869 \ .. '\d STORE $1.*'
870 \ .. "execute 'help ' .. tag.*"
871 \ .. '\d PUSHS "help ".*'
872 \ .. '\d LOAD $1.*'
873 \ .. '\d CONCAT.*'
874 \ .. '\d EXECUTE 1.*'
875 \ .. '\d PUSHNR 0.*'
876 \ .. '\d RETURN'
877 \, res)
878enddef
879
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100880def SomeStringArg(arg: string)
881 echo arg
882enddef
883
884def SomeAnyArg(arg: any)
885 echo arg
886enddef
887
888def SomeStringArgAndReturn(arg: string): string
889 return arg
890enddef
891
892def Test_display_func()
893 let res1 = execute('function SomeStringArg')
894 assert_match('.* def SomeStringArg(arg: string).*'
895 \ .. ' echo arg.*'
896 \ .. ' enddef'
897 \, res1)
898
899 let res2 = execute('function SomeAnyArg')
900 assert_match('.* def SomeAnyArg(arg: any).*'
901 \ .. ' echo arg.*'
902 \ .. ' enddef'
903 \, res2)
904
905 let res3 = execute('function SomeStringArgAndReturn')
906 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*'
907 \ .. ' return arg.*'
908 \ .. ' enddef'
909 \, res3)
910enddef
911
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100912" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker