blob: 6cde5dda71f615bfc945630d10504c67927a12ce [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
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020020 echo &lines
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010021 echo v:version
22 echo s:scriptvar
23 echo g:globalvar
Bram Moolenaard3aac292020-04-19 14:32:17 +020024 echo b:buffervar
25 echo w:windowvar
26 echo t:tabpagevar
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010027 echo &tabstop
28 echo $ENVVAR
29 echo @z
30enddef
31
Bram Moolenaarf2460a32020-02-07 22:09:54 +010032def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010033 assert_fails('disass NoFunc', 'E1061:')
34 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010035 assert_fails('disass', 'E471:')
36 assert_fails('disass [', 'E475:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +020037 assert_fails('disass 234', 'E129:')
38 assert_fails('disass <XX>foo', 'E129:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010039
40 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020041 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
42 'buffers.*' ..
43 ' EXEC \+buffers.*' ..
44 ' LOAD arg\[-1\].*' ..
45 ' LOAD $0.*' ..
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020046 ' LOADOPT &lines.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020047 ' LOADV v:version.*' ..
48 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
49 ' LOADG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020050 ' LOADB b:buffervar.*' ..
51 ' LOADW w:windowvar.*' ..
52 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020053 ' LOADENV $ENVVAR.*' ..
54 ' LOADREG @z.*',
55 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010056enddef
57
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020058def s:EditExpand()
59 let filename = "file"
60 let filenr = 123
61 edit the`=filename``=filenr`.txt
62enddef
63
64def Test_disassemble_exec_expr()
65 let res = execute('disass s:EditExpand')
66 assert_match('<SNR>\d*_EditExpand.*' ..
67 ' let filename = "file".*' ..
68 '\d PUSHS "file".*' ..
69 '\d STORE $0.*' ..
70 ' let filenr = 123.*' ..
71 '\d STORE 123 in $1.*' ..
72 ' edit the`=filename``=filenr`.txt.*' ..
73 '\d PUSHS "edit the".*' ..
74 '\d LOAD $0.*' ..
75 '\d LOAD $1.*' ..
76 '\d 2STRING stack\[-1\].*' ..
77 '\d PUSHS ".txt".*' ..
78 '\d EXECCONCAT 4.*' ..
79 '\d PUSHNR 0.*' ..
80 '\d RETURN',
81 res)
82enddef
83
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010084def s:ScriptFuncPush()
85 let localbool = true
86 let localspec = v:none
87 let localblob = 0z1234
88 if has('float')
89 let localfloat = 1.234
90 endif
91enddef
92
Bram Moolenaarf2460a32020-02-07 22:09:54 +010093def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010094 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +020095 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
96 'localbool = true.*' ..
97 ' PUSH v:true.*' ..
98 'localspec = v:none.*' ..
99 ' PUSH v:none.*' ..
100 'localblob = 0z1234.*' ..
101 ' PUSHBLOB 0z1234.*',
102 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100103 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200104 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
105 'localfloat = 1.234.*' ..
106 ' PUSHF 1.234.*',
107 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100108 endif
109enddef
110
111def s:ScriptFuncStore()
112 let localnr = 1
113 localnr = 2
114 let localstr = 'abc'
115 localstr = 'xyz'
116 v:char = 'abc'
117 s:scriptvar = 'sv'
118 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200119 b:buffervar = 'bv'
120 w:windowvar = 'wv'
121 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100122 &tabstop = 8
123 $ENVVAR = 'ev'
124 @z = 'rv'
125enddef
126
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100127def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100128 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200129 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
130 'let localnr = 1.*' ..
131 'localnr = 2.*' ..
132 ' STORE 2 in $0.*' ..
133 'let localstr = ''abc''.*' ..
134 'localstr = ''xyz''.*' ..
135 ' STORE $1.*' ..
136 'v:char = ''abc''.*' ..
137 'STOREV v:char.*' ..
138 's:scriptvar = ''sv''.*' ..
139 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
140 'g:globalvar = ''gv''.*' ..
141 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200142 'b:buffervar = ''bv''.*' ..
143 ' STOREB b:buffervar.*' ..
144 'w:windowvar = ''wv''.*' ..
145 ' STOREW w:windowvar.*' ..
146 't:tabpagevar = ''tv''.*' ..
147 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200148 '&tabstop = 8.*' ..
149 ' STOREOPT &tabstop.*' ..
150 '$ENVVAR = ''ev''.*' ..
151 ' STOREENV $ENVVAR.*' ..
152 '@z = ''rv''.*' ..
153 ' STOREREG @z.*',
154 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100155enddef
156
Bram Moolenaarcb790402020-05-15 20:53:00 +0200157def s:ScriptFuncStoreMember()
158 let locallist: list<number> = []
159 locallist[0] = 123
160 let localdict: dict<number> = {}
161 localdict["a"] = 456
162enddef
163
164def Test_disassemble_store_member()
165 let res = execute('disass s:ScriptFuncStoreMember')
166 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
167 'let locallist: list<number> = []\_s*' ..
168 '\d NEWLIST size 0\_s*' ..
169 '\d STORE $0\_s*' ..
170 'locallist\[0\] = 123\_s*' ..
171 '\d PUSHNR 123\_s*' ..
172 '\d PUSHNR 0\_s*' ..
173 '\d LOAD $0\_s*' ..
174 '\d STORELIST\_s*' ..
175 'let localdict: dict<number> = {}\_s*' ..
176 '\d NEWDICT size 0\_s*' ..
177 '\d STORE $1\_s*' ..
178 'localdict\["a"\] = 456\_s*' ..
179 '\d\+ PUSHNR 456\_s*' ..
180 '\d\+ PUSHS "a"\_s*' ..
181 '\d\+ LOAD $1\_s*' ..
182 '\d\+ STOREDICT\_s*' ..
183 '\d\+ PUSHNR 0\_s*' ..
184 '\d\+ RETURN',
185 res)
186enddef
187
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200188def s:ListAssign()
189 let x: string
190 let y: string
191 let l: list<any>
192 [x, y; l] = g:stringlist
193enddef
194
195def Test_disassemble_list_assign()
196 let res = execute('disass s:ListAssign')
197 assert_match('<SNR>\d*_ListAssign\_s*' ..
198 'let x: string\_s*' ..
199 '\d PUSHS "\[NULL\]"\_s*' ..
200 '\d STORE $0\_s*' ..
201 'let y: string\_s*' ..
202 '\d PUSHS "\[NULL\]"\_s*' ..
203 '\d STORE $1\_s*' ..
204 'let l: list<any>\_s*' ..
205 '\d NEWLIST size 0\_s*' ..
206 '\d STORE $2\_s*' ..
207 '\[x, y; l\] = g:stringlist\_s*' ..
208 '\d LOADG g:stringlist\_s*' ..
209 '\d CHECKTYPE list stack\[-1\]\_s*' ..
210 '\d CHECKLEN >= 2\_s*' ..
211 '\d\+ ITEM 0\_s*' ..
212 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
213 '\d\+ STORE $0\_s*' ..
214 '\d\+ ITEM 1\_s*' ..
215 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
216 '\d\+ STORE $1\_s*' ..
217 '\d\+ SLICE 2\_s*' ..
218 '\d\+ STORE $2\_s*' ..
219 '\d\+ PUSHNR 0\_s*' ..
220 '\d\+ RETURN',
221 res)
222enddef
223
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200224def s:ScriptFuncUnlet()
225 g:somevar = "value"
226 unlet g:somevar
227 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200228 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200229enddef
230
231def Test_disassemble_unlet()
232 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200233 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
234 'g:somevar = "value"\_s*' ..
235 '\d PUSHS "value"\_s*' ..
236 '\d STOREG g:somevar\_s*' ..
237 'unlet g:somevar\_s*' ..
238 '\d UNLET g:somevar\_s*' ..
239 'unlet! g:somevar\_s*' ..
240 '\d UNLET! g:somevar\_s*' ..
241 'unlet $SOMEVAR\_s*' ..
242 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200243 res)
244enddef
245
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100246def s:ScriptFuncTry()
247 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200248 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100249 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200250 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100251 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200252 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100253 endtry
254enddef
255
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100256def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100257 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200258 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
259 'try\_s*' ..
260 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
261 'echo "yes"\_s*' ..
262 '\d PUSHS "yes"\_s*' ..
263 '\d ECHO 1\_s*' ..
264 'catch /fail/\_s*' ..
265 '\d JUMP -> \d\+\_s*' ..
266 '\d PUSH v:exception\_s*' ..
267 '\d PUSHS "fail"\_s*' ..
268 '\d COMPARESTRING =\~\_s*' ..
269 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
270 '\d CATCH\_s*' ..
271 'echo "no"\_s*' ..
272 '\d\+ PUSHS "no"\_s*' ..
273 '\d\+ ECHO 1\_s*' ..
274 'finally\_s*' ..
275 'throw "end"\_s*' ..
276 '\d\+ PUSHS "end"\_s*' ..
277 '\d\+ THROW\_s*' ..
278 'endtry\_s*' ..
279 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200280 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100281enddef
282
283def s:ScriptFuncNew()
284 let ll = [1, "two", 333]
285 let dd = #{one: 1, two: "val"}
286enddef
287
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100288def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100289 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200290 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
291 'let ll = \[1, "two", 333\]\_s*' ..
292 '\d PUSHNR 1\_s*' ..
293 '\d PUSHS "two"\_s*' ..
294 '\d PUSHNR 333\_s*' ..
295 '\d NEWLIST size 3\_s*' ..
296 '\d STORE $0\_s*' ..
297 'let dd = #{one: 1, two: "val"}\_s*' ..
298 '\d PUSHS "one"\_s*' ..
299 '\d PUSHNR 1\_s*' ..
300 '\d PUSHS "two"\_s*' ..
301 '\d PUSHS "val"\_s*' ..
302 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200303 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100304enddef
305
Bram Moolenaar6e949782020-04-13 17:21:00 +0200306def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100307 echo arg
308enddef
309
310func UserFunc()
311 echo 'nothing'
312endfunc
313
314func UserFuncWithArg(arg)
315 echo a:arg
316endfunc
317
318def s:ScriptFuncCall(): string
319 changenr()
320 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100321 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100322 FuncWithArg(343)
323 ScriptFuncNew()
324 s:ScriptFuncNew()
325 UserFunc()
326 UserFuncWithArg("foo")
327 let FuncRef = function("UserFunc")
328 FuncRef()
329 let FuncRefWithArg = function("UserFuncWithArg")
330 FuncRefWithArg("bar")
331 return "yes"
332enddef
333
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100334def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100335 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200336 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
337 'changenr()\_s*' ..
338 '\d BCALL changenr(argc 0)\_s*' ..
339 '\d DROP\_s*' ..
340 'char2nr("abc")\_s*' ..
341 '\d PUSHS "abc"\_s*' ..
342 '\d BCALL char2nr(argc 1)\_s*' ..
343 '\d DROP\_s*' ..
344 'Test_disassemble_new()\_s*' ..
345 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
346 '\d DROP\_s*' ..
347 'FuncWithArg(343)\_s*' ..
348 '\d\+ PUSHNR 343\_s*' ..
349 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
350 '\d\+ DROP\_s*' ..
351 'ScriptFuncNew()\_s*' ..
352 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
353 '\d\+ DROP\_s*' ..
354 's:ScriptFuncNew()\_s*' ..
355 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
356 '\d\+ DROP\_s*' ..
357 'UserFunc()\_s*' ..
358 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
359 '\d\+ DROP\_s*' ..
360 'UserFuncWithArg("foo")\_s*' ..
361 '\d\+ PUSHS "foo"\_s*' ..
362 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
363 '\d\+ DROP\_s*' ..
364 'let FuncRef = function("UserFunc")\_s*' ..
365 '\d\+ PUSHS "UserFunc"\_s*' ..
366 '\d\+ BCALL function(argc 1)\_s*' ..
367 '\d\+ STORE $0\_s*' ..
368 'FuncRef()\_s*' ..
369 '\d\+ LOAD $\d\_s*' ..
370 '\d\+ PCALL (argc 0)\_s*' ..
371 '\d\+ DROP\_s*' ..
372 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
373 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
374 '\d\+ BCALL function(argc 1)\_s*' ..
375 '\d\+ STORE $1\_s*' ..
376 'FuncRefWithArg("bar")\_s*' ..
377 '\d\+ PUSHS "bar"\_s*' ..
378 '\d\+ LOAD $\d\_s*' ..
379 '\d\+ PCALL (argc 1)\_s*' ..
380 '\d\+ DROP\_s*' ..
381 'return "yes"\_s*' ..
382 '\d\+ PUSHS "yes"\_s*' ..
383 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200384 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100385enddef
386
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200387def s:CreateRefs()
388 let local = 'a'
389 def Append(arg: string)
390 local ..= arg
391 enddef
392 g:Append = Append
393 def Get(): string
394 return local
395 enddef
396 g:Get = Get
397enddef
398
399def Test_disassemble_closure()
400 CreateRefs()
401 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200402 assert_match('<lambda>\d\_s*' ..
403 'local ..= arg\_s*' ..
404 '\d LOADOUTER $0\_s*' ..
405 '\d LOAD arg\[-1\]\_s*' ..
406 '\d CONCAT\_s*' ..
407 '\d STOREOUTER $0\_s*' ..
408 '\d PUSHNR 0\_s*' ..
409 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200410 res)
411
412 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200413 assert_match('<lambda>\d\_s*' ..
414 'return local\_s*' ..
415 '\d LOADOUTER $0\_s*' ..
416 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200417 res)
418
419 unlet g:Append
420 unlet g:Get
421enddef
422
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100423
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200424def EchoArg(arg: string): string
425 return arg
426enddef
427def RefThis(): func
428 return function('EchoArg')
429enddef
430def s:ScriptPCall()
431 RefThis()("text")
432enddef
433
434def Test_disassemble_pcall()
435 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200436 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
437 'RefThis()("text")\_s*' ..
438 '\d DCALL RefThis(argc 0)\_s*' ..
439 '\d PUSHS "text"\_s*' ..
440 '\d PCALL top (argc 1)\_s*' ..
441 '\d PCALL end\_s*' ..
442 '\d DROP\_s*' ..
443 '\d PUSHNR 0\_s*' ..
444 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200445 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200446enddef
447
448
Bram Moolenaara26b9702020-04-18 19:53:28 +0200449def s:FuncWithForwardCall(): string
450 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100451enddef
452
453def DefinedLater(arg: string): string
454 return arg
455enddef
456
457def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200458 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200459 assert_match('FuncWithForwardCall\_s*' ..
460 'return g:DefinedLater("yes")\_s*' ..
461 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200462 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200463 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200464 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100465
466 " Calling the function will change UCALL into the faster DCALL
467 assert_equal('yes', FuncWithForwardCall())
468
Bram Moolenaara26b9702020-04-18 19:53:28 +0200469 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200470 assert_match('FuncWithForwardCall\_s*' ..
471 'return g:DefinedLater("yes")\_s*' ..
472 '\d PUSHS "yes"\_s*' ..
473 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200474 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200475 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100476enddef
477
478
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100479def FuncWithDefault(arg: string = 'default'): string
480 return arg
481enddef
482
483def Test_disassemble_call_default()
484 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200485 assert_match('FuncWithDefault\_s*' ..
486 '\d PUSHS "default"\_s*' ..
487 '\d STORE arg\[-1]\_s*' ..
488 'return arg\_s*' ..
489 '\d LOAD arg\[-1]\_s*' ..
490 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200491 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100492enddef
493
494
Bram Moolenaar158906c2020-02-06 20:39:45 +0100495def HasEval()
496 if has("eval")
497 echo "yes"
498 else
499 echo "no"
500 endif
501enddef
502
503def HasNothing()
504 if has("nothing")
505 echo "yes"
506 else
507 echo "no"
508 endif
509enddef
510
511def HasSomething()
512 if has("nothing")
513 echo "nothing"
514 elseif has("something")
515 echo "something"
516 elseif has("eval")
517 echo "eval"
518 elseif has("less")
519 echo "less"
520 endif
521enddef
522
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100523def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100524 assert_equal("\nyes", execute('call HasEval()'))
525 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200526 assert_match('HasEval\_s*' ..
527 'if has("eval")\_s*' ..
528 'echo "yes"\_s*' ..
529 '\d PUSHS "yes"\_s*' ..
530 '\d ECHO 1\_s*' ..
531 'else\_s*' ..
532 'echo "no"\_s*' ..
533 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200534 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100535 assert_notmatch('JUMP', instr)
536
537 assert_equal("\nno", execute('call HasNothing()'))
538 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200539 assert_match('HasNothing\_s*' ..
540 'if has("nothing")\_s*' ..
541 'echo "yes"\_s*' ..
542 'else\_s*' ..
543 'echo "no"\_s*' ..
544 '\d PUSHS "no"\_s*' ..
545 '\d ECHO 1\_s*' ..
546 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200547 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100548 assert_notmatch('PUSHS "yes"', instr)
549 assert_notmatch('JUMP', instr)
550
551 assert_equal("\neval", execute('call HasSomething()'))
552 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200553 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200554 'if has("nothing")\_s*' ..
555 'echo "nothing"\_s*' ..
556 'elseif has("something")\_s*' ..
557 'echo "something"\_s*' ..
558 'elseif has("eval")\_s*' ..
559 'echo "eval"\_s*' ..
560 '\d PUSHS "eval"\_s*' ..
561 '\d ECHO 1\_s*' ..
562 'elseif has("less").*' ..
563 'echo "less"\_s*' ..
564 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200565 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100566 assert_notmatch('PUSHS "nothing"', instr)
567 assert_notmatch('PUSHS "something"', instr)
568 assert_notmatch('PUSHS "less"', instr)
569 assert_notmatch('JUMP', instr)
570enddef
571
Bram Moolenaarefd88552020-06-18 20:50:10 +0200572def ReturnInIf(): string
573 if g:cond
574 return "yes"
575 else
576 return "no"
577 endif
578enddef
579
580def Test_disassemble_return_in_if()
581 let instr = execute('disassemble ReturnInIf')
582 assert_match('ReturnInIf\_s*' ..
583 'if g:cond\_s*' ..
584 '0 LOADG g:cond\_s*' ..
585 '1 JUMP_IF_FALSE -> 4\_s*' ..
586 'return "yes"\_s*' ..
587 '2 PUSHS "yes"\_s*' ..
588 '3 RETURN\_s*' ..
589 'else\_s*' ..
590 ' return "no"\_s*' ..
591 '4 PUSHS "no"\_s*' ..
592 '5 RETURN$',
593 instr)
594enddef
595
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100596def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200597 let Funky1: func
598 let Funky2: func = function("len")
599 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100600enddef
601
602def Test_disassemble_function()
603 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200604 assert_match('WithFunc\_s*' ..
605 'let Funky1: func\_s*' ..
606 '0 PUSHFUNC "\[none]"\_s*' ..
607 '1 STORE $0\_s*' ..
608 'let Funky2: func = function("len")\_s*' ..
609 '2 PUSHS "len"\_s*' ..
610 '3 BCALL function(argc 1)\_s*' ..
611 '4 STORE $1\_s*' ..
612 'let Party2: func = funcref("UserFunc")\_s*' ..
613 '\d PUSHS "UserFunc"\_s*' ..
614 '\d BCALL funcref(argc 1)\_s*' ..
615 '\d STORE $2\_s*' ..
616 '\d PUSHNR 0\_s*' ..
617 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200618 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100619enddef
620
621if has('channel')
622 def WithChannel()
623 let job1: job
624 let job2: job = job_start("donothing")
625 let chan1: channel
626 enddef
627endif
628
629def Test_disassemble_channel()
630 CheckFeature channel
631
632 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200633 assert_match('WithChannel\_s*' ..
634 'let job1: job\_s*' ..
635 '\d PUSHJOB "no process"\_s*' ..
636 '\d STORE $0\_s*' ..
637 'let job2: job = job_start("donothing")\_s*' ..
638 '\d PUSHS "donothing"\_s*' ..
639 '\d BCALL job_start(argc 1)\_s*' ..
640 '\d STORE $1\_s*' ..
641 'let chan1: channel\_s*' ..
642 '\d PUSHCHANNEL 0\_s*' ..
643 '\d STORE $2\_s*' ..
644 '\d PUSHNR 0\_s*' ..
645 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200646 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100647enddef
648
Bram Moolenaar777770f2020-02-06 21:27:08 +0100649def WithLambda(): string
650 let F = {a -> "X" .. a .. "X"}
651 return F("x")
652enddef
653
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100654def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100655 assert_equal("XxX", WithLambda())
656 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200657 assert_match('WithLambda\_s*' ..
658 'let F = {a -> "X" .. a .. "X"}\_s*' ..
659 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
660 '\d STORE $0\_s*' ..
661 'return F("x")\_s*' ..
662 '\d PUSHS "x"\_s*' ..
663 '\d LOAD $0\_s*' ..
664 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200665 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200666 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100667enddef
668
Bram Moolenaar6e949782020-04-13 17:21:00 +0200669def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100670 if arg == 1 && arg != 2 || arg == 4
671 return 'yes'
672 endif
673 return 'no'
674enddef
675
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100676def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100677 assert_equal("yes", AndOr(1))
678 assert_equal("no", AndOr(2))
679 assert_equal("yes", AndOr(4))
680 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200681 assert_match('AndOr\_s*' ..
682 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
683 '\d LOAD arg\[-1]\_s*' ..
684 '\d PUSHNR 1\_s*' ..
685 '\d COMPAREANY ==\_s*' ..
686 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
687 '\d LOAD arg\[-1]\_s*' ..
688 '\d PUSHNR 2\_s*' ..
689 '\d COMPAREANY !=\_s*' ..
690 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
691 '\d LOAD arg\[-1]\_s*' ..
692 '\d\+ PUSHNR 4\_s*' ..
693 '\d\+ COMPAREANY ==\_s*' ..
694 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200695 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100696enddef
697
Bram Moolenaar04d05222020-02-06 22:06:54 +0100698def ForLoop(): list<number>
699 let res: list<number>
700 for i in range(3)
701 res->add(i)
702 endfor
703 return res
704enddef
705
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100706def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100707 assert_equal([0, 1, 2], ForLoop())
708 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200709 assert_match('ForLoop\_s*' ..
710 'let res: list<number>\_s*' ..
711 '\d NEWLIST size 0\_s*' ..
712 '\d STORE $0\_s*' ..
713 'for i in range(3)\_s*' ..
714 '\d STORE -1 in $1\_s*' ..
715 '\d PUSHNR 3\_s*' ..
716 '\d BCALL range(argc 1)\_s*' ..
717 '\d FOR $1 -> \d\+\_s*' ..
718 '\d STORE $2\_s*' ..
719 'res->add(i)\_s*' ..
720 '\d LOAD $0\_s*' ..
721 '\d LOAD $2\_s*' ..
722 '\d\+ BCALL add(argc 2)\_s*' ..
723 '\d\+ DROP\_s*' ..
724 'endfor\_s*' ..
725 '\d\+ JUMP -> \d\+\_s*' ..
726 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200727 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100728enddef
729
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200730def ForLoopEval(): string
731 let res = ""
732 for str in eval('["one", "two"]')
733 res ..= str
734 endfor
735 return res
736enddef
737
738def Test_disassemble_for_loop_eval()
739 assert_equal('onetwo', ForLoopEval())
740 let instr = execute('disassemble ForLoopEval')
741 assert_match('ForLoopEval\_s*' ..
742 'let res = ""\_s*' ..
743 '\d PUSHS ""\_s*' ..
744 '\d STORE $0\_s*' ..
745 'for str in eval(''\["one", "two"\]'')\_s*' ..
746 '\d STORE -1 in $1\_s*' ..
747 '\d PUSHS "\["one", "two"\]"\_s*' ..
748 '\d BCALL eval(argc 1)\_s*' ..
749 '\d CHECKTYPE list stack\[-1\]\_s*' ..
750 '\d FOR $1 -> \d\+\_s*' ..
751 '\d STORE $2\_s*' ..
752 'res ..= str\_s*' ..
753 '\d\+ LOAD $0\_s*' ..
754 '\d\+ LOAD $2\_s*' ..
755 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
756 '\d\+ CONCAT\_s*' ..
757 '\d\+ STORE $0\_s*' ..
758 'endfor\_s*' ..
759 '\d\+ JUMP -> 6\_s*' ..
760 '\d\+ DROP\_s*' ..
761 'return res\_s*' ..
762 '\d\+ LOAD $0\_s*' ..
763 '\d\+ RETURN',
764 instr)
765enddef
766
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100767let g:number = 42
768
769def Computing()
770 let nr = 3
771 let nrres = nr + 7
772 nrres = nr - 7
773 nrres = nr * 7
774 nrres = nr / 7
775 nrres = nr % 7
776
777 let anyres = g:number + 7
778 anyres = g:number - 7
779 anyres = g:number * 7
780 anyres = g:number / 7
781 anyres = g:number % 7
782
783 if has('float')
784 let fl = 3.0
785 let flres = fl + 7.0
786 flres = fl - 7.0
787 flres = fl * 7.0
788 flres = fl / 7.0
789 endif
790enddef
791
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100792def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100793 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200794 assert_match('Computing.*' ..
795 'let nr = 3.*' ..
796 '\d STORE 3 in $0.*' ..
797 'let nrres = nr + 7.*' ..
798 '\d LOAD $0.*' ..
799 '\d PUSHNR 7.*' ..
800 '\d OPNR +.*' ..
801 '\d STORE $1.*' ..
802 'nrres = nr - 7.*' ..
803 '\d OPNR -.*' ..
804 'nrres = nr \* 7.*' ..
805 '\d OPNR \*.*' ..
806 'nrres = nr / 7.*' ..
807 '\d OPNR /.*' ..
808 'nrres = nr % 7.*' ..
809 '\d OPNR %.*' ..
810 'let anyres = g:number + 7.*' ..
811 '\d LOADG g:number.*' ..
812 '\d PUSHNR 7.*' ..
813 '\d OPANY +.*' ..
814 '\d STORE $2.*' ..
815 'anyres = g:number - 7.*' ..
816 '\d OPANY -.*' ..
817 'anyres = g:number \* 7.*' ..
818 '\d OPANY \*.*' ..
819 'anyres = g:number / 7.*' ..
820 '\d OPANY /.*' ..
821 'anyres = g:number % 7.*' ..
822 '\d OPANY %.*',
823 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100824 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200825 assert_match('Computing.*' ..
826 'let fl = 3.0.*' ..
827 '\d PUSHF 3.0.*' ..
828 '\d STORE $3.*' ..
829 'let flres = fl + 7.0.*' ..
830 '\d LOAD $3.*' ..
831 '\d PUSHF 7.0.*' ..
832 '\d OPFLOAT +.*' ..
833 '\d STORE $4.*' ..
834 'flres = fl - 7.0.*' ..
835 '\d OPFLOAT -.*' ..
836 'flres = fl \* 7.0.*' ..
837 '\d OPFLOAT \*.*' ..
838 'flres = fl / 7.0.*' ..
839 '\d OPFLOAT /.*',
840 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100841 endif
842enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100843
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100844def AddListBlob()
845 let reslist = [1, 2] + [3, 4]
846 let resblob = 0z1122 + 0z3344
847enddef
848
849def Test_disassemble_add_list_blob()
850 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200851 assert_match('AddListBlob.*' ..
852 'let reslist = \[1, 2] + \[3, 4].*' ..
853 '\d PUSHNR 1.*' ..
854 '\d PUSHNR 2.*' ..
855 '\d NEWLIST size 2.*' ..
856 '\d PUSHNR 3.*' ..
857 '\d PUSHNR 4.*' ..
858 '\d NEWLIST size 2.*' ..
859 '\d ADDLIST.*' ..
860 '\d STORE $.*.*' ..
861 'let resblob = 0z1122 + 0z3344.*' ..
862 '\d PUSHBLOB 0z1122.*' ..
863 '\d PUSHBLOB 0z3344.*' ..
864 '\d ADDBLOB.*' ..
865 '\d STORE $.*',
866 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100867enddef
868
869let g:aa = 'aa'
870def ConcatString(): string
871 let res = g:aa .. "bb"
872 return res
873enddef
874
875def Test_disassemble_concat()
876 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200877 assert_match('ConcatString.*' ..
878 'let res = g:aa .. "bb".*' ..
879 '\d LOADG g:aa.*' ..
880 '\d PUSHS "bb".*' ..
881 '\d 2STRING stack\[-2].*' ..
882 '\d CONCAT.*' ..
883 '\d STORE $.*',
884 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100885 assert_equal('aabb', ConcatString())
886enddef
887
888def ListIndex(): number
889 let l = [1, 2, 3]
890 let res = l[1]
891 return res
892enddef
893
894def Test_disassemble_list_index()
895 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200896 assert_match('ListIndex\_s*' ..
897 'let l = \[1, 2, 3]\_s*' ..
898 '\d PUSHNR 1\_s*' ..
899 '\d PUSHNR 2\_s*' ..
900 '\d PUSHNR 3\_s*' ..
901 '\d NEWLIST size 3\_s*' ..
902 '\d STORE $0\_s*' ..
903 'let res = l\[1]\_s*' ..
904 '\d LOAD $0\_s*' ..
905 '\d PUSHNR 1\_s*' ..
906 '\d INDEX\_s*' ..
907 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200908 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100909 assert_equal(2, ListIndex())
910enddef
911
912def DictMember(): number
913 let d = #{item: 1}
914 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200915 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100916 return res
917enddef
918
919def Test_disassemble_dict_member()
920 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200921 assert_match('DictMember\_s*' ..
922 'let d = #{item: 1}\_s*' ..
923 '\d PUSHS "item"\_s*' ..
924 '\d PUSHNR 1\_s*' ..
925 '\d NEWDICT size 1\_s*' ..
926 '\d STORE $0\_s*' ..
927 'let res = d.item\_s*' ..
928 '\d\+ LOAD $0\_s*' ..
929 '\d\+ MEMBER item\_s*' ..
930 '\d\+ STORE $1\_s*' ..
931 'res = d\["item"\]\_s*' ..
932 '\d\+ LOAD $0\_s*' ..
933 '\d\+ PUSHS "item"\_s*' ..
934 '\d\+ MEMBER\_s*' ..
935 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200936 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100937 call assert_equal(1, DictMember())
938enddef
939
940def NegateNumber(): number
941 let nr = 9
942 let plus = +nr
943 let res = -nr
944 return res
945enddef
946
947def Test_disassemble_negate_number()
948 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200949 assert_match('NegateNumber\_s*' ..
950 'let nr = 9\_s*' ..
951 '\d STORE 9 in $0\_s*' ..
952 'let plus = +nr\_s*' ..
953 '\d LOAD $0\_s*' ..
954 '\d CHECKNR\_s*' ..
955 '\d STORE $1\_s*' ..
956 'let res = -nr\_s*' ..
957 '\d LOAD $0\_s*' ..
958 '\d NEGATENR\_s*' ..
959 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200960 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100961 call assert_equal(-9, NegateNumber())
962enddef
963
964def InvertBool(): bool
965 let flag = true
966 let invert = !flag
967 let res = !!flag
968 return res
969enddef
970
971def Test_disassemble_invert_bool()
972 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200973 assert_match('InvertBool\_s*' ..
974 'let flag = true\_s*' ..
975 '\d PUSH v:true\_s*' ..
976 '\d STORE $0\_s*' ..
977 'let invert = !flag\_s*' ..
978 '\d LOAD $0\_s*' ..
979 '\d INVERT (!val)\_s*' ..
980 '\d STORE $1\_s*' ..
981 'let res = !!flag\_s*' ..
982 '\d LOAD $0\_s*' ..
983 '\d 2BOOL (!!val)\_s*' ..
984 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200985 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100986 call assert_equal(true, InvertBool())
987enddef
988
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100989def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100990 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +0200991 ['true == isFalse', 'COMPAREBOOL =='],
992 ['true != isFalse', 'COMPAREBOOL !='],
993 ['v:none == isNull', 'COMPARESPECIAL =='],
994 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +0200995
Bram Moolenaara5565e42020-05-09 15:44:01 +0200996 ['111 == aNumber', 'COMPARENR =='],
997 ['111 != aNumber', 'COMPARENR !='],
998 ['111 > aNumber', 'COMPARENR >'],
999 ['111 < aNumber', 'COMPARENR <'],
1000 ['111 >= aNumber', 'COMPARENR >='],
1001 ['111 <= aNumber', 'COMPARENR <='],
1002 ['111 =~ aNumber', 'COMPARENR =\~'],
1003 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001004
Bram Moolenaara5565e42020-05-09 15:44:01 +02001005 ['"xx" != aString', 'COMPARESTRING !='],
1006 ['"xx" > aString', 'COMPARESTRING >'],
1007 ['"xx" < aString', 'COMPARESTRING <'],
1008 ['"xx" >= aString', 'COMPARESTRING >='],
1009 ['"xx" <= aString', 'COMPARESTRING <='],
1010 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1011 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1012 ['"xx" is aString', 'COMPARESTRING is'],
1013 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001014
Bram Moolenaara5565e42020-05-09 15:44:01 +02001015 ['0z11 == aBlob', 'COMPAREBLOB =='],
1016 ['0z11 != aBlob', 'COMPAREBLOB !='],
1017 ['0z11 is aBlob', 'COMPAREBLOB is'],
1018 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001019
Bram Moolenaara5565e42020-05-09 15:44:01 +02001020 ['[1, 2] == aList', 'COMPARELIST =='],
1021 ['[1, 2] != aList', 'COMPARELIST !='],
1022 ['[1, 2] is aList', 'COMPARELIST is'],
1023 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001024
Bram Moolenaara5565e42020-05-09 15:44:01 +02001025 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1026 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1027 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1028 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001029
1030 ['{->33} == {->44}', 'COMPAREFUNC =='],
1031 ['{->33} != {->44}', 'COMPAREFUNC !='],
1032 ['{->33} is {->44}', 'COMPAREFUNC is'],
1033 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1034
1035 ['77 == g:xx', 'COMPAREANY =='],
1036 ['77 != g:xx', 'COMPAREANY !='],
1037 ['77 > g:xx', 'COMPAREANY >'],
1038 ['77 < g:xx', 'COMPAREANY <'],
1039 ['77 >= g:xx', 'COMPAREANY >='],
1040 ['77 <= g:xx', 'COMPAREANY <='],
1041 ['77 =~ g:xx', 'COMPAREANY =\~'],
1042 ['77 !~ g:xx', 'COMPAREANY !\~'],
1043 ['77 is g:xx', 'COMPAREANY is'],
1044 ['77 isnot g:xx', 'COMPAREANY isnot'],
1045 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001046 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001047 if has('float')
1048 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001049 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1050 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1051 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1052 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1053 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1054 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1055 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1056 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001057 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001058 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001059 endif
1060
1061 let nr = 1
1062 for case in cases
Bram Moolenaara5565e42020-05-09 15:44:01 +02001063 " declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001064 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001065 ' let isFalse = false',
1066 ' let isNull = v:null',
1067 ' let aNumber = 222',
1068 ' let aString = "yy"',
1069 ' let aBlob = 0z22',
1070 ' let aList = [3, 4]',
1071 ' let aDict = #{x: 2}',
1072 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001073 ' if ' .. case[0],
1074 ' echo 42'
1075 ' endif',
1076 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001077 source Xdisassemble
1078 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001079 assert_match('TestCase' .. nr .. '.*' ..
1080 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1081 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001082 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001083 '\d ' .. case[1] .. '.*' ..
1084 '\d JUMP_IF_FALSE -> \d\+.*',
1085 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001086
1087 nr += 1
1088 endfor
1089
Bram Moolenaar22da5592020-03-19 14:52:20 +01001090 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001091enddef
1092
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001093def Test_disassemble_compare_const()
1094 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001095 ['"xx" == "yy"', false],
1096 ['"aa" == "aa"', true],
1097 ['has("eval") ? true : false', true],
1098 ['has("asdf") ? true : false', false],
1099 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001100
1101 let nr = 1
1102 for case in cases
1103 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001104 ' if ' .. case[0],
1105 ' echo 42'
1106 ' endif',
1107 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001108 source Xdisassemble
1109 let instr = execute('disassemble TestCase' .. nr)
1110 if case[1]
1111 " condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001112 assert_match('TestCase' .. nr .. '.*' ..
1113 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1114 '\d PUSHNR 42.*' ..
1115 '\d ECHO 1.*' ..
1116 '\d PUSHNR 0.*' ..
1117 '\d RETURN.*',
1118 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001119 else
1120 " condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001121 assert_match('TestCase' .. nr .. '.*' ..
1122 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1123 'echo 42[ \n]*' ..
1124 'endif[ \n]*' ..
1125 '\s*\d PUSHNR 0.*' ..
1126 '\d RETURN.*',
1127 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001128 endif
1129
1130 nr += 1
1131 endfor
1132
1133 delete('Xdisassemble')
1134enddef
1135
Bram Moolenaarad39c092020-02-26 18:23:43 +01001136def s:Execute()
1137 execute 'help vim9.txt'
1138 let cmd = 'help vim9.txt'
1139 execute cmd
1140 let tag = 'vim9.txt'
1141 execute 'help ' .. tag
1142enddef
1143
1144def Test_disassemble_execute()
1145 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001146 assert_match('\<SNR>\d*_Execute\_s*' ..
1147 "execute 'help vim9.txt'\\_s*" ..
1148 '\d PUSHS "help vim9.txt"\_s*' ..
1149 '\d EXECUTE 1\_s*' ..
1150 "let cmd = 'help vim9.txt'\\_s*" ..
1151 '\d PUSHS "help vim9.txt"\_s*' ..
1152 '\d STORE $0\_s*' ..
1153 'execute cmd\_s*' ..
1154 '\d LOAD $0\_s*' ..
1155 '\d EXECUTE 1\_s*' ..
1156 "let tag = 'vim9.txt'\\_s*" ..
1157 '\d PUSHS "vim9.txt"\_s*' ..
1158 '\d STORE $1\_s*' ..
1159 "execute 'help ' .. tag\\_s*" ..
1160 '\d\+ PUSHS "help "\_s*' ..
1161 '\d\+ LOAD $1\_s*' ..
1162 '\d\+ CONCAT\_s*' ..
1163 '\d\+ EXECUTE 1\_s*' ..
1164 '\d\+ PUSHNR 0\_s*' ..
1165 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001166 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001167enddef
1168
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001169def s:Echomsg()
1170 echomsg 'some' 'message'
1171 echoerr 'went' .. 'wrong'
1172enddef
1173
1174def Test_disassemble_echomsg()
1175 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001176 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1177 "echomsg 'some' 'message'\\_s*" ..
1178 '\d PUSHS "some"\_s*' ..
1179 '\d PUSHS "message"\_s*' ..
1180 '\d ECHOMSG 2\_s*' ..
1181 "echoerr 'went' .. 'wrong'\\_s*" ..
1182 '\d PUSHS "wentwrong"\_s*' ..
1183 '\d ECHOERR 1\_s*' ..
1184 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001185 '\d RETURN',
1186 res)
1187enddef
1188
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001189def SomeStringArg(arg: string)
1190 echo arg
1191enddef
1192
1193def SomeAnyArg(arg: any)
1194 echo arg
1195enddef
1196
1197def SomeStringArgAndReturn(arg: string): string
1198 return arg
1199enddef
1200
1201def Test_display_func()
1202 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001203 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1204 '\d *echo arg.*' ..
1205 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001206 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001207
1208 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001209 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1210 '\d *echo arg\_s*' ..
1211 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001212 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001213
1214 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001215 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1216 '\d *return arg\_s*' ..
1217 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001218 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001219enddef
1220
Bram Moolenaar09689a02020-05-09 22:50:08 +02001221def Test_vim9script_forward_func()
1222 let lines =<< trim END
1223 vim9script
1224 def FuncOne(): string
1225 return FuncTwo()
1226 enddef
1227 def FuncTwo(): string
1228 return 'two'
1229 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001230 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001231 END
1232 writefile(lines, 'Xdisassemble')
1233 source Xdisassemble
1234
1235 " check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001236 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1237 'return FuncTwo()\_s*' ..
1238 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001239 '\d RETURN',
1240 g:res_FuncOne)
1241
1242 delete('Xdisassemble')
1243 unlet g:res_FuncOne
1244enddef
1245
Bram Moolenaar61a89812020-05-07 16:58:17 +02001246def s:ConcatStrings(): string
1247 return 'one' .. 'two' .. 'three'
1248enddef
1249
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001250def s:ComputeConst(): number
1251 return 2 + 3 * 4 / 6 + 7
1252enddef
1253
Bram Moolenaar1c747212020-05-09 18:28:34 +02001254def s:ComputeConstParen(): number
1255 return ((2 + 4) * (8 / 2)) / (3 + 4)
1256enddef
1257
Bram Moolenaar61a89812020-05-07 16:58:17 +02001258def Test_simplify_const_expr()
1259 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001260 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1261 "return 'one' .. 'two' .. 'three'\\_s*" ..
1262 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001263 '\d RETURN',
1264 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001265
1266 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001267 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1268 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1269 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001270 '\d RETURN',
1271 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001272
1273 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001274 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1275 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1276 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001277 '\d RETURN',
1278 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001279enddef
1280
Bram Moolenaar389df252020-07-09 21:20:47 +02001281def s:CallAppend()
1282 eval "some text"->append(2)
1283enddef
1284
1285def Test_shuffle()
1286 let res = execute('disass s:CallAppend')
1287 assert_match('<SNR>\d*_CallAppend\_s*' ..
1288 'eval "some text"->append(2)\_s*' ..
1289 '\d PUSHS "some text"\_s*' ..
1290 '\d PUSHNR 2\_s*' ..
1291 '\d SHUFFLE 2 up 1\_s*' ..
1292 '\d BCALL append(argc 2)\_s*' ..
1293 '\d DROP\_s*' ..
1294 '\d PUSHNR 0\_s*' ..
1295 '\d RETURN',
1296 res)
1297enddef
1298
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001299" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker