blob: 74804b4cf2d34a8e93bc5727c06bd511573254f7 [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*' ..
426 '\d UCALL g:DefinedLater(argc 1)\_s*' ..
427 '\d CHECKTYPE string stack\[-1]\_s*' ..
428 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200429 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100430
431 " Calling the function will change UCALL into the faster DCALL
432 assert_equal('yes', FuncWithForwardCall())
433
Bram Moolenaara26b9702020-04-18 19:53:28 +0200434 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200435 assert_match('FuncWithForwardCall\_s*' ..
436 'return g:DefinedLater("yes")\_s*' ..
437 '\d PUSHS "yes"\_s*' ..
438 '\d DCALL DefinedLater(argc 1)\_s*' ..
439 '\d CHECKTYPE string stack\[-1]\_s*' ..
440 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200441 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100442enddef
443
444
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100445def FuncWithDefault(arg: string = 'default'): string
446 return arg
447enddef
448
449def Test_disassemble_call_default()
450 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200451 assert_match('FuncWithDefault\_s*' ..
452 '\d PUSHS "default"\_s*' ..
453 '\d STORE arg\[-1]\_s*' ..
454 'return arg\_s*' ..
455 '\d LOAD arg\[-1]\_s*' ..
456 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200457 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100458enddef
459
460
Bram Moolenaar158906c2020-02-06 20:39:45 +0100461def HasEval()
462 if has("eval")
463 echo "yes"
464 else
465 echo "no"
466 endif
467enddef
468
469def HasNothing()
470 if has("nothing")
471 echo "yes"
472 else
473 echo "no"
474 endif
475enddef
476
477def HasSomething()
478 if has("nothing")
479 echo "nothing"
480 elseif has("something")
481 echo "something"
482 elseif has("eval")
483 echo "eval"
484 elseif has("less")
485 echo "less"
486 endif
487enddef
488
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100489def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100490 assert_equal("\nyes", execute('call HasEval()'))
491 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200492 assert_match('HasEval\_s*' ..
493 'if has("eval")\_s*' ..
494 'echo "yes"\_s*' ..
495 '\d PUSHS "yes"\_s*' ..
496 '\d ECHO 1\_s*' ..
497 'else\_s*' ..
498 'echo "no"\_s*' ..
499 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200500 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100501 assert_notmatch('JUMP', instr)
502
503 assert_equal("\nno", execute('call HasNothing()'))
504 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200505 assert_match('HasNothing\_s*' ..
506 'if has("nothing")\_s*' ..
507 'echo "yes"\_s*' ..
508 'else\_s*' ..
509 'echo "no"\_s*' ..
510 '\d PUSHS "no"\_s*' ..
511 '\d ECHO 1\_s*' ..
512 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200513 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100514 assert_notmatch('PUSHS "yes"', instr)
515 assert_notmatch('JUMP', instr)
516
517 assert_equal("\neval", execute('call HasSomething()'))
518 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200519 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200520 'if has("nothing")\_s*' ..
521 'echo "nothing"\_s*' ..
522 'elseif has("something")\_s*' ..
523 'echo "something"\_s*' ..
524 'elseif has("eval")\_s*' ..
525 'echo "eval"\_s*' ..
526 '\d PUSHS "eval"\_s*' ..
527 '\d ECHO 1\_s*' ..
528 'elseif has("less").*' ..
529 'echo "less"\_s*' ..
530 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200531 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100532 assert_notmatch('PUSHS "nothing"', instr)
533 assert_notmatch('PUSHS "something"', instr)
534 assert_notmatch('PUSHS "less"', instr)
535 assert_notmatch('JUMP', instr)
536enddef
537
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100538def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200539 let Funky1: func
540 let Funky2: func = function("len")
541 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100542enddef
543
544def Test_disassemble_function()
545 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200546 assert_match('WithFunc\_s*' ..
547 'let Funky1: func\_s*' ..
548 '0 PUSHFUNC "\[none]"\_s*' ..
549 '1 STORE $0\_s*' ..
550 'let Funky2: func = function("len")\_s*' ..
551 '2 PUSHS "len"\_s*' ..
552 '3 BCALL function(argc 1)\_s*' ..
553 '4 STORE $1\_s*' ..
554 'let Party2: func = funcref("UserFunc")\_s*' ..
555 '\d PUSHS "UserFunc"\_s*' ..
556 '\d BCALL funcref(argc 1)\_s*' ..
557 '\d STORE $2\_s*' ..
558 '\d PUSHNR 0\_s*' ..
559 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200560 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100561enddef
562
563if has('channel')
564 def WithChannel()
565 let job1: job
566 let job2: job = job_start("donothing")
567 let chan1: channel
568 enddef
569endif
570
571def Test_disassemble_channel()
572 CheckFeature channel
573
574 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200575 assert_match('WithChannel\_s*' ..
576 'let job1: job\_s*' ..
577 '\d PUSHJOB "no process"\_s*' ..
578 '\d STORE $0\_s*' ..
579 'let job2: job = job_start("donothing")\_s*' ..
580 '\d PUSHS "donothing"\_s*' ..
581 '\d BCALL job_start(argc 1)\_s*' ..
582 '\d STORE $1\_s*' ..
583 'let chan1: channel\_s*' ..
584 '\d PUSHCHANNEL 0\_s*' ..
585 '\d STORE $2\_s*' ..
586 '\d PUSHNR 0\_s*' ..
587 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200588 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100589enddef
590
Bram Moolenaar777770f2020-02-06 21:27:08 +0100591def WithLambda(): string
592 let F = {a -> "X" .. a .. "X"}
593 return F("x")
594enddef
595
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100596def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100597 assert_equal("XxX", WithLambda())
598 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200599 assert_match('WithLambda\_s*' ..
600 'let F = {a -> "X" .. a .. "X"}\_s*' ..
601 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
602 '\d STORE $0\_s*' ..
603 'return F("x")\_s*' ..
604 '\d PUSHS "x"\_s*' ..
605 '\d LOAD $0\_s*' ..
606 '\d PCALL (argc 1)\_s*' ..
607 '\d CHECKTYPE string stack\[-1]',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200608 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100609enddef
610
Bram Moolenaar6e949782020-04-13 17:21:00 +0200611def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100612 if arg == 1 && arg != 2 || arg == 4
613 return 'yes'
614 endif
615 return 'no'
616enddef
617
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100618def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100619 assert_equal("yes", AndOr(1))
620 assert_equal("no", AndOr(2))
621 assert_equal("yes", AndOr(4))
622 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200623 assert_match('AndOr\_s*' ..
624 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
625 '\d LOAD arg\[-1]\_s*' ..
626 '\d PUSHNR 1\_s*' ..
627 '\d COMPAREANY ==\_s*' ..
628 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
629 '\d LOAD arg\[-1]\_s*' ..
630 '\d PUSHNR 2\_s*' ..
631 '\d COMPAREANY !=\_s*' ..
632 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
633 '\d LOAD arg\[-1]\_s*' ..
634 '\d\+ PUSHNR 4\_s*' ..
635 '\d\+ COMPAREANY ==\_s*' ..
636 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200637 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100638enddef
639
Bram Moolenaar04d05222020-02-06 22:06:54 +0100640def ForLoop(): list<number>
641 let res: list<number>
642 for i in range(3)
643 res->add(i)
644 endfor
645 return res
646enddef
647
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100648def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100649 assert_equal([0, 1, 2], ForLoop())
650 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200651 assert_match('ForLoop\_s*' ..
652 'let res: list<number>\_s*' ..
653 '\d NEWLIST size 0\_s*' ..
654 '\d STORE $0\_s*' ..
655 'for i in range(3)\_s*' ..
656 '\d STORE -1 in $1\_s*' ..
657 '\d PUSHNR 3\_s*' ..
658 '\d BCALL range(argc 1)\_s*' ..
659 '\d FOR $1 -> \d\+\_s*' ..
660 '\d STORE $2\_s*' ..
661 'res->add(i)\_s*' ..
662 '\d LOAD $0\_s*' ..
663 '\d LOAD $2\_s*' ..
664 '\d\+ BCALL add(argc 2)\_s*' ..
665 '\d\+ DROP\_s*' ..
666 'endfor\_s*' ..
667 '\d\+ JUMP -> \d\+\_s*' ..
668 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200669 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100670enddef
671
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100672let g:number = 42
673
674def Computing()
675 let nr = 3
676 let nrres = nr + 7
677 nrres = nr - 7
678 nrres = nr * 7
679 nrres = nr / 7
680 nrres = nr % 7
681
682 let anyres = g:number + 7
683 anyres = g:number - 7
684 anyres = g:number * 7
685 anyres = g:number / 7
686 anyres = g:number % 7
687
688 if has('float')
689 let fl = 3.0
690 let flres = fl + 7.0
691 flres = fl - 7.0
692 flres = fl * 7.0
693 flres = fl / 7.0
694 endif
695enddef
696
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100697def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100698 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200699 assert_match('Computing.*' ..
700 'let nr = 3.*' ..
701 '\d STORE 3 in $0.*' ..
702 'let nrres = nr + 7.*' ..
703 '\d LOAD $0.*' ..
704 '\d PUSHNR 7.*' ..
705 '\d OPNR +.*' ..
706 '\d STORE $1.*' ..
707 'nrres = nr - 7.*' ..
708 '\d OPNR -.*' ..
709 'nrres = nr \* 7.*' ..
710 '\d OPNR \*.*' ..
711 'nrres = nr / 7.*' ..
712 '\d OPNR /.*' ..
713 'nrres = nr % 7.*' ..
714 '\d OPNR %.*' ..
715 'let anyres = g:number + 7.*' ..
716 '\d LOADG g:number.*' ..
717 '\d PUSHNR 7.*' ..
718 '\d OPANY +.*' ..
719 '\d STORE $2.*' ..
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 'anyres = g:number % 7.*' ..
727 '\d OPANY %.*',
728 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100729 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200730 assert_match('Computing.*' ..
731 'let fl = 3.0.*' ..
732 '\d PUSHF 3.0.*' ..
733 '\d STORE $3.*' ..
734 'let flres = fl + 7.0.*' ..
735 '\d LOAD $3.*' ..
736 '\d PUSHF 7.0.*' ..
737 '\d OPFLOAT +.*' ..
738 '\d STORE $4.*' ..
739 'flres = fl - 7.0.*' ..
740 '\d OPFLOAT -.*' ..
741 'flres = fl \* 7.0.*' ..
742 '\d OPFLOAT \*.*' ..
743 'flres = fl / 7.0.*' ..
744 '\d OPFLOAT /.*',
745 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100746 endif
747enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100748
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100749def AddListBlob()
750 let reslist = [1, 2] + [3, 4]
751 let resblob = 0z1122 + 0z3344
752enddef
753
754def Test_disassemble_add_list_blob()
755 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200756 assert_match('AddListBlob.*' ..
757 'let reslist = \[1, 2] + \[3, 4].*' ..
758 '\d PUSHNR 1.*' ..
759 '\d PUSHNR 2.*' ..
760 '\d NEWLIST size 2.*' ..
761 '\d PUSHNR 3.*' ..
762 '\d PUSHNR 4.*' ..
763 '\d NEWLIST size 2.*' ..
764 '\d ADDLIST.*' ..
765 '\d STORE $.*.*' ..
766 'let resblob = 0z1122 + 0z3344.*' ..
767 '\d PUSHBLOB 0z1122.*' ..
768 '\d PUSHBLOB 0z3344.*' ..
769 '\d ADDBLOB.*' ..
770 '\d STORE $.*',
771 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100772enddef
773
774let g:aa = 'aa'
775def ConcatString(): string
776 let res = g:aa .. "bb"
777 return res
778enddef
779
780def Test_disassemble_concat()
781 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200782 assert_match('ConcatString.*' ..
783 'let res = g:aa .. "bb".*' ..
784 '\d LOADG g:aa.*' ..
785 '\d PUSHS "bb".*' ..
786 '\d 2STRING stack\[-2].*' ..
787 '\d CONCAT.*' ..
788 '\d STORE $.*',
789 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100790 assert_equal('aabb', ConcatString())
791enddef
792
793def ListIndex(): number
794 let l = [1, 2, 3]
795 let res = l[1]
796 return res
797enddef
798
799def Test_disassemble_list_index()
800 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200801 assert_match('ListIndex\_s*' ..
802 'let l = \[1, 2, 3]\_s*' ..
803 '\d PUSHNR 1\_s*' ..
804 '\d PUSHNR 2\_s*' ..
805 '\d PUSHNR 3\_s*' ..
806 '\d NEWLIST size 3\_s*' ..
807 '\d STORE $0\_s*' ..
808 'let res = l\[1]\_s*' ..
809 '\d LOAD $0\_s*' ..
810 '\d PUSHNR 1\_s*' ..
811 '\d INDEX\_s*' ..
812 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200813 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100814 assert_equal(2, ListIndex())
815enddef
816
817def DictMember(): number
818 let d = #{item: 1}
819 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200820 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100821 return res
822enddef
823
824def Test_disassemble_dict_member()
825 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200826 assert_match('DictMember\_s*' ..
827 'let d = #{item: 1}\_s*' ..
828 '\d PUSHS "item"\_s*' ..
829 '\d PUSHNR 1\_s*' ..
830 '\d NEWDICT size 1\_s*' ..
831 '\d STORE $0\_s*' ..
832 'let res = d.item\_s*' ..
833 '\d\+ LOAD $0\_s*' ..
834 '\d\+ MEMBER item\_s*' ..
835 '\d\+ STORE $1\_s*' ..
836 'res = d\["item"\]\_s*' ..
837 '\d\+ LOAD $0\_s*' ..
838 '\d\+ PUSHS "item"\_s*' ..
839 '\d\+ MEMBER\_s*' ..
840 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200841 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100842 call assert_equal(1, DictMember())
843enddef
844
845def NegateNumber(): number
846 let nr = 9
847 let plus = +nr
848 let res = -nr
849 return res
850enddef
851
852def Test_disassemble_negate_number()
853 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200854 assert_match('NegateNumber\_s*' ..
855 'let nr = 9\_s*' ..
856 '\d STORE 9 in $0\_s*' ..
857 'let plus = +nr\_s*' ..
858 '\d LOAD $0\_s*' ..
859 '\d CHECKNR\_s*' ..
860 '\d STORE $1\_s*' ..
861 'let res = -nr\_s*' ..
862 '\d LOAD $0\_s*' ..
863 '\d NEGATENR\_s*' ..
864 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200865 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100866 call assert_equal(-9, NegateNumber())
867enddef
868
869def InvertBool(): bool
870 let flag = true
871 let invert = !flag
872 let res = !!flag
873 return res
874enddef
875
876def Test_disassemble_invert_bool()
877 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200878 assert_match('InvertBool\_s*' ..
879 'let flag = true\_s*' ..
880 '\d PUSH v:true\_s*' ..
881 '\d STORE $0\_s*' ..
882 'let invert = !flag\_s*' ..
883 '\d LOAD $0\_s*' ..
884 '\d INVERT (!val)\_s*' ..
885 '\d STORE $1\_s*' ..
886 'let res = !!flag\_s*' ..
887 '\d LOAD $0\_s*' ..
888 '\d 2BOOL (!!val)\_s*' ..
889 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200890 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100891 call assert_equal(true, InvertBool())
892enddef
893
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100894def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100895 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +0200896 ['true == isFalse', 'COMPAREBOOL =='],
897 ['true != isFalse', 'COMPAREBOOL !='],
898 ['v:none == isNull', 'COMPARESPECIAL =='],
899 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200900
Bram Moolenaara5565e42020-05-09 15:44:01 +0200901 ['111 == aNumber', 'COMPARENR =='],
902 ['111 != aNumber', 'COMPARENR !='],
903 ['111 > aNumber', 'COMPARENR >'],
904 ['111 < aNumber', 'COMPARENR <'],
905 ['111 >= aNumber', 'COMPARENR >='],
906 ['111 <= aNumber', 'COMPARENR <='],
907 ['111 =~ aNumber', 'COMPARENR =\~'],
908 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200909
Bram Moolenaara5565e42020-05-09 15:44:01 +0200910 ['"xx" != aString', 'COMPARESTRING !='],
911 ['"xx" > aString', 'COMPARESTRING >'],
912 ['"xx" < aString', 'COMPARESTRING <'],
913 ['"xx" >= aString', 'COMPARESTRING >='],
914 ['"xx" <= aString', 'COMPARESTRING <='],
915 ['"xx" =~ aString', 'COMPARESTRING =\~'],
916 ['"xx" !~ aString', 'COMPARESTRING !\~'],
917 ['"xx" is aString', 'COMPARESTRING is'],
918 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200919
Bram Moolenaara5565e42020-05-09 15:44:01 +0200920 ['0z11 == aBlob', 'COMPAREBLOB =='],
921 ['0z11 != aBlob', 'COMPAREBLOB !='],
922 ['0z11 is aBlob', 'COMPAREBLOB is'],
923 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200924
Bram Moolenaara5565e42020-05-09 15:44:01 +0200925 ['[1, 2] == aList', 'COMPARELIST =='],
926 ['[1, 2] != aList', 'COMPARELIST !='],
927 ['[1, 2] is aList', 'COMPARELIST is'],
928 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200929
Bram Moolenaara5565e42020-05-09 15:44:01 +0200930 ['#{a: 1} == aDict', 'COMPAREDICT =='],
931 ['#{a: 1} != aDict', 'COMPAREDICT !='],
932 ['#{a: 1} is aDict', 'COMPAREDICT is'],
933 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200934
935 ['{->33} == {->44}', 'COMPAREFUNC =='],
936 ['{->33} != {->44}', 'COMPAREFUNC !='],
937 ['{->33} is {->44}', 'COMPAREFUNC is'],
938 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
939
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 =~ g:xx', 'COMPAREANY =\~'],
947 ['77 !~ g:xx', 'COMPAREANY !\~'],
948 ['77 is g:xx', 'COMPAREANY is'],
949 ['77 isnot g:xx', 'COMPAREANY isnot'],
950 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +0200951 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100952 if has('float')
953 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +0200954 ['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 <='],
960 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
961 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200962 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +0200963 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100964 endif
965
966 let nr = 1
967 for case in cases
Bram Moolenaara5565e42020-05-09 15:44:01 +0200968 " declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100969 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +0200970 ' let isFalse = false',
971 ' let isNull = v:null',
972 ' let aNumber = 222',
973 ' let aString = "yy"',
974 ' let aBlob = 0z22',
975 ' let aList = [3, 4]',
976 ' let aDict = #{x: 2}',
977 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +0200978 ' if ' .. case[0],
979 ' echo 42'
980 ' endif',
981 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100982 source Xdisassemble
983 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200984 assert_match('TestCase' .. nr .. '.*' ..
985 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
986 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +0200987 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200988 '\d ' .. case[1] .. '.*' ..
989 '\d JUMP_IF_FALSE -> \d\+.*',
990 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100991
992 nr += 1
993 endfor
994
Bram Moolenaar22da5592020-03-19 14:52:20 +0100995 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100996enddef
997
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200998def Test_disassemble_compare_const()
999 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001000 ['"xx" == "yy"', false],
1001 ['"aa" == "aa"', true],
1002 ['has("eval") ? true : false', true],
1003 ['has("asdf") ? true : false', false],
1004 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001005
1006 let nr = 1
1007 for case in cases
1008 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001009 ' if ' .. case[0],
1010 ' echo 42'
1011 ' endif',
1012 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001013 source Xdisassemble
1014 let instr = execute('disassemble TestCase' .. nr)
1015 if case[1]
1016 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001017 assert_match('TestCase' .. nr .. '.*' ..
1018 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1019 '\d PUSHNR 42.*' ..
1020 '\d ECHO 1.*' ..
1021 '\d PUSHNR 0.*' ..
1022 '\d RETURN.*',
1023 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001024 else
1025 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001026 assert_match('TestCase' .. nr .. '.*' ..
1027 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1028 'echo 42[ \n]*' ..
1029 'endif[ \n]*' ..
1030 '\s*\d PUSHNR 0.*' ..
1031 '\d RETURN.*',
1032 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001033 endif
1034
1035 nr += 1
1036 endfor
1037
1038 delete('Xdisassemble')
1039enddef
1040
Bram Moolenaarad39c092020-02-26 18:23:43 +01001041def s:Execute()
1042 execute 'help vim9.txt'
1043 let cmd = 'help vim9.txt'
1044 execute cmd
1045 let tag = 'vim9.txt'
1046 execute 'help ' .. tag
1047enddef
1048
1049def Test_disassemble_execute()
1050 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001051 assert_match('\<SNR>\d*_Execute\_s*' ..
1052 "execute 'help vim9.txt'\\_s*" ..
1053 '\d PUSHS "help vim9.txt"\_s*' ..
1054 '\d EXECUTE 1\_s*' ..
1055 "let cmd = 'help vim9.txt'\\_s*" ..
1056 '\d PUSHS "help vim9.txt"\_s*' ..
1057 '\d STORE $0\_s*' ..
1058 'execute cmd\_s*' ..
1059 '\d LOAD $0\_s*' ..
1060 '\d EXECUTE 1\_s*' ..
1061 "let tag = 'vim9.txt'\\_s*" ..
1062 '\d PUSHS "vim9.txt"\_s*' ..
1063 '\d STORE $1\_s*' ..
1064 "execute 'help ' .. tag\\_s*" ..
1065 '\d\+ PUSHS "help "\_s*' ..
1066 '\d\+ LOAD $1\_s*' ..
1067 '\d\+ CONCAT\_s*' ..
1068 '\d\+ EXECUTE 1\_s*' ..
1069 '\d\+ PUSHNR 0\_s*' ..
1070 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001071 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001072enddef
1073
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001074def s:Echomsg()
1075 echomsg 'some' 'message'
1076 echoerr 'went' .. 'wrong'
1077enddef
1078
1079def Test_disassemble_echomsg()
1080 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001081 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1082 "echomsg 'some' 'message'\\_s*" ..
1083 '\d PUSHS "some"\_s*' ..
1084 '\d PUSHS "message"\_s*' ..
1085 '\d ECHOMSG 2\_s*' ..
1086 "echoerr 'went' .. 'wrong'\\_s*" ..
1087 '\d PUSHS "wentwrong"\_s*' ..
1088 '\d ECHOERR 1\_s*' ..
1089 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001090 '\d RETURN',
1091 res)
1092enddef
1093
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001094def SomeStringArg(arg: string)
1095 echo arg
1096enddef
1097
1098def SomeAnyArg(arg: any)
1099 echo arg
1100enddef
1101
1102def SomeStringArgAndReturn(arg: string): string
1103 return arg
1104enddef
1105
1106def Test_display_func()
1107 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001108 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1109 '\d *echo arg.*' ..
1110 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001111 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001112
1113 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001114 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1115 '\d *echo arg\_s*' ..
1116 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001117 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001118
1119 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001120 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1121 '\d *return arg\_s*' ..
1122 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001123 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001124enddef
1125
Bram Moolenaar09689a02020-05-09 22:50:08 +02001126def Test_vim9script_forward_func()
1127 let lines =<< trim END
1128 vim9script
1129 def FuncOne(): string
1130 return FuncTwo()
1131 enddef
1132 def FuncTwo(): string
1133 return 'two'
1134 enddef
Bram Moolenaar32e35112020-05-14 22:41:15 +02001135 let g:res_FuncOne: string = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001136 END
1137 writefile(lines, 'Xdisassemble')
1138 source Xdisassemble
1139
1140 " check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001141 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1142 'return FuncTwo()\_s*' ..
1143 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001144 '\d RETURN',
1145 g:res_FuncOne)
1146
1147 delete('Xdisassemble')
1148 unlet g:res_FuncOne
1149enddef
1150
Bram Moolenaar61a89812020-05-07 16:58:17 +02001151def s:ConcatStrings(): string
1152 return 'one' .. 'two' .. 'three'
1153enddef
1154
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001155def s:ComputeConst(): number
1156 return 2 + 3 * 4 / 6 + 7
1157enddef
1158
Bram Moolenaar1c747212020-05-09 18:28:34 +02001159def s:ComputeConstParen(): number
1160 return ((2 + 4) * (8 / 2)) / (3 + 4)
1161enddef
1162
Bram Moolenaar61a89812020-05-07 16:58:17 +02001163def Test_simplify_const_expr()
1164 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001165 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1166 "return 'one' .. 'two' .. 'three'\\_s*" ..
1167 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001168 '\d RETURN',
1169 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001170
1171 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001172 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1173 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1174 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001175 '\d RETURN',
1176 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001177
1178 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001179 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1180 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1181 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001182 '\d RETURN',
1183 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001184enddef
1185
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001186" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker