blob: 11703416d12de43dd0e0fa5a1116bfaeb1940f3b [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 Moolenaarb68b3462020-05-06 21:06:30 +0200294def s:CreateRefs()
295 let local = 'a'
296 def Append(arg: string)
297 local ..= arg
298 enddef
299 g:Append = Append
300 def Get(): string
301 return local
302 enddef
303 g:Get = Get
304enddef
305
306def Test_disassemble_closure()
307 CreateRefs()
308 let res = execute('disass g:Append')
309 assert_match('<lambda>\d.*' ..
310 'local ..= arg.*' ..
311 '\d LOADOUTER $0.*' ..
312 '\d LOAD arg\[-1\].*' ..
313 '\d CONCAT.*' ..
314 '\d STOREOUTER $0.*' ..
315 '\d PUSHNR 0.*' ..
316 '\d RETURN.*',
317 res)
318
319 res = execute('disass g:Get')
320 assert_match('<lambda>\d.*' ..
321 'return local.*' ..
322 '\d LOADOUTER $0.*' ..
323 '\d RETURN.*',
324 res)
325
326 unlet g:Append
327 unlet g:Get
328enddef
329
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100330
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200331def EchoArg(arg: string): string
332 return arg
333enddef
334def RefThis(): func
335 return function('EchoArg')
336enddef
337def s:ScriptPCall()
338 RefThis()("text")
339enddef
340
341def Test_disassemble_pcall()
342 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200343 assert_match('<SNR>\d\+_ScriptPCall.*' ..
344 'RefThis()("text").*' ..
345 '\d DCALL RefThis(argc 0).*' ..
346 '\d PUSHS "text".*' ..
347 '\d PCALL top (argc 1).*' ..
348 '\d PCALL end.*' ..
349 '\d DROP.*' ..
350 '\d PUSHNR 0.*' ..
351 '\d RETURN.*',
352 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200353enddef
354
355
Bram Moolenaara26b9702020-04-18 19:53:28 +0200356def s:FuncWithForwardCall(): string
357 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100358enddef
359
360def DefinedLater(arg: string): string
361 return arg
362enddef
363
364def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200365 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200366 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200367 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200368 '\d PUSHS "yes".*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200369 '\d UCALL g:DefinedLater(argc 1).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200370 '\d CHECKTYPE string stack\[-1].*' ..
371 '\d RETURN.*',
372 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100373
374 " Calling the function will change UCALL into the faster DCALL
375 assert_equal('yes', FuncWithForwardCall())
376
Bram Moolenaara26b9702020-04-18 19:53:28 +0200377 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200378 assert_match('FuncWithForwardCall.*' ..
Bram Moolenaara26b9702020-04-18 19:53:28 +0200379 'return g:DefinedLater("yes").*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200380 '\d PUSHS "yes".*' ..
381 '\d DCALL DefinedLater(argc 1).*' ..
382 '\d CHECKTYPE string stack\[-1].*' ..
383 '\d RETURN.*',
384 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100385enddef
386
387
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100388def FuncWithDefault(arg: string = 'default'): string
389 return arg
390enddef
391
392def Test_disassemble_call_default()
393 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200394 assert_match('FuncWithDefault.*' ..
395 '\d PUSHS "default".*' ..
396 '\d STORE arg\[-1].*' ..
397 'return arg.*' ..
398 '\d LOAD arg\[-1].*' ..
399 '\d RETURN.*',
400 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100401enddef
402
403
Bram Moolenaar158906c2020-02-06 20:39:45 +0100404def HasEval()
405 if has("eval")
406 echo "yes"
407 else
408 echo "no"
409 endif
410enddef
411
412def HasNothing()
413 if has("nothing")
414 echo "yes"
415 else
416 echo "no"
417 endif
418enddef
419
420def HasSomething()
421 if has("nothing")
422 echo "nothing"
423 elseif has("something")
424 echo "something"
425 elseif has("eval")
426 echo "eval"
427 elseif has("less")
428 echo "less"
429 endif
430enddef
431
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100432def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100433 assert_equal("\nyes", execute('call HasEval()'))
434 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200435 assert_match('HasEval.*' ..
436 'if has("eval").*' ..
437 ' PUSHS "yes".*',
438 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100439 assert_notmatch('JUMP', instr)
440
441 assert_equal("\nno", execute('call HasNothing()'))
442 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200443 assert_match('HasNothing.*' ..
444 'if has("nothing").*' ..
445 'else.*' ..
446 ' PUSHS "no".*',
447 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100448 assert_notmatch('PUSHS "yes"', instr)
449 assert_notmatch('JUMP', instr)
450
451 assert_equal("\neval", execute('call HasSomething()'))
452 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200453 assert_match('HasSomething.*' ..
454 'if has("nothing").*' ..
455 'elseif has("something").*' ..
456 'elseif has("eval").*' ..
457 ' PUSHS "eval".*' ..
458 'elseif has("less").*',
459 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100460 assert_notmatch('PUSHS "nothing"', instr)
461 assert_notmatch('PUSHS "something"', instr)
462 assert_notmatch('PUSHS "less"', instr)
463 assert_notmatch('JUMP', instr)
464enddef
465
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100466def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200467 let Funky1: func
468 let Funky2: func = function("len")
469 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100470enddef
471
472def Test_disassemble_function()
473 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200474 assert_match('WithFunc.*' ..
475 'let Funky1: func.*' ..
476 '0 PUSHFUNC "\[none]".*' ..
477 '1 STORE $0.*' ..
478 'let Funky2: func = function("len").*' ..
479 '2 PUSHS "len".*' ..
480 '3 BCALL function(argc 1).*' ..
481 '4 STORE $1.*' ..
482 'let Party2: func = funcref("UserFunc").*' ..
483 '\d PUSHS "UserFunc".*' ..
484 '\d BCALL funcref(argc 1).*' ..
485 '\d STORE $2.*' ..
486 '\d PUSHNR 0.*' ..
487 '\d RETURN.*',
488 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100489enddef
490
491if has('channel')
492 def WithChannel()
493 let job1: job
494 let job2: job = job_start("donothing")
495 let chan1: channel
496 enddef
497endif
498
499def Test_disassemble_channel()
500 CheckFeature channel
501
502 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200503 assert_match('WithChannel.*' ..
504 'let job1: job.*' ..
505 '\d PUSHJOB "no process".*' ..
506 '\d STORE $0.*' ..
507 'let job2: job = job_start("donothing").*' ..
508 '\d PUSHS "donothing".*' ..
509 '\d BCALL job_start(argc 1).*' ..
510 '\d STORE $1.*' ..
511 'let chan1: channel.*' ..
512 '\d PUSHCHANNEL 0.*' ..
513 '\d STORE $2.*' ..
514 '\d PUSHNR 0.*' ..
515 '\d RETURN.*',
516 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100517enddef
518
Bram Moolenaar777770f2020-02-06 21:27:08 +0100519def WithLambda(): string
520 let F = {a -> "X" .. a .. "X"}
521 return F("x")
522enddef
523
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100524def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100525 assert_equal("XxX", WithLambda())
526 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200527 assert_match('WithLambda.*' ..
528 'let F = {a -> "X" .. a .. "X"}.*' ..
529 ' FUNCREF <lambda>\d\+.*' ..
530 'PUSHS "x".*' ..
531 ' LOAD $0.*' ..
532 ' PCALL (argc 1).*' ..
533 ' CHECKTYPE string stack\[-1].*',
534 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100535enddef
536
Bram Moolenaar6e949782020-04-13 17:21:00 +0200537def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100538 if arg == 1 && arg != 2 || arg == 4
539 return 'yes'
540 endif
541 return 'no'
542enddef
543
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100544def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100545 assert_equal("yes", AndOr(1))
546 assert_equal("no", AndOr(2))
547 assert_equal("yes", AndOr(4))
548 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200549 assert_match('AndOr.*' ..
550 'if arg == 1 && arg != 2 || arg == 4.*' ..
551 '\d LOAD arg\[-1].*' ..
552 '\d PUSHNR 1.*' ..
553 '\d COMPAREANY ==.*' ..
554 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
555 '\d LOAD arg\[-1].*' ..
556 '\d PUSHNR 2.*' ..
557 '\d COMPAREANY !=.*' ..
558 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
559 '\d LOAD arg\[-1].*' ..
560 '\d PUSHNR 4.*' ..
561 '\d COMPAREANY ==.*' ..
562 '\d JUMP_IF_FALSE -> \d\+.*',
563 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100564enddef
565
Bram Moolenaar04d05222020-02-06 22:06:54 +0100566def ForLoop(): list<number>
567 let res: list<number>
568 for i in range(3)
569 res->add(i)
570 endfor
571 return res
572enddef
573
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100574def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100575 assert_equal([0, 1, 2], ForLoop())
576 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200577 assert_match('ForLoop.*' ..
578 'let res: list<number>.*' ..
579 ' NEWLIST size 0.*' ..
580 '\d STORE $0.*' ..
581 'for i in range(3).*' ..
582 '\d STORE -1 in $1.*' ..
583 '\d PUSHNR 3.*' ..
584 '\d BCALL range(argc 1).*' ..
585 '\d FOR $1 -> \d\+.*' ..
586 '\d STORE $2.*' ..
587 'res->add(i).*' ..
588 '\d LOAD $0.*' ..
589 '\d LOAD $2.*' ..
590 '\d BCALL add(argc 2).*' ..
591 '\d DROP.*' ..
592 'endfor.*' ..
593 '\d JUMP -> \d\+.*' ..
594 '\d DROP.*',
595 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100596enddef
597
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100598let g:number = 42
599
600def Computing()
601 let nr = 3
602 let nrres = nr + 7
603 nrres = nr - 7
604 nrres = nr * 7
605 nrres = nr / 7
606 nrres = nr % 7
607
608 let anyres = g:number + 7
609 anyres = g:number - 7
610 anyres = g:number * 7
611 anyres = g:number / 7
612 anyres = g:number % 7
613
614 if has('float')
615 let fl = 3.0
616 let flres = fl + 7.0
617 flres = fl - 7.0
618 flres = fl * 7.0
619 flres = fl / 7.0
620 endif
621enddef
622
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100623def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100624 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200625 assert_match('Computing.*' ..
626 'let nr = 3.*' ..
627 '\d STORE 3 in $0.*' ..
628 'let nrres = nr + 7.*' ..
629 '\d LOAD $0.*' ..
630 '\d PUSHNR 7.*' ..
631 '\d OPNR +.*' ..
632 '\d STORE $1.*' ..
633 'nrres = nr - 7.*' ..
634 '\d OPNR -.*' ..
635 'nrres = nr \* 7.*' ..
636 '\d OPNR \*.*' ..
637 'nrres = nr / 7.*' ..
638 '\d OPNR /.*' ..
639 'nrres = nr % 7.*' ..
640 '\d OPNR %.*' ..
641 'let anyres = g:number + 7.*' ..
642 '\d LOADG g:number.*' ..
643 '\d PUSHNR 7.*' ..
644 '\d OPANY +.*' ..
645 '\d STORE $2.*' ..
646 'anyres = g:number - 7.*' ..
647 '\d OPANY -.*' ..
648 'anyres = g:number \* 7.*' ..
649 '\d OPANY \*.*' ..
650 'anyres = g:number / 7.*' ..
651 '\d OPANY /.*' ..
652 'anyres = g:number % 7.*' ..
653 '\d OPANY %.*',
654 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100655 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200656 assert_match('Computing.*' ..
657 'let fl = 3.0.*' ..
658 '\d PUSHF 3.0.*' ..
659 '\d STORE $3.*' ..
660 'let flres = fl + 7.0.*' ..
661 '\d LOAD $3.*' ..
662 '\d PUSHF 7.0.*' ..
663 '\d OPFLOAT +.*' ..
664 '\d STORE $4.*' ..
665 'flres = fl - 7.0.*' ..
666 '\d OPFLOAT -.*' ..
667 'flres = fl \* 7.0.*' ..
668 '\d OPFLOAT \*.*' ..
669 'flres = fl / 7.0.*' ..
670 '\d OPFLOAT /.*',
671 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100672 endif
673enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100674
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100675def AddListBlob()
676 let reslist = [1, 2] + [3, 4]
677 let resblob = 0z1122 + 0z3344
678enddef
679
680def Test_disassemble_add_list_blob()
681 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200682 assert_match('AddListBlob.*' ..
683 'let reslist = \[1, 2] + \[3, 4].*' ..
684 '\d PUSHNR 1.*' ..
685 '\d PUSHNR 2.*' ..
686 '\d NEWLIST size 2.*' ..
687 '\d PUSHNR 3.*' ..
688 '\d PUSHNR 4.*' ..
689 '\d NEWLIST size 2.*' ..
690 '\d ADDLIST.*' ..
691 '\d STORE $.*.*' ..
692 'let resblob = 0z1122 + 0z3344.*' ..
693 '\d PUSHBLOB 0z1122.*' ..
694 '\d PUSHBLOB 0z3344.*' ..
695 '\d ADDBLOB.*' ..
696 '\d STORE $.*',
697 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100698enddef
699
700let g:aa = 'aa'
701def ConcatString(): string
702 let res = g:aa .. "bb"
703 return res
704enddef
705
706def Test_disassemble_concat()
707 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200708 assert_match('ConcatString.*' ..
709 'let res = g:aa .. "bb".*' ..
710 '\d LOADG g:aa.*' ..
711 '\d PUSHS "bb".*' ..
712 '\d 2STRING stack\[-2].*' ..
713 '\d CONCAT.*' ..
714 '\d STORE $.*',
715 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100716 assert_equal('aabb', ConcatString())
717enddef
718
719def ListIndex(): number
720 let l = [1, 2, 3]
721 let res = l[1]
722 return res
723enddef
724
725def Test_disassemble_list_index()
726 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200727 assert_match('ListIndex.*' ..
728 'let l = \[1, 2, 3].*' ..
729 '\d PUSHNR 1.*' ..
730 '\d PUSHNR 2.*' ..
731 '\d PUSHNR 3.*' ..
732 '\d NEWLIST size 3.*' ..
733 '\d STORE $0.*' ..
734 'let res = l\[1].*' ..
735 '\d LOAD $0.*' ..
736 '\d PUSHNR 1.*' ..
737 '\d INDEX.*' ..
738 '\d STORE $1.*',
739 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100740 assert_equal(2, ListIndex())
741enddef
742
743def DictMember(): number
744 let d = #{item: 1}
745 let res = d.item
746 return res
747enddef
748
749def Test_disassemble_dict_member()
750 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200751 assert_match('DictMember.*' ..
752 'let d = #{item: 1}.*' ..
753 '\d PUSHS "item".*' ..
754 '\d PUSHNR 1.*' ..
755 '\d NEWDICT size 1.*' ..
756 '\d STORE $0.*' ..
757 'let res = d.item.*' ..
758 '\d LOAD $0.*' ..
759 '\d MEMBER item.*' ..
760 '\d STORE $1.*',
761 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100762 call assert_equal(1, DictMember())
763enddef
764
765def NegateNumber(): number
766 let nr = 9
767 let plus = +nr
768 let res = -nr
769 return res
770enddef
771
772def Test_disassemble_negate_number()
773 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200774 assert_match('NegateNumber.*' ..
775 'let nr = 9.*' ..
776 '\d STORE 9 in $0.*' ..
777 'let plus = +nr.*' ..
778 '\d LOAD $0.*' ..
779 '\d CHECKNR.*' ..
780 '\d STORE $1.*' ..
781 'let res = -nr.*' ..
782 '\d LOAD $0.*' ..
783 '\d NEGATENR.*' ..
784 '\d STORE $2.*',
785 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100786 call assert_equal(-9, NegateNumber())
787enddef
788
789def InvertBool(): bool
790 let flag = true
791 let invert = !flag
792 let res = !!flag
793 return res
794enddef
795
796def Test_disassemble_invert_bool()
797 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200798 assert_match('InvertBool.*' ..
799 'let flag = true.*' ..
800 '\d PUSH v:true.*' ..
801 '\d STORE $0.*' ..
802 'let invert = !flag.*' ..
803 '\d LOAD $0.*' ..
804 '\d INVERT (!val).*' ..
805 '\d STORE $1.*' ..
806 'let res = !!flag.*' ..
807 '\d LOAD $0.*' ..
808 '\d 2BOOL (!!val).*' ..
809 '\d STORE $2.*',
810 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100811 call assert_equal(true, InvertBool())
812enddef
813
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100814def Test_disassemble_compare()
815 " TODO: COMPAREFUNC
816 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200817 ['true == false', 'COMPAREBOOL =='],
818 ['true != false', 'COMPAREBOOL !='],
819 ['v:none == v:null', 'COMPARESPECIAL =='],
820 ['v:none != v:null', 'COMPARESPECIAL !='],
821
822 ['111 == 222', 'COMPARENR =='],
823 ['111 != 222', 'COMPARENR !='],
824 ['111 > 222', 'COMPARENR >'],
825 ['111 < 222', 'COMPARENR <'],
826 ['111 >= 222', 'COMPARENR >='],
827 ['111 <= 222', 'COMPARENR <='],
828 ['111 =~ 222', 'COMPARENR =\~'],
829 ['111 !~ 222', 'COMPARENR !\~'],
830
831 ['"xx" != "yy"', 'COMPARESTRING !='],
832 ['"xx" > "yy"', 'COMPARESTRING >'],
833 ['"xx" < "yy"', 'COMPARESTRING <'],
834 ['"xx" >= "yy"', 'COMPARESTRING >='],
835 ['"xx" <= "yy"', 'COMPARESTRING <='],
836 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
837 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
838 ['"xx" is "yy"', 'COMPARESTRING is'],
839 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
840
841 ['0z11 == 0z22', 'COMPAREBLOB =='],
842 ['0z11 != 0z22', 'COMPAREBLOB !='],
843 ['0z11 is 0z22', 'COMPAREBLOB is'],
844 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
845
846 ['[1,2] == [3,4]', 'COMPARELIST =='],
847 ['[1,2] != [3,4]', 'COMPARELIST !='],
848 ['[1,2] is [3,4]', 'COMPARELIST is'],
849 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
850
851 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
852 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
853 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
854 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
855
856 ['{->33} == {->44}', 'COMPAREFUNC =='],
857 ['{->33} != {->44}', 'COMPAREFUNC !='],
858 ['{->33} is {->44}', 'COMPAREFUNC is'],
859 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
860
861 ['77 == g:xx', 'COMPAREANY =='],
862 ['77 != g:xx', 'COMPAREANY !='],
863 ['77 > g:xx', 'COMPAREANY >'],
864 ['77 < g:xx', 'COMPAREANY <'],
865 ['77 >= g:xx', 'COMPAREANY >='],
866 ['77 <= g:xx', 'COMPAREANY <='],
867 ['77 =~ g:xx', 'COMPAREANY =\~'],
868 ['77 !~ g:xx', 'COMPAREANY !\~'],
869 ['77 is g:xx', 'COMPAREANY is'],
870 ['77 isnot g:xx', 'COMPAREANY isnot'],
871 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100872 if has('float')
873 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200874 ['1.1 == 2.2', 'COMPAREFLOAT =='],
875 ['1.1 != 2.2', 'COMPAREFLOAT !='],
876 ['1.1 > 2.2', 'COMPAREFLOAT >'],
877 ['1.1 < 2.2', 'COMPAREFLOAT <'],
878 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
879 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
880 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
881 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
882 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100883 endif
884
885 let nr = 1
886 for case in cases
887 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200888 ' if ' .. case[0],
889 ' echo 42'
890 ' endif',
891 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100892 source Xdisassemble
893 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200894 assert_match('TestCase' .. nr .. '.*' ..
895 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
896 '\d \(PUSH\|FUNCREF\).*' ..
897 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
898 '\d ' .. case[1] .. '.*' ..
899 '\d JUMP_IF_FALSE -> \d\+.*',
900 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100901
902 nr += 1
903 endfor
904
Bram Moolenaar22da5592020-03-19 14:52:20 +0100905 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100906enddef
907
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200908def Test_disassemble_compare_const()
909 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200910 ['"xx" == "yy"', false],
911 ['"aa" == "aa"', true],
912 ['has("eval") ? true : false', true],
913 ['has("asdf") ? true : false', false],
914 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200915
916 let nr = 1
917 for case in cases
918 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200919 ' if ' .. case[0],
920 ' echo 42'
921 ' endif',
922 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200923 source Xdisassemble
924 let instr = execute('disassemble TestCase' .. nr)
925 if case[1]
926 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200927 assert_match('TestCase' .. nr .. '.*' ..
928 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
929 '\d PUSHNR 42.*' ..
930 '\d ECHO 1.*' ..
931 '\d PUSHNR 0.*' ..
932 '\d RETURN.*',
933 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200934 else
935 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200936 assert_match('TestCase' .. nr .. '.*' ..
937 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
938 'echo 42[ \n]*' ..
939 'endif[ \n]*' ..
940 '\s*\d PUSHNR 0.*' ..
941 '\d RETURN.*',
942 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200943 endif
944
945 nr += 1
946 endfor
947
948 delete('Xdisassemble')
949enddef
950
Bram Moolenaarad39c092020-02-26 18:23:43 +0100951def s:Execute()
952 execute 'help vim9.txt'
953 let cmd = 'help vim9.txt'
954 execute cmd
955 let tag = 'vim9.txt'
956 execute 'help ' .. tag
957enddef
958
959def Test_disassemble_execute()
960 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200961 assert_match('\<SNR>\d*_Execute.*' ..
962 "execute 'help vim9.txt'.*" ..
963 '\d PUSHS "help vim9.txt".*' ..
964 '\d EXECUTE 1.*' ..
965 "let cmd = 'help vim9.txt'.*" ..
966 '\d PUSHS "help vim9.txt".*' ..
967 '\d STORE $0.*' ..
968 'execute cmd.*' ..
969 '\d LOAD $0.*' ..
970 '\d EXECUTE 1.*' ..
971 "let tag = 'vim9.txt'.*" ..
972 '\d PUSHS "vim9.txt".*' ..
973 '\d STORE $1.*' ..
974 "execute 'help ' .. tag.*" ..
975 '\d PUSHS "help ".*' ..
976 '\d LOAD $1.*' ..
977 '\d CONCAT.*' ..
978 '\d EXECUTE 1.*' ..
979 '\d PUSHNR 0.*' ..
980 '\d RETURN',
981 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100982enddef
983
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200984def s:Echomsg()
985 echomsg 'some' 'message'
986 echoerr 'went' .. 'wrong'
987enddef
988
989def Test_disassemble_echomsg()
990 let res = execute('disass s:Echomsg')
991 assert_match('\<SNR>\d*_Echomsg.*' ..
992 "echomsg 'some' 'message'.*" ..
993 '\d PUSHS "some".*' ..
994 '\d PUSHS "message".*' ..
995 '\d ECHOMSG 2.*' ..
996 "echoerr 'went' .. 'wrong'.*" ..
997 '\d PUSHS "went".*' ..
998 '\d PUSHS "wrong".*' ..
999 '\d CONCAT.*' ..
1000 '\d ECHOERR 1.*' ..
1001 '\d PUSHNR 0.*' ..
1002 '\d RETURN',
1003 res)
1004enddef
1005
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001006def SomeStringArg(arg: string)
1007 echo arg
1008enddef
1009
1010def SomeAnyArg(arg: any)
1011 echo arg
1012enddef
1013
1014def SomeStringArgAndReturn(arg: string): string
1015 return arg
1016enddef
1017
1018def Test_display_func()
1019 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001020 assert_match('.* def SomeStringArg(arg: string).*' ..
1021 ' echo arg.*' ..
1022 ' enddef',
1023 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001024
1025 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001026 assert_match('.* def SomeAnyArg(arg: any).*' ..
1027 ' echo arg.*' ..
1028 ' enddef',
1029 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001030
1031 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001032 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
1033 ' return arg.*' ..
1034 ' enddef',
1035 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001036enddef
1037
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001038" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker