blob: 7f6d86a56e0cd459245f1ac4a4e0e637bc313af5 [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
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200129def s:ScriptFuncUnlet()
130 g:somevar = "value"
131 unlet g:somevar
132 unlet! g:somevar
133enddef
134
135def Test_disassemble_unlet()
136 let res = execute('disass s:ScriptFuncUnlet')
137 assert_match('<SNR>\d*_ScriptFuncUnlet.*' ..
138 'g:somevar = "value".*' ..
139 '\d PUSHS "value".*' ..
140 '\d STOREG g:somevar.*' ..
141 'unlet g:somevar.*' ..
142 '\d UNLET g:somevar.*' ..
143 'unlet! g:somevar.*' ..
144 '\d UNLET! g:somevar.*',
145 res)
146enddef
147
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100148def s:ScriptFuncTry()
149 try
150 echo 'yes'
151 catch /fail/
152 echo 'no'
153 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100154 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100155 endtry
156enddef
157
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100158def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100159 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200160 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
161 'try.*' ..
162 'TRY catch -> \d\+, finally -> \d\+.*' ..
163 'catch /fail/.*' ..
164 ' JUMP -> \d\+.*' ..
165 ' PUSH v:exception.*' ..
166 ' PUSHS "fail".*' ..
167 ' COMPARESTRING =\~.*' ..
168 ' JUMP_IF_FALSE -> \d\+.*' ..
169 ' CATCH.*' ..
170 'finally.*' ..
171 ' PUSHS "end".*' ..
172 ' THROW.*' ..
173 'endtry.*' ..
174 ' ENDTRY.*',
175 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100176enddef
177
178def s:ScriptFuncNew()
179 let ll = [1, "two", 333]
180 let dd = #{one: 1, two: "val"}
181enddef
182
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100183def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100184 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200185 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
186 'let ll = \[1, "two", 333].*' ..
187 'PUSHNR 1.*' ..
188 'PUSHS "two".*' ..
189 'PUSHNR 333.*' ..
190 'NEWLIST size 3.*' ..
191 'let dd = #{one: 1, two: "val"}.*' ..
192 'PUSHS "one".*' ..
193 'PUSHNR 1.*' ..
194 'PUSHS "two".*' ..
195 'PUSHS "val".*' ..
196 'NEWDICT size 2.*',
197 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100198enddef
199
Bram Moolenaar6e949782020-04-13 17:21:00 +0200200def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100201 echo arg
202enddef
203
204func UserFunc()
205 echo 'nothing'
206endfunc
207
208func UserFuncWithArg(arg)
209 echo a:arg
210endfunc
211
212def s:ScriptFuncCall(): string
213 changenr()
214 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100215 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100216 FuncWithArg(343)
217 ScriptFuncNew()
218 s:ScriptFuncNew()
219 UserFunc()
220 UserFuncWithArg("foo")
221 let FuncRef = function("UserFunc")
222 FuncRef()
223 let FuncRefWithArg = function("UserFuncWithArg")
224 FuncRefWithArg("bar")
225 return "yes"
226enddef
227
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100228def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100229 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200230 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
231 'changenr().*' ..
232 ' BCALL changenr(argc 0).*' ..
233 'char2nr("abc").*' ..
234 ' PUSHS "abc".*' ..
235 ' BCALL char2nr(argc 1).*' ..
236 'Test_disassemble_new().*' ..
237 ' DCALL Test_disassemble_new(argc 0).*' ..
238 'FuncWithArg(343).*' ..
239 ' PUSHNR 343.*' ..
240 ' DCALL FuncWithArg(argc 1).*' ..
241 'ScriptFuncNew().*' ..
242 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
243 's:ScriptFuncNew().*' ..
244 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
245 'UserFunc().*' ..
246 ' UCALL UserFunc(argc 0).*' ..
247 'UserFuncWithArg("foo").*' ..
248 ' PUSHS "foo".*' ..
249 ' UCALL UserFuncWithArg(argc 1).*' ..
250 'let FuncRef = function("UserFunc").*' ..
251 'FuncRef().*' ..
252 ' LOAD $\d.*' ..
253 ' PCALL (argc 0).*' ..
254 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
255 'FuncRefWithArg("bar").*' ..
256 ' PUSHS "bar".*' ..
257 ' LOAD $\d.*' ..
258 ' PCALL (argc 1).*' ..
259 'return "yes".*' ..
260 ' PUSHS "yes".*' ..
261 ' RETURN.*',
262 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100263enddef
264
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100265
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200266def EchoArg(arg: string): string
267 return arg
268enddef
269def RefThis(): func
270 return function('EchoArg')
271enddef
272def s:ScriptPCall()
273 RefThis()("text")
274enddef
275
276def Test_disassemble_pcall()
277 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200278 assert_match('<SNR>\d\+_ScriptPCall.*' ..
279 'RefThis()("text").*' ..
280 '\d DCALL RefThis(argc 0).*' ..
281 '\d PUSHS "text".*' ..
282 '\d PCALL top (argc 1).*' ..
283 '\d PCALL end.*' ..
284 '\d DROP.*' ..
285 '\d PUSHNR 0.*' ..
286 '\d RETURN.*',
287 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200288enddef
289
290
Bram Moolenaara26b9702020-04-18 19:53:28 +0200291def s:FuncWithForwardCall(): string
292 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100293enddef
294
295def DefinedLater(arg: string): string
296 return arg
297enddef
298
299def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200300 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200301 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200302 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200303 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200304 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200305 '\d CHECKTYPE string stack\[-1].*' ..
306 '\d RETURN.*',
307 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100308
309 " Calling the function will change UCALL into the faster DCALL
310 assert_equal('yes', FuncWithForwardCall())
311
Bram Moolenaara26b9702020-04-18 19:53:28 +0200312 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200313 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200314 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200315 '\d PUSHS "yes".*' ..
316 '\d DCALL DefinedLater(argc 1).*' ..
317 '\d CHECKTYPE string stack\[-1].*' ..
318 '\d RETURN.*',
319 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100320enddef
321
322
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100323def FuncWithDefault(arg: string = 'default'): string
324 return arg
325enddef
326
327def Test_disassemble_call_default()
328 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200329 assert_match('FuncWithDefault.*' ..
330 '\d PUSHS "default".*' ..
331 '\d STORE arg\[-1].*' ..
332 'return arg.*' ..
333 '\d LOAD arg\[-1].*' ..
334 '\d RETURN.*',
335 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100336enddef
337
338
Bram Moolenaar158906c2020-02-06 20:39:45 +0100339def HasEval()
340 if has("eval")
341 echo "yes"
342 else
343 echo "no"
344 endif
345enddef
346
347def HasNothing()
348 if has("nothing")
349 echo "yes"
350 else
351 echo "no"
352 endif
353enddef
354
355def HasSomething()
356 if has("nothing")
357 echo "nothing"
358 elseif has("something")
359 echo "something"
360 elseif has("eval")
361 echo "eval"
362 elseif has("less")
363 echo "less"
364 endif
365enddef
366
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100367def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100368 assert_equal("\nyes", execute('call HasEval()'))
369 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200370 assert_match('HasEval.*' ..
371 'if has("eval").*' ..
372 ' PUSHS "yes".*',
373 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100374 assert_notmatch('JUMP', instr)
375
376 assert_equal("\nno", execute('call HasNothing()'))
377 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200378 assert_match('HasNothing.*' ..
379 'if has("nothing").*' ..
380 'else.*' ..
381 ' PUSHS "no".*',
382 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100383 assert_notmatch('PUSHS "yes"', instr)
384 assert_notmatch('JUMP', instr)
385
386 assert_equal("\neval", execute('call HasSomething()'))
387 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200388 assert_match('HasSomething.*' ..
389 'if has("nothing").*' ..
390 'elseif has("something").*' ..
391 'elseif has("eval").*' ..
392 ' PUSHS "eval".*' ..
393 'elseif has("less").*',
394 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100395 assert_notmatch('PUSHS "nothing"', instr)
396 assert_notmatch('PUSHS "something"', instr)
397 assert_notmatch('PUSHS "less"', instr)
398 assert_notmatch('JUMP', instr)
399enddef
400
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100401def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200402 let Funky1: func
403 let Funky2: func = function("len")
404 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100405enddef
406
407def Test_disassemble_function()
408 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200409 assert_match('WithFunc.*' ..
410 'let Funky1: func.*' ..
411 '0 PUSHFUNC "\[none]".*' ..
412 '1 STORE $0.*' ..
413 'let Funky2: func = function("len").*' ..
414 '2 PUSHS "len".*' ..
415 '3 BCALL function(argc 1).*' ..
416 '4 STORE $1.*' ..
417 'let Party2: func = funcref("UserFunc").*' ..
418 '\d PUSHS "UserFunc".*' ..
419 '\d BCALL funcref(argc 1).*' ..
420 '\d STORE $2.*' ..
421 '\d PUSHNR 0.*' ..
422 '\d RETURN.*',
423 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100424enddef
425
426if has('channel')
427 def WithChannel()
428 let job1: job
429 let job2: job = job_start("donothing")
430 let chan1: channel
431 enddef
432endif
433
434def Test_disassemble_channel()
435 CheckFeature channel
436
437 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200438 assert_match('WithChannel.*' ..
439 'let job1: job.*' ..
440 '\d PUSHJOB "no process".*' ..
441 '\d STORE $0.*' ..
442 'let job2: job = job_start("donothing").*' ..
443 '\d PUSHS "donothing".*' ..
444 '\d BCALL job_start(argc 1).*' ..
445 '\d STORE $1.*' ..
446 'let chan1: channel.*' ..
447 '\d PUSHCHANNEL 0.*' ..
448 '\d STORE $2.*' ..
449 '\d PUSHNR 0.*' ..
450 '\d RETURN.*',
451 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100452enddef
453
Bram Moolenaar777770f2020-02-06 21:27:08 +0100454def WithLambda(): string
455 let F = {a -> "X" .. a .. "X"}
456 return F("x")
457enddef
458
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100459def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100460 assert_equal("XxX", WithLambda())
461 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200462 assert_match('WithLambda.*' ..
463 'let F = {a -> "X" .. a .. "X"}.*' ..
464 ' FUNCREF <lambda>\d\+.*' ..
465 'PUSHS "x".*' ..
466 ' LOAD $0.*' ..
467 ' PCALL (argc 1).*' ..
468 ' CHECKTYPE string stack\[-1].*',
469 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100470enddef
471
Bram Moolenaar6e949782020-04-13 17:21:00 +0200472def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100473 if arg == 1 && arg != 2 || arg == 4
474 return 'yes'
475 endif
476 return 'no'
477enddef
478
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100479def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100480 assert_equal("yes", AndOr(1))
481 assert_equal("no", AndOr(2))
482 assert_equal("yes", AndOr(4))
483 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200484 assert_match('AndOr.*' ..
485 'if arg == 1 && arg != 2 || arg == 4.*' ..
486 '\d LOAD arg\[-1].*' ..
487 '\d PUSHNR 1.*' ..
488 '\d COMPAREANY ==.*' ..
489 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
490 '\d LOAD arg\[-1].*' ..
491 '\d PUSHNR 2.*' ..
492 '\d COMPAREANY !=.*' ..
493 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
494 '\d LOAD arg\[-1].*' ..
495 '\d PUSHNR 4.*' ..
496 '\d COMPAREANY ==.*' ..
497 '\d JUMP_IF_FALSE -> \d\+.*',
498 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100499enddef
500
Bram Moolenaar04d05222020-02-06 22:06:54 +0100501def ForLoop(): list<number>
502 let res: list<number>
503 for i in range(3)
504 res->add(i)
505 endfor
506 return res
507enddef
508
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100509def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100510 assert_equal([0, 1, 2], ForLoop())
511 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200512 assert_match('ForLoop.*' ..
513 'let res: list<number>.*' ..
514 ' NEWLIST size 0.*' ..
515 '\d STORE $0.*' ..
516 'for i in range(3).*' ..
517 '\d STORE -1 in $1.*' ..
518 '\d PUSHNR 3.*' ..
519 '\d BCALL range(argc 1).*' ..
520 '\d FOR $1 -> \d\+.*' ..
521 '\d STORE $2.*' ..
522 'res->add(i).*' ..
523 '\d LOAD $0.*' ..
524 '\d LOAD $2.*' ..
525 '\d BCALL add(argc 2).*' ..
526 '\d DROP.*' ..
527 'endfor.*' ..
528 '\d JUMP -> \d\+.*' ..
529 '\d DROP.*',
530 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100531enddef
532
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100533let g:number = 42
534
535def Computing()
536 let nr = 3
537 let nrres = nr + 7
538 nrres = nr - 7
539 nrres = nr * 7
540 nrres = nr / 7
541 nrres = nr % 7
542
543 let anyres = g:number + 7
544 anyres = g:number - 7
545 anyres = g:number * 7
546 anyres = g:number / 7
547 anyres = g:number % 7
548
549 if has('float')
550 let fl = 3.0
551 let flres = fl + 7.0
552 flres = fl - 7.0
553 flres = fl * 7.0
554 flres = fl / 7.0
555 endif
556enddef
557
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100558def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100559 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200560 assert_match('Computing.*' ..
561 'let nr = 3.*' ..
562 '\d STORE 3 in $0.*' ..
563 'let nrres = nr + 7.*' ..
564 '\d LOAD $0.*' ..
565 '\d PUSHNR 7.*' ..
566 '\d OPNR +.*' ..
567 '\d STORE $1.*' ..
568 'nrres = nr - 7.*' ..
569 '\d OPNR -.*' ..
570 'nrres = nr \* 7.*' ..
571 '\d OPNR \*.*' ..
572 'nrres = nr / 7.*' ..
573 '\d OPNR /.*' ..
574 'nrres = nr % 7.*' ..
575 '\d OPNR %.*' ..
576 'let anyres = g:number + 7.*' ..
577 '\d LOADG g:number.*' ..
578 '\d PUSHNR 7.*' ..
579 '\d OPANY +.*' ..
580 '\d STORE $2.*' ..
581 'anyres = g:number - 7.*' ..
582 '\d OPANY -.*' ..
583 'anyres = g:number \* 7.*' ..
584 '\d OPANY \*.*' ..
585 'anyres = g:number / 7.*' ..
586 '\d OPANY /.*' ..
587 'anyres = g:number % 7.*' ..
588 '\d OPANY %.*',
589 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100590 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200591 assert_match('Computing.*' ..
592 'let fl = 3.0.*' ..
593 '\d PUSHF 3.0.*' ..
594 '\d STORE $3.*' ..
595 'let flres = fl + 7.0.*' ..
596 '\d LOAD $3.*' ..
597 '\d PUSHF 7.0.*' ..
598 '\d OPFLOAT +.*' ..
599 '\d STORE $4.*' ..
600 'flres = fl - 7.0.*' ..
601 '\d OPFLOAT -.*' ..
602 'flres = fl \* 7.0.*' ..
603 '\d OPFLOAT \*.*' ..
604 'flres = fl / 7.0.*' ..
605 '\d OPFLOAT /.*',
606 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100607 endif
608enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100609
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100610def AddListBlob()
611 let reslist = [1, 2] + [3, 4]
612 let resblob = 0z1122 + 0z3344
613enddef
614
615def Test_disassemble_add_list_blob()
616 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200617 assert_match('AddListBlob.*' ..
618 'let reslist = \[1, 2] + \[3, 4].*' ..
619 '\d PUSHNR 1.*' ..
620 '\d PUSHNR 2.*' ..
621 '\d NEWLIST size 2.*' ..
622 '\d PUSHNR 3.*' ..
623 '\d PUSHNR 4.*' ..
624 '\d NEWLIST size 2.*' ..
625 '\d ADDLIST.*' ..
626 '\d STORE $.*.*' ..
627 'let resblob = 0z1122 + 0z3344.*' ..
628 '\d PUSHBLOB 0z1122.*' ..
629 '\d PUSHBLOB 0z3344.*' ..
630 '\d ADDBLOB.*' ..
631 '\d STORE $.*',
632 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100633enddef
634
635let g:aa = 'aa'
636def ConcatString(): string
637 let res = g:aa .. "bb"
638 return res
639enddef
640
641def Test_disassemble_concat()
642 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200643 assert_match('ConcatString.*' ..
644 'let res = g:aa .. "bb".*' ..
645 '\d LOADG g:aa.*' ..
646 '\d PUSHS "bb".*' ..
647 '\d 2STRING stack\[-2].*' ..
648 '\d CONCAT.*' ..
649 '\d STORE $.*',
650 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100651 assert_equal('aabb', ConcatString())
652enddef
653
654def ListIndex(): number
655 let l = [1, 2, 3]
656 let res = l[1]
657 return res
658enddef
659
660def Test_disassemble_list_index()
661 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200662 assert_match('ListIndex.*' ..
663 'let l = \[1, 2, 3].*' ..
664 '\d PUSHNR 1.*' ..
665 '\d PUSHNR 2.*' ..
666 '\d PUSHNR 3.*' ..
667 '\d NEWLIST size 3.*' ..
668 '\d STORE $0.*' ..
669 'let res = l\[1].*' ..
670 '\d LOAD $0.*' ..
671 '\d PUSHNR 1.*' ..
672 '\d INDEX.*' ..
673 '\d STORE $1.*',
674 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100675 assert_equal(2, ListIndex())
676enddef
677
678def DictMember(): number
679 let d = #{item: 1}
680 let res = d.item
681 return res
682enddef
683
684def Test_disassemble_dict_member()
685 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200686 assert_match('DictMember.*' ..
687 'let d = #{item: 1}.*' ..
688 '\d PUSHS "item".*' ..
689 '\d PUSHNR 1.*' ..
690 '\d NEWDICT size 1.*' ..
691 '\d STORE $0.*' ..
692 'let res = d.item.*' ..
693 '\d LOAD $0.*' ..
694 '\d MEMBER item.*' ..
695 '\d STORE $1.*',
696 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100697 call assert_equal(1, DictMember())
698enddef
699
700def NegateNumber(): number
701 let nr = 9
702 let plus = +nr
703 let res = -nr
704 return res
705enddef
706
707def Test_disassemble_negate_number()
708 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200709 assert_match('NegateNumber.*' ..
710 'let nr = 9.*' ..
711 '\d STORE 9 in $0.*' ..
712 'let plus = +nr.*' ..
713 '\d LOAD $0.*' ..
714 '\d CHECKNR.*' ..
715 '\d STORE $1.*' ..
716 'let res = -nr.*' ..
717 '\d LOAD $0.*' ..
718 '\d NEGATENR.*' ..
719 '\d STORE $2.*',
720 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100721 call assert_equal(-9, NegateNumber())
722enddef
723
724def InvertBool(): bool
725 let flag = true
726 let invert = !flag
727 let res = !!flag
728 return res
729enddef
730
731def Test_disassemble_invert_bool()
732 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200733 assert_match('InvertBool.*' ..
734 'let flag = true.*' ..
735 '\d PUSH v:true.*' ..
736 '\d STORE $0.*' ..
737 'let invert = !flag.*' ..
738 '\d LOAD $0.*' ..
739 '\d INVERT (!val).*' ..
740 '\d STORE $1.*' ..
741 'let res = !!flag.*' ..
742 '\d LOAD $0.*' ..
743 '\d 2BOOL (!!val).*' ..
744 '\d STORE $2.*',
745 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100746 call assert_equal(true, InvertBool())
747enddef
748
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100749def Test_disassemble_compare()
750 " TODO: COMPAREFUNC
751 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200752 ['true == false', 'COMPAREBOOL =='],
753 ['true != false', 'COMPAREBOOL !='],
754 ['v:none == v:null', 'COMPARESPECIAL =='],
755 ['v:none != v:null', 'COMPARESPECIAL !='],
756
757 ['111 == 222', 'COMPARENR =='],
758 ['111 != 222', 'COMPARENR !='],
759 ['111 > 222', 'COMPARENR >'],
760 ['111 < 222', 'COMPARENR <'],
761 ['111 >= 222', 'COMPARENR >='],
762 ['111 <= 222', 'COMPARENR <='],
763 ['111 =~ 222', 'COMPARENR =\~'],
764 ['111 !~ 222', 'COMPARENR !\~'],
765
766 ['"xx" != "yy"', 'COMPARESTRING !='],
767 ['"xx" > "yy"', 'COMPARESTRING >'],
768 ['"xx" < "yy"', 'COMPARESTRING <'],
769 ['"xx" >= "yy"', 'COMPARESTRING >='],
770 ['"xx" <= "yy"', 'COMPARESTRING <='],
771 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
772 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
773 ['"xx" is "yy"', 'COMPARESTRING is'],
774 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
775
776 ['0z11 == 0z22', 'COMPAREBLOB =='],
777 ['0z11 != 0z22', 'COMPAREBLOB !='],
778 ['0z11 is 0z22', 'COMPAREBLOB is'],
779 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
780
781 ['[1,2] == [3,4]', 'COMPARELIST =='],
782 ['[1,2] != [3,4]', 'COMPARELIST !='],
783 ['[1,2] is [3,4]', 'COMPARELIST is'],
784 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
785
786 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
787 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
788 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
789 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
790
791 ['{->33} == {->44}', 'COMPAREFUNC =='],
792 ['{->33} != {->44}', 'COMPAREFUNC !='],
793 ['{->33} is {->44}', 'COMPAREFUNC is'],
794 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
795
796 ['77 == g:xx', 'COMPAREANY =='],
797 ['77 != g:xx', 'COMPAREANY !='],
798 ['77 > g:xx', 'COMPAREANY >'],
799 ['77 < g:xx', 'COMPAREANY <'],
800 ['77 >= g:xx', 'COMPAREANY >='],
801 ['77 <= g:xx', 'COMPAREANY <='],
802 ['77 =~ g:xx', 'COMPAREANY =\~'],
803 ['77 !~ g:xx', 'COMPAREANY !\~'],
804 ['77 is g:xx', 'COMPAREANY is'],
805 ['77 isnot g:xx', 'COMPAREANY isnot'],
806 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100807 if has('float')
808 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200809 ['1.1 == 2.2', 'COMPAREFLOAT =='],
810 ['1.1 != 2.2', 'COMPAREFLOAT !='],
811 ['1.1 > 2.2', 'COMPAREFLOAT >'],
812 ['1.1 < 2.2', 'COMPAREFLOAT <'],
813 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
814 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
815 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
816 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
817 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100818 endif
819
820 let nr = 1
821 for case in cases
822 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200823 ' if ' .. case[0],
824 ' echo 42'
825 ' endif',
826 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100827 source Xdisassemble
828 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200829 assert_match('TestCase' .. nr .. '.*' ..
830 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
831 '\d \(PUSH\|FUNCREF\).*' ..
832 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
833 '\d ' .. case[1] .. '.*' ..
834 '\d JUMP_IF_FALSE -> \d\+.*',
835 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100836
837 nr += 1
838 endfor
839
Bram Moolenaar22da5592020-03-19 14:52:20 +0100840 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100841enddef
842
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200843def Test_disassemble_compare_const()
844 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200845 ['"xx" == "yy"', false],
846 ['"aa" == "aa"', true],
847 ['has("eval") ? true : false', true],
848 ['has("asdf") ? true : false', false],
849 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200850
851 let nr = 1
852 for case in cases
853 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200854 ' if ' .. case[0],
855 ' echo 42'
856 ' endif',
857 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200858 source Xdisassemble
859 let instr = execute('disassemble TestCase' .. nr)
860 if case[1]
861 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200862 assert_match('TestCase' .. nr .. '.*' ..
863 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
864 '\d PUSHNR 42.*' ..
865 '\d ECHO 1.*' ..
866 '\d PUSHNR 0.*' ..
867 '\d RETURN.*',
868 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200869 else
870 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200871 assert_match('TestCase' .. nr .. '.*' ..
872 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
873 'echo 42[ \n]*' ..
874 'endif[ \n]*' ..
875 '\s*\d PUSHNR 0.*' ..
876 '\d RETURN.*',
877 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200878 endif
879
880 nr += 1
881 endfor
882
883 delete('Xdisassemble')
884enddef
885
Bram Moolenaarad39c092020-02-26 18:23:43 +0100886def s:Execute()
887 execute 'help vim9.txt'
888 let cmd = 'help vim9.txt'
889 execute cmd
890 let tag = 'vim9.txt'
891 execute 'help ' .. tag
892enddef
893
894def Test_disassemble_execute()
895 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200896 assert_match('\<SNR>\d*_Execute.*' ..
897 "execute 'help vim9.txt'.*" ..
898 '\d PUSHS "help vim9.txt".*' ..
899 '\d EXECUTE 1.*' ..
900 "let cmd = 'help vim9.txt'.*" ..
901 '\d PUSHS "help vim9.txt".*' ..
902 '\d STORE $0.*' ..
903 'execute cmd.*' ..
904 '\d LOAD $0.*' ..
905 '\d EXECUTE 1.*' ..
906 "let tag = 'vim9.txt'.*" ..
907 '\d PUSHS "vim9.txt".*' ..
908 '\d STORE $1.*' ..
909 "execute 'help ' .. tag.*" ..
910 '\d PUSHS "help ".*' ..
911 '\d LOAD $1.*' ..
912 '\d CONCAT.*' ..
913 '\d EXECUTE 1.*' ..
914 '\d PUSHNR 0.*' ..
915 '\d RETURN',
916 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100917enddef
918
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100919def SomeStringArg(arg: string)
920 echo arg
921enddef
922
923def SomeAnyArg(arg: any)
924 echo arg
925enddef
926
927def SomeStringArgAndReturn(arg: string): string
928 return arg
929enddef
930
931def Test_display_func()
932 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200933 assert_match('.* def SomeStringArg(arg: string).*' ..
934 ' echo arg.*' ..
935 ' enddef',
936 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100937
938 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200939 assert_match('.* def SomeAnyArg(arg: any).*' ..
940 ' echo arg.*' ..
941 ' enddef',
942 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100943
944 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200945 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
946 ' return arg.*' ..
947 ' enddef',
948 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100949enddef
950
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100951" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker