blob: 3448d8557e1211965b6b1255cdc5dd1606b03785 [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
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200901def StringIndex(): number
902 let s = "abcd"
903 let res = s[1]
904 return res
905enddef
906
907def Test_disassemble_string_index()
908 let instr = execute('disassemble StringIndex')
909 assert_match('StringIndex\_s*' ..
910 'let s = "abcd"\_s*' ..
911 '\d PUSHS "abcd"\_s*' ..
912 '\d STORE $0\_s*' ..
913 'let res = s\[1]\_s*' ..
914 '\d LOAD $0\_s*' ..
915 '\d PUSHNR 1\_s*' ..
916 '\d STRINDEX\_s*' ..
917 '\d STORE $1\_s*',
918 instr)
919 assert_equal('b', StringIndex())
920enddef
921
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100922def ListIndex(): number
923 let l = [1, 2, 3]
924 let res = l[1]
925 return res
926enddef
927
928def Test_disassemble_list_index()
929 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200930 assert_match('ListIndex\_s*' ..
931 'let l = \[1, 2, 3]\_s*' ..
932 '\d PUSHNR 1\_s*' ..
933 '\d PUSHNR 2\_s*' ..
934 '\d PUSHNR 3\_s*' ..
935 '\d NEWLIST size 3\_s*' ..
936 '\d STORE $0\_s*' ..
937 'let res = l\[1]\_s*' ..
938 '\d LOAD $0\_s*' ..
939 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200940 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200941 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200942 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100943 assert_equal(2, ListIndex())
944enddef
945
946def DictMember(): number
947 let d = #{item: 1}
948 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200949 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100950 return res
951enddef
952
953def Test_disassemble_dict_member()
954 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200955 assert_match('DictMember\_s*' ..
956 'let d = #{item: 1}\_s*' ..
957 '\d PUSHS "item"\_s*' ..
958 '\d PUSHNR 1\_s*' ..
959 '\d NEWDICT size 1\_s*' ..
960 '\d STORE $0\_s*' ..
961 'let res = d.item\_s*' ..
962 '\d\+ LOAD $0\_s*' ..
963 '\d\+ MEMBER item\_s*' ..
964 '\d\+ STORE $1\_s*' ..
965 'res = d\["item"\]\_s*' ..
966 '\d\+ LOAD $0\_s*' ..
967 '\d\+ PUSHS "item"\_s*' ..
968 '\d\+ MEMBER\_s*' ..
969 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200970 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100971 call assert_equal(1, DictMember())
972enddef
973
974def NegateNumber(): number
975 let nr = 9
976 let plus = +nr
977 let res = -nr
978 return res
979enddef
980
981def Test_disassemble_negate_number()
982 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200983 assert_match('NegateNumber\_s*' ..
984 'let nr = 9\_s*' ..
985 '\d STORE 9 in $0\_s*' ..
986 'let plus = +nr\_s*' ..
987 '\d LOAD $0\_s*' ..
988 '\d CHECKNR\_s*' ..
989 '\d STORE $1\_s*' ..
990 'let res = -nr\_s*' ..
991 '\d LOAD $0\_s*' ..
992 '\d NEGATENR\_s*' ..
993 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200994 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100995 call assert_equal(-9, NegateNumber())
996enddef
997
998def InvertBool(): bool
999 let flag = true
1000 let invert = !flag
1001 let res = !!flag
1002 return res
1003enddef
1004
1005def Test_disassemble_invert_bool()
1006 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001007 assert_match('InvertBool\_s*' ..
1008 'let flag = true\_s*' ..
1009 '\d PUSH v:true\_s*' ..
1010 '\d STORE $0\_s*' ..
1011 'let invert = !flag\_s*' ..
1012 '\d LOAD $0\_s*' ..
1013 '\d INVERT (!val)\_s*' ..
1014 '\d STORE $1\_s*' ..
1015 'let res = !!flag\_s*' ..
1016 '\d LOAD $0\_s*' ..
1017 '\d 2BOOL (!!val)\_s*' ..
1018 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001019 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001020 call assert_equal(true, InvertBool())
1021enddef
1022
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001023def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001024 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001025 ['true == isFalse', 'COMPAREBOOL =='],
1026 ['true != isFalse', 'COMPAREBOOL !='],
1027 ['v:none == isNull', 'COMPARESPECIAL =='],
1028 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001029
Bram Moolenaara5565e42020-05-09 15:44:01 +02001030 ['111 == aNumber', 'COMPARENR =='],
1031 ['111 != aNumber', 'COMPARENR !='],
1032 ['111 > aNumber', 'COMPARENR >'],
1033 ['111 < aNumber', 'COMPARENR <'],
1034 ['111 >= aNumber', 'COMPARENR >='],
1035 ['111 <= aNumber', 'COMPARENR <='],
1036 ['111 =~ aNumber', 'COMPARENR =\~'],
1037 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001038
Bram Moolenaara5565e42020-05-09 15:44:01 +02001039 ['"xx" != aString', 'COMPARESTRING !='],
1040 ['"xx" > aString', 'COMPARESTRING >'],
1041 ['"xx" < aString', 'COMPARESTRING <'],
1042 ['"xx" >= aString', 'COMPARESTRING >='],
1043 ['"xx" <= aString', 'COMPARESTRING <='],
1044 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1045 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1046 ['"xx" is aString', 'COMPARESTRING is'],
1047 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001048
Bram Moolenaara5565e42020-05-09 15:44:01 +02001049 ['0z11 == aBlob', 'COMPAREBLOB =='],
1050 ['0z11 != aBlob', 'COMPAREBLOB !='],
1051 ['0z11 is aBlob', 'COMPAREBLOB is'],
1052 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001053
Bram Moolenaara5565e42020-05-09 15:44:01 +02001054 ['[1, 2] == aList', 'COMPARELIST =='],
1055 ['[1, 2] != aList', 'COMPARELIST !='],
1056 ['[1, 2] is aList', 'COMPARELIST is'],
1057 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001058
Bram Moolenaara5565e42020-05-09 15:44:01 +02001059 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1060 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1061 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1062 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001063
1064 ['{->33} == {->44}', 'COMPAREFUNC =='],
1065 ['{->33} != {->44}', 'COMPAREFUNC !='],
1066 ['{->33} is {->44}', 'COMPAREFUNC is'],
1067 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1068
1069 ['77 == g:xx', 'COMPAREANY =='],
1070 ['77 != g:xx', 'COMPAREANY !='],
1071 ['77 > g:xx', 'COMPAREANY >'],
1072 ['77 < g:xx', 'COMPAREANY <'],
1073 ['77 >= g:xx', 'COMPAREANY >='],
1074 ['77 <= g:xx', 'COMPAREANY <='],
1075 ['77 =~ g:xx', 'COMPAREANY =\~'],
1076 ['77 !~ g:xx', 'COMPAREANY !\~'],
1077 ['77 is g:xx', 'COMPAREANY is'],
1078 ['77 isnot g:xx', 'COMPAREANY isnot'],
1079 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001080 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001081 if has('float')
1082 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001083 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1084 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1085 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1086 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1087 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1088 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1089 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1090 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001091 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001092 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001093 endif
1094
1095 let nr = 1
1096 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001097 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001098 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001099 ' let isFalse = false',
1100 ' let isNull = v:null',
1101 ' let aNumber = 222',
1102 ' let aString = "yy"',
1103 ' let aBlob = 0z22',
1104 ' let aList = [3, 4]',
1105 ' let aDict = #{x: 2}',
1106 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001107 ' if ' .. case[0],
1108 ' echo 42'
1109 ' endif',
1110 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001111 source Xdisassemble
1112 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001113 assert_match('TestCase' .. nr .. '.*' ..
1114 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1115 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001116 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001117 '\d ' .. case[1] .. '.*' ..
1118 '\d JUMP_IF_FALSE -> \d\+.*',
1119 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001120
1121 nr += 1
1122 endfor
1123
Bram Moolenaar22da5592020-03-19 14:52:20 +01001124 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001125enddef
1126
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001127def Test_disassemble_compare_const()
1128 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001129 ['"xx" == "yy"', false],
1130 ['"aa" == "aa"', true],
1131 ['has("eval") ? true : false', true],
1132 ['has("asdf") ? true : false', false],
1133 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001134
1135 let nr = 1
1136 for case in cases
1137 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001138 ' if ' .. case[0],
1139 ' echo 42'
1140 ' endif',
1141 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001142 source Xdisassemble
1143 let instr = execute('disassemble TestCase' .. nr)
1144 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001145 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001146 assert_match('TestCase' .. nr .. '.*' ..
1147 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1148 '\d PUSHNR 42.*' ..
1149 '\d ECHO 1.*' ..
1150 '\d PUSHNR 0.*' ..
1151 '\d RETURN.*',
1152 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001153 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001154 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001155 assert_match('TestCase' .. nr .. '.*' ..
1156 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1157 'echo 42[ \n]*' ..
1158 'endif[ \n]*' ..
1159 '\s*\d PUSHNR 0.*' ..
1160 '\d RETURN.*',
1161 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001162 endif
1163
1164 nr += 1
1165 endfor
1166
1167 delete('Xdisassemble')
1168enddef
1169
Bram Moolenaarad39c092020-02-26 18:23:43 +01001170def s:Execute()
1171 execute 'help vim9.txt'
1172 let cmd = 'help vim9.txt'
1173 execute cmd
1174 let tag = 'vim9.txt'
1175 execute 'help ' .. tag
1176enddef
1177
1178def Test_disassemble_execute()
1179 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001180 assert_match('\<SNR>\d*_Execute\_s*' ..
1181 "execute 'help vim9.txt'\\_s*" ..
1182 '\d PUSHS "help vim9.txt"\_s*' ..
1183 '\d EXECUTE 1\_s*' ..
1184 "let cmd = 'help vim9.txt'\\_s*" ..
1185 '\d PUSHS "help vim9.txt"\_s*' ..
1186 '\d STORE $0\_s*' ..
1187 'execute cmd\_s*' ..
1188 '\d LOAD $0\_s*' ..
1189 '\d EXECUTE 1\_s*' ..
1190 "let tag = 'vim9.txt'\\_s*" ..
1191 '\d PUSHS "vim9.txt"\_s*' ..
1192 '\d STORE $1\_s*' ..
1193 "execute 'help ' .. tag\\_s*" ..
1194 '\d\+ PUSHS "help "\_s*' ..
1195 '\d\+ LOAD $1\_s*' ..
1196 '\d\+ CONCAT\_s*' ..
1197 '\d\+ EXECUTE 1\_s*' ..
1198 '\d\+ PUSHNR 0\_s*' ..
1199 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001200 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001201enddef
1202
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001203def s:Echomsg()
1204 echomsg 'some' 'message'
1205 echoerr 'went' .. 'wrong'
1206enddef
1207
1208def Test_disassemble_echomsg()
1209 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001210 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1211 "echomsg 'some' 'message'\\_s*" ..
1212 '\d PUSHS "some"\_s*' ..
1213 '\d PUSHS "message"\_s*' ..
1214 '\d ECHOMSG 2\_s*' ..
1215 "echoerr 'went' .. 'wrong'\\_s*" ..
1216 '\d PUSHS "wentwrong"\_s*' ..
1217 '\d ECHOERR 1\_s*' ..
1218 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001219 '\d RETURN',
1220 res)
1221enddef
1222
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001223def SomeStringArg(arg: string)
1224 echo arg
1225enddef
1226
1227def SomeAnyArg(arg: any)
1228 echo arg
1229enddef
1230
1231def SomeStringArgAndReturn(arg: string): string
1232 return arg
1233enddef
1234
1235def Test_display_func()
1236 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001237 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1238 '\d *echo arg.*' ..
1239 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001240 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001241
1242 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001243 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1244 '\d *echo arg\_s*' ..
1245 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001246 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001247
1248 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001249 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1250 '\d *return arg\_s*' ..
1251 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001252 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001253enddef
1254
Bram Moolenaar09689a02020-05-09 22:50:08 +02001255def Test_vim9script_forward_func()
1256 let lines =<< trim END
1257 vim9script
1258 def FuncOne(): string
1259 return FuncTwo()
1260 enddef
1261 def FuncTwo(): string
1262 return 'two'
1263 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001264 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001265 END
1266 writefile(lines, 'Xdisassemble')
1267 source Xdisassemble
1268
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001269 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001270 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1271 'return FuncTwo()\_s*' ..
1272 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001273 '\d RETURN',
1274 g:res_FuncOne)
1275
1276 delete('Xdisassemble')
1277 unlet g:res_FuncOne
1278enddef
1279
Bram Moolenaar61a89812020-05-07 16:58:17 +02001280def s:ConcatStrings(): string
1281 return 'one' .. 'two' .. 'three'
1282enddef
1283
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001284def s:ComputeConst(): number
1285 return 2 + 3 * 4 / 6 + 7
1286enddef
1287
Bram Moolenaar1c747212020-05-09 18:28:34 +02001288def s:ComputeConstParen(): number
1289 return ((2 + 4) * (8 / 2)) / (3 + 4)
1290enddef
1291
Bram Moolenaar61a89812020-05-07 16:58:17 +02001292def Test_simplify_const_expr()
1293 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001294 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1295 "return 'one' .. 'two' .. 'three'\\_s*" ..
1296 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001297 '\d RETURN',
1298 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001299
1300 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001301 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1302 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1303 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001304 '\d RETURN',
1305 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001306
1307 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001308 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1309 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1310 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001311 '\d RETURN',
1312 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001313enddef
1314
Bram Moolenaar389df252020-07-09 21:20:47 +02001315def s:CallAppend()
1316 eval "some text"->append(2)
1317enddef
1318
1319def Test_shuffle()
1320 let res = execute('disass s:CallAppend')
1321 assert_match('<SNR>\d*_CallAppend\_s*' ..
1322 'eval "some text"->append(2)\_s*' ..
1323 '\d PUSHS "some text"\_s*' ..
1324 '\d PUSHNR 2\_s*' ..
1325 '\d SHUFFLE 2 up 1\_s*' ..
1326 '\d BCALL append(argc 2)\_s*' ..
1327 '\d DROP\_s*' ..
1328 '\d PUSHNR 0\_s*' ..
1329 '\d RETURN',
1330 res)
1331enddef
1332
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001333" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker