blob: f6de6858e1b68a2f073593f08bf433194b66717a [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'
11
12def s:ScriptFuncLoad(arg: string)
13 let local = 1
14 buffers
15 echo arg
16 echo local
17 echo v:version
18 echo s:scriptvar
19 echo g:globalvar
20 echo &tabstop
21 echo $ENVVAR
22 echo @z
23enddef
24
Bram Moolenaarf2460a32020-02-07 22:09:54 +010025def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010026 assert_fails('disass NoFunc', 'E1061:')
27 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010028 assert_fails('disass', 'E471:')
29 assert_fails('disass [', 'E475:')
30 assert_fails('disass 234', 'E475:')
31 assert_fails('disass <XX>foo', 'E475:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010032
33 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020034 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
35 'buffers.*' ..
36 ' EXEC \+buffers.*' ..
37 ' LOAD arg\[-1\].*' ..
38 ' LOAD $0.*' ..
39 ' LOADV v:version.*' ..
40 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
41 ' LOADG g:globalvar.*' ..
42 ' LOADENV $ENVVAR.*' ..
43 ' LOADREG @z.*',
44 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010045enddef
46
47def s:ScriptFuncPush()
48 let localbool = true
49 let localspec = v:none
50 let localblob = 0z1234
51 if has('float')
52 let localfloat = 1.234
53 endif
54enddef
55
Bram Moolenaarf2460a32020-02-07 22:09:54 +010056def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010057 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020058 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
59 'localbool = true.*' ..
60 ' PUSH v:true.*' ..
61 'localspec = v:none.*' ..
62 ' PUSH v:none.*' ..
63 'localblob = 0z1234.*' ..
64 ' PUSHBLOB 0z1234.*',
65 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010066 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +020067 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
68 'localfloat = 1.234.*' ..
69 ' PUSHF 1.234.*',
70 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010071 endif
72enddef
73
74def s:ScriptFuncStore()
75 let localnr = 1
76 localnr = 2
77 let localstr = 'abc'
78 localstr = 'xyz'
79 v:char = 'abc'
80 s:scriptvar = 'sv'
81 g:globalvar = 'gv'
82 &tabstop = 8
83 $ENVVAR = 'ev'
84 @z = 'rv'
85enddef
86
Bram Moolenaarf2460a32020-02-07 22:09:54 +010087def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010088 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +020089 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
90 'let localnr = 1.*' ..
91 'localnr = 2.*' ..
92 ' STORE 2 in $0.*' ..
93 'let localstr = ''abc''.*' ..
94 'localstr = ''xyz''.*' ..
95 ' STORE $1.*' ..
96 'v:char = ''abc''.*' ..
97 'STOREV v:char.*' ..
98 's:scriptvar = ''sv''.*' ..
99 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
100 'g:globalvar = ''gv''.*' ..
101 ' STOREG g:globalvar.*' ..
102 '&tabstop = 8.*' ..
103 ' STOREOPT &tabstop.*' ..
104 '$ENVVAR = ''ev''.*' ..
105 ' STOREENV $ENVVAR.*' ..
106 '@z = ''rv''.*' ..
107 ' STOREREG @z.*',
108 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100109enddef
110
111def s:ScriptFuncTry()
112 try
113 echo 'yes'
114 catch /fail/
115 echo 'no'
116 finally
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100117 throw 'end'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100118 endtry
119enddef
120
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100121def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100122 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200123 assert_match('<SNR>\d*_ScriptFuncTry.*' ..
124 'try.*' ..
125 'TRY catch -> \d\+, finally -> \d\+.*' ..
126 'catch /fail/.*' ..
127 ' JUMP -> \d\+.*' ..
128 ' PUSH v:exception.*' ..
129 ' PUSHS "fail".*' ..
130 ' COMPARESTRING =\~.*' ..
131 ' JUMP_IF_FALSE -> \d\+.*' ..
132 ' CATCH.*' ..
133 'finally.*' ..
134 ' PUSHS "end".*' ..
135 ' THROW.*' ..
136 'endtry.*' ..
137 ' ENDTRY.*',
138 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100139enddef
140
141def s:ScriptFuncNew()
142 let ll = [1, "two", 333]
143 let dd = #{one: 1, two: "val"}
144enddef
145
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100146def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100147 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200148 assert_match('<SNR>\d*_ScriptFuncNew.*' ..
149 'let ll = \[1, "two", 333].*' ..
150 'PUSHNR 1.*' ..
151 'PUSHS "two".*' ..
152 'PUSHNR 333.*' ..
153 'NEWLIST size 3.*' ..
154 'let dd = #{one: 1, two: "val"}.*' ..
155 'PUSHS "one".*' ..
156 'PUSHNR 1.*' ..
157 'PUSHS "two".*' ..
158 'PUSHS "val".*' ..
159 'NEWDICT size 2.*',
160 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100161enddef
162
Bram Moolenaar6e949782020-04-13 17:21:00 +0200163def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100164 echo arg
165enddef
166
167func UserFunc()
168 echo 'nothing'
169endfunc
170
171func UserFuncWithArg(arg)
172 echo a:arg
173endfunc
174
175def s:ScriptFuncCall(): string
176 changenr()
177 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100178 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100179 FuncWithArg(343)
180 ScriptFuncNew()
181 s:ScriptFuncNew()
182 UserFunc()
183 UserFuncWithArg("foo")
184 let FuncRef = function("UserFunc")
185 FuncRef()
186 let FuncRefWithArg = function("UserFuncWithArg")
187 FuncRefWithArg("bar")
188 return "yes"
189enddef
190
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100191def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100192 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200193 assert_match('<SNR>\d\+_ScriptFuncCall.*' ..
194 'changenr().*' ..
195 ' BCALL changenr(argc 0).*' ..
196 'char2nr("abc").*' ..
197 ' PUSHS "abc".*' ..
198 ' BCALL char2nr(argc 1).*' ..
199 'Test_disassemble_new().*' ..
200 ' DCALL Test_disassemble_new(argc 0).*' ..
201 'FuncWithArg(343).*' ..
202 ' PUSHNR 343.*' ..
203 ' DCALL FuncWithArg(argc 1).*' ..
204 'ScriptFuncNew().*' ..
205 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
206 's:ScriptFuncNew().*' ..
207 ' DCALL <SNR>\d\+_ScriptFuncNew(argc 0).*' ..
208 'UserFunc().*' ..
209 ' UCALL UserFunc(argc 0).*' ..
210 'UserFuncWithArg("foo").*' ..
211 ' PUSHS "foo".*' ..
212 ' UCALL UserFuncWithArg(argc 1).*' ..
213 'let FuncRef = function("UserFunc").*' ..
214 'FuncRef().*' ..
215 ' LOAD $\d.*' ..
216 ' PCALL (argc 0).*' ..
217 'let FuncRefWithArg = function("UserFuncWithArg").*' ..
218 'FuncRefWithArg("bar").*' ..
219 ' PUSHS "bar".*' ..
220 ' LOAD $\d.*' ..
221 ' PCALL (argc 1).*' ..
222 'return "yes".*' ..
223 ' PUSHS "yes".*' ..
224 ' RETURN.*',
225 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100226enddef
227
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100228
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200229def EchoArg(arg: string): string
230 return arg
231enddef
232def RefThis(): func
233 return function('EchoArg')
234enddef
235def s:ScriptPCall()
236 RefThis()("text")
237enddef
238
239def Test_disassemble_pcall()
240 let res = execute('disass s:ScriptPCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200241 assert_match('<SNR>\d\+_ScriptPCall.*' ..
242 'RefThis()("text").*' ..
243 '\d DCALL RefThis(argc 0).*' ..
244 '\d PUSHS "text".*' ..
245 '\d PCALL top (argc 1).*' ..
246 '\d PCALL end.*' ..
247 '\d DROP.*' ..
248 '\d PUSHNR 0.*' ..
249 '\d RETURN.*',
250 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200251enddef
252
253
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100254def FuncWithForwardCall(): string
255 return DefinedLater("yes")
256enddef
257
258def DefinedLater(arg: string): string
259 return arg
260enddef
261
262def Test_disassemble_update_instr()
263 let res = execute('disass FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200264 assert_match('FuncWithForwardCall.*' ..
265 'return DefinedLater("yes").*' ..
266 '\d PUSHS "yes".*' ..
267 '\d UCALL DefinedLater(argc 1).*' ..
268 '\d CHECKTYPE string stack\[-1].*' ..
269 '\d RETURN.*',
270 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100271
272 " Calling the function will change UCALL into the faster DCALL
273 assert_equal('yes', FuncWithForwardCall())
274
275 res = execute('disass FuncWithForwardCall')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200276 assert_match('FuncWithForwardCall.*' ..
277 'return DefinedLater("yes").*' ..
278 '\d PUSHS "yes".*' ..
279 '\d DCALL DefinedLater(argc 1).*' ..
280 '\d CHECKTYPE string stack\[-1].*' ..
281 '\d RETURN.*',
282 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100283enddef
284
285
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100286def FuncWithDefault(arg: string = 'default'): string
287 return arg
288enddef
289
290def Test_disassemble_call_default()
291 let res = execute('disass FuncWithDefault')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200292 assert_match('FuncWithDefault.*' ..
293 '\d PUSHS "default".*' ..
294 '\d STORE arg\[-1].*' ..
295 'return arg.*' ..
296 '\d LOAD arg\[-1].*' ..
297 '\d RETURN.*',
298 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100299enddef
300
301
Bram Moolenaar158906c2020-02-06 20:39:45 +0100302def HasEval()
303 if has("eval")
304 echo "yes"
305 else
306 echo "no"
307 endif
308enddef
309
310def HasNothing()
311 if has("nothing")
312 echo "yes"
313 else
314 echo "no"
315 endif
316enddef
317
318def HasSomething()
319 if has("nothing")
320 echo "nothing"
321 elseif has("something")
322 echo "something"
323 elseif has("eval")
324 echo "eval"
325 elseif has("less")
326 echo "less"
327 endif
328enddef
329
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100330def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100331 assert_equal("\nyes", execute('call HasEval()'))
332 let instr = execute('disassemble HasEval')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200333 assert_match('HasEval.*' ..
334 'if has("eval").*' ..
335 ' PUSHS "yes".*',
336 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100337 assert_notmatch('JUMP', instr)
338
339 assert_equal("\nno", execute('call HasNothing()'))
340 instr = execute('disassemble HasNothing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200341 assert_match('HasNothing.*' ..
342 'if has("nothing").*' ..
343 'else.*' ..
344 ' PUSHS "no".*',
345 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100346 assert_notmatch('PUSHS "yes"', instr)
347 assert_notmatch('JUMP', instr)
348
349 assert_equal("\neval", execute('call HasSomething()'))
350 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200351 assert_match('HasSomething.*' ..
352 'if has("nothing").*' ..
353 'elseif has("something").*' ..
354 'elseif has("eval").*' ..
355 ' PUSHS "eval".*' ..
356 'elseif has("less").*',
357 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100358 assert_notmatch('PUSHS "nothing"', instr)
359 assert_notmatch('PUSHS "something"', instr)
360 assert_notmatch('PUSHS "less"', instr)
361 assert_notmatch('JUMP', instr)
362enddef
363
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100364def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200365 let Funky1: func
366 let Funky2: func = function("len")
367 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100368enddef
369
370def Test_disassemble_function()
371 let instr = execute('disassemble WithFunc')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200372 assert_match('WithFunc.*' ..
373 'let Funky1: func.*' ..
374 '0 PUSHFUNC "\[none]".*' ..
375 '1 STORE $0.*' ..
376 'let Funky2: func = function("len").*' ..
377 '2 PUSHS "len".*' ..
378 '3 BCALL function(argc 1).*' ..
379 '4 STORE $1.*' ..
380 'let Party2: func = funcref("UserFunc").*' ..
381 '\d PUSHS "UserFunc".*' ..
382 '\d BCALL funcref(argc 1).*' ..
383 '\d STORE $2.*' ..
384 '\d PUSHNR 0.*' ..
385 '\d RETURN.*',
386 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100387enddef
388
389if has('channel')
390 def WithChannel()
391 let job1: job
392 let job2: job = job_start("donothing")
393 let chan1: channel
394 enddef
395endif
396
397def Test_disassemble_channel()
398 CheckFeature channel
399
400 let instr = execute('disassemble WithChannel')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200401 assert_match('WithChannel.*' ..
402 'let job1: job.*' ..
403 '\d PUSHJOB "no process".*' ..
404 '\d STORE $0.*' ..
405 'let job2: job = job_start("donothing").*' ..
406 '\d PUSHS "donothing".*' ..
407 '\d BCALL job_start(argc 1).*' ..
408 '\d STORE $1.*' ..
409 'let chan1: channel.*' ..
410 '\d PUSHCHANNEL 0.*' ..
411 '\d STORE $2.*' ..
412 '\d PUSHNR 0.*' ..
413 '\d RETURN.*',
414 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100415enddef
416
Bram Moolenaar777770f2020-02-06 21:27:08 +0100417def WithLambda(): string
418 let F = {a -> "X" .. a .. "X"}
419 return F("x")
420enddef
421
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100422def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100423 assert_equal("XxX", WithLambda())
424 let instr = execute('disassemble WithLambda')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200425 assert_match('WithLambda.*' ..
426 'let F = {a -> "X" .. a .. "X"}.*' ..
427 ' FUNCREF <lambda>\d\+.*' ..
428 'PUSHS "x".*' ..
429 ' LOAD $0.*' ..
430 ' PCALL (argc 1).*' ..
431 ' CHECKTYPE string stack\[-1].*',
432 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100433enddef
434
Bram Moolenaar6e949782020-04-13 17:21:00 +0200435def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100436 if arg == 1 && arg != 2 || arg == 4
437 return 'yes'
438 endif
439 return 'no'
440enddef
441
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100442def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100443 assert_equal("yes", AndOr(1))
444 assert_equal("no", AndOr(2))
445 assert_equal("yes", AndOr(4))
446 let instr = execute('disassemble AndOr')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200447 assert_match('AndOr.*' ..
448 'if arg == 1 && arg != 2 || arg == 4.*' ..
449 '\d LOAD arg\[-1].*' ..
450 '\d PUSHNR 1.*' ..
451 '\d COMPAREANY ==.*' ..
452 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+.*' ..
453 '\d LOAD arg\[-1].*' ..
454 '\d PUSHNR 2.*' ..
455 '\d COMPAREANY !=.*' ..
456 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+.*' ..
457 '\d LOAD arg\[-1].*' ..
458 '\d PUSHNR 4.*' ..
459 '\d COMPAREANY ==.*' ..
460 '\d JUMP_IF_FALSE -> \d\+.*',
461 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100462enddef
463
Bram Moolenaar04d05222020-02-06 22:06:54 +0100464def ForLoop(): list<number>
465 let res: list<number>
466 for i in range(3)
467 res->add(i)
468 endfor
469 return res
470enddef
471
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100472def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100473 assert_equal([0, 1, 2], ForLoop())
474 let instr = execute('disassemble ForLoop')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200475 assert_match('ForLoop.*' ..
476 'let res: list<number>.*' ..
477 ' NEWLIST size 0.*' ..
478 '\d STORE $0.*' ..
479 'for i in range(3).*' ..
480 '\d STORE -1 in $1.*' ..
481 '\d PUSHNR 3.*' ..
482 '\d BCALL range(argc 1).*' ..
483 '\d FOR $1 -> \d\+.*' ..
484 '\d STORE $2.*' ..
485 'res->add(i).*' ..
486 '\d LOAD $0.*' ..
487 '\d LOAD $2.*' ..
488 '\d BCALL add(argc 2).*' ..
489 '\d DROP.*' ..
490 'endfor.*' ..
491 '\d JUMP -> \d\+.*' ..
492 '\d DROP.*',
493 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100494enddef
495
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100496let g:number = 42
497
498def Computing()
499 let nr = 3
500 let nrres = nr + 7
501 nrres = nr - 7
502 nrres = nr * 7
503 nrres = nr / 7
504 nrres = nr % 7
505
506 let anyres = g:number + 7
507 anyres = g:number - 7
508 anyres = g:number * 7
509 anyres = g:number / 7
510 anyres = g:number % 7
511
512 if has('float')
513 let fl = 3.0
514 let flres = fl + 7.0
515 flres = fl - 7.0
516 flres = fl * 7.0
517 flres = fl / 7.0
518 endif
519enddef
520
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100521def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100522 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200523 assert_match('Computing.*' ..
524 'let nr = 3.*' ..
525 '\d STORE 3 in $0.*' ..
526 'let nrres = nr + 7.*' ..
527 '\d LOAD $0.*' ..
528 '\d PUSHNR 7.*' ..
529 '\d OPNR +.*' ..
530 '\d STORE $1.*' ..
531 'nrres = nr - 7.*' ..
532 '\d OPNR -.*' ..
533 'nrres = nr \* 7.*' ..
534 '\d OPNR \*.*' ..
535 'nrres = nr / 7.*' ..
536 '\d OPNR /.*' ..
537 'nrres = nr % 7.*' ..
538 '\d OPNR %.*' ..
539 'let anyres = g:number + 7.*' ..
540 '\d LOADG g:number.*' ..
541 '\d PUSHNR 7.*' ..
542 '\d OPANY +.*' ..
543 '\d STORE $2.*' ..
544 'anyres = g:number - 7.*' ..
545 '\d OPANY -.*' ..
546 'anyres = g:number \* 7.*' ..
547 '\d OPANY \*.*' ..
548 'anyres = g:number / 7.*' ..
549 '\d OPANY /.*' ..
550 'anyres = g:number % 7.*' ..
551 '\d OPANY %.*',
552 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100553 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200554 assert_match('Computing.*' ..
555 'let fl = 3.0.*' ..
556 '\d PUSHF 3.0.*' ..
557 '\d STORE $3.*' ..
558 'let flres = fl + 7.0.*' ..
559 '\d LOAD $3.*' ..
560 '\d PUSHF 7.0.*' ..
561 '\d OPFLOAT +.*' ..
562 '\d STORE $4.*' ..
563 'flres = fl - 7.0.*' ..
564 '\d OPFLOAT -.*' ..
565 'flres = fl \* 7.0.*' ..
566 '\d OPFLOAT \*.*' ..
567 'flres = fl / 7.0.*' ..
568 '\d OPFLOAT /.*',
569 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100570 endif
571enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100572
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100573def AddListBlob()
574 let reslist = [1, 2] + [3, 4]
575 let resblob = 0z1122 + 0z3344
576enddef
577
578def Test_disassemble_add_list_blob()
579 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200580 assert_match('AddListBlob.*' ..
581 'let reslist = \[1, 2] + \[3, 4].*' ..
582 '\d PUSHNR 1.*' ..
583 '\d PUSHNR 2.*' ..
584 '\d NEWLIST size 2.*' ..
585 '\d PUSHNR 3.*' ..
586 '\d PUSHNR 4.*' ..
587 '\d NEWLIST size 2.*' ..
588 '\d ADDLIST.*' ..
589 '\d STORE $.*.*' ..
590 'let resblob = 0z1122 + 0z3344.*' ..
591 '\d PUSHBLOB 0z1122.*' ..
592 '\d PUSHBLOB 0z3344.*' ..
593 '\d ADDBLOB.*' ..
594 '\d STORE $.*',
595 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100596enddef
597
598let g:aa = 'aa'
599def ConcatString(): string
600 let res = g:aa .. "bb"
601 return res
602enddef
603
604def Test_disassemble_concat()
605 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200606 assert_match('ConcatString.*' ..
607 'let res = g:aa .. "bb".*' ..
608 '\d LOADG g:aa.*' ..
609 '\d PUSHS "bb".*' ..
610 '\d 2STRING stack\[-2].*' ..
611 '\d CONCAT.*' ..
612 '\d STORE $.*',
613 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100614 assert_equal('aabb', ConcatString())
615enddef
616
617def ListIndex(): number
618 let l = [1, 2, 3]
619 let res = l[1]
620 return res
621enddef
622
623def Test_disassemble_list_index()
624 let instr = execute('disassemble ListIndex')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200625 assert_match('ListIndex.*' ..
626 'let l = \[1, 2, 3].*' ..
627 '\d PUSHNR 1.*' ..
628 '\d PUSHNR 2.*' ..
629 '\d PUSHNR 3.*' ..
630 '\d NEWLIST size 3.*' ..
631 '\d STORE $0.*' ..
632 'let res = l\[1].*' ..
633 '\d LOAD $0.*' ..
634 '\d PUSHNR 1.*' ..
635 '\d INDEX.*' ..
636 '\d STORE $1.*',
637 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100638 assert_equal(2, ListIndex())
639enddef
640
641def DictMember(): number
642 let d = #{item: 1}
643 let res = d.item
644 return res
645enddef
646
647def Test_disassemble_dict_member()
648 let instr = execute('disassemble DictMember')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200649 assert_match('DictMember.*' ..
650 'let d = #{item: 1}.*' ..
651 '\d PUSHS "item".*' ..
652 '\d PUSHNR 1.*' ..
653 '\d NEWDICT size 1.*' ..
654 '\d STORE $0.*' ..
655 'let res = d.item.*' ..
656 '\d LOAD $0.*' ..
657 '\d MEMBER item.*' ..
658 '\d STORE $1.*',
659 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100660 call assert_equal(1, DictMember())
661enddef
662
663def NegateNumber(): number
664 let nr = 9
665 let plus = +nr
666 let res = -nr
667 return res
668enddef
669
670def Test_disassemble_negate_number()
671 let instr = execute('disassemble NegateNumber')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200672 assert_match('NegateNumber.*' ..
673 'let nr = 9.*' ..
674 '\d STORE 9 in $0.*' ..
675 'let plus = +nr.*' ..
676 '\d LOAD $0.*' ..
677 '\d CHECKNR.*' ..
678 '\d STORE $1.*' ..
679 'let res = -nr.*' ..
680 '\d LOAD $0.*' ..
681 '\d NEGATENR.*' ..
682 '\d STORE $2.*',
683 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100684 call assert_equal(-9, NegateNumber())
685enddef
686
687def InvertBool(): bool
688 let flag = true
689 let invert = !flag
690 let res = !!flag
691 return res
692enddef
693
694def Test_disassemble_invert_bool()
695 let instr = execute('disassemble InvertBool')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200696 assert_match('InvertBool.*' ..
697 'let flag = true.*' ..
698 '\d PUSH v:true.*' ..
699 '\d STORE $0.*' ..
700 'let invert = !flag.*' ..
701 '\d LOAD $0.*' ..
702 '\d INVERT (!val).*' ..
703 '\d STORE $1.*' ..
704 'let res = !!flag.*' ..
705 '\d LOAD $0.*' ..
706 '\d 2BOOL (!!val).*' ..
707 '\d STORE $2.*',
708 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100709 call assert_equal(true, InvertBool())
710enddef
711
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100712def Test_disassemble_compare()
713 " TODO: COMPAREFUNC
714 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200715 ['true == false', 'COMPAREBOOL =='],
716 ['true != false', 'COMPAREBOOL !='],
717 ['v:none == v:null', 'COMPARESPECIAL =='],
718 ['v:none != v:null', 'COMPARESPECIAL !='],
719
720 ['111 == 222', 'COMPARENR =='],
721 ['111 != 222', 'COMPARENR !='],
722 ['111 > 222', 'COMPARENR >'],
723 ['111 < 222', 'COMPARENR <'],
724 ['111 >= 222', 'COMPARENR >='],
725 ['111 <= 222', 'COMPARENR <='],
726 ['111 =~ 222', 'COMPARENR =\~'],
727 ['111 !~ 222', 'COMPARENR !\~'],
728
729 ['"xx" != "yy"', 'COMPARESTRING !='],
730 ['"xx" > "yy"', 'COMPARESTRING >'],
731 ['"xx" < "yy"', 'COMPARESTRING <'],
732 ['"xx" >= "yy"', 'COMPARESTRING >='],
733 ['"xx" <= "yy"', 'COMPARESTRING <='],
734 ['"xx" =~ "yy"', 'COMPARESTRING =\~'],
735 ['"xx" !~ "yy"', 'COMPARESTRING !\~'],
736 ['"xx" is "yy"', 'COMPARESTRING is'],
737 ['"xx" isnot "yy"', 'COMPARESTRING isnot'],
738
739 ['0z11 == 0z22', 'COMPAREBLOB =='],
740 ['0z11 != 0z22', 'COMPAREBLOB !='],
741 ['0z11 is 0z22', 'COMPAREBLOB is'],
742 ['0z11 isnot 0z22', 'COMPAREBLOB isnot'],
743
744 ['[1,2] == [3,4]', 'COMPARELIST =='],
745 ['[1,2] != [3,4]', 'COMPARELIST !='],
746 ['[1,2] is [3,4]', 'COMPARELIST is'],
747 ['[1,2] isnot [3,4]', 'COMPARELIST isnot'],
748
749 ['#{a:1} == #{x:2}', 'COMPAREDICT =='],
750 ['#{a:1} != #{x:2}', 'COMPAREDICT !='],
751 ['#{a:1} is #{x:2}', 'COMPAREDICT is'],
752 ['#{a:1} isnot #{x:2}', 'COMPAREDICT isnot'],
753
754 ['{->33} == {->44}', 'COMPAREFUNC =='],
755 ['{->33} != {->44}', 'COMPAREFUNC !='],
756 ['{->33} is {->44}', 'COMPAREFUNC is'],
757 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
758
759 ['77 == g:xx', 'COMPAREANY =='],
760 ['77 != g:xx', 'COMPAREANY !='],
761 ['77 > g:xx', 'COMPAREANY >'],
762 ['77 < g:xx', 'COMPAREANY <'],
763 ['77 >= g:xx', 'COMPAREANY >='],
764 ['77 <= g:xx', 'COMPAREANY <='],
765 ['77 =~ g:xx', 'COMPAREANY =\~'],
766 ['77 !~ g:xx', 'COMPAREANY !\~'],
767 ['77 is g:xx', 'COMPAREANY is'],
768 ['77 isnot g:xx', 'COMPAREANY isnot'],
769 ]
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100770 if has('float')
771 cases->extend([
Bram Moolenaar675f7162020-04-12 22:53:54 +0200772 ['1.1 == 2.2', 'COMPAREFLOAT =='],
773 ['1.1 != 2.2', 'COMPAREFLOAT !='],
774 ['1.1 > 2.2', 'COMPAREFLOAT >'],
775 ['1.1 < 2.2', 'COMPAREFLOAT <'],
776 ['1.1 >= 2.2', 'COMPAREFLOAT >='],
777 ['1.1 <= 2.2', 'COMPAREFLOAT <='],
778 ['1.1 =~ 2.2', 'COMPAREFLOAT =\~'],
779 ['1.1 !~ 2.2', 'COMPAREFLOAT !\~'],
780 ])
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100781 endif
782
783 let nr = 1
784 for case in cases
785 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200786 ' if ' .. case[0],
787 ' echo 42'
788 ' endif',
789 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100790 source Xdisassemble
791 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +0200792 assert_match('TestCase' .. nr .. '.*' ..
793 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
794 '\d \(PUSH\|FUNCREF\).*' ..
795 '\d \(PUSH\|FUNCREF\|LOADG\).*' ..
796 '\d ' .. case[1] .. '.*' ..
797 '\d JUMP_IF_FALSE -> \d\+.*',
798 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100799
800 nr += 1
801 endfor
802
Bram Moolenaar22da5592020-03-19 14:52:20 +0100803 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100804enddef
805
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200806def Test_disassemble_compare_const()
807 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +0200808 ['"xx" == "yy"', false],
809 ['"aa" == "aa"', true],
810 ['has("eval") ? true : false', true],
811 ['has("asdf") ? true : false', false],
812 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200813
814 let nr = 1
815 for case in cases
816 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200817 ' if ' .. case[0],
818 ' echo 42'
819 ' endif',
820 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200821 source Xdisassemble
822 let instr = execute('disassemble TestCase' .. nr)
823 if case[1]
824 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +0200825 assert_match('TestCase' .. nr .. '.*' ..
826 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
827 '\d PUSHNR 42.*' ..
828 '\d ECHO 1.*' ..
829 '\d PUSHNR 0.*' ..
830 '\d RETURN.*',
831 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200832 else
833 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +0200834 assert_match('TestCase' .. nr .. '.*' ..
835 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
836 'echo 42[ \n]*' ..
837 'endif[ \n]*' ..
838 '\s*\d PUSHNR 0.*' ..
839 '\d RETURN.*',
840 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +0200841 endif
842
843 nr += 1
844 endfor
845
846 delete('Xdisassemble')
847enddef
848
Bram Moolenaarad39c092020-02-26 18:23:43 +0100849def s:Execute()
850 execute 'help vim9.txt'
851 let cmd = 'help vim9.txt'
852 execute cmd
853 let tag = 'vim9.txt'
854 execute 'help ' .. tag
855enddef
856
857def Test_disassemble_execute()
858 let res = execute('disass s:Execute')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200859 assert_match('\<SNR>\d*_Execute.*' ..
860 "execute 'help vim9.txt'.*" ..
861 '\d PUSHS "help vim9.txt".*' ..
862 '\d EXECUTE 1.*' ..
863 "let cmd = 'help vim9.txt'.*" ..
864 '\d PUSHS "help vim9.txt".*' ..
865 '\d STORE $0.*' ..
866 'execute cmd.*' ..
867 '\d LOAD $0.*' ..
868 '\d EXECUTE 1.*' ..
869 "let tag = 'vim9.txt'.*" ..
870 '\d PUSHS "vim9.txt".*' ..
871 '\d STORE $1.*' ..
872 "execute 'help ' .. tag.*" ..
873 '\d PUSHS "help ".*' ..
874 '\d LOAD $1.*' ..
875 '\d CONCAT.*' ..
876 '\d EXECUTE 1.*' ..
877 '\d PUSHNR 0.*' ..
878 '\d RETURN',
879 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +0100880enddef
881
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100882def SomeStringArg(arg: string)
883 echo arg
884enddef
885
886def SomeAnyArg(arg: any)
887 echo arg
888enddef
889
890def SomeStringArgAndReturn(arg: string): string
891 return arg
892enddef
893
894def Test_display_func()
895 let res1 = execute('function SomeStringArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200896 assert_match('.* def SomeStringArg(arg: string).*' ..
897 ' echo arg.*' ..
898 ' enddef',
899 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100900
901 let res2 = execute('function SomeAnyArg')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200902 assert_match('.* def SomeAnyArg(arg: any).*' ..
903 ' echo arg.*' ..
904 ' enddef',
905 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100906
907 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200908 assert_match('.* def SomeStringArgAndReturn(arg: string): string.*' ..
909 ' return arg.*' ..
910 ' enddef',
911 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +0100912enddef
913
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100914" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker