blob: 4e2caf09f15f3b68d79d4d0d4888937a577da390 [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
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020056def s:EditExpand()
57 let filename = "file"
58 let filenr = 123
59 edit the`=filename``=filenr`.txt
60enddef
61
62def Test_disassemble_exec_expr()
63 let res = execute('disass s:EditExpand')
64 assert_match('<SNR>\d*_EditExpand.*' ..
65 ' let filename = "file".*' ..
66 '\d PUSHS "file".*' ..
67 '\d STORE $0.*' ..
68 ' let filenr = 123.*' ..
69 '\d STORE 123 in $1.*' ..
70 ' edit the`=filename``=filenr`.txt.*' ..
71 '\d PUSHS "edit the".*' ..
72 '\d LOAD $0.*' ..
73 '\d LOAD $1.*' ..
74 '\d 2STRING stack\[-1\].*' ..
75 '\d PUSHS ".txt".*' ..
76 '\d EXECCONCAT 4.*' ..
77 '\d PUSHNR 0.*' ..
78 '\d RETURN',
79 res)
80enddef
81
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010082def s:ScriptFuncPush()
83 let localbool = true
84 let localspec = v:none
85 let localblob = 0z1234
86 if has('float')
87 let localfloat = 1.234
88 endif
89enddef
90
Bram Moolenaarf2460a32020-02-07 22:09:54 +010091def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010092 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020093 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
94 'localbool = true.*' ..
95 ' PUSH v:true.*' ..
96 'localspec = v:none.*' ..
97 ' PUSH v:none.*' ..
98 'localblob = 0z1234.*' ..
99 ' PUSHBLOB 0z1234.*',
100 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100101 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200102 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
103 'localfloat = 1.234.*' ..
104 ' PUSHF 1.234.*',
105 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100106 endif
107enddef
108
109def s:ScriptFuncStore()
110 let localnr = 1
111 localnr = 2
112 let localstr = 'abc'
113 localstr = 'xyz'
114 v:char = 'abc'
115 s:scriptvar = 'sv'
116 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200117 b:buffervar = 'bv'
118 w:windowvar = 'wv'
119 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100120 &tabstop = 8
121 $ENVVAR = 'ev'
122 @z = 'rv'
123enddef
124
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100125def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100126 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200127 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
128 'let localnr = 1.*' ..
129 'localnr = 2.*' ..
130 ' STORE 2 in $0.*' ..
131 'let localstr = ''abc''.*' ..
132 'localstr = ''xyz''.*' ..
133 ' STORE $1.*' ..
134 'v:char = ''abc''.*' ..
135 'STOREV v:char.*' ..
136 's:scriptvar = ''sv''.*' ..
137 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
138 'g:globalvar = ''gv''.*' ..
139 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200140 'b:buffervar = ''bv''.*' ..
141 ' STOREB b:buffervar.*' ..
142 'w:windowvar = ''wv''.*' ..
143 ' STOREW w:windowvar.*' ..
144 't:tabpagevar = ''tv''.*' ..
145 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200146 '&tabstop = 8.*' ..
147 ' STOREOPT &tabstop.*' ..
148 '$ENVVAR = ''ev''.*' ..
149 ' STOREENV $ENVVAR.*' ..
150 '@z = ''rv''.*' ..
151 ' STOREREG @z.*',
152 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100153enddef
154
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200155def s:ScriptFuncUnlet()
156 g:somevar = "value"
157 unlet g:somevar
158 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200159 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200160enddef
161
162def Test_disassemble_unlet()
163 let res = execute('disass s:ScriptFuncUnlet')
164 assert_match('<SNR>\d*_ScriptFuncUnlet.*' ..
165 'g:somevar = "value".*' ..
166 '\d PUSHS "value".*' ..
167 '\d STOREG g:somevar.*' ..
168 'unlet g:somevar.*' ..
169 '\d UNLET g:somevar.*' ..
170 'unlet! g:somevar.*' ..
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200171 '\d UNLET! g:somevar.*' ..
172 'unlet $SOMEVAR.*' ..
173 '\d UNLETENV $SOMEVAR.*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200174 res)
175enddef
176
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100177def s:ScriptFuncTry()
178 try
179 echo 'yes'
180 catch /fail/
181 echo 'no'
182 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100183 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100184 endtry
185enddef
186
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100187def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100188 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200189 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
190 'try.*' ..
191 'TRY catch -> \d\+, finally -> \d\+.*' ..
192 'catch /fail/.*' ..
193 ' JUMP -> \d\+.*' ..
194 ' PUSH v:exception.*' ..
195 ' PUSHS "fail".*' ..
196 ' COMPARESTRING =\~.*' ..
197 ' JUMP_IF_FALSE -> \d\+.*' ..
198 ' CATCH.*' ..
199 'finally.*' ..
200 ' PUSHS "end".*' ..
201 ' THROW.*' ..
202 'endtry.*' ..
203 ' ENDTRY.*',
204 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100205enddef
206
207def s:ScriptFuncNew()
208 let ll = [1, "two", 333]
209 let dd = #{one: 1, two: "val"}
210enddef
211
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100212def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100213 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200214 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
215 'let ll = \[1, "two", 333].*' ..
216 'PUSHNR 1.*' ..
217 'PUSHS "two".*' ..
218 'PUSHNR 333.*' ..
219 'NEWLIST size 3.*' ..
220 'let dd = #{one: 1, two: "val"}.*' ..
221 'PUSHS "one".*' ..
222 'PUSHNR 1.*' ..
223 'PUSHS "two".*' ..
224 'PUSHS "val".*' ..
225 'NEWDICT size 2.*',
226 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100227enddef
228
Bram Moolenaar6e949782020-04-13 17:21:00 +0200229def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100230 echo arg
231enddef
232
233func UserFunc()
234 echo 'nothing'
235endfunc
236
237func UserFuncWithArg(arg)
238 echo a:arg
239endfunc
240
241def s:ScriptFuncCall(): string
242 changenr()
243 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100244 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100245 FuncWithArg(343)
246 ScriptFuncNew()
247 s:ScriptFuncNew()
248 UserFunc()
249 UserFuncWithArg("foo")
250 let FuncRef = function("UserFunc")
251 FuncRef()
252 let FuncRefWithArg = function("UserFuncWithArg")
253 FuncRefWithArg("bar")
254 return "yes"
255enddef
256
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100257def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100258 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200259 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
260 'changenr().*' ..
261 ' BCALL changenr(argc 0).*' ..
262 'char2nr("abc").*' ..
263 ' PUSHS "abc".*' ..
264 ' BCALL char2nr(argc 1).*' ..
265 'Test_disassemble_new().*' ..
266 ' DCALL Test_disassemble_new(argc 0).*' ..
267 'FuncWithArg(343).*' ..
268 ' PUSHNR 343.*' ..
269 ' DCALL FuncWithArg(argc 1).*' ..
270 'ScriptFuncNew().*' ..
271 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
272 's:ScriptFuncNew().*' ..
273 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
274 'UserFunc().*' ..
275 ' UCALL UserFunc(argc 0).*' ..
276 'UserFuncWithArg("foo").*' ..
277 ' PUSHS "foo".*' ..
278 ' UCALL UserFuncWithArg(argc 1).*' ..
279 'let FuncRef = function("UserFunc").*' ..
280 'FuncRef().*' ..
281 ' LOAD $\d.*' ..
282 ' PCALL (argc 0).*' ..
283 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
284 'FuncRefWithArg("bar").*' ..
285 ' PUSHS "bar".*' ..
286 ' LOAD $\d.*' ..
287 ' PCALL (argc 1).*' ..
288 'return "yes".*' ..
289 ' PUSHS "yes".*' ..
290 ' RETURN.*',
291 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100292enddef
293
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100294
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200295def EchoArg(arg: string): string
296 return arg
297enddef
298def RefThis(): func
299 return function('EchoArg')
300enddef
301def s:ScriptPCall()
302 RefThis()("text")
303enddef
304
305def Test_disassemble_pcall()
306 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200307 assert_match('<SNR>\d\+_ScriptPCall.*' ..
308 'RefThis()("text").*' ..
309 '\d DCALL RefThis(argc 0).*' ..
310 '\d PUSHS "text".*' ..
311 '\d PCALL top (argc 1).*' ..
312 '\d PCALL end.*' ..
313 '\d DROP.*' ..
314 '\d PUSHNR 0.*' ..
315 '\d RETURN.*',
316 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200317enddef
318
319
Bram Moolenaara26b9702020-04-18 19:53:28 +0200320def s:FuncWithForwardCall(): string
321 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100322enddef
323
324def DefinedLater(arg: string): string
325 return arg
326enddef
327
328def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200329 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200330 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200331 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200332 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200333 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200334 '\d CHECKTYPE string stack\[-1].*' ..
335 '\d RETURN.*',
336 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100337
338 " Calling the function will change UCALL into the faster DCALL
339 assert_equal('yes', FuncWithForwardCall())
340
Bram Moolenaara26b9702020-04-18 19:53:28 +0200341 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200342 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200343 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200344 '\d PUSHS "yes".*' ..
345 '\d DCALL DefinedLater(argc 1).*' ..
346 '\d CHECKTYPE string stack\[-1].*' ..
347 '\d RETURN.*',
348 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100349enddef
350
351
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100352def FuncWithDefault(arg: string = 'default'): string
353 return arg
354enddef
355
356def Test_disassemble_call_default()
357 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200358 assert_match('FuncWithDefault.*' ..
359 '\d PUSHS "default".*' ..
360 '\d STORE arg\[-1].*' ..
361 'return arg.*' ..
362 '\d LOAD arg\[-1].*' ..
363 '\d RETURN.*',
364 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100365enddef
366
367
Bram Moolenaar158906c2020-02-06 20:39:45 +0100368def HasEval()
369 if has("eval")
370 echo "yes"
371 else
372 echo "no"
373 endif
374enddef
375
376def HasNothing()
377 if has("nothing")
378 echo "yes"
379 else
380 echo "no"
381 endif
382enddef
383
384def HasSomething()
385 if has("nothing")
386 echo "nothing"
387 elseif has("something")
388 echo "something"
389 elseif has("eval")
390 echo "eval"
391 elseif has("less")
392 echo "less"
393 endif
394enddef
395
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100396def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100397 assert_equal("\nyes", execute('call HasEval()'))
398 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200399 assert_match('HasEval.*' ..
400 'if has("eval").*' ..
401 ' PUSHS "yes".*',
402 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100403 assert_notmatch('JUMP', instr)
404
405 assert_equal("\nno", execute('call HasNothing()'))
406 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200407 assert_match('HasNothing.*' ..
408 'if has("nothing").*' ..
409 'else.*' ..
410 ' PUSHS "no".*',
411 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100412 assert_notmatch('PUSHS "yes"', instr)
413 assert_notmatch('JUMP', instr)
414
415 assert_equal("\neval", execute('call HasSomething()'))
416 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200417 assert_match('HasSomething.*' ..
418 'if has("nothing").*' ..
419 'elseif has("something").*' ..
420 'elseif has("eval").*' ..
421 ' PUSHS "eval".*' ..
422 'elseif has("less").*',
423 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100424 assert_notmatch('PUSHS "nothing"', instr)
425 assert_notmatch('PUSHS "something"', instr)
426 assert_notmatch('PUSHS "less"', instr)
427 assert_notmatch('JUMP', instr)
428enddef
429
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100430def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200431 let Funky1: func
432 let Funky2: func = function("len")
433 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100434enddef
435
436def Test_disassemble_function()
437 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200438 assert_match('WithFunc.*' ..
439 'let Funky1: func.*' ..
440 '0 PUSHFUNC "\[none]".*' ..
441 '1 STORE $0.*' ..
442 'let Funky2: func = function("len").*' ..
443 '2 PUSHS "len".*' ..
444 '3 BCALL function(argc 1).*' ..
445 '4 STORE $1.*' ..
446 'let Party2: func = funcref("UserFunc").*' ..
447 '\d PUSHS "UserFunc".*' ..
448 '\d BCALL funcref(argc 1).*' ..
449 '\d STORE $2.*' ..
450 '\d PUSHNR 0.*' ..
451 '\d RETURN.*',
452 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100453enddef
454
455if has('channel')
456 def WithChannel()
457 let job1: job
458 let job2: job = job_start("donothing")
459 let chan1: channel
460 enddef
461endif
462
463def Test_disassemble_channel()
464 CheckFeature channel
465
466 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200467 assert_match('WithChannel.*' ..
468 'let job1: job.*' ..
469 '\d PUSHJOB "no process".*' ..
470 '\d STORE $0.*' ..
471 'let job2: job = job_start("donothing").*' ..
472 '\d PUSHS "donothing".*' ..
473 '\d BCALL job_start(argc 1).*' ..
474 '\d STORE $1.*' ..
475 'let chan1: channel.*' ..
476 '\d PUSHCHANNEL 0.*' ..
477 '\d STORE $2.*' ..
478 '\d PUSHNR 0.*' ..
479 '\d RETURN.*',
480 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100481enddef
482
Bram Moolenaar777770f2020-02-06 21:27:08 +0100483def WithLambda(): string
484 let F = {a -> "X" .. a .. "X"}
485 return F("x")
486enddef
487
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100488def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100489 assert_equal("XxX", WithLambda())
490 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200491 assert_match('WithLambda.*' ..
492 'let F = {a -> "X" .. a .. "X"}.*' ..
493 ' FUNCREF <lambda>\d\+.*' ..
494 'PUSHS "x".*' ..
495 ' LOAD $0.*' ..
496 ' PCALL (argc 1).*' ..
497 ' CHECKTYPE string stack\[-1].*',
498 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100499enddef
500
Bram Moolenaar6e949782020-04-13 17:21:00 +0200501def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100502 if arg == 1 && arg != 2 || arg == 4
503 return 'yes'
504 endif
505 return 'no'
506enddef
507
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100508def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100509 assert_equal("yes", AndOr(1))
510 assert_equal("no", AndOr(2))
511 assert_equal("yes", AndOr(4))
512 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200513 assert_match('AndOr.*' ..
514 'if arg == 1 && arg != 2 || arg == 4.*' ..
515 '\d LOAD arg\[-1].*' ..
516 '\d PUSHNR 1.*' ..
517 '\d COMPAREANY ==.*' ..
518 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
519 '\d LOAD arg\[-1].*' ..
520 '\d PUSHNR 2.*' ..
521 '\d COMPAREANY !=.*' ..
522 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
523 '\d LOAD arg\[-1].*' ..
524 '\d PUSHNR 4.*' ..
525 '\d COMPAREANY ==.*' ..
526 '\d JUMP_IF_FALSE -> \d\+.*',
527 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100528enddef
529
Bram Moolenaar04d05222020-02-06 22:06:54 +0100530def ForLoop(): list<number>
531 let res: list<number>
532 for i in range(3)
533 res->add(i)
534 endfor
535 return res
536enddef
537
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100538def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100539 assert_equal([0, 1, 2], ForLoop())
540 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200541 assert_match('ForLoop.*' ..
542 'let res: list<number>.*' ..
543 ' NEWLIST size 0.*' ..
544 '\d STORE $0.*' ..
545 'for i in range(3).*' ..
546 '\d STORE -1 in $1.*' ..
547 '\d PUSHNR 3.*' ..
548 '\d BCALL range(argc 1).*' ..
549 '\d FOR $1 -> \d\+.*' ..
550 '\d STORE $2.*' ..
551 'res->add(i).*' ..
552 '\d LOAD $0.*' ..
553 '\d LOAD $2.*' ..
554 '\d BCALL add(argc 2).*' ..
555 '\d DROP.*' ..
556 'endfor.*' ..
557 '\d JUMP -> \d\+.*' ..
558 '\d DROP.*',
559 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100560enddef
561
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100562let g:number = 42
563
564def Computing()
565 let nr = 3
566 let nrres = nr + 7
567 nrres = nr - 7
568 nrres = nr * 7
569 nrres = nr / 7
570 nrres = nr % 7
571
572 let anyres = g:number + 7
573 anyres = g:number - 7
574 anyres = g:number * 7
575 anyres = g:number / 7
576 anyres = g:number % 7
577
578 if has('float')
579 let fl = 3.0
580 let flres = fl + 7.0
581 flres = fl - 7.0
582 flres = fl * 7.0
583 flres = fl / 7.0
584 endif
585enddef
586
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100587def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100588 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200589 assert_match('Computing.*' ..
590 'let nr = 3.*' ..
591 '\d STORE 3 in $0.*' ..
592 'let nrres = nr + 7.*' ..
593 '\d LOAD $0.*' ..
594 '\d PUSHNR 7.*' ..
595 '\d OPNR +.*' ..
596 '\d STORE $1.*' ..
597 'nrres = nr - 7.*' ..
598 '\d OPNR -.*' ..
599 'nrres = nr \* 7.*' ..
600 '\d OPNR \*.*' ..
601 'nrres = nr / 7.*' ..
602 '\d OPNR /.*' ..
603 'nrres = nr % 7.*' ..
604 '\d OPNR %.*' ..
605 'let anyres = g:number + 7.*' ..
606 '\d LOADG g:number.*' ..
607 '\d PUSHNR 7.*' ..
608 '\d OPANY +.*' ..
609 '\d STORE $2.*' ..
610 'anyres = g:number - 7.*' ..
611 '\d OPANY -.*' ..
612 'anyres = g:number \* 7.*' ..
613 '\d OPANY \*.*' ..
614 'anyres = g:number / 7.*' ..
615 '\d OPANY /.*' ..
616 'anyres = g:number % 7.*' ..
617 '\d OPANY %.*',
618 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100619 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200620 assert_match('Computing.*' ..
621 'let fl = 3.0.*' ..
622 '\d PUSHF 3.0.*' ..
623 '\d STORE $3.*' ..
624 'let flres = fl + 7.0.*' ..
625 '\d LOAD $3.*' ..
626 '\d PUSHF 7.0.*' ..
627 '\d OPFLOAT +.*' ..
628 '\d STORE $4.*' ..
629 'flres = fl - 7.0.*' ..
630 '\d OPFLOAT -.*' ..
631 'flres = fl \* 7.0.*' ..
632 '\d OPFLOAT \*.*' ..
633 'flres = fl / 7.0.*' ..
634 '\d OPFLOAT /.*',
635 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100636 endif
637enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100638
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100639def AddListBlob()
640 let reslist = [1, 2] + [3, 4]
641 let resblob = 0z1122 + 0z3344
642enddef
643
644def Test_disassemble_add_list_blob()
645 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200646 assert_match('AddListBlob.*' ..
647 'let reslist = \[1, 2] + \[3, 4].*' ..
648 '\d PUSHNR 1.*' ..
649 '\d PUSHNR 2.*' ..
650 '\d NEWLIST size 2.*' ..
651 '\d PUSHNR 3.*' ..
652 '\d PUSHNR 4.*' ..
653 '\d NEWLIST size 2.*' ..
654 '\d ADDLIST.*' ..
655 '\d STORE $.*.*' ..
656 'let resblob = 0z1122 + 0z3344.*' ..
657 '\d PUSHBLOB 0z1122.*' ..
658 '\d PUSHBLOB 0z3344.*' ..
659 '\d ADDBLOB.*' ..
660 '\d STORE $.*',
661 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100662enddef
663
664let g:aa = 'aa'
665def ConcatString(): string
666 let res = g:aa .. "bb"
667 return res
668enddef
669
670def Test_disassemble_concat()
671 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200672 assert_match('ConcatString.*' ..
673 'let res = g:aa .. "bb".*' ..
674 '\d LOADG g:aa.*' ..
675 '\d PUSHS "bb".*' ..
676 '\d 2STRING stack\[-2].*' ..
677 '\d CONCAT.*' ..
678 '\d STORE $.*',
679 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100680 assert_equal('aabb', ConcatString())
681enddef
682
683def ListIndex(): number
684 let l = [1, 2, 3]
685 let res = l[1]
686 return res
687enddef
688
689def Test_disassemble_list_index()
690 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200691 assert_match('ListIndex.*' ..
692 'let l = \[1, 2, 3].*' ..
693 '\d PUSHNR 1.*' ..
694 '\d PUSHNR 2.*' ..
695 '\d PUSHNR 3.*' ..
696 '\d NEWLIST size 3.*' ..
697 '\d STORE $0.*' ..
698 'let res = l\[1].*' ..
699 '\d LOAD $0.*' ..
700 '\d PUSHNR 1.*' ..
701 '\d INDEX.*' ..
702 '\d STORE $1.*',
703 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100704 assert_equal(2, ListIndex())
705enddef
706
707def DictMember(): number
708 let d = #{item: 1}
709 let res = d.item
710 return res
711enddef
712
713def Test_disassemble_dict_member()
714 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200715 assert_match('DictMember.*' ..
716 'let d = #{item: 1}.*' ..
717 '\d PUSHS "item".*' ..
718 '\d PUSHNR 1.*' ..
719 '\d NEWDICT size 1.*' ..
720 '\d STORE $0.*' ..
721 'let res = d.item.*' ..
722 '\d LOAD $0.*' ..
723 '\d MEMBER item.*' ..
724 '\d STORE $1.*',
725 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100726 call assert_equal(1, DictMember())
727enddef
728
729def NegateNumber(): number
730 let nr = 9
731 let plus = +nr
732 let res = -nr
733 return res
734enddef
735
736def Test_disassemble_negate_number()
737 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200738 assert_match('NegateNumber.*' ..
739 'let nr = 9.*' ..
740 '\d STORE 9 in $0.*' ..
741 'let plus = +nr.*' ..
742 '\d LOAD $0.*' ..
743 '\d CHECKNR.*' ..
744 '\d STORE $1.*' ..
745 'let res = -nr.*' ..
746 '\d LOAD $0.*' ..
747 '\d NEGATENR.*' ..
748 '\d STORE $2.*',
749 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100750 call assert_equal(-9, NegateNumber())
751enddef
752
753def InvertBool(): bool
754 let flag = true
755 let invert = !flag
756 let res = !!flag
757 return res
758enddef
759
760def Test_disassemble_invert_bool()
761 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200762 assert_match('InvertBool.*' ..
763 'let flag = true.*' ..
764 '\d PUSH v:true.*' ..
765 '\d STORE $0.*' ..
766 'let invert = !flag.*' ..
767 '\d LOAD $0.*' ..
768 '\d INVERT (!val).*' ..
769 '\d STORE $1.*' ..
770 'let res = !!flag.*' ..
771 '\d LOAD $0.*' ..
772 '\d 2BOOL (!!val).*' ..
773 '\d STORE $2.*',
774 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100775 call assert_equal(true, InvertBool())
776enddef
777
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100778def Test_disassemble_compare()
779 " TODO: COMPAREFUNC
780 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200781 ['true == false', 'COMPAREBOOL =='],
782 ['true != false', 'COMPAREBOOL !='],
783 ['v:none == v:null', 'COMPARESPECIAL =='],
784 ['v:none != v:null', 'COMPARESPECIAL !='],
785
786 ['111 == 222', 'COMPARENR =='],
787 ['111 != 222', 'COMPARENR !='],
788 ['111 > 222', 'COMPARENR >'],
789 ['111 < 222', 'COMPARENR <'],
790 ['111 >= 222', 'COMPARENR >='],
791 ['111 <= 222', 'COMPARENR <='],
792 ['111 =~ 222', 'COMPARENR =\~'],
793 ['111 !~ 222', 'COMPARENR !\~'],
794
795 ['"xx" != "yy"', 'COMPARESTRING !='],
796 ['"xx" > "yy"', 'COMPARESTRING >'],
797 ['"xx" < "yy"', 'COMPARESTRING <'],
798 ['"xx" >= "yy"', 'COMPARESTRING >='],
799 ['"xx" <= "yy"', 'COMPARESTRING <='],
800 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
801 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
802 ['"xx" is "yy"', 'COMPARESTRING is'],
803 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
804
805 ['0z11 == 0z22', 'COMPAREBLOB =='],
806 ['0z11 != 0z22', 'COMPAREBLOB !='],
807 ['0z11 is 0z22', 'COMPAREBLOB is'],
808 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
809
810 ['[1,2] == [3,4]', 'COMPARELIST =='],
811 ['[1,2] != [3,4]', 'COMPARELIST !='],
812 ['[1,2] is [3,4]', 'COMPARELIST is'],
813 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
814
815 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
816 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
817 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
818 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
819
820 ['{->33} == {->44}', 'COMPAREFUNC =='],
821 ['{->33} != {->44}', 'COMPAREFUNC !='],
822 ['{->33} is {->44}', 'COMPAREFUNC is'],
823 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
824
825 ['77 == g:xx', 'COMPAREANY =='],
826 ['77 != g:xx', 'COMPAREANY !='],
827 ['77 > g:xx', 'COMPAREANY >'],
828 ['77 < g:xx', 'COMPAREANY <'],
829 ['77 >= g:xx', 'COMPAREANY >='],
830 ['77 <= g:xx', 'COMPAREANY <='],
831 ['77 =~ g:xx', 'COMPAREANY =\~'],
832 ['77 !~ g:xx', 'COMPAREANY !\~'],
833 ['77 is g:xx', 'COMPAREANY is'],
834 ['77 isnot g:xx', 'COMPAREANY isnot'],
835 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100836 if has('float')
837 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200838 ['1.1 == 2.2', 'COMPAREFLOAT =='],
839 ['1.1 != 2.2', 'COMPAREFLOAT !='],
840 ['1.1 > 2.2', 'COMPAREFLOAT >'],
841 ['1.1 < 2.2', 'COMPAREFLOAT <'],
842 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
843 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
844 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
845 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
846 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100847 endif
848
849 let nr = 1
850 for case in cases
851 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200852 ' if ' .. case[0],
853 ' echo 42'
854 ' endif',
855 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100856 source Xdisassemble
857 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200858 assert_match('TestCase' .. nr .. '.*' ..
859 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
860 '\d \(PUSH\|FUNCREF\).*' ..
861 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
862 '\d ' .. case[1] .. '.*' ..
863 '\d JUMP_IF_FALSE -> \d\+.*',
864 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100865
866 nr += 1
867 endfor
868
Bram Moolenaar22da5592020-03-19 14:52:20 +0100869 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100870enddef
871
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200872def Test_disassemble_compare_const()
873 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200874 ['"xx" == "yy"', false],
875 ['"aa" == "aa"', true],
876 ['has("eval") ? true : false', true],
877 ['has("asdf") ? true : false', false],
878 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200879
880 let nr = 1
881 for case in cases
882 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200883 ' if ' .. case[0],
884 ' echo 42'
885 ' endif',
886 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200887 source Xdisassemble
888 let instr = execute('disassemble TestCase' .. nr)
889 if case[1]
890 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200891 assert_match('TestCase' .. nr .. '.*' ..
892 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
893 '\d PUSHNR 42.*' ..
894 '\d ECHO 1.*' ..
895 '\d PUSHNR 0.*' ..
896 '\d RETURN.*',
897 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200898 else
899 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200900 assert_match('TestCase' .. nr .. '.*' ..
901 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
902 'echo 42[ \n]*' ..
903 'endif[ \n]*' ..
904 '\s*\d PUSHNR 0.*' ..
905 '\d RETURN.*',
906 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200907 endif
908
909 nr += 1
910 endfor
911
912 delete('Xdisassemble')
913enddef
914
Bram Moolenaarad39c092020-02-26 18:23:43 +0100915def s:Execute()
916 execute 'help vim9.txt'
917 let cmd = 'help vim9.txt'
918 execute cmd
919 let tag = 'vim9.txt'
920 execute 'help ' .. tag
921enddef
922
923def Test_disassemble_execute()
924 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200925 assert_match('\<SNR>\d*_Execute.*' ..
926 "execute 'help vim9.txt'.*" ..
927 '\d PUSHS "help vim9.txt".*' ..
928 '\d EXECUTE 1.*' ..
929 "let cmd = 'help vim9.txt'.*" ..
930 '\d PUSHS "help vim9.txt".*' ..
931 '\d STORE $0.*' ..
932 'execute cmd.*' ..
933 '\d LOAD $0.*' ..
934 '\d EXECUTE 1.*' ..
935 "let tag = 'vim9.txt'.*" ..
936 '\d PUSHS "vim9.txt".*' ..
937 '\d STORE $1.*' ..
938 "execute 'help ' .. tag.*" ..
939 '\d PUSHS "help ".*' ..
940 '\d LOAD $1.*' ..
941 '\d CONCAT.*' ..
942 '\d EXECUTE 1.*' ..
943 '\d PUSHNR 0.*' ..
944 '\d RETURN',
945 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100946enddef
947
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200948def s:Echomsg()
949 echomsg 'some' 'message'
950 echoerr 'went' .. 'wrong'
951enddef
952
953def Test_disassemble_echomsg()
954 let res = execute('disass s:Echomsg')
955 assert_match('\<SNR>\d*_Echomsg.*' ..
956 "echomsg 'some' 'message'.*" ..
957 '\d PUSHS "some".*' ..
958 '\d PUSHS "message".*' ..
959 '\d ECHOMSG 2.*' ..
960 "echoerr 'went' .. 'wrong'.*" ..
961 '\d PUSHS "went".*' ..
962 '\d PUSHS "wrong".*' ..
963 '\d CONCAT.*' ..
964 '\d ECHOERR 1.*' ..
965 '\d PUSHNR 0.*' ..
966 '\d RETURN',
967 res)
968enddef
969
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100970def SomeStringArg(arg: string)
971 echo arg
972enddef
973
974def SomeAnyArg(arg: any)
975 echo arg
976enddef
977
978def SomeStringArgAndReturn(arg: string): string
979 return arg
980enddef
981
982def Test_display_func()
983 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200984 assert_match('.* def SomeStringArg(arg: string).*' ..
985 ' echo arg.*' ..
986 ' enddef',
987 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100988
989 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200990 assert_match('.* def SomeAnyArg(arg: any).*' ..
991 ' echo arg.*' ..
992 ' enddef',
993 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100994
995 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200996 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
997 ' return arg.*' ..
998 ' enddef',
999 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001000enddef
1001
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001002" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker