blob: 2e541d9f924b67926ebdf54f5a31da9b7e831ec7 [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 Moolenaarefd88552020-06-18 20:50:10 +0200536def ReturnInIf(): string
537 if g:cond
538 return "yes"
539 else
540 return "no"
541 endif
542enddef
543
544def Test_disassemble_return_in_if()
545 let instr = execute('disassemble ReturnInIf')
546 assert_match('ReturnInIf\_s*' ..
547 'if g:cond\_s*' ..
548 '0 LOADG g:cond\_s*' ..
549 '1 JUMP_IF_FALSE -> 4\_s*' ..
550 'return "yes"\_s*' ..
551 '2 PUSHS "yes"\_s*' ..
552 '3 RETURN\_s*' ..
553 'else\_s*' ..
554 ' return "no"\_s*' ..
555 '4 PUSHS "no"\_s*' ..
556 '5 RETURN$',
557 instr)
558enddef
559
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100560def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200561 let Funky1: func
562 let Funky2: func = function("len")
563 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100564enddef
565
566def Test_disassemble_function()
567 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200568 assert_match('WithFunc\_s*' ..
569 'let Funky1: func\_s*' ..
570 '0 PUSHFUNC "\[none]"\_s*' ..
571 '1 STORE $0\_s*' ..
572 'let Funky2: func = function("len")\_s*' ..
573 '2 PUSHS "len"\_s*' ..
574 '3 BCALL function(argc 1)\_s*' ..
575 '4 STORE $1\_s*' ..
576 'let Party2: func = funcref("UserFunc")\_s*' ..
577 '\d PUSHS "UserFunc"\_s*' ..
578 '\d BCALL funcref(argc 1)\_s*' ..
579 '\d STORE $2\_s*' ..
580 '\d PUSHNR 0\_s*' ..
581 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200582 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100583enddef
584
585if has('channel')
586 def WithChannel()
587 let job1: job
588 let job2: job = job_start("donothing")
589 let chan1: channel
590 enddef
591endif
592
593def Test_disassemble_channel()
594 CheckFeature channel
595
596 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200597 assert_match('WithChannel\_s*' ..
598 'let job1: job\_s*' ..
599 '\d PUSHJOB "no process"\_s*' ..
600 '\d STORE $0\_s*' ..
601 'let job2: job = job_start("donothing")\_s*' ..
602 '\d PUSHS "donothing"\_s*' ..
603 '\d BCALL job_start(argc 1)\_s*' ..
604 '\d STORE $1\_s*' ..
605 'let chan1: channel\_s*' ..
606 '\d PUSHCHANNEL 0\_s*' ..
607 '\d STORE $2\_s*' ..
608 '\d PUSHNR 0\_s*' ..
609 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200610 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100611enddef
612
Bram Moolenaar777770f2020-02-06 21:27:08 +0100613def WithLambda(): string
614 let F = {a -> "X" .. a .. "X"}
615 return F("x")
616enddef
617
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100618def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100619 assert_equal("XxX", WithLambda())
620 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200621 assert_match('WithLambda\_s*' ..
622 'let F = {a -> "X" .. a .. "X"}\_s*' ..
623 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
624 '\d STORE $0\_s*' ..
625 'return F("x")\_s*' ..
626 '\d PUSHS "x"\_s*' ..
627 '\d LOAD $0\_s*' ..
628 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200629 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200630 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100631enddef
632
Bram Moolenaar6e949782020-04-13 17:21:00 +0200633def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100634 if arg == 1 && arg != 2 || arg == 4
635 return 'yes'
636 endif
637 return 'no'
638enddef
639
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100640def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100641 assert_equal("yes", AndOr(1))
642 assert_equal("no", AndOr(2))
643 assert_equal("yes", AndOr(4))
644 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200645 assert_match('AndOr\_s*' ..
646 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
647 '\d LOAD arg\[-1]\_s*' ..
648 '\d PUSHNR 1\_s*' ..
649 '\d COMPAREANY ==\_s*' ..
650 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
651 '\d LOAD arg\[-1]\_s*' ..
652 '\d PUSHNR 2\_s*' ..
653 '\d COMPAREANY !=\_s*' ..
654 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
655 '\d LOAD arg\[-1]\_s*' ..
656 '\d\+ PUSHNR 4\_s*' ..
657 '\d\+ COMPAREANY ==\_s*' ..
658 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200659 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100660enddef
661
Bram Moolenaar04d05222020-02-06 22:06:54 +0100662def ForLoop(): list<number>
663 let res: list<number>
664 for i in range(3)
665 res->add(i)
666 endfor
667 return res
668enddef
669
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100670def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100671 assert_equal([0, 1, 2], ForLoop())
672 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200673 assert_match('ForLoop\_s*' ..
674 'let res: list<number>\_s*' ..
675 '\d NEWLIST size 0\_s*' ..
676 '\d STORE $0\_s*' ..
677 'for i in range(3)\_s*' ..
678 '\d STORE -1 in $1\_s*' ..
679 '\d PUSHNR 3\_s*' ..
680 '\d BCALL range(argc 1)\_s*' ..
681 '\d FOR $1 -> \d\+\_s*' ..
682 '\d STORE $2\_s*' ..
683 'res->add(i)\_s*' ..
684 '\d LOAD $0\_s*' ..
685 '\d LOAD $2\_s*' ..
686 '\d\+ BCALL add(argc 2)\_s*' ..
687 '\d\+ DROP\_s*' ..
688 'endfor\_s*' ..
689 '\d\+ JUMP -> \d\+\_s*' ..
690 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200691 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100692enddef
693
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100694let g:number = 42
695
696def Computing()
697 let nr = 3
698 let nrres = nr + 7
699 nrres = nr - 7
700 nrres = nr * 7
701 nrres = nr / 7
702 nrres = nr % 7
703
704 let anyres = g:number + 7
705 anyres = g:number - 7
706 anyres = g:number * 7
707 anyres = g:number / 7
708 anyres = g:number % 7
709
710 if has('float')
711 let fl = 3.0
712 let flres = fl + 7.0
713 flres = fl - 7.0
714 flres = fl * 7.0
715 flres = fl / 7.0
716 endif
717enddef
718
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100719def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100720 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200721 assert_match('Computing.*' ..
722 'let nr = 3.*' ..
723 '\d STORE 3 in $0.*' ..
724 'let nrres = nr + 7.*' ..
725 '\d LOAD $0.*' ..
726 '\d PUSHNR 7.*' ..
727 '\d OPNR +.*' ..
728 '\d STORE $1.*' ..
729 'nrres = nr - 7.*' ..
730 '\d OPNR -.*' ..
731 'nrres = nr \* 7.*' ..
732 '\d OPNR \*.*' ..
733 'nrres = nr / 7.*' ..
734 '\d OPNR /.*' ..
735 'nrres = nr % 7.*' ..
736 '\d OPNR %.*' ..
737 'let anyres = g:number + 7.*' ..
738 '\d LOADG g:number.*' ..
739 '\d PUSHNR 7.*' ..
740 '\d OPANY +.*' ..
741 '\d STORE $2.*' ..
742 'anyres = g:number - 7.*' ..
743 '\d OPANY -.*' ..
744 'anyres = g:number \* 7.*' ..
745 '\d OPANY \*.*' ..
746 'anyres = g:number / 7.*' ..
747 '\d OPANY /.*' ..
748 'anyres = g:number % 7.*' ..
749 '\d OPANY %.*',
750 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100751 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200752 assert_match('Computing.*' ..
753 'let fl = 3.0.*' ..
754 '\d PUSHF 3.0.*' ..
755 '\d STORE $3.*' ..
756 'let flres = fl + 7.0.*' ..
757 '\d LOAD $3.*' ..
758 '\d PUSHF 7.0.*' ..
759 '\d OPFLOAT +.*' ..
760 '\d STORE $4.*' ..
761 'flres = fl - 7.0.*' ..
762 '\d OPFLOAT -.*' ..
763 'flres = fl \* 7.0.*' ..
764 '\d OPFLOAT \*.*' ..
765 'flres = fl / 7.0.*' ..
766 '\d OPFLOAT /.*',
767 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100768 endif
769enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100770
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100771def AddListBlob()
772 let reslist = [1, 2] + [3, 4]
773 let resblob = 0z1122 + 0z3344
774enddef
775
776def Test_disassemble_add_list_blob()
777 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200778 assert_match('AddListBlob.*' ..
779 'let reslist = \[1, 2] + \[3, 4].*' ..
780 '\d PUSHNR 1.*' ..
781 '\d PUSHNR 2.*' ..
782 '\d NEWLIST size 2.*' ..
783 '\d PUSHNR 3.*' ..
784 '\d PUSHNR 4.*' ..
785 '\d NEWLIST size 2.*' ..
786 '\d ADDLIST.*' ..
787 '\d STORE $.*.*' ..
788 'let resblob = 0z1122 + 0z3344.*' ..
789 '\d PUSHBLOB 0z1122.*' ..
790 '\d PUSHBLOB 0z3344.*' ..
791 '\d ADDBLOB.*' ..
792 '\d STORE $.*',
793 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100794enddef
795
796let g:aa = 'aa'
797def ConcatString(): string
798 let res = g:aa .. "bb"
799 return res
800enddef
801
802def Test_disassemble_concat()
803 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200804 assert_match('ConcatString.*' ..
805 'let res = g:aa .. "bb".*' ..
806 '\d LOADG g:aa.*' ..
807 '\d PUSHS "bb".*' ..
808 '\d 2STRING stack\[-2].*' ..
809 '\d CONCAT.*' ..
810 '\d STORE $.*',
811 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100812 assert_equal('aabb', ConcatString())
813enddef
814
815def ListIndex(): number
816 let l = [1, 2, 3]
817 let res = l[1]
818 return res
819enddef
820
821def Test_disassemble_list_index()
822 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200823 assert_match('ListIndex\_s*' ..
824 'let l = \[1, 2, 3]\_s*' ..
825 '\d PUSHNR 1\_s*' ..
826 '\d PUSHNR 2\_s*' ..
827 '\d PUSHNR 3\_s*' ..
828 '\d NEWLIST size 3\_s*' ..
829 '\d STORE $0\_s*' ..
830 'let res = l\[1]\_s*' ..
831 '\d LOAD $0\_s*' ..
832 '\d PUSHNR 1\_s*' ..
833 '\d INDEX\_s*' ..
834 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200835 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100836 assert_equal(2, ListIndex())
837enddef
838
839def DictMember(): number
840 let d = #{item: 1}
841 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200842 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100843 return res
844enddef
845
846def Test_disassemble_dict_member()
847 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200848 assert_match('DictMember\_s*' ..
849 'let d = #{item: 1}\_s*' ..
850 '\d PUSHS "item"\_s*' ..
851 '\d PUSHNR 1\_s*' ..
852 '\d NEWDICT size 1\_s*' ..
853 '\d STORE $0\_s*' ..
854 'let res = d.item\_s*' ..
855 '\d\+ LOAD $0\_s*' ..
856 '\d\+ MEMBER item\_s*' ..
857 '\d\+ STORE $1\_s*' ..
858 'res = d\["item"\]\_s*' ..
859 '\d\+ LOAD $0\_s*' ..
860 '\d\+ PUSHS "item"\_s*' ..
861 '\d\+ MEMBER\_s*' ..
862 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200863 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100864 call assert_equal(1, DictMember())
865enddef
866
867def NegateNumber(): number
868 let nr = 9
869 let plus = +nr
870 let res = -nr
871 return res
872enddef
873
874def Test_disassemble_negate_number()
875 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200876 assert_match('NegateNumber\_s*' ..
877 'let nr = 9\_s*' ..
878 '\d STORE 9 in $0\_s*' ..
879 'let plus = +nr\_s*' ..
880 '\d LOAD $0\_s*' ..
881 '\d CHECKNR\_s*' ..
882 '\d STORE $1\_s*' ..
883 'let res = -nr\_s*' ..
884 '\d LOAD $0\_s*' ..
885 '\d NEGATENR\_s*' ..
886 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200887 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100888 call assert_equal(-9, NegateNumber())
889enddef
890
891def InvertBool(): bool
892 let flag = true
893 let invert = !flag
894 let res = !!flag
895 return res
896enddef
897
898def Test_disassemble_invert_bool()
899 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200900 assert_match('InvertBool\_s*' ..
901 'let flag = true\_s*' ..
902 '\d PUSH v:true\_s*' ..
903 '\d STORE $0\_s*' ..
904 'let invert = !flag\_s*' ..
905 '\d LOAD $0\_s*' ..
906 '\d INVERT (!val)\_s*' ..
907 '\d STORE $1\_s*' ..
908 'let res = !!flag\_s*' ..
909 '\d LOAD $0\_s*' ..
910 '\d 2BOOL (!!val)\_s*' ..
911 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200912 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100913 call assert_equal(true, InvertBool())
914enddef
915
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100916def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100917 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +0200918 ['true == isFalse', 'COMPAREBOOL =='],
919 ['true != isFalse', 'COMPAREBOOL !='],
920 ['v:none == isNull', 'COMPARESPECIAL =='],
921 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200922
Bram Moolenaara5565e42020-05-09 15:44:01 +0200923 ['111 == aNumber', 'COMPARENR =='],
924 ['111 != aNumber', 'COMPARENR !='],
925 ['111 > aNumber', 'COMPARENR >'],
926 ['111 < aNumber', 'COMPARENR <'],
927 ['111 >= aNumber', 'COMPARENR >='],
928 ['111 <= aNumber', 'COMPARENR <='],
929 ['111 =~ aNumber', 'COMPARENR =\~'],
930 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200931
Bram Moolenaara5565e42020-05-09 15:44:01 +0200932 ['"xx" != aString', 'COMPARESTRING !='],
933 ['"xx" > aString', 'COMPARESTRING >'],
934 ['"xx" < aString', 'COMPARESTRING <'],
935 ['"xx" >= aString', 'COMPARESTRING >='],
936 ['"xx" <= aString', 'COMPARESTRING <='],
937 ['"xx" =~ aString', 'COMPARESTRING =\~'],
938 ['"xx" !~ aString', 'COMPARESTRING !\~'],
939 ['"xx" is aString', 'COMPARESTRING is'],
940 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200941
Bram Moolenaara5565e42020-05-09 15:44:01 +0200942 ['0z11 == aBlob', 'COMPAREBLOB =='],
943 ['0z11 != aBlob', 'COMPAREBLOB !='],
944 ['0z11 is aBlob', 'COMPAREBLOB is'],
945 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200946
Bram Moolenaara5565e42020-05-09 15:44:01 +0200947 ['[1, 2] == aList', 'COMPARELIST =='],
948 ['[1, 2] != aList', 'COMPARELIST !='],
949 ['[1, 2] is aList', 'COMPARELIST is'],
950 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200951
Bram Moolenaara5565e42020-05-09 15:44:01 +0200952 ['#{a: 1} == aDict', 'COMPAREDICT =='],
953 ['#{a: 1} != aDict', 'COMPAREDICT !='],
954 ['#{a: 1} is aDict', 'COMPAREDICT is'],
955 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200956
957 ['{->33} == {->44}', 'COMPAREFUNC =='],
958 ['{->33} != {->44}', 'COMPAREFUNC !='],
959 ['{->33} is {->44}', 'COMPAREFUNC is'],
960 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
961
962 ['77 == g:xx', 'COMPAREANY =='],
963 ['77 != g:xx', 'COMPAREANY !='],
964 ['77 > g:xx', 'COMPAREANY >'],
965 ['77 < g:xx', 'COMPAREANY <'],
966 ['77 >= g:xx', 'COMPAREANY >='],
967 ['77 <= g:xx', 'COMPAREANY <='],
968 ['77 =~ g:xx', 'COMPAREANY =\~'],
969 ['77 !~ g:xx', 'COMPAREANY !\~'],
970 ['77 is g:xx', 'COMPAREANY is'],
971 ['77 isnot g:xx', 'COMPAREANY isnot'],
972 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +0200973 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100974 if has('float')
975 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +0200976 ['1.1 == aFloat', 'COMPAREFLOAT =='],
977 ['1.1 != aFloat', 'COMPAREFLOAT !='],
978 ['1.1 > aFloat', 'COMPAREFLOAT >'],
979 ['1.1 < aFloat', 'COMPAREFLOAT <'],
980 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
981 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
982 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
983 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200984 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +0200985 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100986 endif
987
988 let nr = 1
989 for case in cases
Bram Moolenaara5565e42020-05-09 15:44:01 +0200990 " declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100991 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +0200992 ' let isFalse = false',
993 ' let isNull = v:null',
994 ' let aNumber = 222',
995 ' let aString = "yy"',
996 ' let aBlob = 0z22',
997 ' let aList = [3, 4]',
998 ' let aDict = #{x: 2}',
999 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001000 ' if ' .. case[0],
1001 ' echo 42'
1002 ' endif',
1003 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001004 source Xdisassemble
1005 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001006 assert_match('TestCase' .. nr .. '.*' ..
1007 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1008 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001009 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001010 '\d ' .. case[1] .. '.*' ..
1011 '\d JUMP_IF_FALSE -> \d\+.*',
1012 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001013
1014 nr += 1
1015 endfor
1016
Bram Moolenaar22da5592020-03-19 14:52:20 +01001017 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001018enddef
1019
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001020def Test_disassemble_compare_const()
1021 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001022 ['"xx" == "yy"', false],
1023 ['"aa" == "aa"', true],
1024 ['has("eval") ? true : false', true],
1025 ['has("asdf") ? true : false', false],
1026 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001027
1028 let nr = 1
1029 for case in cases
1030 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001031 ' if ' .. case[0],
1032 ' echo 42'
1033 ' endif',
1034 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001035 source Xdisassemble
1036 let instr = execute('disassemble TestCase' .. nr)
1037 if case[1]
1038 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001039 assert_match('TestCase' .. nr .. '.*' ..
1040 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1041 '\d PUSHNR 42.*' ..
1042 '\d ECHO 1.*' ..
1043 '\d PUSHNR 0.*' ..
1044 '\d RETURN.*',
1045 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001046 else
1047 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001048 assert_match('TestCase' .. nr .. '.*' ..
1049 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1050 'echo 42[ \n]*' ..
1051 'endif[ \n]*' ..
1052 '\s*\d PUSHNR 0.*' ..
1053 '\d RETURN.*',
1054 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001055 endif
1056
1057 nr += 1
1058 endfor
1059
1060 delete('Xdisassemble')
1061enddef
1062
Bram Moolenaarad39c092020-02-26 18:23:43 +01001063def s:Execute()
1064 execute 'help vim9.txt'
1065 let cmd = 'help vim9.txt'
1066 execute cmd
1067 let tag = 'vim9.txt'
1068 execute 'help ' .. tag
1069enddef
1070
1071def Test_disassemble_execute()
1072 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001073 assert_match('\<SNR>\d*_Execute\_s*' ..
1074 "execute 'help vim9.txt'\\_s*" ..
1075 '\d PUSHS "help vim9.txt"\_s*' ..
1076 '\d EXECUTE 1\_s*' ..
1077 "let cmd = 'help vim9.txt'\\_s*" ..
1078 '\d PUSHS "help vim9.txt"\_s*' ..
1079 '\d STORE $0\_s*' ..
1080 'execute cmd\_s*' ..
1081 '\d LOAD $0\_s*' ..
1082 '\d EXECUTE 1\_s*' ..
1083 "let tag = 'vim9.txt'\\_s*" ..
1084 '\d PUSHS "vim9.txt"\_s*' ..
1085 '\d STORE $1\_s*' ..
1086 "execute 'help ' .. tag\\_s*" ..
1087 '\d\+ PUSHS "help "\_s*' ..
1088 '\d\+ LOAD $1\_s*' ..
1089 '\d\+ CONCAT\_s*' ..
1090 '\d\+ EXECUTE 1\_s*' ..
1091 '\d\+ PUSHNR 0\_s*' ..
1092 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001093 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001094enddef
1095
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001096def s:Echomsg()
1097 echomsg 'some' 'message'
1098 echoerr 'went' .. 'wrong'
1099enddef
1100
1101def Test_disassemble_echomsg()
1102 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001103 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1104 "echomsg 'some' 'message'\\_s*" ..
1105 '\d PUSHS "some"\_s*' ..
1106 '\d PUSHS "message"\_s*' ..
1107 '\d ECHOMSG 2\_s*' ..
1108 "echoerr 'went' .. 'wrong'\\_s*" ..
1109 '\d PUSHS "wentwrong"\_s*' ..
1110 '\d ECHOERR 1\_s*' ..
1111 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001112 '\d RETURN',
1113 res)
1114enddef
1115
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001116def SomeStringArg(arg: string)
1117 echo arg
1118enddef
1119
1120def SomeAnyArg(arg: any)
1121 echo arg
1122enddef
1123
1124def SomeStringArgAndReturn(arg: string): string
1125 return arg
1126enddef
1127
1128def Test_display_func()
1129 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001130 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1131 '\d *echo arg.*' ..
1132 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001133 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001134
1135 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001136 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1137 '\d *echo arg\_s*' ..
1138 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001139 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001140
1141 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001142 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1143 '\d *return arg\_s*' ..
1144 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001145 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001146enddef
1147
Bram Moolenaar09689a02020-05-09 22:50:08 +02001148def Test_vim9script_forward_func()
1149 let lines =<< trim END
1150 vim9script
1151 def FuncOne(): string
1152 return FuncTwo()
1153 enddef
1154 def FuncTwo(): string
1155 return 'two'
1156 enddef
Bram Moolenaar32e35112020-05-14 22:41:15 +02001157 let g:res_FuncOne: string = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001158 END
1159 writefile(lines, 'Xdisassemble')
1160 source Xdisassemble
1161
1162 " check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001163 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1164 'return FuncTwo()\_s*' ..
1165 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001166 '\d RETURN',
1167 g:res_FuncOne)
1168
1169 delete('Xdisassemble')
1170 unlet g:res_FuncOne
1171enddef
1172
Bram Moolenaar61a89812020-05-07 16:58:17 +02001173def s:ConcatStrings(): string
1174 return 'one' .. 'two' .. 'three'
1175enddef
1176
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001177def s:ComputeConst(): number
1178 return 2 + 3 * 4 / 6 + 7
1179enddef
1180
Bram Moolenaar1c747212020-05-09 18:28:34 +02001181def s:ComputeConstParen(): number
1182 return ((2 + 4) * (8 / 2)) / (3 + 4)
1183enddef
1184
Bram Moolenaar61a89812020-05-07 16:58:17 +02001185def Test_simplify_const_expr()
1186 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001187 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1188 "return 'one' .. 'two' .. 'three'\\_s*" ..
1189 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001190 '\d RETURN',
1191 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001192
1193 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001194 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1195 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1196 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001197 '\d RETURN',
1198 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001199
1200 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001201 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1202 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1203 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001204 '\d RETURN',
1205 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001206enddef
1207
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001208" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker