blob: 78149527896035277da1f47010d187a3af330aca [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
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200133 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200134enddef
135
136def Test_disassemble_unlet()
137 let res = execute('disass s:ScriptFuncUnlet')
138 assert_match('<SNR>\d*_ScriptFuncUnlet.*' ..
139 'g:somevar = "value".*' ..
140 '\d PUSHS "value".*' ..
141 '\d STOREG g:somevar.*' ..
142 'unlet g:somevar.*' ..
143 '\d UNLET g:somevar.*' ..
144 'unlet! g:somevar.*' ..
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200145 '\d UNLET! g:somevar.*' ..
146 'unlet $SOMEVAR.*' ..
147 '\d UNLETENV $SOMEVAR.*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200148 res)
149enddef
150
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100151def s:ScriptFuncTry()
152 try
153 echo 'yes'
154 catch /fail/
155 echo 'no'
156 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100157 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100158 endtry
159enddef
160
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100161def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100162 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200163 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
164 'try.*' ..
165 'TRY catch -> \d\+, finally -> \d\+.*' ..
166 'catch /fail/.*' ..
167 ' JUMP -> \d\+.*' ..
168 ' PUSH v:exception.*' ..
169 ' PUSHS "fail".*' ..
170 ' COMPARESTRING =\~.*' ..
171 ' JUMP_IF_FALSE -> \d\+.*' ..
172 ' CATCH.*' ..
173 'finally.*' ..
174 ' PUSHS "end".*' ..
175 ' THROW.*' ..
176 'endtry.*' ..
177 ' ENDTRY.*',
178 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100179enddef
180
181def s:ScriptFuncNew()
182 let ll = [1, "two", 333]
183 let dd = #{one: 1, two: "val"}
184enddef
185
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100186def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100187 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200188 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
189 'let ll = \[1, "two", 333].*' ..
190 'PUSHNR 1.*' ..
191 'PUSHS "two".*' ..
192 'PUSHNR 333.*' ..
193 'NEWLIST size 3.*' ..
194 'let dd = #{one: 1, two: "val"}.*' ..
195 'PUSHS "one".*' ..
196 'PUSHNR 1.*' ..
197 'PUSHS "two".*' ..
198 'PUSHS "val".*' ..
199 'NEWDICT size 2.*',
200 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100201enddef
202
Bram Moolenaar6e949782020-04-13 17:21:00 +0200203def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100204 echo arg
205enddef
206
207func UserFunc()
208 echo 'nothing'
209endfunc
210
211func UserFuncWithArg(arg)
212 echo a:arg
213endfunc
214
215def s:ScriptFuncCall(): string
216 changenr()
217 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100218 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100219 FuncWithArg(343)
220 ScriptFuncNew()
221 s:ScriptFuncNew()
222 UserFunc()
223 UserFuncWithArg("foo")
224 let FuncRef = function("UserFunc")
225 FuncRef()
226 let FuncRefWithArg = function("UserFuncWithArg")
227 FuncRefWithArg("bar")
228 return "yes"
229enddef
230
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100231def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100232 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200233 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
234 'changenr().*' ..
235 ' BCALL changenr(argc 0).*' ..
236 'char2nr("abc").*' ..
237 ' PUSHS "abc".*' ..
238 ' BCALL char2nr(argc 1).*' ..
239 'Test_disassemble_new().*' ..
240 ' DCALL Test_disassemble_new(argc 0).*' ..
241 'FuncWithArg(343).*' ..
242 ' PUSHNR 343.*' ..
243 ' DCALL FuncWithArg(argc 1).*' ..
244 'ScriptFuncNew().*' ..
245 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
246 's:ScriptFuncNew().*' ..
247 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
248 'UserFunc().*' ..
249 ' UCALL UserFunc(argc 0).*' ..
250 'UserFuncWithArg("foo").*' ..
251 ' PUSHS "foo".*' ..
252 ' UCALL UserFuncWithArg(argc 1).*' ..
253 'let FuncRef = function("UserFunc").*' ..
254 'FuncRef().*' ..
255 ' LOAD $\d.*' ..
256 ' PCALL (argc 0).*' ..
257 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
258 'FuncRefWithArg("bar").*' ..
259 ' PUSHS "bar".*' ..
260 ' LOAD $\d.*' ..
261 ' PCALL (argc 1).*' ..
262 'return "yes".*' ..
263 ' PUSHS "yes".*' ..
264 ' RETURN.*',
265 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100266enddef
267
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100268
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200269def EchoArg(arg: string): string
270 return arg
271enddef
272def RefThis(): func
273 return function('EchoArg')
274enddef
275def s:ScriptPCall()
276 RefThis()("text")
277enddef
278
279def Test_disassemble_pcall()
280 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200281 assert_match('<SNR>\d\+_ScriptPCall.*' ..
282 'RefThis()("text").*' ..
283 '\d DCALL RefThis(argc 0).*' ..
284 '\d PUSHS "text".*' ..
285 '\d PCALL top (argc 1).*' ..
286 '\d PCALL end.*' ..
287 '\d DROP.*' ..
288 '\d PUSHNR 0.*' ..
289 '\d RETURN.*',
290 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200291enddef
292
293
Bram Moolenaara26b9702020-04-18 19:53:28 +0200294def s:FuncWithForwardCall(): string
295 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100296enddef
297
298def DefinedLater(arg: string): string
299 return arg
300enddef
301
302def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200303 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200304 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200305 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200306 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200307 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200308 '\d CHECKTYPE string stack\[-1].*' ..
309 '\d RETURN.*',
310 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100311
312 " Calling the function will change UCALL into the faster DCALL
313 assert_equal('yes', FuncWithForwardCall())
314
Bram Moolenaara26b9702020-04-18 19:53:28 +0200315 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200316 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200317 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200318 '\d PUSHS "yes".*' ..
319 '\d DCALL DefinedLater(argc 1).*' ..
320 '\d CHECKTYPE string stack\[-1].*' ..
321 '\d RETURN.*',
322 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100323enddef
324
325
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100326def FuncWithDefault(arg: string = 'default'): string
327 return arg
328enddef
329
330def Test_disassemble_call_default()
331 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200332 assert_match('FuncWithDefault.*' ..
333 '\d PUSHS "default".*' ..
334 '\d STORE arg\[-1].*' ..
335 'return arg.*' ..
336 '\d LOAD arg\[-1].*' ..
337 '\d RETURN.*',
338 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100339enddef
340
341
Bram Moolenaar158906c2020-02-06 20:39:45 +0100342def HasEval()
343 if has("eval")
344 echo "yes"
345 else
346 echo "no"
347 endif
348enddef
349
350def HasNothing()
351 if has("nothing")
352 echo "yes"
353 else
354 echo "no"
355 endif
356enddef
357
358def HasSomething()
359 if has("nothing")
360 echo "nothing"
361 elseif has("something")
362 echo "something"
363 elseif has("eval")
364 echo "eval"
365 elseif has("less")
366 echo "less"
367 endif
368enddef
369
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100370def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100371 assert_equal("\nyes", execute('call HasEval()'))
372 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200373 assert_match('HasEval.*' ..
374 'if has("eval").*' ..
375 ' PUSHS "yes".*',
376 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100377 assert_notmatch('JUMP', instr)
378
379 assert_equal("\nno", execute('call HasNothing()'))
380 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200381 assert_match('HasNothing.*' ..
382 'if has("nothing").*' ..
383 'else.*' ..
384 ' PUSHS "no".*',
385 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100386 assert_notmatch('PUSHS "yes"', instr)
387 assert_notmatch('JUMP', instr)
388
389 assert_equal("\neval", execute('call HasSomething()'))
390 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200391 assert_match('HasSomething.*' ..
392 'if has("nothing").*' ..
393 'elseif has("something").*' ..
394 'elseif has("eval").*' ..
395 ' PUSHS "eval".*' ..
396 'elseif has("less").*',
397 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100398 assert_notmatch('PUSHS "nothing"', instr)
399 assert_notmatch('PUSHS "something"', instr)
400 assert_notmatch('PUSHS "less"', instr)
401 assert_notmatch('JUMP', instr)
402enddef
403
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100404def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200405 let Funky1: func
406 let Funky2: func = function("len")
407 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100408enddef
409
410def Test_disassemble_function()
411 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200412 assert_match('WithFunc.*' ..
413 'let Funky1: func.*' ..
414 '0 PUSHFUNC "\[none]".*' ..
415 '1 STORE $0.*' ..
416 'let Funky2: func = function("len").*' ..
417 '2 PUSHS "len".*' ..
418 '3 BCALL function(argc 1).*' ..
419 '4 STORE $1.*' ..
420 'let Party2: func = funcref("UserFunc").*' ..
421 '\d PUSHS "UserFunc".*' ..
422 '\d BCALL funcref(argc 1).*' ..
423 '\d STORE $2.*' ..
424 '\d PUSHNR 0.*' ..
425 '\d RETURN.*',
426 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100427enddef
428
429if has('channel')
430 def WithChannel()
431 let job1: job
432 let job2: job = job_start("donothing")
433 let chan1: channel
434 enddef
435endif
436
437def Test_disassemble_channel()
438 CheckFeature channel
439
440 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200441 assert_match('WithChannel.*' ..
442 'let job1: job.*' ..
443 '\d PUSHJOB "no process".*' ..
444 '\d STORE $0.*' ..
445 'let job2: job = job_start("donothing").*' ..
446 '\d PUSHS "donothing".*' ..
447 '\d BCALL job_start(argc 1).*' ..
448 '\d STORE $1.*' ..
449 'let chan1: channel.*' ..
450 '\d PUSHCHANNEL 0.*' ..
451 '\d STORE $2.*' ..
452 '\d PUSHNR 0.*' ..
453 '\d RETURN.*',
454 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100455enddef
456
Bram Moolenaar777770f2020-02-06 21:27:08 +0100457def WithLambda(): string
458 let F = {a -> "X" .. a .. "X"}
459 return F("x")
460enddef
461
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100462def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100463 assert_equal("XxX", WithLambda())
464 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200465 assert_match('WithLambda.*' ..
466 'let F = {a -> "X" .. a .. "X"}.*' ..
467 ' FUNCREF <lambda>\d\+.*' ..
468 'PUSHS "x".*' ..
469 ' LOAD $0.*' ..
470 ' PCALL (argc 1).*' ..
471 ' CHECKTYPE string stack\[-1].*',
472 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100473enddef
474
Bram Moolenaar6e949782020-04-13 17:21:00 +0200475def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100476 if arg == 1 && arg != 2 || arg == 4
477 return 'yes'
478 endif
479 return 'no'
480enddef
481
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100482def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100483 assert_equal("yes", AndOr(1))
484 assert_equal("no", AndOr(2))
485 assert_equal("yes", AndOr(4))
486 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200487 assert_match('AndOr.*' ..
488 'if arg == 1 && arg != 2 || arg == 4.*' ..
489 '\d LOAD arg\[-1].*' ..
490 '\d PUSHNR 1.*' ..
491 '\d COMPAREANY ==.*' ..
492 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
493 '\d LOAD arg\[-1].*' ..
494 '\d PUSHNR 2.*' ..
495 '\d COMPAREANY !=.*' ..
496 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
497 '\d LOAD arg\[-1].*' ..
498 '\d PUSHNR 4.*' ..
499 '\d COMPAREANY ==.*' ..
500 '\d JUMP_IF_FALSE -> \d\+.*',
501 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100502enddef
503
Bram Moolenaar04d05222020-02-06 22:06:54 +0100504def ForLoop(): list<number>
505 let res: list<number>
506 for i in range(3)
507 res->add(i)
508 endfor
509 return res
510enddef
511
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100512def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100513 assert_equal([0, 1, 2], ForLoop())
514 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200515 assert_match('ForLoop.*' ..
516 'let res: list<number>.*' ..
517 ' NEWLIST size 0.*' ..
518 '\d STORE $0.*' ..
519 'for i in range(3).*' ..
520 '\d STORE -1 in $1.*' ..
521 '\d PUSHNR 3.*' ..
522 '\d BCALL range(argc 1).*' ..
523 '\d FOR $1 -> \d\+.*' ..
524 '\d STORE $2.*' ..
525 'res->add(i).*' ..
526 '\d LOAD $0.*' ..
527 '\d LOAD $2.*' ..
528 '\d BCALL add(argc 2).*' ..
529 '\d DROP.*' ..
530 'endfor.*' ..
531 '\d JUMP -> \d\+.*' ..
532 '\d DROP.*',
533 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100534enddef
535
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100536let g:number = 42
537
538def Computing()
539 let nr = 3
540 let nrres = nr + 7
541 nrres = nr - 7
542 nrres = nr * 7
543 nrres = nr / 7
544 nrres = nr % 7
545
546 let anyres = g:number + 7
547 anyres = g:number - 7
548 anyres = g:number * 7
549 anyres = g:number / 7
550 anyres = g:number % 7
551
552 if has('float')
553 let fl = 3.0
554 let flres = fl + 7.0
555 flres = fl - 7.0
556 flres = fl * 7.0
557 flres = fl / 7.0
558 endif
559enddef
560
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100561def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100562 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200563 assert_match('Computing.*' ..
564 'let nr = 3.*' ..
565 '\d STORE 3 in $0.*' ..
566 'let nrres = nr + 7.*' ..
567 '\d LOAD $0.*' ..
568 '\d PUSHNR 7.*' ..
569 '\d OPNR +.*' ..
570 '\d STORE $1.*' ..
571 'nrres = nr - 7.*' ..
572 '\d OPNR -.*' ..
573 'nrres = nr \* 7.*' ..
574 '\d OPNR \*.*' ..
575 'nrres = nr / 7.*' ..
576 '\d OPNR /.*' ..
577 'nrres = nr % 7.*' ..
578 '\d OPNR %.*' ..
579 'let anyres = g:number + 7.*' ..
580 '\d LOADG g:number.*' ..
581 '\d PUSHNR 7.*' ..
582 '\d OPANY +.*' ..
583 '\d STORE $2.*' ..
584 'anyres = g:number - 7.*' ..
585 '\d OPANY -.*' ..
586 'anyres = g:number \* 7.*' ..
587 '\d OPANY \*.*' ..
588 'anyres = g:number / 7.*' ..
589 '\d OPANY /.*' ..
590 'anyres = g:number % 7.*' ..
591 '\d OPANY %.*',
592 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100593 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200594 assert_match('Computing.*' ..
595 'let fl = 3.0.*' ..
596 '\d PUSHF 3.0.*' ..
597 '\d STORE $3.*' ..
598 'let flres = fl + 7.0.*' ..
599 '\d LOAD $3.*' ..
600 '\d PUSHF 7.0.*' ..
601 '\d OPFLOAT +.*' ..
602 '\d STORE $4.*' ..
603 'flres = fl - 7.0.*' ..
604 '\d OPFLOAT -.*' ..
605 'flres = fl \* 7.0.*' ..
606 '\d OPFLOAT \*.*' ..
607 'flres = fl / 7.0.*' ..
608 '\d OPFLOAT /.*',
609 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100610 endif
611enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100612
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100613def AddListBlob()
614 let reslist = [1, 2] + [3, 4]
615 let resblob = 0z1122 + 0z3344
616enddef
617
618def Test_disassemble_add_list_blob()
619 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200620 assert_match('AddListBlob.*' ..
621 'let reslist = \[1, 2] + \[3, 4].*' ..
622 '\d PUSHNR 1.*' ..
623 '\d PUSHNR 2.*' ..
624 '\d NEWLIST size 2.*' ..
625 '\d PUSHNR 3.*' ..
626 '\d PUSHNR 4.*' ..
627 '\d NEWLIST size 2.*' ..
628 '\d ADDLIST.*' ..
629 '\d STORE $.*.*' ..
630 'let resblob = 0z1122 + 0z3344.*' ..
631 '\d PUSHBLOB 0z1122.*' ..
632 '\d PUSHBLOB 0z3344.*' ..
633 '\d ADDBLOB.*' ..
634 '\d STORE $.*',
635 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100636enddef
637
638let g:aa = 'aa'
639def ConcatString(): string
640 let res = g:aa .. "bb"
641 return res
642enddef
643
644def Test_disassemble_concat()
645 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200646 assert_match('ConcatString.*' ..
647 'let res = g:aa .. "bb".*' ..
648 '\d LOADG g:aa.*' ..
649 '\d PUSHS "bb".*' ..
650 '\d 2STRING stack\[-2].*' ..
651 '\d CONCAT.*' ..
652 '\d STORE $.*',
653 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100654 assert_equal('aabb', ConcatString())
655enddef
656
657def ListIndex(): number
658 let l = [1, 2, 3]
659 let res = l[1]
660 return res
661enddef
662
663def Test_disassemble_list_index()
664 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200665 assert_match('ListIndex.*' ..
666 'let l = \[1, 2, 3].*' ..
667 '\d PUSHNR 1.*' ..
668 '\d PUSHNR 2.*' ..
669 '\d PUSHNR 3.*' ..
670 '\d NEWLIST size 3.*' ..
671 '\d STORE $0.*' ..
672 'let res = l\[1].*' ..
673 '\d LOAD $0.*' ..
674 '\d PUSHNR 1.*' ..
675 '\d INDEX.*' ..
676 '\d STORE $1.*',
677 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100678 assert_equal(2, ListIndex())
679enddef
680
681def DictMember(): number
682 let d = #{item: 1}
683 let res = d.item
684 return res
685enddef
686
687def Test_disassemble_dict_member()
688 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200689 assert_match('DictMember.*' ..
690 'let d = #{item: 1}.*' ..
691 '\d PUSHS "item".*' ..
692 '\d PUSHNR 1.*' ..
693 '\d NEWDICT size 1.*' ..
694 '\d STORE $0.*' ..
695 'let res = d.item.*' ..
696 '\d LOAD $0.*' ..
697 '\d MEMBER item.*' ..
698 '\d STORE $1.*',
699 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100700 call assert_equal(1, DictMember())
701enddef
702
703def NegateNumber(): number
704 let nr = 9
705 let plus = +nr
706 let res = -nr
707 return res
708enddef
709
710def Test_disassemble_negate_number()
711 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200712 assert_match('NegateNumber.*' ..
713 'let nr = 9.*' ..
714 '\d STORE 9 in $0.*' ..
715 'let plus = +nr.*' ..
716 '\d LOAD $0.*' ..
717 '\d CHECKNR.*' ..
718 '\d STORE $1.*' ..
719 'let res = -nr.*' ..
720 '\d LOAD $0.*' ..
721 '\d NEGATENR.*' ..
722 '\d STORE $2.*',
723 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100724 call assert_equal(-9, NegateNumber())
725enddef
726
727def InvertBool(): bool
728 let flag = true
729 let invert = !flag
730 let res = !!flag
731 return res
732enddef
733
734def Test_disassemble_invert_bool()
735 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200736 assert_match('InvertBool.*' ..
737 'let flag = true.*' ..
738 '\d PUSH v:true.*' ..
739 '\d STORE $0.*' ..
740 'let invert = !flag.*' ..
741 '\d LOAD $0.*' ..
742 '\d INVERT (!val).*' ..
743 '\d STORE $1.*' ..
744 'let res = !!flag.*' ..
745 '\d LOAD $0.*' ..
746 '\d 2BOOL (!!val).*' ..
747 '\d STORE $2.*',
748 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100749 call assert_equal(true, InvertBool())
750enddef
751
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100752def Test_disassemble_compare()
753 " TODO: COMPAREFUNC
754 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200755 ['true == false', 'COMPAREBOOL =='],
756 ['true != false', 'COMPAREBOOL !='],
757 ['v:none == v:null', 'COMPARESPECIAL =='],
758 ['v:none != v:null', 'COMPARESPECIAL !='],
759
760 ['111 == 222', 'COMPARENR =='],
761 ['111 != 222', 'COMPARENR !='],
762 ['111 > 222', 'COMPARENR >'],
763 ['111 < 222', 'COMPARENR <'],
764 ['111 >= 222', 'COMPARENR >='],
765 ['111 <= 222', 'COMPARENR <='],
766 ['111 =~ 222', 'COMPARENR =\~'],
767 ['111 !~ 222', 'COMPARENR !\~'],
768
769 ['"xx" != "yy"', 'COMPARESTRING !='],
770 ['"xx" > "yy"', 'COMPARESTRING >'],
771 ['"xx" < "yy"', 'COMPARESTRING <'],
772 ['"xx" >= "yy"', 'COMPARESTRING >='],
773 ['"xx" <= "yy"', 'COMPARESTRING <='],
774 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
775 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
776 ['"xx" is "yy"', 'COMPARESTRING is'],
777 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
778
779 ['0z11 == 0z22', 'COMPAREBLOB =='],
780 ['0z11 != 0z22', 'COMPAREBLOB !='],
781 ['0z11 is 0z22', 'COMPAREBLOB is'],
782 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
783
784 ['[1,2] == [3,4]', 'COMPARELIST =='],
785 ['[1,2] != [3,4]', 'COMPARELIST !='],
786 ['[1,2] is [3,4]', 'COMPARELIST is'],
787 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
788
789 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
790 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
791 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
792 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
793
794 ['{->33} == {->44}', 'COMPAREFUNC =='],
795 ['{->33} != {->44}', 'COMPAREFUNC !='],
796 ['{->33} is {->44}', 'COMPAREFUNC is'],
797 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
798
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 <= g:xx', 'COMPAREANY <='],
805 ['77 =~ g:xx', 'COMPAREANY =\~'],
806 ['77 !~ g:xx', 'COMPAREANY !\~'],
807 ['77 is g:xx', 'COMPAREANY is'],
808 ['77 isnot g:xx', 'COMPAREANY isnot'],
809 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100810 if has('float')
811 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200812 ['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 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
818 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
819 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
820 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100821 endif
822
823 let nr = 1
824 for case in cases
825 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200826 ' if ' .. case[0],
827 ' echo 42'
828 ' endif',
829 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100830 source Xdisassemble
831 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200832 assert_match('TestCase' .. nr .. '.*' ..
833 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
834 '\d \(PUSH\|FUNCREF\).*' ..
835 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
836 '\d ' .. case[1] .. '.*' ..
837 '\d JUMP_IF_FALSE -> \d\+.*',
838 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100839
840 nr += 1
841 endfor
842
Bram Moolenaar22da5592020-03-19 14:52:20 +0100843 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100844enddef
845
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200846def Test_disassemble_compare_const()
847 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200848 ['"xx" == "yy"', false],
849 ['"aa" == "aa"', true],
850 ['has("eval") ? true : false', true],
851 ['has("asdf") ? true : false', false],
852 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200853
854 let nr = 1
855 for case in cases
856 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200857 ' if ' .. case[0],
858 ' echo 42'
859 ' endif',
860 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200861 source Xdisassemble
862 let instr = execute('disassemble TestCase' .. nr)
863 if case[1]
864 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200865 assert_match('TestCase' .. nr .. '.*' ..
866 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
867 '\d PUSHNR 42.*' ..
868 '\d ECHO 1.*' ..
869 '\d PUSHNR 0.*' ..
870 '\d RETURN.*',
871 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200872 else
873 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200874 assert_match('TestCase' .. nr .. '.*' ..
875 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
876 'echo 42[ \n]*' ..
877 'endif[ \n]*' ..
878 '\s*\d PUSHNR 0.*' ..
879 '\d RETURN.*',
880 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200881 endif
882
883 nr += 1
884 endfor
885
886 delete('Xdisassemble')
887enddef
888
Bram Moolenaarad39c092020-02-26 18:23:43 +0100889def s:Execute()
890 execute 'help vim9.txt'
891 let cmd = 'help vim9.txt'
892 execute cmd
893 let tag = 'vim9.txt'
894 execute 'help ' .. tag
895enddef
896
897def Test_disassemble_execute()
898 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200899 assert_match('\<SNR>\d*_Execute.*' ..
900 "execute 'help vim9.txt'.*" ..
901 '\d PUSHS "help vim9.txt".*' ..
902 '\d EXECUTE 1.*' ..
903 "let cmd = 'help vim9.txt'.*" ..
904 '\d PUSHS "help vim9.txt".*' ..
905 '\d STORE $0.*' ..
906 'execute cmd.*' ..
907 '\d LOAD $0.*' ..
908 '\d EXECUTE 1.*' ..
909 "let tag = 'vim9.txt'.*" ..
910 '\d PUSHS "vim9.txt".*' ..
911 '\d STORE $1.*' ..
912 "execute 'help ' .. tag.*" ..
913 '\d PUSHS "help ".*' ..
914 '\d LOAD $1.*' ..
915 '\d CONCAT.*' ..
916 '\d EXECUTE 1.*' ..
917 '\d PUSHNR 0.*' ..
918 '\d RETURN',
919 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100920enddef
921
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100922def SomeStringArg(arg: string)
923 echo arg
924enddef
925
926def SomeAnyArg(arg: any)
927 echo arg
928enddef
929
930def SomeStringArgAndReturn(arg: string): string
931 return arg
932enddef
933
934def Test_display_func()
935 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200936 assert_match('.* def SomeStringArg(arg: string).*' ..
937 ' echo arg.*' ..
938 ' enddef',
939 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100940
941 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200942 assert_match('.* def SomeAnyArg(arg: any).*' ..
943 ' echo arg.*' ..
944 ' enddef',
945 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100946
947 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200948 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
949 ' return arg.*' ..
950 ' enddef',
951 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100952enddef
953
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100954" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker