blob: 13d9542622835a9de7e072a1e08278992652866c [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
20 echo v:version
21 echo s:scriptvar
22 echo g:globalvar
Bram Moolenaard3aac292020-04-19 14:32:17 +020023 echo b:buffervar
24 echo w:windowvar
25 echo t:tabpagevar
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010026 echo &tabstop
27 echo $ENVVAR
28 echo @z
29enddef
30
Bram Moolenaarf2460a32020-02-07 22:09:54 +010031def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010032 assert_fails('disass NoFunc', 'E1061:')
33 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010034 assert_fails('disass', 'E471:')
35 assert_fails('disass [', 'E475:')
36 assert_fails('disass 234', 'E475:')
37 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010038
39 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020040 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
41 'buffers.*' ..
42 ' EXEC \+buffers.*' ..
43 ' LOAD arg\[-1\].*' ..
44 ' LOAD $0.*' ..
45 ' LOADV v:version.*' ..
46 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
47 ' LOADG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020048 ' LOADB b:buffervar.*' ..
49 ' LOADW w:windowvar.*' ..
50 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020051 ' LOADENV $ENVVAR.*' ..
52 ' LOADREG @z.*',
53 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010054enddef
55
56def s:ScriptFuncPush()
57 let localbool = true
58 let localspec = v:none
59 let localblob = 0z1234
60 if has('float')
61 let localfloat = 1.234
62 endif
63enddef
64
Bram Moolenaarf2460a32020-02-07 22:09:54 +010065def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010066 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020067 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
68 'localbool = true.*' ..
69 ' PUSH v:true.*' ..
70 'localspec = v:none.*' ..
71 ' PUSH v:none.*' ..
72 'localblob = 0z1234.*' ..
73 ' PUSHBLOB 0z1234.*',
74 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010075 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +020076 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
77 'localfloat = 1.234.*' ..
78 ' PUSHF 1.234.*',
79 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010080 endif
81enddef
82
83def s:ScriptFuncStore()
84 let localnr = 1
85 localnr = 2
86 let localstr = 'abc'
87 localstr = 'xyz'
88 v:char = 'abc'
89 s:scriptvar = 'sv'
90 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +020091 b:buffervar = 'bv'
92 w:windowvar = 'wv'
93 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010094 &tabstop = 8
95 $ENVVAR = 'ev'
96 @z = 'rv'
97enddef
98
Bram Moolenaarf2460a32020-02-07 22:09:54 +010099def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100100 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200101 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
102 'let localnr = 1.*' ..
103 'localnr = 2.*' ..
104 ' STORE 2 in $0.*' ..
105 'let localstr = ''abc''.*' ..
106 'localstr = ''xyz''.*' ..
107 ' STORE $1.*' ..
108 'v:char = ''abc''.*' ..
109 'STOREV v:char.*' ..
110 's:scriptvar = ''sv''.*' ..
111 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
112 'g:globalvar = ''gv''.*' ..
113 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200114 'b:buffervar = ''bv''.*' ..
115 ' STOREB b:buffervar.*' ..
116 'w:windowvar = ''wv''.*' ..
117 ' STOREW w:windowvar.*' ..
118 't:tabpagevar = ''tv''.*' ..
119 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200120 '&tabstop = 8.*' ..
121 ' STOREOPT &tabstop.*' ..
122 '$ENVVAR = ''ev''.*' ..
123 ' STOREENV $ENVVAR.*' ..
124 '@z = ''rv''.*' ..
125 ' STOREREG @z.*',
126 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100127enddef
128
129def s:ScriptFuncTry()
130 try
131 echo 'yes'
132 catch /fail/
133 echo 'no'
134 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100135 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100136 endtry
137enddef
138
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100139def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100140 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200141 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
142 'try.*' ..
143 'TRY catch -> \d\+, finally -> \d\+.*' ..
144 'catch /fail/.*' ..
145 ' JUMP -> \d\+.*' ..
146 ' PUSH v:exception.*' ..
147 ' PUSHS "fail".*' ..
148 ' COMPARESTRING =\~.*' ..
149 ' JUMP_IF_FALSE -> \d\+.*' ..
150 ' CATCH.*' ..
151 'finally.*' ..
152 ' PUSHS "end".*' ..
153 ' THROW.*' ..
154 'endtry.*' ..
155 ' ENDTRY.*',
156 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100157enddef
158
159def s:ScriptFuncNew()
160 let ll = [1, "two", 333]
161 let dd = #{one: 1, two: "val"}
162enddef
163
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100164def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100165 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200166 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
167 'let ll = \[1, "two", 333].*' ..
168 'PUSHNR 1.*' ..
169 'PUSHS "two".*' ..
170 'PUSHNR 333.*' ..
171 'NEWLIST size 3.*' ..
172 'let dd = #{one: 1, two: "val"}.*' ..
173 'PUSHS "one".*' ..
174 'PUSHNR 1.*' ..
175 'PUSHS "two".*' ..
176 'PUSHS "val".*' ..
177 'NEWDICT size 2.*',
178 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100179enddef
180
Bram Moolenaar6e949782020-04-13 17:21:00 +0200181def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100182 echo arg
183enddef
184
185func UserFunc()
186 echo 'nothing'
187endfunc
188
189func UserFuncWithArg(arg)
190 echo a:arg
191endfunc
192
193def s:ScriptFuncCall(): string
194 changenr()
195 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100196 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100197 FuncWithArg(343)
198 ScriptFuncNew()
199 s:ScriptFuncNew()
200 UserFunc()
201 UserFuncWithArg("foo")
202 let FuncRef = function("UserFunc")
203 FuncRef()
204 let FuncRefWithArg = function("UserFuncWithArg")
205 FuncRefWithArg("bar")
206 return "yes"
207enddef
208
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100209def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100210 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200211 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
212 'changenr().*' ..
213 ' BCALL changenr(argc 0).*' ..
214 'char2nr("abc").*' ..
215 ' PUSHS "abc".*' ..
216 ' BCALL char2nr(argc 1).*' ..
217 'Test_disassemble_new().*' ..
218 ' DCALL Test_disassemble_new(argc 0).*' ..
219 'FuncWithArg(343).*' ..
220 ' PUSHNR 343.*' ..
221 ' DCALL FuncWithArg(argc 1).*' ..
222 'ScriptFuncNew().*' ..
223 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
224 's:ScriptFuncNew().*' ..
225 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
226 'UserFunc().*' ..
227 ' UCALL UserFunc(argc 0).*' ..
228 'UserFuncWithArg("foo").*' ..
229 ' PUSHS "foo".*' ..
230 ' UCALL UserFuncWithArg(argc 1).*' ..
231 'let FuncRef = function("UserFunc").*' ..
232 'FuncRef().*' ..
233 ' LOAD $\d.*' ..
234 ' PCALL (argc 0).*' ..
235 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
236 'FuncRefWithArg("bar").*' ..
237 ' PUSHS "bar".*' ..
238 ' LOAD $\d.*' ..
239 ' PCALL (argc 1).*' ..
240 'return "yes".*' ..
241 ' PUSHS "yes".*' ..
242 ' RETURN.*',
243 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100244enddef
245
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100246
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200247def EchoArg(arg: string): string
248 return arg
249enddef
250def RefThis(): func
251 return function('EchoArg')
252enddef
253def s:ScriptPCall()
254 RefThis()("text")
255enddef
256
257def Test_disassemble_pcall()
258 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200259 assert_match('<SNR>\d\+_ScriptPCall.*' ..
260 'RefThis()("text").*' ..
261 '\d DCALL RefThis(argc 0).*' ..
262 '\d PUSHS "text".*' ..
263 '\d PCALL top (argc 1).*' ..
264 '\d PCALL end.*' ..
265 '\d DROP.*' ..
266 '\d PUSHNR 0.*' ..
267 '\d RETURN.*',
268 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200269enddef
270
271
Bram Moolenaara26b9702020-04-18 19:53:28 +0200272def s:FuncWithForwardCall(): string
273 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100274enddef
275
276def DefinedLater(arg: string): string
277 return arg
278enddef
279
280def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200281 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200282 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200283 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200284 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200285 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200286 '\d CHECKTYPE string stack\[-1].*' ..
287 '\d RETURN.*',
288 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100289
290 " Calling the function will change UCALL into the faster DCALL
291 assert_equal('yes', FuncWithForwardCall())
292
Bram Moolenaara26b9702020-04-18 19:53:28 +0200293 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200294 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200295 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200296 '\d PUSHS "yes".*' ..
297 '\d DCALL DefinedLater(argc 1).*' ..
298 '\d CHECKTYPE string stack\[-1].*' ..
299 '\d RETURN.*',
300 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100301enddef
302
303
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100304def FuncWithDefault(arg: string = 'default'): string
305 return arg
306enddef
307
308def Test_disassemble_call_default()
309 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200310 assert_match('FuncWithDefault.*' ..
311 '\d PUSHS "default".*' ..
312 '\d STORE arg\[-1].*' ..
313 'return arg.*' ..
314 '\d LOAD arg\[-1].*' ..
315 '\d RETURN.*',
316 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100317enddef
318
319
Bram Moolenaar158906c2020-02-06 20:39:45 +0100320def HasEval()
321 if has("eval")
322 echo "yes"
323 else
324 echo "no"
325 endif
326enddef
327
328def HasNothing()
329 if has("nothing")
330 echo "yes"
331 else
332 echo "no"
333 endif
334enddef
335
336def HasSomething()
337 if has("nothing")
338 echo "nothing"
339 elseif has("something")
340 echo "something"
341 elseif has("eval")
342 echo "eval"
343 elseif has("less")
344 echo "less"
345 endif
346enddef
347
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100348def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100349 assert_equal("\nyes", execute('call HasEval()'))
350 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200351 assert_match('HasEval.*' ..
352 'if has("eval").*' ..
353 ' PUSHS "yes".*',
354 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100355 assert_notmatch('JUMP', instr)
356
357 assert_equal("\nno", execute('call HasNothing()'))
358 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200359 assert_match('HasNothing.*' ..
360 'if has("nothing").*' ..
361 'else.*' ..
362 ' PUSHS "no".*',
363 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100364 assert_notmatch('PUSHS "yes"', instr)
365 assert_notmatch('JUMP', instr)
366
367 assert_equal("\neval", execute('call HasSomething()'))
368 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200369 assert_match('HasSomething.*' ..
370 'if has("nothing").*' ..
371 'elseif has("something").*' ..
372 'elseif has("eval").*' ..
373 ' PUSHS "eval".*' ..
374 'elseif has("less").*',
375 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100376 assert_notmatch('PUSHS "nothing"', instr)
377 assert_notmatch('PUSHS "something"', instr)
378 assert_notmatch('PUSHS "less"', instr)
379 assert_notmatch('JUMP', instr)
380enddef
381
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100382def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200383 let Funky1: func
384 let Funky2: func = function("len")
385 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100386enddef
387
388def Test_disassemble_function()
389 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200390 assert_match('WithFunc.*' ..
391 'let Funky1: func.*' ..
392 '0 PUSHFUNC "\[none]".*' ..
393 '1 STORE $0.*' ..
394 'let Funky2: func = function("len").*' ..
395 '2 PUSHS "len".*' ..
396 '3 BCALL function(argc 1).*' ..
397 '4 STORE $1.*' ..
398 'let Party2: func = funcref("UserFunc").*' ..
399 '\d PUSHS "UserFunc".*' ..
400 '\d BCALL funcref(argc 1).*' ..
401 '\d STORE $2.*' ..
402 '\d PUSHNR 0.*' ..
403 '\d RETURN.*',
404 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100405enddef
406
407if has('channel')
408 def WithChannel()
409 let job1: job
410 let job2: job = job_start("donothing")
411 let chan1: channel
412 enddef
413endif
414
415def Test_disassemble_channel()
416 CheckFeature channel
417
418 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200419 assert_match('WithChannel.*' ..
420 'let job1: job.*' ..
421 '\d PUSHJOB "no process".*' ..
422 '\d STORE $0.*' ..
423 'let job2: job = job_start("donothing").*' ..
424 '\d PUSHS "donothing".*' ..
425 '\d BCALL job_start(argc 1).*' ..
426 '\d STORE $1.*' ..
427 'let chan1: channel.*' ..
428 '\d PUSHCHANNEL 0.*' ..
429 '\d STORE $2.*' ..
430 '\d PUSHNR 0.*' ..
431 '\d RETURN.*',
432 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100433enddef
434
Bram Moolenaar777770f2020-02-06 21:27:08 +0100435def WithLambda(): string
436 let F = {a -> "X" .. a .. "X"}
437 return F("x")
438enddef
439
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100440def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100441 assert_equal("XxX", WithLambda())
442 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200443 assert_match('WithLambda.*' ..
444 'let F = {a -> "X" .. a .. "X"}.*' ..
445 ' FUNCREF <lambda>\d\+.*' ..
446 'PUSHS "x".*' ..
447 ' LOAD $0.*' ..
448 ' PCALL (argc 1).*' ..
449 ' CHECKTYPE string stack\[-1].*',
450 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100451enddef
452
Bram Moolenaar6e949782020-04-13 17:21:00 +0200453def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100454 if arg == 1 && arg != 2 || arg == 4
455 return 'yes'
456 endif
457 return 'no'
458enddef
459
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100460def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100461 assert_equal("yes", AndOr(1))
462 assert_equal("no", AndOr(2))
463 assert_equal("yes", AndOr(4))
464 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200465 assert_match('AndOr.*' ..
466 'if arg == 1 && arg != 2 || arg == 4.*' ..
467 '\d LOAD arg\[-1].*' ..
468 '\d PUSHNR 1.*' ..
469 '\d COMPAREANY ==.*' ..
470 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
471 '\d LOAD arg\[-1].*' ..
472 '\d PUSHNR 2.*' ..
473 '\d COMPAREANY !=.*' ..
474 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
475 '\d LOAD arg\[-1].*' ..
476 '\d PUSHNR 4.*' ..
477 '\d COMPAREANY ==.*' ..
478 '\d JUMP_IF_FALSE -> \d\+.*',
479 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100480enddef
481
Bram Moolenaar04d05222020-02-06 22:06:54 +0100482def ForLoop(): list<number>
483 let res: list<number>
484 for i in range(3)
485 res->add(i)
486 endfor
487 return res
488enddef
489
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100490def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100491 assert_equal([0, 1, 2], ForLoop())
492 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200493 assert_match('ForLoop.*' ..
494 'let res: list<number>.*' ..
495 ' NEWLIST size 0.*' ..
496 '\d STORE $0.*' ..
497 'for i in range(3).*' ..
498 '\d STORE -1 in $1.*' ..
499 '\d PUSHNR 3.*' ..
500 '\d BCALL range(argc 1).*' ..
501 '\d FOR $1 -> \d\+.*' ..
502 '\d STORE $2.*' ..
503 'res->add(i).*' ..
504 '\d LOAD $0.*' ..
505 '\d LOAD $2.*' ..
506 '\d BCALL add(argc 2).*' ..
507 '\d DROP.*' ..
508 'endfor.*' ..
509 '\d JUMP -> \d\+.*' ..
510 '\d DROP.*',
511 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100512enddef
513
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100514let g:number = 42
515
516def Computing()
517 let nr = 3
518 let nrres = nr + 7
519 nrres = nr - 7
520 nrres = nr * 7
521 nrres = nr / 7
522 nrres = nr % 7
523
524 let anyres = g:number + 7
525 anyres = g:number - 7
526 anyres = g:number * 7
527 anyres = g:number / 7
528 anyres = g:number % 7
529
530 if has('float')
531 let fl = 3.0
532 let flres = fl + 7.0
533 flres = fl - 7.0
534 flres = fl * 7.0
535 flres = fl / 7.0
536 endif
537enddef
538
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100539def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100540 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200541 assert_match('Computing.*' ..
542 'let nr = 3.*' ..
543 '\d STORE 3 in $0.*' ..
544 'let nrres = nr + 7.*' ..
545 '\d LOAD $0.*' ..
546 '\d PUSHNR 7.*' ..
547 '\d OPNR +.*' ..
548 '\d STORE $1.*' ..
549 'nrres = nr - 7.*' ..
550 '\d OPNR -.*' ..
551 'nrres = nr \* 7.*' ..
552 '\d OPNR \*.*' ..
553 'nrres = nr / 7.*' ..
554 '\d OPNR /.*' ..
555 'nrres = nr % 7.*' ..
556 '\d OPNR %.*' ..
557 'let anyres = g:number + 7.*' ..
558 '\d LOADG g:number.*' ..
559 '\d PUSHNR 7.*' ..
560 '\d OPANY +.*' ..
561 '\d STORE $2.*' ..
562 'anyres = g:number - 7.*' ..
563 '\d OPANY -.*' ..
564 'anyres = g:number \* 7.*' ..
565 '\d OPANY \*.*' ..
566 'anyres = g:number / 7.*' ..
567 '\d OPANY /.*' ..
568 'anyres = g:number % 7.*' ..
569 '\d OPANY %.*',
570 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100571 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200572 assert_match('Computing.*' ..
573 'let fl = 3.0.*' ..
574 '\d PUSHF 3.0.*' ..
575 '\d STORE $3.*' ..
576 'let flres = fl + 7.0.*' ..
577 '\d LOAD $3.*' ..
578 '\d PUSHF 7.0.*' ..
579 '\d OPFLOAT +.*' ..
580 '\d STORE $4.*' ..
581 'flres = fl - 7.0.*' ..
582 '\d OPFLOAT -.*' ..
583 'flres = fl \* 7.0.*' ..
584 '\d OPFLOAT \*.*' ..
585 'flres = fl / 7.0.*' ..
586 '\d OPFLOAT /.*',
587 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100588 endif
589enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100590
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100591def AddListBlob()
592 let reslist = [1, 2] + [3, 4]
593 let resblob = 0z1122 + 0z3344
594enddef
595
596def Test_disassemble_add_list_blob()
597 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200598 assert_match('AddListBlob.*' ..
599 'let reslist = \[1, 2] + \[3, 4].*' ..
600 '\d PUSHNR 1.*' ..
601 '\d PUSHNR 2.*' ..
602 '\d NEWLIST size 2.*' ..
603 '\d PUSHNR 3.*' ..
604 '\d PUSHNR 4.*' ..
605 '\d NEWLIST size 2.*' ..
606 '\d ADDLIST.*' ..
607 '\d STORE $.*.*' ..
608 'let resblob = 0z1122 + 0z3344.*' ..
609 '\d PUSHBLOB 0z1122.*' ..
610 '\d PUSHBLOB 0z3344.*' ..
611 '\d ADDBLOB.*' ..
612 '\d STORE $.*',
613 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100614enddef
615
616let g:aa = 'aa'
617def ConcatString(): string
618 let res = g:aa .. "bb"
619 return res
620enddef
621
622def Test_disassemble_concat()
623 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200624 assert_match('ConcatString.*' ..
625 'let res = g:aa .. "bb".*' ..
626 '\d LOADG g:aa.*' ..
627 '\d PUSHS "bb".*' ..
628 '\d 2STRING stack\[-2].*' ..
629 '\d CONCAT.*' ..
630 '\d STORE $.*',
631 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100632 assert_equal('aabb', ConcatString())
633enddef
634
635def ListIndex(): number
636 let l = [1, 2, 3]
637 let res = l[1]
638 return res
639enddef
640
641def Test_disassemble_list_index()
642 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200643 assert_match('ListIndex.*' ..
644 'let l = \[1, 2, 3].*' ..
645 '\d PUSHNR 1.*' ..
646 '\d PUSHNR 2.*' ..
647 '\d PUSHNR 3.*' ..
648 '\d NEWLIST size 3.*' ..
649 '\d STORE $0.*' ..
650 'let res = l\[1].*' ..
651 '\d LOAD $0.*' ..
652 '\d PUSHNR 1.*' ..
653 '\d INDEX.*' ..
654 '\d STORE $1.*',
655 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100656 assert_equal(2, ListIndex())
657enddef
658
659def DictMember(): number
660 let d = #{item: 1}
661 let res = d.item
662 return res
663enddef
664
665def Test_disassemble_dict_member()
666 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200667 assert_match('DictMember.*' ..
668 'let d = #{item: 1}.*' ..
669 '\d PUSHS "item".*' ..
670 '\d PUSHNR 1.*' ..
671 '\d NEWDICT size 1.*' ..
672 '\d STORE $0.*' ..
673 'let res = d.item.*' ..
674 '\d LOAD $0.*' ..
675 '\d MEMBER item.*' ..
676 '\d STORE $1.*',
677 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100678 call assert_equal(1, DictMember())
679enddef
680
681def NegateNumber(): number
682 let nr = 9
683 let plus = +nr
684 let res = -nr
685 return res
686enddef
687
688def Test_disassemble_negate_number()
689 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200690 assert_match('NegateNumber.*' ..
691 'let nr = 9.*' ..
692 '\d STORE 9 in $0.*' ..
693 'let plus = +nr.*' ..
694 '\d LOAD $0.*' ..
695 '\d CHECKNR.*' ..
696 '\d STORE $1.*' ..
697 'let res = -nr.*' ..
698 '\d LOAD $0.*' ..
699 '\d NEGATENR.*' ..
700 '\d STORE $2.*',
701 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100702 call assert_equal(-9, NegateNumber())
703enddef
704
705def InvertBool(): bool
706 let flag = true
707 let invert = !flag
708 let res = !!flag
709 return res
710enddef
711
712def Test_disassemble_invert_bool()
713 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200714 assert_match('InvertBool.*' ..
715 'let flag = true.*' ..
716 '\d PUSH v:true.*' ..
717 '\d STORE $0.*' ..
718 'let invert = !flag.*' ..
719 '\d LOAD $0.*' ..
720 '\d INVERT (!val).*' ..
721 '\d STORE $1.*' ..
722 'let res = !!flag.*' ..
723 '\d LOAD $0.*' ..
724 '\d 2BOOL (!!val).*' ..
725 '\d STORE $2.*',
726 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100727 call assert_equal(true, InvertBool())
728enddef
729
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100730def Test_disassemble_compare()
731 " TODO: COMPAREFUNC
732 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200733 ['true == false', 'COMPAREBOOL =='],
734 ['true != false', 'COMPAREBOOL !='],
735 ['v:none == v:null', 'COMPARESPECIAL =='],
736 ['v:none != v:null', 'COMPARESPECIAL !='],
737
738 ['111 == 222', 'COMPARENR =='],
739 ['111 != 222', 'COMPARENR !='],
740 ['111 > 222', 'COMPARENR >'],
741 ['111 < 222', 'COMPARENR <'],
742 ['111 >= 222', 'COMPARENR >='],
743 ['111 <= 222', 'COMPARENR <='],
744 ['111 =~ 222', 'COMPARENR =\~'],
745 ['111 !~ 222', 'COMPARENR !\~'],
746
747 ['"xx" != "yy"', 'COMPARESTRING !='],
748 ['"xx" > "yy"', 'COMPARESTRING >'],
749 ['"xx" < "yy"', 'COMPARESTRING <'],
750 ['"xx" >= "yy"', 'COMPARESTRING >='],
751 ['"xx" <= "yy"', 'COMPARESTRING <='],
752 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
753 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
754 ['"xx" is "yy"', 'COMPARESTRING is'],
755 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
756
757 ['0z11 == 0z22', 'COMPAREBLOB =='],
758 ['0z11 != 0z22', 'COMPAREBLOB !='],
759 ['0z11 is 0z22', 'COMPAREBLOB is'],
760 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
761
762 ['[1,2] == [3,4]', 'COMPARELIST =='],
763 ['[1,2] != [3,4]', 'COMPARELIST !='],
764 ['[1,2] is [3,4]', 'COMPARELIST is'],
765 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
766
767 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
768 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
769 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
770 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
771
772 ['{->33} == {->44}', 'COMPAREFUNC =='],
773 ['{->33} != {->44}', 'COMPAREFUNC !='],
774 ['{->33} is {->44}', 'COMPAREFUNC is'],
775 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
776
777 ['77 == g:xx', 'COMPAREANY =='],
778 ['77 != g:xx', 'COMPAREANY !='],
779 ['77 > g:xx', 'COMPAREANY >'],
780 ['77 < g:xx', 'COMPAREANY <'],
781 ['77 >= g:xx', 'COMPAREANY >='],
782 ['77 <= g:xx', 'COMPAREANY <='],
783 ['77 =~ g:xx', 'COMPAREANY =\~'],
784 ['77 !~ g:xx', 'COMPAREANY !\~'],
785 ['77 is g:xx', 'COMPAREANY is'],
786 ['77 isnot g:xx', 'COMPAREANY isnot'],
787 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100788 if has('float')
789 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200790 ['1.1 == 2.2', 'COMPAREFLOAT =='],
791 ['1.1 != 2.2', 'COMPAREFLOAT !='],
792 ['1.1 > 2.2', 'COMPAREFLOAT >'],
793 ['1.1 < 2.2', 'COMPAREFLOAT <'],
794 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
795 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
796 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
797 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
798 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100799 endif
800
801 let nr = 1
802 for case in cases
803 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200804 ' if ' .. case[0],
805 ' echo 42'
806 ' endif',
807 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100808 source Xdisassemble
809 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200810 assert_match('TestCase' .. nr .. '.*' ..
811 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
812 '\d \(PUSH\|FUNCREF\).*' ..
813 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
814 '\d ' .. case[1] .. '.*' ..
815 '\d JUMP_IF_FALSE -> \d\+.*',
816 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100817
818 nr += 1
819 endfor
820
Bram Moolenaar22da5592020-03-19 14:52:20 +0100821 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100822enddef
823
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200824def Test_disassemble_compare_const()
825 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200826 ['"xx" == "yy"', false],
827 ['"aa" == "aa"', true],
828 ['has("eval") ? true : false', true],
829 ['has("asdf") ? true : false', false],
830 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200831
832 let nr = 1
833 for case in cases
834 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200835 ' if ' .. case[0],
836 ' echo 42'
837 ' endif',
838 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200839 source Xdisassemble
840 let instr = execute('disassemble TestCase' .. nr)
841 if case[1]
842 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200843 assert_match('TestCase' .. nr .. '.*' ..
844 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
845 '\d PUSHNR 42.*' ..
846 '\d ECHO 1.*' ..
847 '\d PUSHNR 0.*' ..
848 '\d RETURN.*',
849 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200850 else
851 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200852 assert_match('TestCase' .. nr .. '.*' ..
853 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
854 'echo 42[ \n]*' ..
855 'endif[ \n]*' ..
856 '\s*\d PUSHNR 0.*' ..
857 '\d RETURN.*',
858 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200859 endif
860
861 nr += 1
862 endfor
863
864 delete('Xdisassemble')
865enddef
866
Bram Moolenaarad39c092020-02-26 18:23:43 +0100867def s:Execute()
868 execute 'help vim9.txt'
869 let cmd = 'help vim9.txt'
870 execute cmd
871 let tag = 'vim9.txt'
872 execute 'help ' .. tag
873enddef
874
875def Test_disassemble_execute()
876 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200877 assert_match('\<SNR>\d*_Execute.*' ..
878 "execute 'help vim9.txt'.*" ..
879 '\d PUSHS "help vim9.txt".*' ..
880 '\d EXECUTE 1.*' ..
881 "let cmd = 'help vim9.txt'.*" ..
882 '\d PUSHS "help vim9.txt".*' ..
883 '\d STORE $0.*' ..
884 'execute cmd.*' ..
885 '\d LOAD $0.*' ..
886 '\d EXECUTE 1.*' ..
887 "let tag = 'vim9.txt'.*" ..
888 '\d PUSHS "vim9.txt".*' ..
889 '\d STORE $1.*' ..
890 "execute 'help ' .. tag.*" ..
891 '\d PUSHS "help ".*' ..
892 '\d LOAD $1.*' ..
893 '\d CONCAT.*' ..
894 '\d EXECUTE 1.*' ..
895 '\d PUSHNR 0.*' ..
896 '\d RETURN',
897 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100898enddef
899
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100900def SomeStringArg(arg: string)
901 echo arg
902enddef
903
904def SomeAnyArg(arg: any)
905 echo arg
906enddef
907
908def SomeStringArgAndReturn(arg: string): string
909 return arg
910enddef
911
912def Test_display_func()
913 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200914 assert_match('.* def SomeStringArg(arg: string).*' ..
915 ' echo arg.*' ..
916 ' enddef',
917 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100918
919 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200920 assert_match('.* def SomeAnyArg(arg: any).*' ..
921 ' echo arg.*' ..
922 ' enddef',
923 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100924
925 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200926 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
927 ' return arg.*' ..
928 ' enddef',
929 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100930enddef
931
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100932" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker