blob: 3c7724df112b1a8b8fc56130e26acfea8bf60de4 [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 Moolenaar2f8ce0a2020-07-19 19:47:35 +020024 echo get(g:, "global")
Bram Moolenaard3aac292020-04-19 14:32:17 +020025 echo b:buffervar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020026 echo get(b:, "buffer")
Bram Moolenaard3aac292020-04-19 14:32:17 +020027 echo w:windowvar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020028 echo get(w:, "window")
Bram Moolenaard3aac292020-04-19 14:32:17 +020029 echo t:tabpagevar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020030 echo get(t:, "tab")
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010031 echo &tabstop
32 echo $ENVVAR
33 echo @z
34enddef
35
Bram Moolenaarf2460a32020-02-07 22:09:54 +010036def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010037 assert_fails('disass NoFunc', 'E1061:')
38 assert_fails('disass NotCompiled', 'E1062:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010039 assert_fails('disass', 'E471:')
40 assert_fails('disass [', 'E475:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +020041 assert_fails('disass 234', 'E129:')
42 assert_fails('disass <XX>foo', 'E129:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010043
44 let res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020045 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
46 'buffers.*' ..
47 ' EXEC \+buffers.*' ..
48 ' LOAD arg\[-1\].*' ..
49 ' LOAD $0.*' ..
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020050 ' LOADOPT &lines.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020051 ' LOADV v:version.*' ..
52 ' LOADS s:scriptvar from .*test_vim9_disassemble.vim.*' ..
53 ' LOADG g:globalvar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020054 'echo get(g:, "global")\_s*' ..
55 '\d\+ LOAD g:\_s*' ..
56 '\d\+ PUSHS "global"\_s*' ..
57 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020058 ' LOADB b:buffervar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020059 'echo get(b:, "buffer")\_s*' ..
60 '\d\+ LOAD b:\_s*' ..
61 '\d\+ PUSHS "buffer"\_s*' ..
62 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020063 ' LOADW w:windowvar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020064 'echo get(w:, "window")\_s*' ..
65 '\d\+ LOAD w:\_s*' ..
66 '\d\+ PUSHS "window"\_s*' ..
67 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020068 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020069 'echo get(t:, "tab")\_s*' ..
70 '\d\+ LOAD t:\_s*' ..
71 '\d\+ PUSHS "tab"\_s*' ..
72 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020073 ' LOADENV $ENVVAR.*' ..
74 ' LOADREG @z.*',
75 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010076enddef
77
Bram Moolenaarcfe435d2020-04-25 20:02:55 +020078def s:EditExpand()
79 let filename = "file"
80 let filenr = 123
81 edit the`=filename``=filenr`.txt
82enddef
83
84def Test_disassemble_exec_expr()
85 let res = execute('disass s:EditExpand')
Bram Moolenaar7c5ad342020-08-12 15:48:55 +020086 assert_match('<SNR>\d*_EditExpand\_s*' ..
87 ' let filename = "file"\_s*' ..
88 '\d PUSHS "file"\_s*' ..
89 '\d STORE $0\_s*' ..
90 ' let filenr = 123\_s*' ..
91 '\d STORE 123 in $1\_s*' ..
92 ' edit the`=filename``=filenr`.txt\_s*' ..
93 '\d PUSHS "edit the"\_s*' ..
94 '\d LOAD $0\_s*' ..
95 '\d LOAD $1\_s*' ..
96 '\d 2STRING stack\[-1\]\_s*' ..
97 '\d\+ PUSHS ".txt"\_s*' ..
98 '\d\+ EXECCONCAT 4\_s*' ..
99 '\d\+ PUSHNR 0\_s*' ..
100 '\d\+ RETURN',
101 res)
102enddef
103
104def s:YankRange()
105 norm! m[jjm]
106 :'[,']yank
107enddef
108
109def Test_disassemble_yank_range()
110 let res = execute('disass s:YankRange')
111 assert_match('<SNR>\d*_YankRange.*' ..
112 ' norm! m\[jjm\]\_s*' ..
113 '\d EXEC norm! m\[jjm\]\_s*' ..
114 ' :''\[,''\]yank\_s*' ..
115 '\d EXEC :''\[,''\]yank\_s*' ..
116 '\d PUSHNR 0\_s*' ..
Bram Moolenaarcfe435d2020-04-25 20:02:55 +0200117 '\d RETURN',
118 res)
119enddef
120
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100121def s:ScriptFuncPush()
122 let localbool = true
123 let localspec = v:none
124 let localblob = 0z1234
125 if has('float')
126 let localfloat = 1.234
127 endif
128enddef
129
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100130def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100131 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200132 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
133 'localbool = true.*' ..
134 ' PUSH v:true.*' ..
135 'localspec = v:none.*' ..
136 ' PUSH v:none.*' ..
137 'localblob = 0z1234.*' ..
138 ' PUSHBLOB 0z1234.*',
139 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100140 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200141 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
142 'localfloat = 1.234.*' ..
143 ' PUSHF 1.234.*',
144 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100145 endif
146enddef
147
148def s:ScriptFuncStore()
149 let localnr = 1
150 localnr = 2
151 let localstr = 'abc'
152 localstr = 'xyz'
153 v:char = 'abc'
154 s:scriptvar = 'sv'
155 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200156 b:buffervar = 'bv'
157 w:windowvar = 'wv'
158 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100159 &tabstop = 8
160 $ENVVAR = 'ev'
161 @z = 'rv'
162enddef
163
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100164def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100165 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200166 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
167 'let localnr = 1.*' ..
168 'localnr = 2.*' ..
169 ' STORE 2 in $0.*' ..
170 'let localstr = ''abc''.*' ..
171 'localstr = ''xyz''.*' ..
172 ' STORE $1.*' ..
173 'v:char = ''abc''.*' ..
174 'STOREV v:char.*' ..
175 's:scriptvar = ''sv''.*' ..
176 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
177 'g:globalvar = ''gv''.*' ..
178 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200179 'b:buffervar = ''bv''.*' ..
180 ' STOREB b:buffervar.*' ..
181 'w:windowvar = ''wv''.*' ..
182 ' STOREW w:windowvar.*' ..
183 't:tabpagevar = ''tv''.*' ..
184 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200185 '&tabstop = 8.*' ..
186 ' STOREOPT &tabstop.*' ..
187 '$ENVVAR = ''ev''.*' ..
188 ' STOREENV $ENVVAR.*' ..
189 '@z = ''rv''.*' ..
190 ' STOREREG @z.*',
191 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100192enddef
193
Bram Moolenaarcb790402020-05-15 20:53:00 +0200194def s:ScriptFuncStoreMember()
195 let locallist: list<number> = []
196 locallist[0] = 123
197 let localdict: dict<number> = {}
198 localdict["a"] = 456
199enddef
200
201def Test_disassemble_store_member()
202 let res = execute('disass s:ScriptFuncStoreMember')
203 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
204 'let locallist: list<number> = []\_s*' ..
205 '\d NEWLIST size 0\_s*' ..
206 '\d STORE $0\_s*' ..
207 'locallist\[0\] = 123\_s*' ..
208 '\d PUSHNR 123\_s*' ..
209 '\d PUSHNR 0\_s*' ..
210 '\d LOAD $0\_s*' ..
211 '\d STORELIST\_s*' ..
212 'let localdict: dict<number> = {}\_s*' ..
213 '\d NEWDICT size 0\_s*' ..
214 '\d STORE $1\_s*' ..
215 'localdict\["a"\] = 456\_s*' ..
216 '\d\+ PUSHNR 456\_s*' ..
217 '\d\+ PUSHS "a"\_s*' ..
218 '\d\+ LOAD $1\_s*' ..
219 '\d\+ STOREDICT\_s*' ..
220 '\d\+ PUSHNR 0\_s*' ..
221 '\d\+ RETURN',
222 res)
223enddef
224
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200225def s:ListAssign()
226 let x: string
227 let y: string
228 let l: list<any>
229 [x, y; l] = g:stringlist
230enddef
231
232def Test_disassemble_list_assign()
233 let res = execute('disass s:ListAssign')
234 assert_match('<SNR>\d*_ListAssign\_s*' ..
235 'let x: string\_s*' ..
236 '\d PUSHS "\[NULL\]"\_s*' ..
237 '\d STORE $0\_s*' ..
238 'let y: string\_s*' ..
239 '\d PUSHS "\[NULL\]"\_s*' ..
240 '\d STORE $1\_s*' ..
241 'let l: list<any>\_s*' ..
242 '\d NEWLIST size 0\_s*' ..
243 '\d STORE $2\_s*' ..
244 '\[x, y; l\] = g:stringlist\_s*' ..
245 '\d LOADG g:stringlist\_s*' ..
246 '\d CHECKTYPE list stack\[-1\]\_s*' ..
247 '\d CHECKLEN >= 2\_s*' ..
248 '\d\+ ITEM 0\_s*' ..
249 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
250 '\d\+ STORE $0\_s*' ..
251 '\d\+ ITEM 1\_s*' ..
252 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
253 '\d\+ STORE $1\_s*' ..
254 '\d\+ SLICE 2\_s*' ..
255 '\d\+ STORE $2\_s*' ..
256 '\d\+ PUSHNR 0\_s*' ..
257 '\d\+ RETURN',
258 res)
259enddef
260
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200261def s:ScriptFuncUnlet()
262 g:somevar = "value"
263 unlet g:somevar
264 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200265 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200266enddef
267
268def Test_disassemble_unlet()
269 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200270 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
271 'g:somevar = "value"\_s*' ..
272 '\d PUSHS "value"\_s*' ..
273 '\d STOREG g:somevar\_s*' ..
274 'unlet g:somevar\_s*' ..
275 '\d UNLET g:somevar\_s*' ..
276 'unlet! g:somevar\_s*' ..
277 '\d UNLET! g:somevar\_s*' ..
278 'unlet $SOMEVAR\_s*' ..
279 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200280 res)
281enddef
282
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100283def s:ScriptFuncTry()
284 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200285 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100286 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200287 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100288 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200289 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100290 endtry
291enddef
292
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100293def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100294 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200295 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
296 'try\_s*' ..
297 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
298 'echo "yes"\_s*' ..
299 '\d PUSHS "yes"\_s*' ..
300 '\d ECHO 1\_s*' ..
301 'catch /fail/\_s*' ..
302 '\d JUMP -> \d\+\_s*' ..
303 '\d PUSH v:exception\_s*' ..
304 '\d PUSHS "fail"\_s*' ..
305 '\d COMPARESTRING =\~\_s*' ..
306 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
307 '\d CATCH\_s*' ..
308 'echo "no"\_s*' ..
309 '\d\+ PUSHS "no"\_s*' ..
310 '\d\+ ECHO 1\_s*' ..
311 'finally\_s*' ..
312 'throw "end"\_s*' ..
313 '\d\+ PUSHS "end"\_s*' ..
314 '\d\+ THROW\_s*' ..
315 'endtry\_s*' ..
316 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200317 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100318enddef
319
320def s:ScriptFuncNew()
321 let ll = [1, "two", 333]
322 let dd = #{one: 1, two: "val"}
323enddef
324
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100325def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100326 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200327 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
328 'let ll = \[1, "two", 333\]\_s*' ..
329 '\d PUSHNR 1\_s*' ..
330 '\d PUSHS "two"\_s*' ..
331 '\d PUSHNR 333\_s*' ..
332 '\d NEWLIST size 3\_s*' ..
333 '\d STORE $0\_s*' ..
334 'let dd = #{one: 1, two: "val"}\_s*' ..
335 '\d PUSHS "one"\_s*' ..
336 '\d PUSHNR 1\_s*' ..
337 '\d PUSHS "two"\_s*' ..
338 '\d PUSHS "val"\_s*' ..
339 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200340 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100341enddef
342
Bram Moolenaar6e949782020-04-13 17:21:00 +0200343def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100344 echo arg
345enddef
346
347func UserFunc()
348 echo 'nothing'
349endfunc
350
351func UserFuncWithArg(arg)
352 echo a:arg
353endfunc
354
355def s:ScriptFuncCall(): string
356 changenr()
357 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100358 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100359 FuncWithArg(343)
360 ScriptFuncNew()
361 s:ScriptFuncNew()
362 UserFunc()
363 UserFuncWithArg("foo")
364 let FuncRef = function("UserFunc")
365 FuncRef()
366 let FuncRefWithArg = function("UserFuncWithArg")
367 FuncRefWithArg("bar")
368 return "yes"
369enddef
370
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100371def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100372 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200373 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
374 'changenr()\_s*' ..
375 '\d BCALL changenr(argc 0)\_s*' ..
376 '\d DROP\_s*' ..
377 'char2nr("abc")\_s*' ..
378 '\d PUSHS "abc"\_s*' ..
379 '\d BCALL char2nr(argc 1)\_s*' ..
380 '\d DROP\_s*' ..
381 'Test_disassemble_new()\_s*' ..
382 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
383 '\d DROP\_s*' ..
384 'FuncWithArg(343)\_s*' ..
385 '\d\+ PUSHNR 343\_s*' ..
386 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
387 '\d\+ DROP\_s*' ..
388 'ScriptFuncNew()\_s*' ..
389 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
390 '\d\+ DROP\_s*' ..
391 's:ScriptFuncNew()\_s*' ..
392 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
393 '\d\+ DROP\_s*' ..
394 'UserFunc()\_s*' ..
395 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
396 '\d\+ DROP\_s*' ..
397 'UserFuncWithArg("foo")\_s*' ..
398 '\d\+ PUSHS "foo"\_s*' ..
399 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
400 '\d\+ DROP\_s*' ..
401 'let FuncRef = function("UserFunc")\_s*' ..
402 '\d\+ PUSHS "UserFunc"\_s*' ..
403 '\d\+ BCALL function(argc 1)\_s*' ..
404 '\d\+ STORE $0\_s*' ..
405 'FuncRef()\_s*' ..
406 '\d\+ LOAD $\d\_s*' ..
407 '\d\+ PCALL (argc 0)\_s*' ..
408 '\d\+ DROP\_s*' ..
409 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
410 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
411 '\d\+ BCALL function(argc 1)\_s*' ..
412 '\d\+ STORE $1\_s*' ..
413 'FuncRefWithArg("bar")\_s*' ..
414 '\d\+ PUSHS "bar"\_s*' ..
415 '\d\+ LOAD $\d\_s*' ..
416 '\d\+ PCALL (argc 1)\_s*' ..
417 '\d\+ DROP\_s*' ..
418 'return "yes"\_s*' ..
419 '\d\+ PUSHS "yes"\_s*' ..
420 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200421 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100422enddef
423
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200424def s:CreateRefs()
425 let local = 'a'
426 def Append(arg: string)
427 local ..= arg
428 enddef
429 g:Append = Append
430 def Get(): string
431 return local
432 enddef
433 g:Get = Get
434enddef
435
436def Test_disassemble_closure()
437 CreateRefs()
438 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200439 assert_match('<lambda>\d\_s*' ..
440 'local ..= arg\_s*' ..
441 '\d LOADOUTER $0\_s*' ..
442 '\d LOAD arg\[-1\]\_s*' ..
443 '\d CONCAT\_s*' ..
444 '\d STOREOUTER $0\_s*' ..
445 '\d PUSHNR 0\_s*' ..
446 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200447 res)
448
449 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200450 assert_match('<lambda>\d\_s*' ..
451 'return local\_s*' ..
452 '\d LOADOUTER $0\_s*' ..
453 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200454 res)
455
456 unlet g:Append
457 unlet g:Get
458enddef
459
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100460
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200461def EchoArg(arg: string): string
462 return arg
463enddef
464def RefThis(): func
465 return function('EchoArg')
466enddef
467def s:ScriptPCall()
468 RefThis()("text")
469enddef
470
471def Test_disassemble_pcall()
472 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200473 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
474 'RefThis()("text")\_s*' ..
475 '\d DCALL RefThis(argc 0)\_s*' ..
476 '\d PUSHS "text"\_s*' ..
477 '\d PCALL top (argc 1)\_s*' ..
478 '\d PCALL end\_s*' ..
479 '\d DROP\_s*' ..
480 '\d PUSHNR 0\_s*' ..
481 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200482 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200483enddef
484
485
Bram Moolenaara26b9702020-04-18 19:53:28 +0200486def s:FuncWithForwardCall(): string
487 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100488enddef
489
490def DefinedLater(arg: string): string
491 return arg
492enddef
493
494def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200495 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200496 assert_match('FuncWithForwardCall\_s*' ..
497 'return g:DefinedLater("yes")\_s*' ..
498 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200499 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200500 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200501 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100502
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200503 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100504 assert_equal('yes', FuncWithForwardCall())
505
Bram Moolenaara26b9702020-04-18 19:53:28 +0200506 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200507 assert_match('FuncWithForwardCall\_s*' ..
508 'return g:DefinedLater("yes")\_s*' ..
509 '\d PUSHS "yes"\_s*' ..
510 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200511 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200512 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100513enddef
514
515
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100516def FuncWithDefault(arg: string = 'default'): string
517 return arg
518enddef
519
520def Test_disassemble_call_default()
521 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200522 assert_match('FuncWithDefault\_s*' ..
523 '\d PUSHS "default"\_s*' ..
524 '\d STORE arg\[-1]\_s*' ..
525 'return arg\_s*' ..
526 '\d LOAD arg\[-1]\_s*' ..
527 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200528 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100529enddef
530
531
Bram Moolenaar158906c2020-02-06 20:39:45 +0100532def HasEval()
533 if has("eval")
534 echo "yes"
535 else
536 echo "no"
537 endif
538enddef
539
540def HasNothing()
541 if has("nothing")
542 echo "yes"
543 else
544 echo "no"
545 endif
546enddef
547
548def HasSomething()
549 if has("nothing")
550 echo "nothing"
551 elseif has("something")
552 echo "something"
553 elseif has("eval")
554 echo "eval"
555 elseif has("less")
556 echo "less"
557 endif
558enddef
559
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100560def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100561 assert_equal("\nyes", execute('call HasEval()'))
562 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200563 assert_match('HasEval\_s*' ..
564 'if has("eval")\_s*' ..
565 'echo "yes"\_s*' ..
566 '\d PUSHS "yes"\_s*' ..
567 '\d ECHO 1\_s*' ..
568 'else\_s*' ..
569 'echo "no"\_s*' ..
570 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200571 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100572 assert_notmatch('JUMP', instr)
573
574 assert_equal("\nno", execute('call HasNothing()'))
575 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200576 assert_match('HasNothing\_s*' ..
577 'if has("nothing")\_s*' ..
578 'echo "yes"\_s*' ..
579 'else\_s*' ..
580 'echo "no"\_s*' ..
581 '\d PUSHS "no"\_s*' ..
582 '\d ECHO 1\_s*' ..
583 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200584 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100585 assert_notmatch('PUSHS "yes"', instr)
586 assert_notmatch('JUMP', instr)
587
588 assert_equal("\neval", execute('call HasSomething()'))
589 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200590 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200591 'if has("nothing")\_s*' ..
592 'echo "nothing"\_s*' ..
593 'elseif has("something")\_s*' ..
594 'echo "something"\_s*' ..
595 'elseif has("eval")\_s*' ..
596 'echo "eval"\_s*' ..
597 '\d PUSHS "eval"\_s*' ..
598 '\d ECHO 1\_s*' ..
599 'elseif has("less").*' ..
600 'echo "less"\_s*' ..
601 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200602 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100603 assert_notmatch('PUSHS "nothing"', instr)
604 assert_notmatch('PUSHS "something"', instr)
605 assert_notmatch('PUSHS "less"', instr)
606 assert_notmatch('JUMP', instr)
607enddef
608
Bram Moolenaarefd88552020-06-18 20:50:10 +0200609def ReturnInIf(): string
610 if g:cond
611 return "yes"
612 else
613 return "no"
614 endif
615enddef
616
617def Test_disassemble_return_in_if()
618 let instr = execute('disassemble ReturnInIf')
619 assert_match('ReturnInIf\_s*' ..
620 'if g:cond\_s*' ..
621 '0 LOADG g:cond\_s*' ..
622 '1 JUMP_IF_FALSE -> 4\_s*' ..
623 'return "yes"\_s*' ..
624 '2 PUSHS "yes"\_s*' ..
625 '3 RETURN\_s*' ..
626 'else\_s*' ..
627 ' return "no"\_s*' ..
628 '4 PUSHS "no"\_s*' ..
629 '5 RETURN$',
630 instr)
631enddef
632
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100633def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200634 let Funky1: func
635 let Funky2: func = function("len")
636 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100637enddef
638
639def Test_disassemble_function()
640 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200641 assert_match('WithFunc\_s*' ..
642 'let Funky1: func\_s*' ..
643 '0 PUSHFUNC "\[none]"\_s*' ..
644 '1 STORE $0\_s*' ..
645 'let Funky2: func = function("len")\_s*' ..
646 '2 PUSHS "len"\_s*' ..
647 '3 BCALL function(argc 1)\_s*' ..
648 '4 STORE $1\_s*' ..
649 'let Party2: func = funcref("UserFunc")\_s*' ..
650 '\d PUSHS "UserFunc"\_s*' ..
651 '\d BCALL funcref(argc 1)\_s*' ..
652 '\d STORE $2\_s*' ..
653 '\d PUSHNR 0\_s*' ..
654 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200655 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100656enddef
657
658if has('channel')
659 def WithChannel()
660 let job1: job
661 let job2: job = job_start("donothing")
662 let chan1: channel
663 enddef
664endif
665
666def Test_disassemble_channel()
667 CheckFeature channel
668
669 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200670 assert_match('WithChannel\_s*' ..
671 'let job1: job\_s*' ..
672 '\d PUSHJOB "no process"\_s*' ..
673 '\d STORE $0\_s*' ..
674 'let job2: job = job_start("donothing")\_s*' ..
675 '\d PUSHS "donothing"\_s*' ..
676 '\d BCALL job_start(argc 1)\_s*' ..
677 '\d STORE $1\_s*' ..
678 'let chan1: channel\_s*' ..
679 '\d PUSHCHANNEL 0\_s*' ..
680 '\d STORE $2\_s*' ..
681 '\d PUSHNR 0\_s*' ..
682 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200683 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100684enddef
685
Bram Moolenaar777770f2020-02-06 21:27:08 +0100686def WithLambda(): string
687 let F = {a -> "X" .. a .. "X"}
688 return F("x")
689enddef
690
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100691def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100692 assert_equal("XxX", WithLambda())
693 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200694 assert_match('WithLambda\_s*' ..
695 'let F = {a -> "X" .. a .. "X"}\_s*' ..
696 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
697 '\d STORE $0\_s*' ..
698 'return F("x")\_s*' ..
699 '\d PUSHS "x"\_s*' ..
700 '\d LOAD $0\_s*' ..
701 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200702 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200703 instr)
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200704
705 let name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
706 instr = execute('disassemble ' .. name)
707 assert_match('<lambda>\d\+\_s*' ..
708 'return "X" .. a .. "X"\_s*' ..
709 '\d PUSHS "X"\_s*' ..
710 '\d LOAD arg\[-1\]\_s*' ..
711 '\d 2STRING stack\[-1\]\_s*' ..
712 '\d CONCAT\_s*' ..
713 '\d PUSHS "X"\_s*' ..
714 '\d CONCAT\_s*' ..
715 '\d RETURN',
716 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100717enddef
718
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200719def NestedOuter()
720 def g:Inner()
721 echomsg "inner"
722 enddef
723enddef
724
725def Test_nested_func()
726 let instr = execute('disassemble NestedOuter')
727 assert_match('NestedOuter\_s*' ..
728 'def g:Inner()\_s*' ..
729 'echomsg "inner"\_s*' ..
730 'enddef\_s*' ..
731 '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
732 '\d PUSHNR 0\_s*' ..
733 '\d RETURN',
734 instr)
735enddef
736
Bram Moolenaar6e949782020-04-13 17:21:00 +0200737def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100738 if arg == 1 && arg != 2 || arg == 4
739 return 'yes'
740 endif
741 return 'no'
742enddef
743
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100744def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100745 assert_equal("yes", AndOr(1))
746 assert_equal("no", AndOr(2))
747 assert_equal("yes", AndOr(4))
748 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200749 assert_match('AndOr\_s*' ..
750 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
751 '\d LOAD arg\[-1]\_s*' ..
752 '\d PUSHNR 1\_s*' ..
753 '\d COMPAREANY ==\_s*' ..
754 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
755 '\d LOAD arg\[-1]\_s*' ..
756 '\d PUSHNR 2\_s*' ..
757 '\d COMPAREANY !=\_s*' ..
758 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
759 '\d LOAD arg\[-1]\_s*' ..
760 '\d\+ PUSHNR 4\_s*' ..
761 '\d\+ COMPAREANY ==\_s*' ..
762 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200763 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100764enddef
765
Bram Moolenaar04d05222020-02-06 22:06:54 +0100766def ForLoop(): list<number>
767 let res: list<number>
768 for i in range(3)
769 res->add(i)
770 endfor
771 return res
772enddef
773
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100774def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100775 assert_equal([0, 1, 2], ForLoop())
776 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200777 assert_match('ForLoop\_s*' ..
778 'let res: list<number>\_s*' ..
779 '\d NEWLIST size 0\_s*' ..
780 '\d STORE $0\_s*' ..
781 'for i in range(3)\_s*' ..
782 '\d STORE -1 in $1\_s*' ..
783 '\d PUSHNR 3\_s*' ..
784 '\d BCALL range(argc 1)\_s*' ..
785 '\d FOR $1 -> \d\+\_s*' ..
786 '\d STORE $2\_s*' ..
787 'res->add(i)\_s*' ..
788 '\d LOAD $0\_s*' ..
789 '\d LOAD $2\_s*' ..
790 '\d\+ BCALL add(argc 2)\_s*' ..
791 '\d\+ DROP\_s*' ..
792 'endfor\_s*' ..
793 '\d\+ JUMP -> \d\+\_s*' ..
794 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200795 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100796enddef
797
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200798def ForLoopEval(): string
799 let res = ""
800 for str in eval('["one", "two"]')
801 res ..= str
802 endfor
803 return res
804enddef
805
806def Test_disassemble_for_loop_eval()
807 assert_equal('onetwo', ForLoopEval())
808 let instr = execute('disassemble ForLoopEval')
809 assert_match('ForLoopEval\_s*' ..
810 'let res = ""\_s*' ..
811 '\d PUSHS ""\_s*' ..
812 '\d STORE $0\_s*' ..
813 'for str in eval(''\["one", "two"\]'')\_s*' ..
814 '\d STORE -1 in $1\_s*' ..
815 '\d PUSHS "\["one", "two"\]"\_s*' ..
816 '\d BCALL eval(argc 1)\_s*' ..
817 '\d CHECKTYPE list stack\[-1\]\_s*' ..
818 '\d FOR $1 -> \d\+\_s*' ..
819 '\d STORE $2\_s*' ..
820 'res ..= str\_s*' ..
821 '\d\+ LOAD $0\_s*' ..
822 '\d\+ LOAD $2\_s*' ..
823 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
824 '\d\+ CONCAT\_s*' ..
825 '\d\+ STORE $0\_s*' ..
826 'endfor\_s*' ..
827 '\d\+ JUMP -> 6\_s*' ..
828 '\d\+ DROP\_s*' ..
829 'return res\_s*' ..
830 '\d\+ LOAD $0\_s*' ..
831 '\d\+ RETURN',
832 instr)
833enddef
834
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100835let g:number = 42
836
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200837def TypeCast()
838 let l: list<number> = [23, <number>g:number]
839enddef
840
841def Test_disassemble_typecast()
842 let instr = execute('disassemble TypeCast')
843 assert_match('TypeCast.*' ..
844 'let l: list<number> = \[23, <number>g:number\].*' ..
845 '\d PUSHNR 23\_s*' ..
846 '\d LOADG g:number\_s*' ..
847 '\d CHECKTYPE number stack\[-1\]\_s*' ..
848 '\d NEWLIST size 2\_s*' ..
849 '\d STORE $0\_s*' ..
850 '\d PUSHNR 0\_s*' ..
851 '\d RETURN\_s*',
852 instr)
853enddef
854
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100855def Computing()
856 let nr = 3
857 let nrres = nr + 7
858 nrres = nr - 7
859 nrres = nr * 7
860 nrres = nr / 7
861 nrres = nr % 7
862
863 let anyres = g:number + 7
864 anyres = g:number - 7
865 anyres = g:number * 7
866 anyres = g:number / 7
867 anyres = g:number % 7
868
869 if has('float')
870 let fl = 3.0
871 let flres = fl + 7.0
872 flres = fl - 7.0
873 flres = fl * 7.0
874 flres = fl / 7.0
875 endif
876enddef
877
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100878def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100879 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200880 assert_match('Computing.*' ..
881 'let nr = 3.*' ..
882 '\d STORE 3 in $0.*' ..
883 'let nrres = nr + 7.*' ..
884 '\d LOAD $0.*' ..
885 '\d PUSHNR 7.*' ..
886 '\d OPNR +.*' ..
887 '\d STORE $1.*' ..
888 'nrres = nr - 7.*' ..
889 '\d OPNR -.*' ..
890 'nrres = nr \* 7.*' ..
891 '\d OPNR \*.*' ..
892 'nrres = nr / 7.*' ..
893 '\d OPNR /.*' ..
894 'nrres = nr % 7.*' ..
895 '\d OPNR %.*' ..
896 'let anyres = g:number + 7.*' ..
897 '\d LOADG g:number.*' ..
898 '\d PUSHNR 7.*' ..
899 '\d OPANY +.*' ..
900 '\d STORE $2.*' ..
901 'anyres = g:number - 7.*' ..
902 '\d OPANY -.*' ..
903 'anyres = g:number \* 7.*' ..
904 '\d OPANY \*.*' ..
905 'anyres = g:number / 7.*' ..
906 '\d OPANY /.*' ..
907 'anyres = g:number % 7.*' ..
908 '\d OPANY %.*',
909 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100910 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200911 assert_match('Computing.*' ..
912 'let fl = 3.0.*' ..
913 '\d PUSHF 3.0.*' ..
914 '\d STORE $3.*' ..
915 'let flres = fl + 7.0.*' ..
916 '\d LOAD $3.*' ..
917 '\d PUSHF 7.0.*' ..
918 '\d OPFLOAT +.*' ..
919 '\d STORE $4.*' ..
920 'flres = fl - 7.0.*' ..
921 '\d OPFLOAT -.*' ..
922 'flres = fl \* 7.0.*' ..
923 '\d OPFLOAT \*.*' ..
924 'flres = fl / 7.0.*' ..
925 '\d OPFLOAT /.*',
926 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100927 endif
928enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100929
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100930def AddListBlob()
931 let reslist = [1, 2] + [3, 4]
932 let resblob = 0z1122 + 0z3344
933enddef
934
935def Test_disassemble_add_list_blob()
936 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200937 assert_match('AddListBlob.*' ..
938 'let reslist = \[1, 2] + \[3, 4].*' ..
939 '\d PUSHNR 1.*' ..
940 '\d PUSHNR 2.*' ..
941 '\d NEWLIST size 2.*' ..
942 '\d PUSHNR 3.*' ..
943 '\d PUSHNR 4.*' ..
944 '\d NEWLIST size 2.*' ..
945 '\d ADDLIST.*' ..
946 '\d STORE $.*.*' ..
947 'let resblob = 0z1122 + 0z3344.*' ..
948 '\d PUSHBLOB 0z1122.*' ..
949 '\d PUSHBLOB 0z3344.*' ..
950 '\d ADDBLOB.*' ..
951 '\d STORE $.*',
952 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100953enddef
954
955let g:aa = 'aa'
956def ConcatString(): string
957 let res = g:aa .. "bb"
958 return res
959enddef
960
961def Test_disassemble_concat()
962 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200963 assert_match('ConcatString.*' ..
964 'let res = g:aa .. "bb".*' ..
965 '\d LOADG g:aa.*' ..
966 '\d PUSHS "bb".*' ..
967 '\d 2STRING stack\[-2].*' ..
968 '\d CONCAT.*' ..
969 '\d STORE $.*',
970 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100971 assert_equal('aabb', ConcatString())
972enddef
973
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200974def StringIndex(): number
975 let s = "abcd"
976 let res = s[1]
977 return res
978enddef
979
980def Test_disassemble_string_index()
981 let instr = execute('disassemble StringIndex')
982 assert_match('StringIndex\_s*' ..
983 'let s = "abcd"\_s*' ..
984 '\d PUSHS "abcd"\_s*' ..
985 '\d STORE $0\_s*' ..
986 'let res = s\[1]\_s*' ..
987 '\d LOAD $0\_s*' ..
988 '\d PUSHNR 1\_s*' ..
989 '\d STRINDEX\_s*' ..
990 '\d STORE $1\_s*',
991 instr)
992 assert_equal('b', StringIndex())
993enddef
994
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100995def ListIndex(): number
996 let l = [1, 2, 3]
997 let res = l[1]
998 return res
999enddef
1000
1001def Test_disassemble_list_index()
1002 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001003 assert_match('ListIndex\_s*' ..
1004 'let l = \[1, 2, 3]\_s*' ..
1005 '\d PUSHNR 1\_s*' ..
1006 '\d PUSHNR 2\_s*' ..
1007 '\d PUSHNR 3\_s*' ..
1008 '\d NEWLIST size 3\_s*' ..
1009 '\d STORE $0\_s*' ..
1010 'let res = l\[1]\_s*' ..
1011 '\d LOAD $0\_s*' ..
1012 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001013 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001014 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001015 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001016 assert_equal(2, ListIndex())
1017enddef
1018
1019def DictMember(): number
1020 let d = #{item: 1}
1021 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001022 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001023 return res
1024enddef
1025
1026def Test_disassemble_dict_member()
1027 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001028 assert_match('DictMember\_s*' ..
1029 'let d = #{item: 1}\_s*' ..
1030 '\d PUSHS "item"\_s*' ..
1031 '\d PUSHNR 1\_s*' ..
1032 '\d NEWDICT size 1\_s*' ..
1033 '\d STORE $0\_s*' ..
1034 'let res = d.item\_s*' ..
1035 '\d\+ LOAD $0\_s*' ..
1036 '\d\+ MEMBER item\_s*' ..
1037 '\d\+ STORE $1\_s*' ..
1038 'res = d\["item"\]\_s*' ..
1039 '\d\+ LOAD $0\_s*' ..
1040 '\d\+ PUSHS "item"\_s*' ..
1041 '\d\+ MEMBER\_s*' ..
1042 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001043 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001044 call assert_equal(1, DictMember())
1045enddef
1046
1047def NegateNumber(): number
1048 let nr = 9
1049 let plus = +nr
1050 let res = -nr
1051 return res
1052enddef
1053
1054def Test_disassemble_negate_number()
1055 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001056 assert_match('NegateNumber\_s*' ..
1057 'let nr = 9\_s*' ..
1058 '\d STORE 9 in $0\_s*' ..
1059 'let plus = +nr\_s*' ..
1060 '\d LOAD $0\_s*' ..
1061 '\d CHECKNR\_s*' ..
1062 '\d STORE $1\_s*' ..
1063 'let res = -nr\_s*' ..
1064 '\d LOAD $0\_s*' ..
1065 '\d NEGATENR\_s*' ..
1066 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001067 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001068 call assert_equal(-9, NegateNumber())
1069enddef
1070
1071def InvertBool(): bool
1072 let flag = true
1073 let invert = !flag
1074 let res = !!flag
1075 return res
1076enddef
1077
1078def Test_disassemble_invert_bool()
1079 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001080 assert_match('InvertBool\_s*' ..
1081 'let flag = true\_s*' ..
1082 '\d PUSH v:true\_s*' ..
1083 '\d STORE $0\_s*' ..
1084 'let invert = !flag\_s*' ..
1085 '\d LOAD $0\_s*' ..
1086 '\d INVERT (!val)\_s*' ..
1087 '\d STORE $1\_s*' ..
1088 'let res = !!flag\_s*' ..
1089 '\d LOAD $0\_s*' ..
1090 '\d 2BOOL (!!val)\_s*' ..
1091 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001092 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001093 call assert_equal(true, InvertBool())
1094enddef
1095
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001096def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001097 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001098 ['true == isFalse', 'COMPAREBOOL =='],
1099 ['true != isFalse', 'COMPAREBOOL !='],
1100 ['v:none == isNull', 'COMPARESPECIAL =='],
1101 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001102
Bram Moolenaara5565e42020-05-09 15:44:01 +02001103 ['111 == aNumber', 'COMPARENR =='],
1104 ['111 != aNumber', 'COMPARENR !='],
1105 ['111 > aNumber', 'COMPARENR >'],
1106 ['111 < aNumber', 'COMPARENR <'],
1107 ['111 >= aNumber', 'COMPARENR >='],
1108 ['111 <= aNumber', 'COMPARENR <='],
1109 ['111 =~ aNumber', 'COMPARENR =\~'],
1110 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001111
Bram Moolenaara5565e42020-05-09 15:44:01 +02001112 ['"xx" != aString', 'COMPARESTRING !='],
1113 ['"xx" > aString', 'COMPARESTRING >'],
1114 ['"xx" < aString', 'COMPARESTRING <'],
1115 ['"xx" >= aString', 'COMPARESTRING >='],
1116 ['"xx" <= aString', 'COMPARESTRING <='],
1117 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1118 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1119 ['"xx" is aString', 'COMPARESTRING is'],
1120 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001121
Bram Moolenaara5565e42020-05-09 15:44:01 +02001122 ['0z11 == aBlob', 'COMPAREBLOB =='],
1123 ['0z11 != aBlob', 'COMPAREBLOB !='],
1124 ['0z11 is aBlob', 'COMPAREBLOB is'],
1125 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001126
Bram Moolenaara5565e42020-05-09 15:44:01 +02001127 ['[1, 2] == aList', 'COMPARELIST =='],
1128 ['[1, 2] != aList', 'COMPARELIST !='],
1129 ['[1, 2] is aList', 'COMPARELIST is'],
1130 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001131
Bram Moolenaara5565e42020-05-09 15:44:01 +02001132 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1133 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1134 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1135 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001136
1137 ['{->33} == {->44}', 'COMPAREFUNC =='],
1138 ['{->33} != {->44}', 'COMPAREFUNC !='],
1139 ['{->33} is {->44}', 'COMPAREFUNC is'],
1140 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1141
1142 ['77 == g:xx', 'COMPAREANY =='],
1143 ['77 != g:xx', 'COMPAREANY !='],
1144 ['77 > g:xx', 'COMPAREANY >'],
1145 ['77 < g:xx', 'COMPAREANY <'],
1146 ['77 >= g:xx', 'COMPAREANY >='],
1147 ['77 <= g:xx', 'COMPAREANY <='],
1148 ['77 =~ g:xx', 'COMPAREANY =\~'],
1149 ['77 !~ g:xx', 'COMPAREANY !\~'],
1150 ['77 is g:xx', 'COMPAREANY is'],
1151 ['77 isnot g:xx', 'COMPAREANY isnot'],
1152 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001153 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001154 if has('float')
1155 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001156 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1157 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1158 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1159 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1160 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1161 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1162 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1163 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001164 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001165 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001166 endif
1167
1168 let nr = 1
1169 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001170 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001171 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001172 ' let isFalse = false',
1173 ' let isNull = v:null',
1174 ' let aNumber = 222',
1175 ' let aString = "yy"',
1176 ' let aBlob = 0z22',
1177 ' let aList = [3, 4]',
1178 ' let aDict = #{x: 2}',
1179 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001180 ' if ' .. case[0],
1181 ' echo 42'
1182 ' endif',
1183 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001184 source Xdisassemble
1185 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001186 assert_match('TestCase' .. nr .. '.*' ..
1187 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1188 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001189 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001190 '\d ' .. case[1] .. '.*' ..
1191 '\d JUMP_IF_FALSE -> \d\+.*',
1192 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001193
1194 nr += 1
1195 endfor
1196
Bram Moolenaar22da5592020-03-19 14:52:20 +01001197 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001198enddef
1199
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001200def Test_disassemble_compare_const()
1201 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001202 ['"xx" == "yy"', false],
1203 ['"aa" == "aa"', true],
1204 ['has("eval") ? true : false', true],
1205 ['has("asdf") ? true : false', false],
1206 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001207
1208 let nr = 1
1209 for case in cases
1210 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001211 ' if ' .. case[0],
1212 ' echo 42'
1213 ' endif',
1214 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001215 source Xdisassemble
1216 let instr = execute('disassemble TestCase' .. nr)
1217 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001218 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001219 assert_match('TestCase' .. nr .. '.*' ..
1220 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1221 '\d PUSHNR 42.*' ..
1222 '\d ECHO 1.*' ..
1223 '\d PUSHNR 0.*' ..
1224 '\d RETURN.*',
1225 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001226 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001227 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001228 assert_match('TestCase' .. nr .. '.*' ..
1229 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1230 'echo 42[ \n]*' ..
1231 'endif[ \n]*' ..
1232 '\s*\d PUSHNR 0.*' ..
1233 '\d RETURN.*',
1234 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001235 endif
1236
1237 nr += 1
1238 endfor
1239
1240 delete('Xdisassemble')
1241enddef
1242
Bram Moolenaarad39c092020-02-26 18:23:43 +01001243def s:Execute()
1244 execute 'help vim9.txt'
1245 let cmd = 'help vim9.txt'
1246 execute cmd
1247 let tag = 'vim9.txt'
1248 execute 'help ' .. tag
1249enddef
1250
1251def Test_disassemble_execute()
1252 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001253 assert_match('\<SNR>\d*_Execute\_s*' ..
1254 "execute 'help vim9.txt'\\_s*" ..
1255 '\d PUSHS "help vim9.txt"\_s*' ..
1256 '\d EXECUTE 1\_s*' ..
1257 "let cmd = 'help vim9.txt'\\_s*" ..
1258 '\d PUSHS "help vim9.txt"\_s*' ..
1259 '\d STORE $0\_s*' ..
1260 'execute cmd\_s*' ..
1261 '\d LOAD $0\_s*' ..
1262 '\d EXECUTE 1\_s*' ..
1263 "let tag = 'vim9.txt'\\_s*" ..
1264 '\d PUSHS "vim9.txt"\_s*' ..
1265 '\d STORE $1\_s*' ..
1266 "execute 'help ' .. tag\\_s*" ..
1267 '\d\+ PUSHS "help "\_s*' ..
1268 '\d\+ LOAD $1\_s*' ..
1269 '\d\+ CONCAT\_s*' ..
1270 '\d\+ EXECUTE 1\_s*' ..
1271 '\d\+ PUSHNR 0\_s*' ..
1272 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001273 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001274enddef
1275
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001276def s:Echomsg()
1277 echomsg 'some' 'message'
1278 echoerr 'went' .. 'wrong'
1279enddef
1280
1281def Test_disassemble_echomsg()
1282 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001283 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1284 "echomsg 'some' 'message'\\_s*" ..
1285 '\d PUSHS "some"\_s*' ..
1286 '\d PUSHS "message"\_s*' ..
1287 '\d ECHOMSG 2\_s*' ..
1288 "echoerr 'went' .. 'wrong'\\_s*" ..
1289 '\d PUSHS "wentwrong"\_s*' ..
1290 '\d ECHOERR 1\_s*' ..
1291 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001292 '\d RETURN',
1293 res)
1294enddef
1295
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001296def SomeStringArg(arg: string)
1297 echo arg
1298enddef
1299
1300def SomeAnyArg(arg: any)
1301 echo arg
1302enddef
1303
1304def SomeStringArgAndReturn(arg: string): string
1305 return arg
1306enddef
1307
1308def Test_display_func()
1309 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001310 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1311 '\d *echo arg.*' ..
1312 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001313 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001314
1315 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001316 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1317 '\d *echo arg\_s*' ..
1318 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001319 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001320
1321 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001322 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1323 '\d *return arg\_s*' ..
1324 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001325 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001326enddef
1327
Bram Moolenaar09689a02020-05-09 22:50:08 +02001328def Test_vim9script_forward_func()
1329 let lines =<< trim END
1330 vim9script
1331 def FuncOne(): string
1332 return FuncTwo()
1333 enddef
1334 def FuncTwo(): string
1335 return 'two'
1336 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001337 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001338 END
1339 writefile(lines, 'Xdisassemble')
1340 source Xdisassemble
1341
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001342 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001343 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1344 'return FuncTwo()\_s*' ..
1345 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001346 '\d RETURN',
1347 g:res_FuncOne)
1348
1349 delete('Xdisassemble')
1350 unlet g:res_FuncOne
1351enddef
1352
Bram Moolenaar61a89812020-05-07 16:58:17 +02001353def s:ConcatStrings(): string
1354 return 'one' .. 'two' .. 'three'
1355enddef
1356
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001357def s:ComputeConst(): number
1358 return 2 + 3 * 4 / 6 + 7
1359enddef
1360
Bram Moolenaar1c747212020-05-09 18:28:34 +02001361def s:ComputeConstParen(): number
1362 return ((2 + 4) * (8 / 2)) / (3 + 4)
1363enddef
1364
Bram Moolenaar61a89812020-05-07 16:58:17 +02001365def Test_simplify_const_expr()
1366 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001367 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1368 "return 'one' .. 'two' .. 'three'\\_s*" ..
1369 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001370 '\d RETURN',
1371 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001372
1373 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001374 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1375 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1376 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001377 '\d RETURN',
1378 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001379
1380 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001381 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1382 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1383 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001384 '\d RETURN',
1385 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001386enddef
1387
Bram Moolenaar389df252020-07-09 21:20:47 +02001388def s:CallAppend()
1389 eval "some text"->append(2)
1390enddef
1391
1392def Test_shuffle()
1393 let res = execute('disass s:CallAppend')
1394 assert_match('<SNR>\d*_CallAppend\_s*' ..
1395 'eval "some text"->append(2)\_s*' ..
1396 '\d PUSHS "some text"\_s*' ..
1397 '\d PUSHNR 2\_s*' ..
1398 '\d SHUFFLE 2 up 1\_s*' ..
1399 '\d BCALL append(argc 2)\_s*' ..
1400 '\d DROP\_s*' ..
1401 '\d PUSHNR 0\_s*' ..
1402 '\d RETURN',
1403 res)
1404enddef
1405
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001406" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker