blob: e1042588cffbfea2b2e6fdd59b3dcc2af8c18276 [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 Moolenaarcb790402020-05-15 20:53:00 +0200157def s:ScriptFuncStoreMember()
158 let locallist: list<number> = []
159 locallist[0] = 123
160 let localdict: dict<number> = {}
161 localdict["a"] = 456
162enddef
163
164def Test_disassemble_store_member()
165 let res = execute('disass s:ScriptFuncStoreMember')
166 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
167 'let locallist: list<number> = []\_s*' ..
168 '\d NEWLIST size 0\_s*' ..
169 '\d STORE $0\_s*' ..
170 'locallist\[0\] = 123\_s*' ..
171 '\d PUSHNR 123\_s*' ..
172 '\d PUSHNR 0\_s*' ..
173 '\d LOAD $0\_s*' ..
174 '\d STORELIST\_s*' ..
175 'let localdict: dict<number> = {}\_s*' ..
176 '\d NEWDICT size 0\_s*' ..
177 '\d STORE $1\_s*' ..
178 'localdict\["a"\] = 456\_s*' ..
179 '\d\+ PUSHNR 456\_s*' ..
180 '\d\+ PUSHS "a"\_s*' ..
181 '\d\+ LOAD $1\_s*' ..
182 '\d\+ STOREDICT\_s*' ..
183 '\d\+ PUSHNR 0\_s*' ..
184 '\d\+ RETURN',
185 res)
186enddef
187
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200188def s:ScriptFuncUnlet()
189 g:somevar = "value"
190 unlet g:somevar
191 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200192 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200193enddef
194
195def Test_disassemble_unlet()
196 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200197 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
198 'g:somevar = "value"\_s*' ..
199 '\d PUSHS "value"\_s*' ..
200 '\d STOREG g:somevar\_s*' ..
201 'unlet g:somevar\_s*' ..
202 '\d UNLET g:somevar\_s*' ..
203 'unlet! g:somevar\_s*' ..
204 '\d UNLET! g:somevar\_s*' ..
205 'unlet $SOMEVAR\_s*' ..
206 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200207 res)
208enddef
209
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100210def s:ScriptFuncTry()
211 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200212 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100213 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200214 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100215 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200216 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100217 endtry
218enddef
219
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100220def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100221 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200222 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
223 'try\_s*' ..
224 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
225 'echo "yes"\_s*' ..
226 '\d PUSHS "yes"\_s*' ..
227 '\d ECHO 1\_s*' ..
228 'catch /fail/\_s*' ..
229 '\d JUMP -> \d\+\_s*' ..
230 '\d PUSH v:exception\_s*' ..
231 '\d PUSHS "fail"\_s*' ..
232 '\d COMPARESTRING =\~\_s*' ..
233 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
234 '\d CATCH\_s*' ..
235 'echo "no"\_s*' ..
236 '\d\+ PUSHS "no"\_s*' ..
237 '\d\+ ECHO 1\_s*' ..
238 'finally\_s*' ..
239 'throw "end"\_s*' ..
240 '\d\+ PUSHS "end"\_s*' ..
241 '\d\+ THROW\_s*' ..
242 'endtry\_s*' ..
243 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200244 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100245enddef
246
247def s:ScriptFuncNew()
248 let ll = [1, "two", 333]
249 let dd = #{one: 1, two: "val"}
250enddef
251
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100252def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100253 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200254 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
255 'let ll = \[1, "two", 333\]\_s*' ..
256 '\d PUSHNR 1\_s*' ..
257 '\d PUSHS "two"\_s*' ..
258 '\d PUSHNR 333\_s*' ..
259 '\d NEWLIST size 3\_s*' ..
260 '\d STORE $0\_s*' ..
261 'let dd = #{one: 1, two: "val"}\_s*' ..
262 '\d PUSHS "one"\_s*' ..
263 '\d PUSHNR 1\_s*' ..
264 '\d PUSHS "two"\_s*' ..
265 '\d PUSHS "val"\_s*' ..
266 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200267 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100268enddef
269
Bram Moolenaar6e949782020-04-13 17:21:00 +0200270def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100271 echo arg
272enddef
273
274func UserFunc()
275 echo 'nothing'
276endfunc
277
278func UserFuncWithArg(arg)
279 echo a:arg
280endfunc
281
282def s:ScriptFuncCall(): string
283 changenr()
284 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100285 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100286 FuncWithArg(343)
287 ScriptFuncNew()
288 s:ScriptFuncNew()
289 UserFunc()
290 UserFuncWithArg("foo")
291 let FuncRef = function("UserFunc")
292 FuncRef()
293 let FuncRefWithArg = function("UserFuncWithArg")
294 FuncRefWithArg("bar")
295 return "yes"
296enddef
297
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100298def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100299 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200300 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
301 'changenr()\_s*' ..
302 '\d BCALL changenr(argc 0)\_s*' ..
303 '\d DROP\_s*' ..
304 'char2nr("abc")\_s*' ..
305 '\d PUSHS "abc"\_s*' ..
306 '\d BCALL char2nr(argc 1)\_s*' ..
307 '\d DROP\_s*' ..
308 'Test_disassemble_new()\_s*' ..
309 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
310 '\d DROP\_s*' ..
311 'FuncWithArg(343)\_s*' ..
312 '\d\+ PUSHNR 343\_s*' ..
313 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
314 '\d\+ DROP\_s*' ..
315 'ScriptFuncNew()\_s*' ..
316 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
317 '\d\+ DROP\_s*' ..
318 's:ScriptFuncNew()\_s*' ..
319 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
320 '\d\+ DROP\_s*' ..
321 'UserFunc()\_s*' ..
322 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
323 '\d\+ DROP\_s*' ..
324 'UserFuncWithArg("foo")\_s*' ..
325 '\d\+ PUSHS "foo"\_s*' ..
326 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
327 '\d\+ DROP\_s*' ..
328 'let FuncRef = function("UserFunc")\_s*' ..
329 '\d\+ PUSHS "UserFunc"\_s*' ..
330 '\d\+ BCALL function(argc 1)\_s*' ..
331 '\d\+ STORE $0\_s*' ..
332 'FuncRef()\_s*' ..
333 '\d\+ LOAD $\d\_s*' ..
334 '\d\+ PCALL (argc 0)\_s*' ..
335 '\d\+ DROP\_s*' ..
336 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
337 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
338 '\d\+ BCALL function(argc 1)\_s*' ..
339 '\d\+ STORE $1\_s*' ..
340 'FuncRefWithArg("bar")\_s*' ..
341 '\d\+ PUSHS "bar"\_s*' ..
342 '\d\+ LOAD $\d\_s*' ..
343 '\d\+ PCALL (argc 1)\_s*' ..
344 '\d\+ DROP\_s*' ..
345 'return "yes"\_s*' ..
346 '\d\+ PUSHS "yes"\_s*' ..
347 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200348 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100349enddef
350
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200351def s:CreateRefs()
352 let local = 'a'
353 def Append(arg: string)
354 local ..= arg
355 enddef
356 g:Append = Append
357 def Get(): string
358 return local
359 enddef
360 g:Get = Get
361enddef
362
363def Test_disassemble_closure()
364 CreateRefs()
365 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200366 assert_match('<lambda>\d\_s*' ..
367 'local ..= arg\_s*' ..
368 '\d LOADOUTER $0\_s*' ..
369 '\d LOAD arg\[-1\]\_s*' ..
370 '\d CONCAT\_s*' ..
371 '\d STOREOUTER $0\_s*' ..
372 '\d PUSHNR 0\_s*' ..
373 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200374 res)
375
376 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200377 assert_match('<lambda>\d\_s*' ..
378 'return local\_s*' ..
379 '\d LOADOUTER $0\_s*' ..
380 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200381 res)
382
383 unlet g:Append
384 unlet g:Get
385enddef
386
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100387
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200388def EchoArg(arg: string): string
389 return arg
390enddef
391def RefThis(): func
392 return function('EchoArg')
393enddef
394def s:ScriptPCall()
395 RefThis()("text")
396enddef
397
398def Test_disassemble_pcall()
399 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200400 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
401 'RefThis()("text")\_s*' ..
402 '\d DCALL RefThis(argc 0)\_s*' ..
403 '\d PUSHS "text"\_s*' ..
404 '\d PCALL top (argc 1)\_s*' ..
405 '\d PCALL end\_s*' ..
406 '\d DROP\_s*' ..
407 '\d PUSHNR 0\_s*' ..
408 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200409 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200410enddef
411
412
Bram Moolenaara26b9702020-04-18 19:53:28 +0200413def s:FuncWithForwardCall(): string
414 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100415enddef
416
417def DefinedLater(arg: string): string
418 return arg
419enddef
420
421def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200422 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200423 assert_match('FuncWithForwardCall\_s*' ..
424 'return g:DefinedLater("yes")\_s*' ..
425 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200426 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200427 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200428 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100429
430 " Calling the function will change UCALL into the faster DCALL
431 assert_equal('yes', FuncWithForwardCall())
432
Bram Moolenaara26b9702020-04-18 19:53:28 +0200433 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200434 assert_match('FuncWithForwardCall\_s*' ..
435 'return g:DefinedLater("yes")\_s*' ..
436 '\d PUSHS "yes"\_s*' ..
437 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200438 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200439 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100440enddef
441
442
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100443def FuncWithDefault(arg: string = 'default'): string
444 return arg
445enddef
446
447def Test_disassemble_call_default()
448 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200449 assert_match('FuncWithDefault\_s*' ..
450 '\d PUSHS "default"\_s*' ..
451 '\d STORE arg\[-1]\_s*' ..
452 'return arg\_s*' ..
453 '\d LOAD arg\[-1]\_s*' ..
454 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200455 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100456enddef
457
458
Bram Moolenaar158906c2020-02-06 20:39:45 +0100459def HasEval()
460 if has("eval")
461 echo "yes"
462 else
463 echo "no"
464 endif
465enddef
466
467def HasNothing()
468 if has("nothing")
469 echo "yes"
470 else
471 echo "no"
472 endif
473enddef
474
475def HasSomething()
476 if has("nothing")
477 echo "nothing"
478 elseif has("something")
479 echo "something"
480 elseif has("eval")
481 echo "eval"
482 elseif has("less")
483 echo "less"
484 endif
485enddef
486
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100487def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100488 assert_equal("\nyes", execute('call HasEval()'))
489 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200490 assert_match('HasEval\_s*' ..
491 'if has("eval")\_s*' ..
492 'echo "yes"\_s*' ..
493 '\d PUSHS "yes"\_s*' ..
494 '\d ECHO 1\_s*' ..
495 'else\_s*' ..
496 'echo "no"\_s*' ..
497 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200498 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100499 assert_notmatch('JUMP', instr)
500
501 assert_equal("\nno", execute('call HasNothing()'))
502 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200503 assert_match('HasNothing\_s*' ..
504 'if has("nothing")\_s*' ..
505 'echo "yes"\_s*' ..
506 'else\_s*' ..
507 'echo "no"\_s*' ..
508 '\d PUSHS "no"\_s*' ..
509 '\d ECHO 1\_s*' ..
510 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200511 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100512 assert_notmatch('PUSHS "yes"', instr)
513 assert_notmatch('JUMP', instr)
514
515 assert_equal("\neval", execute('call HasSomething()'))
516 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200517 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200518 'if has("nothing")\_s*' ..
519 'echo "nothing"\_s*' ..
520 'elseif has("something")\_s*' ..
521 'echo "something"\_s*' ..
522 'elseif has("eval")\_s*' ..
523 'echo "eval"\_s*' ..
524 '\d PUSHS "eval"\_s*' ..
525 '\d ECHO 1\_s*' ..
526 'elseif has("less").*' ..
527 'echo "less"\_s*' ..
528 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200529 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100530 assert_notmatch('PUSHS "nothing"', instr)
531 assert_notmatch('PUSHS "something"', instr)
532 assert_notmatch('PUSHS "less"', instr)
533 assert_notmatch('JUMP', instr)
534enddef
535
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100536def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200537 let Funky1: func
538 let Funky2: func = function("len")
539 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100540enddef
541
542def Test_disassemble_function()
543 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200544 assert_match('WithFunc\_s*' ..
545 'let Funky1: func\_s*' ..
546 '0 PUSHFUNC "\[none]"\_s*' ..
547 '1 STORE $0\_s*' ..
548 'let Funky2: func = function("len")\_s*' ..
549 '2 PUSHS "len"\_s*' ..
550 '3 BCALL function(argc 1)\_s*' ..
551 '4 STORE $1\_s*' ..
552 'let Party2: func = funcref("UserFunc")\_s*' ..
553 '\d PUSHS "UserFunc"\_s*' ..
554 '\d BCALL funcref(argc 1)\_s*' ..
555 '\d STORE $2\_s*' ..
556 '\d PUSHNR 0\_s*' ..
557 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200558 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100559enddef
560
561if has('channel')
562 def WithChannel()
563 let job1: job
564 let job2: job = job_start("donothing")
565 let chan1: channel
566 enddef
567endif
568
569def Test_disassemble_channel()
570 CheckFeature channel
571
572 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200573 assert_match('WithChannel\_s*' ..
574 'let job1: job\_s*' ..
575 '\d PUSHJOB "no process"\_s*' ..
576 '\d STORE $0\_s*' ..
577 'let job2: job = job_start("donothing")\_s*' ..
578 '\d PUSHS "donothing"\_s*' ..
579 '\d BCALL job_start(argc 1)\_s*' ..
580 '\d STORE $1\_s*' ..
581 'let chan1: channel\_s*' ..
582 '\d PUSHCHANNEL 0\_s*' ..
583 '\d STORE $2\_s*' ..
584 '\d PUSHNR 0\_s*' ..
585 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200586 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100587enddef
588
Bram Moolenaar777770f2020-02-06 21:27:08 +0100589def WithLambda(): string
590 let F = {a -> "X" .. a .. "X"}
591 return F("x")
592enddef
593
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100594def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100595 assert_equal("XxX", WithLambda())
596 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200597 assert_match('WithLambda\_s*' ..
598 'let F = {a -> "X" .. a .. "X"}\_s*' ..
599 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
600 '\d STORE $0\_s*' ..
601 'return F("x")\_s*' ..
602 '\d PUSHS "x"\_s*' ..
603 '\d LOAD $0\_s*' ..
604 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200605 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200606 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100607enddef
608
Bram Moolenaar6e949782020-04-13 17:21:00 +0200609def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100610 if arg == 1 && arg != 2 || arg == 4
611 return 'yes'
612 endif
613 return 'no'
614enddef
615
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100616def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100617 assert_equal("yes", AndOr(1))
618 assert_equal("no", AndOr(2))
619 assert_equal("yes", AndOr(4))
620 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200621 assert_match('AndOr\_s*' ..
622 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
623 '\d LOAD arg\[-1]\_s*' ..
624 '\d PUSHNR 1\_s*' ..
625 '\d COMPAREANY ==\_s*' ..
626 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
627 '\d LOAD arg\[-1]\_s*' ..
628 '\d PUSHNR 2\_s*' ..
629 '\d COMPAREANY !=\_s*' ..
630 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
631 '\d LOAD arg\[-1]\_s*' ..
632 '\d\+ PUSHNR 4\_s*' ..
633 '\d\+ COMPAREANY ==\_s*' ..
634 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200635 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100636enddef
637
Bram Moolenaar04d05222020-02-06 22:06:54 +0100638def ForLoop(): list<number>
639 let res: list<number>
640 for i in range(3)
641 res->add(i)
642 endfor
643 return res
644enddef
645
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100646def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100647 assert_equal([0, 1, 2], ForLoop())
648 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200649 assert_match('ForLoop\_s*' ..
650 'let res: list<number>\_s*' ..
651 '\d NEWLIST size 0\_s*' ..
652 '\d STORE $0\_s*' ..
653 'for i in range(3)\_s*' ..
654 '\d STORE -1 in $1\_s*' ..
655 '\d PUSHNR 3\_s*' ..
656 '\d BCALL range(argc 1)\_s*' ..
657 '\d FOR $1 -> \d\+\_s*' ..
658 '\d STORE $2\_s*' ..
659 'res->add(i)\_s*' ..
660 '\d LOAD $0\_s*' ..
661 '\d LOAD $2\_s*' ..
662 '\d\+ BCALL add(argc 2)\_s*' ..
663 '\d\+ DROP\_s*' ..
664 'endfor\_s*' ..
665 '\d\+ JUMP -> \d\+\_s*' ..
666 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200667 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100668enddef
669
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100670let g:number = 42
671
672def Computing()
673 let nr = 3
674 let nrres = nr + 7
675 nrres = nr - 7
676 nrres = nr * 7
677 nrres = nr / 7
678 nrres = nr % 7
679
680 let anyres = g:number + 7
681 anyres = g:number - 7
682 anyres = g:number * 7
683 anyres = g:number / 7
684 anyres = g:number % 7
685
686 if has('float')
687 let fl = 3.0
688 let flres = fl + 7.0
689 flres = fl - 7.0
690 flres = fl * 7.0
691 flres = fl / 7.0
692 endif
693enddef
694
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100695def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100696 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200697 assert_match('Computing.*' ..
698 'let nr = 3.*' ..
699 '\d STORE 3 in $0.*' ..
700 'let nrres = nr + 7.*' ..
701 '\d LOAD $0.*' ..
702 '\d PUSHNR 7.*' ..
703 '\d OPNR +.*' ..
704 '\d STORE $1.*' ..
705 'nrres = nr - 7.*' ..
706 '\d OPNR -.*' ..
707 'nrres = nr \* 7.*' ..
708 '\d OPNR \*.*' ..
709 'nrres = nr / 7.*' ..
710 '\d OPNR /.*' ..
711 'nrres = nr % 7.*' ..
712 '\d OPNR %.*' ..
713 'let anyres = g:number + 7.*' ..
714 '\d LOADG g:number.*' ..
715 '\d PUSHNR 7.*' ..
716 '\d OPANY +.*' ..
717 '\d STORE $2.*' ..
718 'anyres = g:number - 7.*' ..
719 '\d OPANY -.*' ..
720 'anyres = g:number \* 7.*' ..
721 '\d OPANY \*.*' ..
722 'anyres = g:number / 7.*' ..
723 '\d OPANY /.*' ..
724 'anyres = g:number % 7.*' ..
725 '\d OPANY %.*',
726 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100727 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200728 assert_match('Computing.*' ..
729 'let fl = 3.0.*' ..
730 '\d PUSHF 3.0.*' ..
731 '\d STORE $3.*' ..
732 'let flres = fl + 7.0.*' ..
733 '\d LOAD $3.*' ..
734 '\d PUSHF 7.0.*' ..
735 '\d OPFLOAT +.*' ..
736 '\d STORE $4.*' ..
737 'flres = fl - 7.0.*' ..
738 '\d OPFLOAT -.*' ..
739 'flres = fl \* 7.0.*' ..
740 '\d OPFLOAT \*.*' ..
741 'flres = fl / 7.0.*' ..
742 '\d OPFLOAT /.*',
743 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100744 endif
745enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100746
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100747def AddListBlob()
748 let reslist = [1, 2] + [3, 4]
749 let resblob = 0z1122 + 0z3344
750enddef
751
752def Test_disassemble_add_list_blob()
753 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200754 assert_match('AddListBlob.*' ..
755 'let reslist = \[1, 2] + \[3, 4].*' ..
756 '\d PUSHNR 1.*' ..
757 '\d PUSHNR 2.*' ..
758 '\d NEWLIST size 2.*' ..
759 '\d PUSHNR 3.*' ..
760 '\d PUSHNR 4.*' ..
761 '\d NEWLIST size 2.*' ..
762 '\d ADDLIST.*' ..
763 '\d STORE $.*.*' ..
764 'let resblob = 0z1122 + 0z3344.*' ..
765 '\d PUSHBLOB 0z1122.*' ..
766 '\d PUSHBLOB 0z3344.*' ..
767 '\d ADDBLOB.*' ..
768 '\d STORE $.*',
769 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100770enddef
771
772let g:aa = 'aa'
773def ConcatString(): string
774 let res = g:aa .. "bb"
775 return res
776enddef
777
778def Test_disassemble_concat()
779 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200780 assert_match('ConcatString.*' ..
781 'let res = g:aa .. "bb".*' ..
782 '\d LOADG g:aa.*' ..
783 '\d PUSHS "bb".*' ..
784 '\d 2STRING stack\[-2].*' ..
785 '\d CONCAT.*' ..
786 '\d STORE $.*',
787 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100788 assert_equal('aabb', ConcatString())
789enddef
790
791def ListIndex(): number
792 let l = [1, 2, 3]
793 let res = l[1]
794 return res
795enddef
796
797def Test_disassemble_list_index()
798 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200799 assert_match('ListIndex\_s*' ..
800 'let l = \[1, 2, 3]\_s*' ..
801 '\d PUSHNR 1\_s*' ..
802 '\d PUSHNR 2\_s*' ..
803 '\d PUSHNR 3\_s*' ..
804 '\d NEWLIST size 3\_s*' ..
805 '\d STORE $0\_s*' ..
806 'let res = l\[1]\_s*' ..
807 '\d LOAD $0\_s*' ..
808 '\d PUSHNR 1\_s*' ..
809 '\d INDEX\_s*' ..
810 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200811 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100812 assert_equal(2, ListIndex())
813enddef
814
815def DictMember(): number
816 let d = #{item: 1}
817 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200818 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100819 return res
820enddef
821
822def Test_disassemble_dict_member()
823 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200824 assert_match('DictMember\_s*' ..
825 'let d = #{item: 1}\_s*' ..
826 '\d PUSHS "item"\_s*' ..
827 '\d PUSHNR 1\_s*' ..
828 '\d NEWDICT size 1\_s*' ..
829 '\d STORE $0\_s*' ..
830 'let res = d.item\_s*' ..
831 '\d\+ LOAD $0\_s*' ..
832 '\d\+ MEMBER item\_s*' ..
833 '\d\+ STORE $1\_s*' ..
834 'res = d\["item"\]\_s*' ..
835 '\d\+ LOAD $0\_s*' ..
836 '\d\+ PUSHS "item"\_s*' ..
837 '\d\+ MEMBER\_s*' ..
838 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200839 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100840 call assert_equal(1, DictMember())
841enddef
842
843def NegateNumber(): number
844 let nr = 9
845 let plus = +nr
846 let res = -nr
847 return res
848enddef
849
850def Test_disassemble_negate_number()
851 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200852 assert_match('NegateNumber\_s*' ..
853 'let nr = 9\_s*' ..
854 '\d STORE 9 in $0\_s*' ..
855 'let plus = +nr\_s*' ..
856 '\d LOAD $0\_s*' ..
857 '\d CHECKNR\_s*' ..
858 '\d STORE $1\_s*' ..
859 'let res = -nr\_s*' ..
860 '\d LOAD $0\_s*' ..
861 '\d NEGATENR\_s*' ..
862 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200863 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100864 call assert_equal(-9, NegateNumber())
865enddef
866
867def InvertBool(): bool
868 let flag = true
869 let invert = !flag
870 let res = !!flag
871 return res
872enddef
873
874def Test_disassemble_invert_bool()
875 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200876 assert_match('InvertBool\_s*' ..
877 'let flag = true\_s*' ..
878 '\d PUSH v:true\_s*' ..
879 '\d STORE $0\_s*' ..
880 'let invert = !flag\_s*' ..
881 '\d LOAD $0\_s*' ..
882 '\d INVERT (!val)\_s*' ..
883 '\d STORE $1\_s*' ..
884 'let res = !!flag\_s*' ..
885 '\d LOAD $0\_s*' ..
886 '\d 2BOOL (!!val)\_s*' ..
887 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200888 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100889 call assert_equal(true, InvertBool())
890enddef
891
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100892def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100893 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +0200894 ['true == isFalse', 'COMPAREBOOL =='],
895 ['true != isFalse', 'COMPAREBOOL !='],
896 ['v:none == isNull', 'COMPARESPECIAL =='],
897 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200898
Bram Moolenaara5565e42020-05-09 15:44:01 +0200899 ['111 == aNumber', 'COMPARENR =='],
900 ['111 != aNumber', 'COMPARENR !='],
901 ['111 > aNumber', 'COMPARENR >'],
902 ['111 < aNumber', 'COMPARENR <'],
903 ['111 >= aNumber', 'COMPARENR >='],
904 ['111 <= aNumber', 'COMPARENR <='],
905 ['111 =~ aNumber', 'COMPARENR =\~'],
906 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200907
Bram Moolenaara5565e42020-05-09 15:44:01 +0200908 ['"xx" != aString', 'COMPARESTRING !='],
909 ['"xx" > aString', 'COMPARESTRING >'],
910 ['"xx" < aString', 'COMPARESTRING <'],
911 ['"xx" >= aString', 'COMPARESTRING >='],
912 ['"xx" <= aString', 'COMPARESTRING <='],
913 ['"xx" =~ aString', 'COMPARESTRING =\~'],
914 ['"xx" !~ aString', 'COMPARESTRING !\~'],
915 ['"xx" is aString', 'COMPARESTRING is'],
916 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200917
Bram Moolenaara5565e42020-05-09 15:44:01 +0200918 ['0z11 == aBlob', 'COMPAREBLOB =='],
919 ['0z11 != aBlob', 'COMPAREBLOB !='],
920 ['0z11 is aBlob', 'COMPAREBLOB is'],
921 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200922
Bram Moolenaara5565e42020-05-09 15:44:01 +0200923 ['[1, 2] == aList', 'COMPARELIST =='],
924 ['[1, 2] != aList', 'COMPARELIST !='],
925 ['[1, 2] is aList', 'COMPARELIST is'],
926 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200927
Bram Moolenaara5565e42020-05-09 15:44:01 +0200928 ['#{a: 1} == aDict', 'COMPAREDICT =='],
929 ['#{a: 1} != aDict', 'COMPAREDICT !='],
930 ['#{a: 1} is aDict', 'COMPAREDICT is'],
931 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200932
933 ['{->33} == {->44}', 'COMPAREFUNC =='],
934 ['{->33} != {->44}', 'COMPAREFUNC !='],
935 ['{->33} is {->44}', 'COMPAREFUNC is'],
936 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
937
938 ['77 == g:xx', 'COMPAREANY =='],
939 ['77 != g:xx', 'COMPAREANY !='],
940 ['77 > g:xx', 'COMPAREANY >'],
941 ['77 < g:xx', 'COMPAREANY <'],
942 ['77 >= g:xx', 'COMPAREANY >='],
943 ['77 <= g:xx', 'COMPAREANY <='],
944 ['77 =~ g:xx', 'COMPAREANY =\~'],
945 ['77 !~ g:xx', 'COMPAREANY !\~'],
946 ['77 is g:xx', 'COMPAREANY is'],
947 ['77 isnot g:xx', 'COMPAREANY isnot'],
948 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +0200949 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100950 if has('float')
951 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +0200952 ['1.1 == aFloat', 'COMPAREFLOAT =='],
953 ['1.1 != aFloat', 'COMPAREFLOAT !='],
954 ['1.1 > aFloat', 'COMPAREFLOAT >'],
955 ['1.1 < aFloat', 'COMPAREFLOAT <'],
956 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
957 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
958 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
959 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200960 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +0200961 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100962 endif
963
964 let nr = 1
965 for case in cases
Bram Moolenaara5565e42020-05-09 15:44:01 +0200966 " declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100967 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +0200968 ' let isFalse = false',
969 ' let isNull = v:null',
970 ' let aNumber = 222',
971 ' let aString = "yy"',
972 ' let aBlob = 0z22',
973 ' let aList = [3, 4]',
974 ' let aDict = #{x: 2}',
975 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +0200976 ' if ' .. case[0],
977 ' echo 42'
978 ' endif',
979 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100980 source Xdisassemble
981 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200982 assert_match('TestCase' .. nr .. '.*' ..
983 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
984 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +0200985 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200986 '\d ' .. case[1] .. '.*' ..
987 '\d JUMP_IF_FALSE -> \d\+.*',
988 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100989
990 nr += 1
991 endfor
992
Bram Moolenaar22da5592020-03-19 14:52:20 +0100993 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100994enddef
995
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200996def Test_disassemble_compare_const()
997 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200998 ['"xx" == "yy"', false],
999 ['"aa" == "aa"', true],
1000 ['has("eval") ? true : false', true],
1001 ['has("asdf") ? true : false', false],
1002 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001003
1004 let nr = 1
1005 for case in cases
1006 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001007 ' if ' .. case[0],
1008 ' echo 42'
1009 ' endif',
1010 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001011 source Xdisassemble
1012 let instr = execute('disassemble TestCase' .. nr)
1013 if case[1]
1014 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001015 assert_match('TestCase' .. nr .. '.*' ..
1016 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1017 '\d PUSHNR 42.*' ..
1018 '\d ECHO 1.*' ..
1019 '\d PUSHNR 0.*' ..
1020 '\d RETURN.*',
1021 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001022 else
1023 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001024 assert_match('TestCase' .. nr .. '.*' ..
1025 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1026 'echo 42[ \n]*' ..
1027 'endif[ \n]*' ..
1028 '\s*\d PUSHNR 0.*' ..
1029 '\d RETURN.*',
1030 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001031 endif
1032
1033 nr += 1
1034 endfor
1035
1036 delete('Xdisassemble')
1037enddef
1038
Bram Moolenaarad39c092020-02-26 18:23:43 +01001039def s:Execute()
1040 execute 'help vim9.txt'
1041 let cmd = 'help vim9.txt'
1042 execute cmd
1043 let tag = 'vim9.txt'
1044 execute 'help ' .. tag
1045enddef
1046
1047def Test_disassemble_execute()
1048 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001049 assert_match('\<SNR>\d*_Execute\_s*' ..
1050 "execute 'help vim9.txt'\\_s*" ..
1051 '\d PUSHS "help vim9.txt"\_s*' ..
1052 '\d EXECUTE 1\_s*' ..
1053 "let cmd = 'help vim9.txt'\\_s*" ..
1054 '\d PUSHS "help vim9.txt"\_s*' ..
1055 '\d STORE $0\_s*' ..
1056 'execute cmd\_s*' ..
1057 '\d LOAD $0\_s*' ..
1058 '\d EXECUTE 1\_s*' ..
1059 "let tag = 'vim9.txt'\\_s*" ..
1060 '\d PUSHS "vim9.txt"\_s*' ..
1061 '\d STORE $1\_s*' ..
1062 "execute 'help ' .. tag\\_s*" ..
1063 '\d\+ PUSHS "help "\_s*' ..
1064 '\d\+ LOAD $1\_s*' ..
1065 '\d\+ CONCAT\_s*' ..
1066 '\d\+ EXECUTE 1\_s*' ..
1067 '\d\+ PUSHNR 0\_s*' ..
1068 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001069 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001070enddef
1071
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001072def s:Echomsg()
1073 echomsg 'some' 'message'
1074 echoerr 'went' .. 'wrong'
1075enddef
1076
1077def Test_disassemble_echomsg()
1078 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001079 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1080 "echomsg 'some' 'message'\\_s*" ..
1081 '\d PUSHS "some"\_s*' ..
1082 '\d PUSHS "message"\_s*' ..
1083 '\d ECHOMSG 2\_s*' ..
1084 "echoerr 'went' .. 'wrong'\\_s*" ..
1085 '\d PUSHS "wentwrong"\_s*' ..
1086 '\d ECHOERR 1\_s*' ..
1087 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001088 '\d RETURN',
1089 res)
1090enddef
1091
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001092def SomeStringArg(arg: string)
1093 echo arg
1094enddef
1095
1096def SomeAnyArg(arg: any)
1097 echo arg
1098enddef
1099
1100def SomeStringArgAndReturn(arg: string): string
1101 return arg
1102enddef
1103
1104def Test_display_func()
1105 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001106 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1107 '\d *echo arg.*' ..
1108 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001109 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001110
1111 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001112 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1113 '\d *echo arg\_s*' ..
1114 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001115 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001116
1117 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001118 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1119 '\d *return arg\_s*' ..
1120 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001121 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001122enddef
1123
Bram Moolenaar09689a02020-05-09 22:50:08 +02001124def Test_vim9script_forward_func()
1125 let lines =<< trim END
1126 vim9script
1127 def FuncOne(): string
1128 return FuncTwo()
1129 enddef
1130 def FuncTwo(): string
1131 return 'two'
1132 enddef
Bram Moolenaar32e35112020-05-14 22:41:15 +02001133 let g:res_FuncOne: string = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001134 END
1135 writefile(lines, 'Xdisassemble')
1136 source Xdisassemble
1137
1138 " check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001139 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1140 'return FuncTwo()\_s*' ..
1141 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001142 '\d RETURN',
1143 g:res_FuncOne)
1144
1145 delete('Xdisassemble')
1146 unlet g:res_FuncOne
1147enddef
1148
Bram Moolenaar61a89812020-05-07 16:58:17 +02001149def s:ConcatStrings(): string
1150 return 'one' .. 'two' .. 'three'
1151enddef
1152
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001153def s:ComputeConst(): number
1154 return 2 + 3 * 4 / 6 + 7
1155enddef
1156
Bram Moolenaar1c747212020-05-09 18:28:34 +02001157def s:ComputeConstParen(): number
1158 return ((2 + 4) * (8 / 2)) / (3 + 4)
1159enddef
1160
Bram Moolenaar61a89812020-05-07 16:58:17 +02001161def Test_simplify_const_expr()
1162 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001163 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1164 "return 'one' .. 'two' .. 'three'\\_s*" ..
1165 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001166 '\d RETURN',
1167 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001168
1169 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001170 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1171 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1172 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001173 '\d RETURN',
1174 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001175
1176 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001177 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1178 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1179 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001180 '\d RETURN',
1181 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001182enddef
1183
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001184" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker