blob: 186ce6d1c6e871071cc4242b87c2403d5e9777fe [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
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200466 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100467 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 Moolenaarbfd65582020-07-13 18:18:00 +0200667
668 let name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
669 instr = execute('disassemble ' .. name)
670 assert_match('<lambda>\d\+\_s*' ..
671 'return "X" .. a .. "X"\_s*' ..
672 '\d PUSHS "X"\_s*' ..
673 '\d LOAD arg\[-1\]\_s*' ..
674 '\d 2STRING stack\[-1\]\_s*' ..
675 '\d CONCAT\_s*' ..
676 '\d PUSHS "X"\_s*' ..
677 '\d CONCAT\_s*' ..
678 '\d RETURN',
679 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100680enddef
681
Bram Moolenaar6e949782020-04-13 17:21:00 +0200682def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100683 if arg == 1 && arg != 2 || arg == 4
684 return 'yes'
685 endif
686 return 'no'
687enddef
688
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100689def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100690 assert_equal("yes", AndOr(1))
691 assert_equal("no", AndOr(2))
692 assert_equal("yes", AndOr(4))
693 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200694 assert_match('AndOr\_s*' ..
695 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
696 '\d LOAD arg\[-1]\_s*' ..
697 '\d PUSHNR 1\_s*' ..
698 '\d COMPAREANY ==\_s*' ..
699 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
700 '\d LOAD arg\[-1]\_s*' ..
701 '\d PUSHNR 2\_s*' ..
702 '\d COMPAREANY !=\_s*' ..
703 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
704 '\d LOAD arg\[-1]\_s*' ..
705 '\d\+ PUSHNR 4\_s*' ..
706 '\d\+ COMPAREANY ==\_s*' ..
707 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200708 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100709enddef
710
Bram Moolenaar04d05222020-02-06 22:06:54 +0100711def ForLoop(): list<number>
712 let res: list<number>
713 for i in range(3)
714 res->add(i)
715 endfor
716 return res
717enddef
718
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100719def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100720 assert_equal([0, 1, 2], ForLoop())
721 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200722 assert_match('ForLoop\_s*' ..
723 'let res: list<number>\_s*' ..
724 '\d NEWLIST size 0\_s*' ..
725 '\d STORE $0\_s*' ..
726 'for i in range(3)\_s*' ..
727 '\d STORE -1 in $1\_s*' ..
728 '\d PUSHNR 3\_s*' ..
729 '\d BCALL range(argc 1)\_s*' ..
730 '\d FOR $1 -> \d\+\_s*' ..
731 '\d STORE $2\_s*' ..
732 'res->add(i)\_s*' ..
733 '\d LOAD $0\_s*' ..
734 '\d LOAD $2\_s*' ..
735 '\d\+ BCALL add(argc 2)\_s*' ..
736 '\d\+ DROP\_s*' ..
737 'endfor\_s*' ..
738 '\d\+ JUMP -> \d\+\_s*' ..
739 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200740 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100741enddef
742
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200743def ForLoopEval(): string
744 let res = ""
745 for str in eval('["one", "two"]')
746 res ..= str
747 endfor
748 return res
749enddef
750
751def Test_disassemble_for_loop_eval()
752 assert_equal('onetwo', ForLoopEval())
753 let instr = execute('disassemble ForLoopEval')
754 assert_match('ForLoopEval\_s*' ..
755 'let res = ""\_s*' ..
756 '\d PUSHS ""\_s*' ..
757 '\d STORE $0\_s*' ..
758 'for str in eval(''\["one", "two"\]'')\_s*' ..
759 '\d STORE -1 in $1\_s*' ..
760 '\d PUSHS "\["one", "two"\]"\_s*' ..
761 '\d BCALL eval(argc 1)\_s*' ..
762 '\d CHECKTYPE list stack\[-1\]\_s*' ..
763 '\d FOR $1 -> \d\+\_s*' ..
764 '\d STORE $2\_s*' ..
765 'res ..= str\_s*' ..
766 '\d\+ LOAD $0\_s*' ..
767 '\d\+ LOAD $2\_s*' ..
768 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
769 '\d\+ CONCAT\_s*' ..
770 '\d\+ STORE $0\_s*' ..
771 'endfor\_s*' ..
772 '\d\+ JUMP -> 6\_s*' ..
773 '\d\+ DROP\_s*' ..
774 'return res\_s*' ..
775 '\d\+ LOAD $0\_s*' ..
776 '\d\+ RETURN',
777 instr)
778enddef
779
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100780let g:number = 42
781
782def Computing()
783 let nr = 3
784 let nrres = nr + 7
785 nrres = nr - 7
786 nrres = nr * 7
787 nrres = nr / 7
788 nrres = nr % 7
789
790 let anyres = g:number + 7
791 anyres = g:number - 7
792 anyres = g:number * 7
793 anyres = g:number / 7
794 anyres = g:number % 7
795
796 if has('float')
797 let fl = 3.0
798 let flres = fl + 7.0
799 flres = fl - 7.0
800 flres = fl * 7.0
801 flres = fl / 7.0
802 endif
803enddef
804
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100805def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100806 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200807 assert_match('Computing.*' ..
808 'let nr = 3.*' ..
809 '\d STORE 3 in $0.*' ..
810 'let nrres = nr + 7.*' ..
811 '\d LOAD $0.*' ..
812 '\d PUSHNR 7.*' ..
813 '\d OPNR +.*' ..
814 '\d STORE $1.*' ..
815 'nrres = nr - 7.*' ..
816 '\d OPNR -.*' ..
817 'nrres = nr \* 7.*' ..
818 '\d OPNR \*.*' ..
819 'nrres = nr / 7.*' ..
820 '\d OPNR /.*' ..
821 'nrres = nr % 7.*' ..
822 '\d OPNR %.*' ..
823 'let anyres = g:number + 7.*' ..
824 '\d LOADG g:number.*' ..
825 '\d PUSHNR 7.*' ..
826 '\d OPANY +.*' ..
827 '\d STORE $2.*' ..
828 'anyres = g:number - 7.*' ..
829 '\d OPANY -.*' ..
830 'anyres = g:number \* 7.*' ..
831 '\d OPANY \*.*' ..
832 'anyres = g:number / 7.*' ..
833 '\d OPANY /.*' ..
834 'anyres = g:number % 7.*' ..
835 '\d OPANY %.*',
836 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100837 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200838 assert_match('Computing.*' ..
839 'let fl = 3.0.*' ..
840 '\d PUSHF 3.0.*' ..
841 '\d STORE $3.*' ..
842 'let flres = fl + 7.0.*' ..
843 '\d LOAD $3.*' ..
844 '\d PUSHF 7.0.*' ..
845 '\d OPFLOAT +.*' ..
846 '\d STORE $4.*' ..
847 'flres = fl - 7.0.*' ..
848 '\d OPFLOAT -.*' ..
849 'flres = fl \* 7.0.*' ..
850 '\d OPFLOAT \*.*' ..
851 'flres = fl / 7.0.*' ..
852 '\d OPFLOAT /.*',
853 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100854 endif
855enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100856
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100857def AddListBlob()
858 let reslist = [1, 2] + [3, 4]
859 let resblob = 0z1122 + 0z3344
860enddef
861
862def Test_disassemble_add_list_blob()
863 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200864 assert_match('AddListBlob.*' ..
865 'let reslist = \[1, 2] + \[3, 4].*' ..
866 '\d PUSHNR 1.*' ..
867 '\d PUSHNR 2.*' ..
868 '\d NEWLIST size 2.*' ..
869 '\d PUSHNR 3.*' ..
870 '\d PUSHNR 4.*' ..
871 '\d NEWLIST size 2.*' ..
872 '\d ADDLIST.*' ..
873 '\d STORE $.*.*' ..
874 'let resblob = 0z1122 + 0z3344.*' ..
875 '\d PUSHBLOB 0z1122.*' ..
876 '\d PUSHBLOB 0z3344.*' ..
877 '\d ADDBLOB.*' ..
878 '\d STORE $.*',
879 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100880enddef
881
882let g:aa = 'aa'
883def ConcatString(): string
884 let res = g:aa .. "bb"
885 return res
886enddef
887
888def Test_disassemble_concat()
889 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200890 assert_match('ConcatString.*' ..
891 'let res = g:aa .. "bb".*' ..
892 '\d LOADG g:aa.*' ..
893 '\d PUSHS "bb".*' ..
894 '\d 2STRING stack\[-2].*' ..
895 '\d CONCAT.*' ..
896 '\d STORE $.*',
897 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100898 assert_equal('aabb', ConcatString())
899enddef
900
901def ListIndex(): number
902 let l = [1, 2, 3]
903 let res = l[1]
904 return res
905enddef
906
907def Test_disassemble_list_index()
908 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200909 assert_match('ListIndex\_s*' ..
910 'let l = \[1, 2, 3]\_s*' ..
911 '\d PUSHNR 1\_s*' ..
912 '\d PUSHNR 2\_s*' ..
913 '\d PUSHNR 3\_s*' ..
914 '\d NEWLIST size 3\_s*' ..
915 '\d STORE $0\_s*' ..
916 'let res = l\[1]\_s*' ..
917 '\d LOAD $0\_s*' ..
918 '\d PUSHNR 1\_s*' ..
919 '\d INDEX\_s*' ..
920 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200921 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100922 assert_equal(2, ListIndex())
923enddef
924
925def DictMember(): number
926 let d = #{item: 1}
927 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200928 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100929 return res
930enddef
931
932def Test_disassemble_dict_member()
933 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200934 assert_match('DictMember\_s*' ..
935 'let d = #{item: 1}\_s*' ..
936 '\d PUSHS "item"\_s*' ..
937 '\d PUSHNR 1\_s*' ..
938 '\d NEWDICT size 1\_s*' ..
939 '\d STORE $0\_s*' ..
940 'let res = d.item\_s*' ..
941 '\d\+ LOAD $0\_s*' ..
942 '\d\+ MEMBER item\_s*' ..
943 '\d\+ STORE $1\_s*' ..
944 'res = d\["item"\]\_s*' ..
945 '\d\+ LOAD $0\_s*' ..
946 '\d\+ PUSHS "item"\_s*' ..
947 '\d\+ MEMBER\_s*' ..
948 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200949 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100950 call assert_equal(1, DictMember())
951enddef
952
953def NegateNumber(): number
954 let nr = 9
955 let plus = +nr
956 let res = -nr
957 return res
958enddef
959
960def Test_disassemble_negate_number()
961 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200962 assert_match('NegateNumber\_s*' ..
963 'let nr = 9\_s*' ..
964 '\d STORE 9 in $0\_s*' ..
965 'let plus = +nr\_s*' ..
966 '\d LOAD $0\_s*' ..
967 '\d CHECKNR\_s*' ..
968 '\d STORE $1\_s*' ..
969 'let res = -nr\_s*' ..
970 '\d LOAD $0\_s*' ..
971 '\d NEGATENR\_s*' ..
972 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200973 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100974 call assert_equal(-9, NegateNumber())
975enddef
976
977def InvertBool(): bool
978 let flag = true
979 let invert = !flag
980 let res = !!flag
981 return res
982enddef
983
984def Test_disassemble_invert_bool()
985 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200986 assert_match('InvertBool\_s*' ..
987 'let flag = true\_s*' ..
988 '\d PUSH v:true\_s*' ..
989 '\d STORE $0\_s*' ..
990 'let invert = !flag\_s*' ..
991 '\d LOAD $0\_s*' ..
992 '\d INVERT (!val)\_s*' ..
993 '\d STORE $1\_s*' ..
994 'let res = !!flag\_s*' ..
995 '\d LOAD $0\_s*' ..
996 '\d 2BOOL (!!val)\_s*' ..
997 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200998 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100999 call assert_equal(true, InvertBool())
1000enddef
1001
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001002def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001003 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001004 ['true == isFalse', 'COMPAREBOOL =='],
1005 ['true != isFalse', 'COMPAREBOOL !='],
1006 ['v:none == isNull', 'COMPARESPECIAL =='],
1007 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001008
Bram Moolenaara5565e42020-05-09 15:44:01 +02001009 ['111 == aNumber', 'COMPARENR =='],
1010 ['111 != aNumber', 'COMPARENR !='],
1011 ['111 > aNumber', 'COMPARENR >'],
1012 ['111 < aNumber', 'COMPARENR <'],
1013 ['111 >= aNumber', 'COMPARENR >='],
1014 ['111 <= aNumber', 'COMPARENR <='],
1015 ['111 =~ aNumber', 'COMPARENR =\~'],
1016 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001017
Bram Moolenaara5565e42020-05-09 15:44:01 +02001018 ['"xx" != aString', 'COMPARESTRING !='],
1019 ['"xx" > aString', 'COMPARESTRING >'],
1020 ['"xx" < aString', 'COMPARESTRING <'],
1021 ['"xx" >= aString', 'COMPARESTRING >='],
1022 ['"xx" <= aString', 'COMPARESTRING <='],
1023 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1024 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1025 ['"xx" is aString', 'COMPARESTRING is'],
1026 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001027
Bram Moolenaara5565e42020-05-09 15:44:01 +02001028 ['0z11 == aBlob', 'COMPAREBLOB =='],
1029 ['0z11 != aBlob', 'COMPAREBLOB !='],
1030 ['0z11 is aBlob', 'COMPAREBLOB is'],
1031 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001032
Bram Moolenaara5565e42020-05-09 15:44:01 +02001033 ['[1, 2] == aList', 'COMPARELIST =='],
1034 ['[1, 2] != aList', 'COMPARELIST !='],
1035 ['[1, 2] is aList', 'COMPARELIST is'],
1036 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001037
Bram Moolenaara5565e42020-05-09 15:44:01 +02001038 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1039 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1040 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1041 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001042
1043 ['{->33} == {->44}', 'COMPAREFUNC =='],
1044 ['{->33} != {->44}', 'COMPAREFUNC !='],
1045 ['{->33} is {->44}', 'COMPAREFUNC is'],
1046 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1047
1048 ['77 == g:xx', 'COMPAREANY =='],
1049 ['77 != g:xx', 'COMPAREANY !='],
1050 ['77 > g:xx', 'COMPAREANY >'],
1051 ['77 < g:xx', 'COMPAREANY <'],
1052 ['77 >= g:xx', 'COMPAREANY >='],
1053 ['77 <= g:xx', 'COMPAREANY <='],
1054 ['77 =~ g:xx', 'COMPAREANY =\~'],
1055 ['77 !~ g:xx', 'COMPAREANY !\~'],
1056 ['77 is g:xx', 'COMPAREANY is'],
1057 ['77 isnot g:xx', 'COMPAREANY isnot'],
1058 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001059 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001060 if has('float')
1061 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001062 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1063 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1064 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1065 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1066 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1067 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1068 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1069 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001070 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001071 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001072 endif
1073
1074 let nr = 1
1075 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001076 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001077 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001078 ' let isFalse = false',
1079 ' let isNull = v:null',
1080 ' let aNumber = 222',
1081 ' let aString = "yy"',
1082 ' let aBlob = 0z22',
1083 ' let aList = [3, 4]',
1084 ' let aDict = #{x: 2}',
1085 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001086 ' if ' .. case[0],
1087 ' echo 42'
1088 ' endif',
1089 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001090 source Xdisassemble
1091 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001092 assert_match('TestCase' .. nr .. '.*' ..
1093 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1094 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001095 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001096 '\d ' .. case[1] .. '.*' ..
1097 '\d JUMP_IF_FALSE -> \d\+.*',
1098 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001099
1100 nr += 1
1101 endfor
1102
Bram Moolenaar22da5592020-03-19 14:52:20 +01001103 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001104enddef
1105
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001106def Test_disassemble_compare_const()
1107 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001108 ['"xx" == "yy"', false],
1109 ['"aa" == "aa"', true],
1110 ['has("eval") ? true : false', true],
1111 ['has("asdf") ? true : false', false],
1112 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001113
1114 let nr = 1
1115 for case in cases
1116 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001117 ' if ' .. case[0],
1118 ' echo 42'
1119 ' endif',
1120 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001121 source Xdisassemble
1122 let instr = execute('disassemble TestCase' .. nr)
1123 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001124 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001125 assert_match('TestCase' .. nr .. '.*' ..
1126 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1127 '\d PUSHNR 42.*' ..
1128 '\d ECHO 1.*' ..
1129 '\d PUSHNR 0.*' ..
1130 '\d RETURN.*',
1131 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001132 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001133 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001134 assert_match('TestCase' .. nr .. '.*' ..
1135 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1136 'echo 42[ \n]*' ..
1137 'endif[ \n]*' ..
1138 '\s*\d PUSHNR 0.*' ..
1139 '\d RETURN.*',
1140 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001141 endif
1142
1143 nr += 1
1144 endfor
1145
1146 delete('Xdisassemble')
1147enddef
1148
Bram Moolenaarad39c092020-02-26 18:23:43 +01001149def s:Execute()
1150 execute 'help vim9.txt'
1151 let cmd = 'help vim9.txt'
1152 execute cmd
1153 let tag = 'vim9.txt'
1154 execute 'help ' .. tag
1155enddef
1156
1157def Test_disassemble_execute()
1158 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001159 assert_match('\<SNR>\d*_Execute\_s*' ..
1160 "execute 'help vim9.txt'\\_s*" ..
1161 '\d PUSHS "help vim9.txt"\_s*' ..
1162 '\d EXECUTE 1\_s*' ..
1163 "let cmd = 'help vim9.txt'\\_s*" ..
1164 '\d PUSHS "help vim9.txt"\_s*' ..
1165 '\d STORE $0\_s*' ..
1166 'execute cmd\_s*' ..
1167 '\d LOAD $0\_s*' ..
1168 '\d EXECUTE 1\_s*' ..
1169 "let tag = 'vim9.txt'\\_s*" ..
1170 '\d PUSHS "vim9.txt"\_s*' ..
1171 '\d STORE $1\_s*' ..
1172 "execute 'help ' .. tag\\_s*" ..
1173 '\d\+ PUSHS "help "\_s*' ..
1174 '\d\+ LOAD $1\_s*' ..
1175 '\d\+ CONCAT\_s*' ..
1176 '\d\+ EXECUTE 1\_s*' ..
1177 '\d\+ PUSHNR 0\_s*' ..
1178 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001179 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001180enddef
1181
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001182def s:Echomsg()
1183 echomsg 'some' 'message'
1184 echoerr 'went' .. 'wrong'
1185enddef
1186
1187def Test_disassemble_echomsg()
1188 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001189 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1190 "echomsg 'some' 'message'\\_s*" ..
1191 '\d PUSHS "some"\_s*' ..
1192 '\d PUSHS "message"\_s*' ..
1193 '\d ECHOMSG 2\_s*' ..
1194 "echoerr 'went' .. 'wrong'\\_s*" ..
1195 '\d PUSHS "wentwrong"\_s*' ..
1196 '\d ECHOERR 1\_s*' ..
1197 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001198 '\d RETURN',
1199 res)
1200enddef
1201
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001202def SomeStringArg(arg: string)
1203 echo arg
1204enddef
1205
1206def SomeAnyArg(arg: any)
1207 echo arg
1208enddef
1209
1210def SomeStringArgAndReturn(arg: string): string
1211 return arg
1212enddef
1213
1214def Test_display_func()
1215 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001216 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1217 '\d *echo arg.*' ..
1218 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001219 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001220
1221 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001222 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1223 '\d *echo arg\_s*' ..
1224 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001225 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001226
1227 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001228 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1229 '\d *return arg\_s*' ..
1230 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001231 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001232enddef
1233
Bram Moolenaar09689a02020-05-09 22:50:08 +02001234def Test_vim9script_forward_func()
1235 let lines =<< trim END
1236 vim9script
1237 def FuncOne(): string
1238 return FuncTwo()
1239 enddef
1240 def FuncTwo(): string
1241 return 'two'
1242 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001243 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001244 END
1245 writefile(lines, 'Xdisassemble')
1246 source Xdisassemble
1247
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001248 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001249 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1250 'return FuncTwo()\_s*' ..
1251 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001252 '\d RETURN',
1253 g:res_FuncOne)
1254
1255 delete('Xdisassemble')
1256 unlet g:res_FuncOne
1257enddef
1258
Bram Moolenaar61a89812020-05-07 16:58:17 +02001259def s:ConcatStrings(): string
1260 return 'one' .. 'two' .. 'three'
1261enddef
1262
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001263def s:ComputeConst(): number
1264 return 2 + 3 * 4 / 6 + 7
1265enddef
1266
Bram Moolenaar1c747212020-05-09 18:28:34 +02001267def s:ComputeConstParen(): number
1268 return ((2 + 4) * (8 / 2)) / (3 + 4)
1269enddef
1270
Bram Moolenaar61a89812020-05-07 16:58:17 +02001271def Test_simplify_const_expr()
1272 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001273 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1274 "return 'one' .. 'two' .. 'three'\\_s*" ..
1275 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001276 '\d RETURN',
1277 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001278
1279 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001280 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1281 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1282 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001283 '\d RETURN',
1284 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001285
1286 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001287 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1288 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1289 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001290 '\d RETURN',
1291 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001292enddef
1293
Bram Moolenaar389df252020-07-09 21:20:47 +02001294def s:CallAppend()
1295 eval "some text"->append(2)
1296enddef
1297
1298def Test_shuffle()
1299 let res = execute('disass s:CallAppend')
1300 assert_match('<SNR>\d*_CallAppend\_s*' ..
1301 'eval "some text"->append(2)\_s*' ..
1302 '\d PUSHS "some text"\_s*' ..
1303 '\d PUSHNR 2\_s*' ..
1304 '\d SHUFFLE 2 up 1\_s*' ..
1305 '\d BCALL append(argc 2)\_s*' ..
1306 '\d DROP\_s*' ..
1307 '\d PUSHNR 0\_s*' ..
1308 '\d RETURN',
1309 res)
1310enddef
1311
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001312" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker