blob: 5c4ecd29077791baaff581ef74def91d97a0f630 [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'
Bram Moolenaard3aac292020-04-19 14:32:17 +020011let b:buffervar = 'b'
12let w:windowvar = 'w'
13let t:tabpagevar = 't'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010014
15def s:ScriptFuncLoad(arg: string)
16 let local = 1
17 buffers
18 echo arg
19 echo local
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020020 echo &lines
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010021 echo v:version
22 echo s:scriptvar
23 echo g:globalvar
Bram Moolenaard3aac292020-04-19 14:32:17 +020024 echo b:buffervar
25 echo w:windowvar
26 echo t:tabpagevar
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010027 echo &tabstop
28 echo $ENVVAR
29 echo @z
30enddef
31
Bram Moolenaarf2460a32020-02-07 22:09:54 +010032def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010033 assert_fails('disass NoFunc', 'E1061:')
34 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010035 assert_fails('disass', 'E471:')
36 assert_fails('disass [', 'E475:')
37 assert_fails('disass 234', 'E475:')
38 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010039
40 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020041 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
42 'buffers.*' ..
43 ' EXEC \+buffers.*' ..
44 ' LOAD arg\[-1\].*' ..
45 ' LOAD $0.*' ..
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020046 ' LOADOPT &lines.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020047 ' LOADV v:version.*' ..
48 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
49 ' LOADG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020050 ' LOADB b:buffervar.*' ..
51 ' LOADW w:windowvar.*' ..
52 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020053 ' LOADENV $ENVVAR.*' ..
54 ' LOADREG @z.*',
55 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010056enddef
57
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020058def s:EditExpand()
59 let filename = "file"
60 let filenr = 123
61 edit the`=filename``=filenr`.txt
62enddef
63
64def Test_disassemble_exec_expr()
65 let res = execute('disass s:EditExpand')
66 assert_match('<SNR>\d*_EditExpand.*' ..
67 ' let filename = "file".*' ..
68 '\d PUSHS "file".*' ..
69 '\d STORE $0.*' ..
70 ' let filenr = 123.*' ..
71 '\d STORE 123 in $1.*' ..
72 ' edit the`=filename``=filenr`.txt.*' ..
73 '\d PUSHS "edit the".*' ..
74 '\d LOAD $0.*' ..
75 '\d LOAD $1.*' ..
76 '\d 2STRING stack\[-1\].*' ..
77 '\d PUSHS ".txt".*' ..
78 '\d EXECCONCAT 4.*' ..
79 '\d PUSHNR 0.*' ..
80 '\d RETURN',
81 res)
82enddef
83
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010084def s:ScriptFuncPush()
85 let localbool = true
86 let localspec = v:none
87 let localblob = 0z1234
88 if has('float')
89 let localfloat = 1.234
90 endif
91enddef
92
Bram Moolenaarf2460a32020-02-07 22:09:54 +010093def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010094 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020095 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
96 'localbool = true.*' ..
97 ' PUSH v:true.*' ..
98 'localspec = v:none.*' ..
99 ' PUSH v:none.*' ..
100 'localblob = 0z1234.*' ..
101 ' PUSHBLOB 0z1234.*',
102 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100103 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200104 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
105 'localfloat = 1.234.*' ..
106 ' PUSHF 1.234.*',
107 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100108 endif
109enddef
110
111def s:ScriptFuncStore()
112 let localnr = 1
113 localnr = 2
114 let localstr = 'abc'
115 localstr = 'xyz'
116 v:char = 'abc'
117 s:scriptvar = 'sv'
118 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200119 b:buffervar = 'bv'
120 w:windowvar = 'wv'
121 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100122 &tabstop = 8
123 $ENVVAR = 'ev'
124 @z = 'rv'
125enddef
126
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100127def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100128 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200129 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
130 'let localnr = 1.*' ..
131 'localnr = 2.*' ..
132 ' STORE 2 in $0.*' ..
133 'let localstr = ''abc''.*' ..
134 'localstr = ''xyz''.*' ..
135 ' STORE $1.*' ..
136 'v:char = ''abc''.*' ..
137 'STOREV v:char.*' ..
138 's:scriptvar = ''sv''.*' ..
139 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
140 'g:globalvar = ''gv''.*' ..
141 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200142 'b:buffervar = ''bv''.*' ..
143 ' STOREB b:buffervar.*' ..
144 'w:windowvar = ''wv''.*' ..
145 ' STOREW w:windowvar.*' ..
146 't:tabpagevar = ''tv''.*' ..
147 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200148 '&tabstop = 8.*' ..
149 ' STOREOPT &tabstop.*' ..
150 '$ENVVAR = ''ev''.*' ..
151 ' STOREENV $ENVVAR.*' ..
152 '@z = ''rv''.*' ..
153 ' STOREREG @z.*',
154 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100155enddef
156
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200157def s:ScriptFuncUnlet()
158 g:somevar = "value"
159 unlet g:somevar
160 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200161 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200162enddef
163
164def Test_disassemble_unlet()
165 let res = execute('disass s:ScriptFuncUnlet')
166 assert_match('<SNR>\d*_ScriptFuncUnlet.*' ..
167 'g:somevar = "value".*' ..
168 '\d PUSHS "value".*' ..
169 '\d STOREG g:somevar.*' ..
170 'unlet g:somevar.*' ..
171 '\d UNLET g:somevar.*' ..
172 'unlet! g:somevar.*' ..
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200173 '\d UNLET! g:somevar.*' ..
174 'unlet $SOMEVAR.*' ..
175 '\d UNLETENV $SOMEVAR.*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200176 res)
177enddef
178
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100179def s:ScriptFuncTry()
180 try
181 echo 'yes'
182 catch /fail/
183 echo 'no'
184 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100185 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100186 endtry
187enddef
188
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100189def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100190 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200191 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
192 'try.*' ..
193 'TRY catch -> \d\+, finally -> \d\+.*' ..
194 'catch /fail/.*' ..
195 ' JUMP -> \d\+.*' ..
196 ' PUSH v:exception.*' ..
197 ' PUSHS "fail".*' ..
198 ' COMPARESTRING =\~.*' ..
199 ' JUMP_IF_FALSE -> \d\+.*' ..
200 ' CATCH.*' ..
201 'finally.*' ..
202 ' PUSHS "end".*' ..
203 ' THROW.*' ..
204 'endtry.*' ..
205 ' ENDTRY.*',
206 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100207enddef
208
209def s:ScriptFuncNew()
210 let ll = [1, "two", 333]
211 let dd = #{one: 1, two: "val"}
212enddef
213
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100214def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100215 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200216 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
217 'let ll = \[1, "two", 333].*' ..
218 'PUSHNR 1.*' ..
219 'PUSHS "two".*' ..
220 'PUSHNR 333.*' ..
221 'NEWLIST size 3.*' ..
222 'let dd = #{one: 1, two: "val"}.*' ..
223 'PUSHS "one".*' ..
224 'PUSHNR 1.*' ..
225 'PUSHS "two".*' ..
226 'PUSHS "val".*' ..
227 'NEWDICT size 2.*',
228 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100229enddef
230
Bram Moolenaar6e949782020-04-13 17:21:00 +0200231def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100232 echo arg
233enddef
234
235func UserFunc()
236 echo 'nothing'
237endfunc
238
239func UserFuncWithArg(arg)
240 echo a:arg
241endfunc
242
243def s:ScriptFuncCall(): string
244 changenr()
245 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100246 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100247 FuncWithArg(343)
248 ScriptFuncNew()
249 s:ScriptFuncNew()
250 UserFunc()
251 UserFuncWithArg("foo")
252 let FuncRef = function("UserFunc")
253 FuncRef()
254 let FuncRefWithArg = function("UserFuncWithArg")
255 FuncRefWithArg("bar")
256 return "yes"
257enddef
258
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100259def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100260 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200261 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
262 'changenr().*' ..
263 ' BCALL changenr(argc 0).*' ..
264 'char2nr("abc").*' ..
265 ' PUSHS "abc".*' ..
266 ' BCALL char2nr(argc 1).*' ..
267 'Test_disassemble_new().*' ..
268 ' DCALL Test_disassemble_new(argc 0).*' ..
269 'FuncWithArg(343).*' ..
270 ' PUSHNR 343.*' ..
271 ' DCALL FuncWithArg(argc 1).*' ..
272 'ScriptFuncNew().*' ..
273 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
274 's:ScriptFuncNew().*' ..
275 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
276 'UserFunc().*' ..
277 ' UCALL UserFunc(argc 0).*' ..
278 'UserFuncWithArg("foo").*' ..
279 ' PUSHS "foo".*' ..
280 ' UCALL UserFuncWithArg(argc 1).*' ..
281 'let FuncRef = function("UserFunc").*' ..
282 'FuncRef().*' ..
283 ' LOAD $\d.*' ..
284 ' PCALL (argc 0).*' ..
285 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
286 'FuncRefWithArg("bar").*' ..
287 ' PUSHS "bar".*' ..
288 ' LOAD $\d.*' ..
289 ' PCALL (argc 1).*' ..
290 'return "yes".*' ..
291 ' PUSHS "yes".*' ..
292 ' RETURN.*',
293 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100294enddef
295
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200296def s:CreateRefs()
297 let local = 'a'
298 def Append(arg: string)
299 local ..= arg
300 enddef
301 g:Append = Append
302 def Get(): string
303 return local
304 enddef
305 g:Get = Get
306enddef
307
308def Test_disassemble_closure()
309 CreateRefs()
310 let res = execute('disass g:Append')
311 assert_match('<lambda>\d.*' ..
312 'local ..= arg.*' ..
313 '\d LOADOUTER $0.*' ..
314 '\d LOAD arg\[-1\].*' ..
315 '\d CONCAT.*' ..
316 '\d STOREOUTER $0.*' ..
317 '\d PUSHNR 0.*' ..
318 '\d RETURN.*',
319 res)
320
321 res = execute('disass g:Get')
322 assert_match('<lambda>\d.*' ..
323 'return local.*' ..
324 '\d LOADOUTER $0.*' ..
325 '\d RETURN.*',
326 res)
327
328 unlet g:Append
329 unlet g:Get
330enddef
331
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100332
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200333def EchoArg(arg: string): string
334 return arg
335enddef
336def RefThis(): func
337 return function('EchoArg')
338enddef
339def s:ScriptPCall()
340 RefThis()("text")
341enddef
342
343def Test_disassemble_pcall()
344 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200345 assert_match('<SNR>\d\+_ScriptPCall.*' ..
346 'RefThis()("text").*' ..
347 '\d DCALL RefThis(argc 0).*' ..
348 '\d PUSHS "text".*' ..
349 '\d PCALL top (argc 1).*' ..
350 '\d PCALL end.*' ..
351 '\d DROP.*' ..
352 '\d PUSHNR 0.*' ..
353 '\d RETURN.*',
354 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200355enddef
356
357
Bram Moolenaara26b9702020-04-18 19:53:28 +0200358def s:FuncWithForwardCall(): string
359 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100360enddef
361
362def DefinedLater(arg: string): string
363 return arg
364enddef
365
366def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200367 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200368 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200369 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200370 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200371 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200372 '\d CHECKTYPE string stack\[-1].*' ..
373 '\d RETURN.*',
374 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100375
376 " Calling the function will change UCALL into the faster DCALL
377 assert_equal('yes', FuncWithForwardCall())
378
Bram Moolenaara26b9702020-04-18 19:53:28 +0200379 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200380 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200381 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200382 '\d PUSHS "yes".*' ..
383 '\d DCALL DefinedLater(argc 1).*' ..
384 '\d CHECKTYPE string stack\[-1].*' ..
385 '\d RETURN.*',
386 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100387enddef
388
389
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100390def FuncWithDefault(arg: string = 'default'): string
391 return arg
392enddef
393
394def Test_disassemble_call_default()
395 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200396 assert_match('FuncWithDefault.*' ..
397 '\d PUSHS "default".*' ..
398 '\d STORE arg\[-1].*' ..
399 'return arg.*' ..
400 '\d LOAD arg\[-1].*' ..
401 '\d RETURN.*',
402 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100403enddef
404
405
Bram Moolenaar158906c2020-02-06 20:39:45 +0100406def HasEval()
407 if has("eval")
408 echo "yes"
409 else
410 echo "no"
411 endif
412enddef
413
414def HasNothing()
415 if has("nothing")
416 echo "yes"
417 else
418 echo "no"
419 endif
420enddef
421
422def HasSomething()
423 if has("nothing")
424 echo "nothing"
425 elseif has("something")
426 echo "something"
427 elseif has("eval")
428 echo "eval"
429 elseif has("less")
430 echo "less"
431 endif
432enddef
433
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100434def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100435 assert_equal("\nyes", execute('call HasEval()'))
436 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200437 assert_match('HasEval.*' ..
438 'if has("eval").*' ..
439 ' PUSHS "yes".*',
440 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100441 assert_notmatch('JUMP', instr)
442
443 assert_equal("\nno", execute('call HasNothing()'))
444 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200445 assert_match('HasNothing.*' ..
446 'if has("nothing").*' ..
447 'else.*' ..
448 ' PUSHS "no".*',
449 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100450 assert_notmatch('PUSHS "yes"', instr)
451 assert_notmatch('JUMP', instr)
452
453 assert_equal("\neval", execute('call HasSomething()'))
454 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200455 assert_match('HasSomething.*' ..
456 'if has("nothing").*' ..
457 'elseif has("something").*' ..
458 'elseif has("eval").*' ..
459 ' PUSHS "eval".*' ..
460 'elseif has("less").*',
461 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100462 assert_notmatch('PUSHS "nothing"', instr)
463 assert_notmatch('PUSHS "something"', instr)
464 assert_notmatch('PUSHS "less"', instr)
465 assert_notmatch('JUMP', instr)
466enddef
467
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100468def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200469 let Funky1: func
470 let Funky2: func = function("len")
471 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100472enddef
473
474def Test_disassemble_function()
475 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200476 assert_match('WithFunc.*' ..
477 'let Funky1: func.*' ..
478 '0 PUSHFUNC "\[none]".*' ..
479 '1 STORE $0.*' ..
480 'let Funky2: func = function("len").*' ..
481 '2 PUSHS "len".*' ..
482 '3 BCALL function(argc 1).*' ..
483 '4 STORE $1.*' ..
484 'let Party2: func = funcref("UserFunc").*' ..
485 '\d PUSHS "UserFunc".*' ..
486 '\d BCALL funcref(argc 1).*' ..
487 '\d STORE $2.*' ..
488 '\d PUSHNR 0.*' ..
489 '\d RETURN.*',
490 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100491enddef
492
493if has('channel')
494 def WithChannel()
495 let job1: job
496 let job2: job = job_start("donothing")
497 let chan1: channel
498 enddef
499endif
500
501def Test_disassemble_channel()
502 CheckFeature channel
503
504 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200505 assert_match('WithChannel.*' ..
506 'let job1: job.*' ..
507 '\d PUSHJOB "no process".*' ..
508 '\d STORE $0.*' ..
509 'let job2: job = job_start("donothing").*' ..
510 '\d PUSHS "donothing".*' ..
511 '\d BCALL job_start(argc 1).*' ..
512 '\d STORE $1.*' ..
513 'let chan1: channel.*' ..
514 '\d PUSHCHANNEL 0.*' ..
515 '\d STORE $2.*' ..
516 '\d PUSHNR 0.*' ..
517 '\d RETURN.*',
518 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100519enddef
520
Bram Moolenaar777770f2020-02-06 21:27:08 +0100521def WithLambda(): string
522 let F = {a -> "X" .. a .. "X"}
523 return F("x")
524enddef
525
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100526def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100527 assert_equal("XxX", WithLambda())
528 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200529 assert_match('WithLambda.*' ..
530 'let F = {a -> "X" .. a .. "X"}.*' ..
531 ' FUNCREF <lambda>\d\+.*' ..
532 'PUSHS "x".*' ..
533 ' LOAD $0.*' ..
534 ' PCALL (argc 1).*' ..
535 ' CHECKTYPE string stack\[-1].*',
536 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100537enddef
538
Bram Moolenaar6e949782020-04-13 17:21:00 +0200539def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100540 if arg == 1 && arg != 2 || arg == 4
541 return 'yes'
542 endif
543 return 'no'
544enddef
545
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100546def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100547 assert_equal("yes", AndOr(1))
548 assert_equal("no", AndOr(2))
549 assert_equal("yes", AndOr(4))
550 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200551 assert_match('AndOr.*' ..
552 'if arg == 1 && arg != 2 || arg == 4.*' ..
553 '\d LOAD arg\[-1].*' ..
554 '\d PUSHNR 1.*' ..
555 '\d COMPAREANY ==.*' ..
556 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
557 '\d LOAD arg\[-1].*' ..
558 '\d PUSHNR 2.*' ..
559 '\d COMPAREANY !=.*' ..
560 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
561 '\d LOAD arg\[-1].*' ..
562 '\d PUSHNR 4.*' ..
563 '\d COMPAREANY ==.*' ..
564 '\d JUMP_IF_FALSE -> \d\+.*',
565 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100566enddef
567
Bram Moolenaar04d05222020-02-06 22:06:54 +0100568def ForLoop(): list<number>
569 let res: list<number>
570 for i in range(3)
571 res->add(i)
572 endfor
573 return res
574enddef
575
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100576def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100577 assert_equal([0, 1, 2], ForLoop())
578 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200579 assert_match('ForLoop.*' ..
580 'let res: list<number>.*' ..
581 ' NEWLIST size 0.*' ..
582 '\d STORE $0.*' ..
583 'for i in range(3).*' ..
584 '\d STORE -1 in $1.*' ..
585 '\d PUSHNR 3.*' ..
586 '\d BCALL range(argc 1).*' ..
587 '\d FOR $1 -> \d\+.*' ..
588 '\d STORE $2.*' ..
589 'res->add(i).*' ..
590 '\d LOAD $0.*' ..
591 '\d LOAD $2.*' ..
592 '\d BCALL add(argc 2).*' ..
593 '\d DROP.*' ..
594 'endfor.*' ..
595 '\d JUMP -> \d\+.*' ..
596 '\d DROP.*',
597 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100598enddef
599
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100600let g:number = 42
601
602def Computing()
603 let nr = 3
604 let nrres = nr + 7
605 nrres = nr - 7
606 nrres = nr * 7
607 nrres = nr / 7
608 nrres = nr % 7
609
610 let anyres = g:number + 7
611 anyres = g:number - 7
612 anyres = g:number * 7
613 anyres = g:number / 7
614 anyres = g:number % 7
615
616 if has('float')
617 let fl = 3.0
618 let flres = fl + 7.0
619 flres = fl - 7.0
620 flres = fl * 7.0
621 flres = fl / 7.0
622 endif
623enddef
624
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100625def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100626 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200627 assert_match('Computing.*' ..
628 'let nr = 3.*' ..
629 '\d STORE 3 in $0.*' ..
630 'let nrres = nr + 7.*' ..
631 '\d LOAD $0.*' ..
632 '\d PUSHNR 7.*' ..
633 '\d OPNR +.*' ..
634 '\d STORE $1.*' ..
635 'nrres = nr - 7.*' ..
636 '\d OPNR -.*' ..
637 'nrres = nr \* 7.*' ..
638 '\d OPNR \*.*' ..
639 'nrres = nr / 7.*' ..
640 '\d OPNR /.*' ..
641 'nrres = nr % 7.*' ..
642 '\d OPNR %.*' ..
643 'let anyres = g:number + 7.*' ..
644 '\d LOADG g:number.*' ..
645 '\d PUSHNR 7.*' ..
646 '\d OPANY +.*' ..
647 '\d STORE $2.*' ..
648 'anyres = g:number - 7.*' ..
649 '\d OPANY -.*' ..
650 'anyres = g:number \* 7.*' ..
651 '\d OPANY \*.*' ..
652 'anyres = g:number / 7.*' ..
653 '\d OPANY /.*' ..
654 'anyres = g:number % 7.*' ..
655 '\d OPANY %.*',
656 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100657 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200658 assert_match('Computing.*' ..
659 'let fl = 3.0.*' ..
660 '\d PUSHF 3.0.*' ..
661 '\d STORE $3.*' ..
662 'let flres = fl + 7.0.*' ..
663 '\d LOAD $3.*' ..
664 '\d PUSHF 7.0.*' ..
665 '\d OPFLOAT +.*' ..
666 '\d STORE $4.*' ..
667 'flres = fl - 7.0.*' ..
668 '\d OPFLOAT -.*' ..
669 'flres = fl \* 7.0.*' ..
670 '\d OPFLOAT \*.*' ..
671 'flres = fl / 7.0.*' ..
672 '\d OPFLOAT /.*',
673 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100674 endif
675enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100676
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100677def AddListBlob()
678 let reslist = [1, 2] + [3, 4]
679 let resblob = 0z1122 + 0z3344
680enddef
681
682def Test_disassemble_add_list_blob()
683 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200684 assert_match('AddListBlob.*' ..
685 'let reslist = \[1, 2] + \[3, 4].*' ..
686 '\d PUSHNR 1.*' ..
687 '\d PUSHNR 2.*' ..
688 '\d NEWLIST size 2.*' ..
689 '\d PUSHNR 3.*' ..
690 '\d PUSHNR 4.*' ..
691 '\d NEWLIST size 2.*' ..
692 '\d ADDLIST.*' ..
693 '\d STORE $.*.*' ..
694 'let resblob = 0z1122 + 0z3344.*' ..
695 '\d PUSHBLOB 0z1122.*' ..
696 '\d PUSHBLOB 0z3344.*' ..
697 '\d ADDBLOB.*' ..
698 '\d STORE $.*',
699 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100700enddef
701
702let g:aa = 'aa'
703def ConcatString(): string
704 let res = g:aa .. "bb"
705 return res
706enddef
707
708def Test_disassemble_concat()
709 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200710 assert_match('ConcatString.*' ..
711 'let res = g:aa .. "bb".*' ..
712 '\d LOADG g:aa.*' ..
713 '\d PUSHS "bb".*' ..
714 '\d 2STRING stack\[-2].*' ..
715 '\d CONCAT.*' ..
716 '\d STORE $.*',
717 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100718 assert_equal('aabb', ConcatString())
719enddef
720
721def ListIndex(): number
722 let l = [1, 2, 3]
723 let res = l[1]
724 return res
725enddef
726
727def Test_disassemble_list_index()
728 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200729 assert_match('ListIndex.*' ..
730 'let l = \[1, 2, 3].*' ..
731 '\d PUSHNR 1.*' ..
732 '\d PUSHNR 2.*' ..
733 '\d PUSHNR 3.*' ..
734 '\d NEWLIST size 3.*' ..
735 '\d STORE $0.*' ..
736 'let res = l\[1].*' ..
737 '\d LOAD $0.*' ..
738 '\d PUSHNR 1.*' ..
739 '\d INDEX.*' ..
740 '\d STORE $1.*',
741 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100742 assert_equal(2, ListIndex())
743enddef
744
745def DictMember(): number
746 let d = #{item: 1}
747 let res = d.item
748 return res
749enddef
750
751def Test_disassemble_dict_member()
752 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200753 assert_match('DictMember.*' ..
754 'let d = #{item: 1}.*' ..
755 '\d PUSHS "item".*' ..
756 '\d PUSHNR 1.*' ..
757 '\d NEWDICT size 1.*' ..
758 '\d STORE $0.*' ..
759 'let res = d.item.*' ..
760 '\d LOAD $0.*' ..
761 '\d MEMBER item.*' ..
762 '\d STORE $1.*',
763 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100764 call assert_equal(1, DictMember())
765enddef
766
767def NegateNumber(): number
768 let nr = 9
769 let plus = +nr
770 let res = -nr
771 return res
772enddef
773
774def Test_disassemble_negate_number()
775 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200776 assert_match('NegateNumber.*' ..
777 'let nr = 9.*' ..
778 '\d STORE 9 in $0.*' ..
779 'let plus = +nr.*' ..
780 '\d LOAD $0.*' ..
781 '\d CHECKNR.*' ..
782 '\d STORE $1.*' ..
783 'let res = -nr.*' ..
784 '\d LOAD $0.*' ..
785 '\d NEGATENR.*' ..
786 '\d STORE $2.*',
787 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100788 call assert_equal(-9, NegateNumber())
789enddef
790
791def InvertBool(): bool
792 let flag = true
793 let invert = !flag
794 let res = !!flag
795 return res
796enddef
797
798def Test_disassemble_invert_bool()
799 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200800 assert_match('InvertBool.*' ..
801 'let flag = true.*' ..
802 '\d PUSH v:true.*' ..
803 '\d STORE $0.*' ..
804 'let invert = !flag.*' ..
805 '\d LOAD $0.*' ..
806 '\d INVERT (!val).*' ..
807 '\d STORE $1.*' ..
808 'let res = !!flag.*' ..
809 '\d LOAD $0.*' ..
810 '\d 2BOOL (!!val).*' ..
811 '\d STORE $2.*',
812 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100813 call assert_equal(true, InvertBool())
814enddef
815
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100816def Test_disassemble_compare()
817 " TODO: COMPAREFUNC
818 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200819 ['true == false', 'COMPAREBOOL =='],
820 ['true != false', 'COMPAREBOOL !='],
821 ['v:none == v:null', 'COMPARESPECIAL =='],
822 ['v:none != v:null', 'COMPARESPECIAL !='],
823
824 ['111 == 222', 'COMPARENR =='],
825 ['111 != 222', 'COMPARENR !='],
826 ['111 > 222', 'COMPARENR >'],
827 ['111 < 222', 'COMPARENR <'],
828 ['111 >= 222', 'COMPARENR >='],
829 ['111 <= 222', 'COMPARENR <='],
830 ['111 =~ 222', 'COMPARENR =\~'],
831 ['111 !~ 222', 'COMPARENR !\~'],
832
833 ['"xx" != "yy"', 'COMPARESTRING !='],
834 ['"xx" > "yy"', 'COMPARESTRING >'],
835 ['"xx" < "yy"', 'COMPARESTRING <'],
836 ['"xx" >= "yy"', 'COMPARESTRING >='],
837 ['"xx" <= "yy"', 'COMPARESTRING <='],
838 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
839 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
840 ['"xx" is "yy"', 'COMPARESTRING is'],
841 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
842
843 ['0z11 == 0z22', 'COMPAREBLOB =='],
844 ['0z11 != 0z22', 'COMPAREBLOB !='],
845 ['0z11 is 0z22', 'COMPAREBLOB is'],
846 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
847
848 ['[1,2] == [3,4]', 'COMPARELIST =='],
849 ['[1,2] != [3,4]', 'COMPARELIST !='],
850 ['[1,2] is [3,4]', 'COMPARELIST is'],
851 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
852
853 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
854 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
855 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
856 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
857
858 ['{->33} == {->44}', 'COMPAREFUNC =='],
859 ['{->33} != {->44}', 'COMPAREFUNC !='],
860 ['{->33} is {->44}', 'COMPAREFUNC is'],
861 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
862
863 ['77 == g:xx', 'COMPAREANY =='],
864 ['77 != g:xx', 'COMPAREANY !='],
865 ['77 > g:xx', 'COMPAREANY >'],
866 ['77 < g:xx', 'COMPAREANY <'],
867 ['77 >= g:xx', 'COMPAREANY >='],
868 ['77 <= g:xx', 'COMPAREANY <='],
869 ['77 =~ g:xx', 'COMPAREANY =\~'],
870 ['77 !~ g:xx', 'COMPAREANY !\~'],
871 ['77 is g:xx', 'COMPAREANY is'],
872 ['77 isnot g:xx', 'COMPAREANY isnot'],
873 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100874 if has('float')
875 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200876 ['1.1 == 2.2', 'COMPAREFLOAT =='],
877 ['1.1 != 2.2', 'COMPAREFLOAT !='],
878 ['1.1 > 2.2', 'COMPAREFLOAT >'],
879 ['1.1 < 2.2', 'COMPAREFLOAT <'],
880 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
881 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
882 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
883 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
884 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100885 endif
886
887 let nr = 1
888 for case in cases
889 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200890 ' if ' .. case[0],
891 ' echo 42'
892 ' endif',
893 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100894 source Xdisassemble
895 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200896 assert_match('TestCase' .. nr .. '.*' ..
897 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
898 '\d \(PUSH\|FUNCREF\).*' ..
899 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
900 '\d ' .. case[1] .. '.*' ..
901 '\d JUMP_IF_FALSE -> \d\+.*',
902 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100903
904 nr += 1
905 endfor
906
Bram Moolenaar22da5592020-03-19 14:52:20 +0100907 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100908enddef
909
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200910def Test_disassemble_compare_const()
911 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200912 ['"xx" == "yy"', false],
913 ['"aa" == "aa"', true],
914 ['has("eval") ? true : false', true],
915 ['has("asdf") ? true : false', false],
916 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200917
918 let nr = 1
919 for case in cases
920 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200921 ' if ' .. case[0],
922 ' echo 42'
923 ' endif',
924 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200925 source Xdisassemble
926 let instr = execute('disassemble TestCase' .. nr)
927 if case[1]
928 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200929 assert_match('TestCase' .. nr .. '.*' ..
930 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
931 '\d PUSHNR 42.*' ..
932 '\d ECHO 1.*' ..
933 '\d PUSHNR 0.*' ..
934 '\d RETURN.*',
935 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200936 else
937 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200938 assert_match('TestCase' .. nr .. '.*' ..
939 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
940 'echo 42[ \n]*' ..
941 'endif[ \n]*' ..
942 '\s*\d PUSHNR 0.*' ..
943 '\d RETURN.*',
944 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200945 endif
946
947 nr += 1
948 endfor
949
950 delete('Xdisassemble')
951enddef
952
Bram Moolenaarad39c092020-02-26 18:23:43 +0100953def s:Execute()
954 execute 'help vim9.txt'
955 let cmd = 'help vim9.txt'
956 execute cmd
957 let tag = 'vim9.txt'
958 execute 'help ' .. tag
959enddef
960
961def Test_disassemble_execute()
962 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200963 assert_match('\<SNR>\d*_Execute.*' ..
964 "execute 'help vim9.txt'.*" ..
965 '\d PUSHS "help vim9.txt".*' ..
966 '\d EXECUTE 1.*' ..
967 "let cmd = 'help vim9.txt'.*" ..
968 '\d PUSHS "help vim9.txt".*' ..
969 '\d STORE $0.*' ..
970 'execute cmd.*' ..
971 '\d LOAD $0.*' ..
972 '\d EXECUTE 1.*' ..
973 "let tag = 'vim9.txt'.*" ..
974 '\d PUSHS "vim9.txt".*' ..
975 '\d STORE $1.*' ..
976 "execute 'help ' .. tag.*" ..
977 '\d PUSHS "help ".*' ..
978 '\d LOAD $1.*' ..
979 '\d CONCAT.*' ..
980 '\d EXECUTE 1.*' ..
981 '\d PUSHNR 0.*' ..
982 '\d RETURN',
983 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100984enddef
985
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200986def s:Echomsg()
987 echomsg 'some' 'message'
988 echoerr 'went' .. 'wrong'
989enddef
990
991def Test_disassemble_echomsg()
992 let res = execute('disass s:Echomsg')
993 assert_match('\<SNR>\d*_Echomsg.*' ..
994 "echomsg 'some' 'message'.*" ..
995 '\d PUSHS "some".*' ..
996 '\d PUSHS "message".*' ..
997 '\d ECHOMSG 2.*' ..
998 "echoerr 'went' .. 'wrong'.*" ..
999 '\d PUSHS "went".*' ..
1000 '\d PUSHS "wrong".*' ..
1001 '\d CONCAT.*' ..
1002 '\d ECHOERR 1.*' ..
1003 '\d PUSHNR 0.*' ..
1004 '\d RETURN',
1005 res)
1006enddef
1007
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001008def SomeStringArg(arg: string)
1009 echo arg
1010enddef
1011
1012def SomeAnyArg(arg: any)
1013 echo arg
1014enddef
1015
1016def SomeStringArgAndReturn(arg: string): string
1017 return arg
1018enddef
1019
1020def Test_display_func()
1021 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001022 assert_match('.* def SomeStringArg(arg: string).*' ..
1023 ' echo arg.*' ..
1024 ' enddef',
1025 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001026
1027 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001028 assert_match('.* def SomeAnyArg(arg: any).*' ..
1029 ' echo arg.*' ..
1030 ' enddef',
1031 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001032
1033 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001034 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
1035 ' return arg.*' ..
1036 ' enddef',
1037 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001038enddef
1039
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001040" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker