blob: 5d9447d8ca11a5c16a9904d46a5ccd7210d1a48c [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')
86 assert_match('<SNR>\d*_EditExpand.*' ..
87 ' let filename = "file".*' ..
88 '\d PUSHS "file".*' ..
89 '\d STORE $0.*' ..
90 ' let filenr = 123.*' ..
91 '\d STORE 123 in $1.*' ..
92 ' edit the`=filename``=filenr`.txt.*' ..
93 '\d PUSHS "edit the".*' ..
94 '\d LOAD $0.*' ..
95 '\d LOAD $1.*' ..
96 '\d 2STRING stack\[-1\].*' ..
97 '\d PUSHS ".txt".*' ..
98 '\d EXECCONCAT 4.*' ..
99 '\d PUSHNR 0.*' ..
100 '\d RETURN',
101 res)
102enddef
103
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100104def s:ScriptFuncPush()
105 let localbool = true
106 let localspec = v:none
107 let localblob = 0z1234
108 if has('float')
109 let localfloat = 1.234
110 endif
111enddef
112
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100113def Test_disassemble_push()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100114 let res = execute('disass s:ScriptFuncPush')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200115 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
116 'localbool = true.*' ..
117 ' PUSH v:true.*' ..
118 'localspec = v:none.*' ..
119 ' PUSH v:none.*' ..
120 'localblob = 0z1234.*' ..
121 ' PUSHBLOB 0z1234.*',
122 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100123 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200124 assert_match('<SNR>\d*_ScriptFuncPush.*' ..
125 'localfloat = 1.234.*' ..
126 ' PUSHF 1.234.*',
127 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100128 endif
129enddef
130
131def s:ScriptFuncStore()
132 let localnr = 1
133 localnr = 2
134 let localstr = 'abc'
135 localstr = 'xyz'
136 v:char = 'abc'
137 s:scriptvar = 'sv'
138 g:globalvar = 'gv'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200139 b:buffervar = 'bv'
140 w:windowvar = 'wv'
141 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100142 &tabstop = 8
143 $ENVVAR = 'ev'
144 @z = 'rv'
145enddef
146
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100147def Test_disassemble_store()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100148 let res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200149 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
150 'let localnr = 1.*' ..
151 'localnr = 2.*' ..
152 ' STORE 2 in $0.*' ..
153 'let localstr = ''abc''.*' ..
154 'localstr = ''xyz''.*' ..
155 ' STORE $1.*' ..
156 'v:char = ''abc''.*' ..
157 'STOREV v:char.*' ..
158 's:scriptvar = ''sv''.*' ..
159 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
160 'g:globalvar = ''gv''.*' ..
161 ' STOREG g:globalvar.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200162 'b:buffervar = ''bv''.*' ..
163 ' STOREB b:buffervar.*' ..
164 'w:windowvar = ''wv''.*' ..
165 ' STOREW w:windowvar.*' ..
166 't:tabpagevar = ''tv''.*' ..
167 ' STORET t:tabpagevar.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200168 '&tabstop = 8.*' ..
169 ' STOREOPT &tabstop.*' ..
170 '$ENVVAR = ''ev''.*' ..
171 ' STOREENV $ENVVAR.*' ..
172 '@z = ''rv''.*' ..
173 ' STOREREG @z.*',
174 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100175enddef
176
Bram Moolenaarcb790402020-05-15 20:53:00 +0200177def s:ScriptFuncStoreMember()
178 let locallist: list<number> = []
179 locallist[0] = 123
180 let localdict: dict<number> = {}
181 localdict["a"] = 456
182enddef
183
184def Test_disassemble_store_member()
185 let res = execute('disass s:ScriptFuncStoreMember')
186 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
187 'let locallist: list<number> = []\_s*' ..
188 '\d NEWLIST size 0\_s*' ..
189 '\d STORE $0\_s*' ..
190 'locallist\[0\] = 123\_s*' ..
191 '\d PUSHNR 123\_s*' ..
192 '\d PUSHNR 0\_s*' ..
193 '\d LOAD $0\_s*' ..
194 '\d STORELIST\_s*' ..
195 'let localdict: dict<number> = {}\_s*' ..
196 '\d NEWDICT size 0\_s*' ..
197 '\d STORE $1\_s*' ..
198 'localdict\["a"\] = 456\_s*' ..
199 '\d\+ PUSHNR 456\_s*' ..
200 '\d\+ PUSHS "a"\_s*' ..
201 '\d\+ LOAD $1\_s*' ..
202 '\d\+ STOREDICT\_s*' ..
203 '\d\+ PUSHNR 0\_s*' ..
204 '\d\+ RETURN',
205 res)
206enddef
207
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200208def s:ListAssign()
209 let x: string
210 let y: string
211 let l: list<any>
212 [x, y; l] = g:stringlist
213enddef
214
215def Test_disassemble_list_assign()
216 let res = execute('disass s:ListAssign')
217 assert_match('<SNR>\d*_ListAssign\_s*' ..
218 'let x: string\_s*' ..
219 '\d PUSHS "\[NULL\]"\_s*' ..
220 '\d STORE $0\_s*' ..
221 'let y: string\_s*' ..
222 '\d PUSHS "\[NULL\]"\_s*' ..
223 '\d STORE $1\_s*' ..
224 'let l: list<any>\_s*' ..
225 '\d NEWLIST size 0\_s*' ..
226 '\d STORE $2\_s*' ..
227 '\[x, y; l\] = g:stringlist\_s*' ..
228 '\d LOADG g:stringlist\_s*' ..
229 '\d CHECKTYPE list stack\[-1\]\_s*' ..
230 '\d CHECKLEN >= 2\_s*' ..
231 '\d\+ ITEM 0\_s*' ..
232 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
233 '\d\+ STORE $0\_s*' ..
234 '\d\+ ITEM 1\_s*' ..
235 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
236 '\d\+ STORE $1\_s*' ..
237 '\d\+ SLICE 2\_s*' ..
238 '\d\+ STORE $2\_s*' ..
239 '\d\+ PUSHNR 0\_s*' ..
240 '\d\+ RETURN',
241 res)
242enddef
243
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200244def s:ScriptFuncUnlet()
245 g:somevar = "value"
246 unlet g:somevar
247 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200248 unlet $SOMEVAR
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200249enddef
250
251def Test_disassemble_unlet()
252 let res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200253 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
254 'g:somevar = "value"\_s*' ..
255 '\d PUSHS "value"\_s*' ..
256 '\d STOREG g:somevar\_s*' ..
257 'unlet g:somevar\_s*' ..
258 '\d UNLET g:somevar\_s*' ..
259 'unlet! g:somevar\_s*' ..
260 '\d UNLET! g:somevar\_s*' ..
261 'unlet $SOMEVAR\_s*' ..
262 '\d UNLETENV $SOMEVAR\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200263 res)
264enddef
265
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100266def s:ScriptFuncTry()
267 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200268 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100269 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200270 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100271 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200272 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100273 endtry
274enddef
275
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100276def Test_disassemble_try()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100277 let res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200278 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
279 'try\_s*' ..
280 '\d TRY catch -> \d\+, finally -> \d\+\_s*' ..
281 'echo "yes"\_s*' ..
282 '\d PUSHS "yes"\_s*' ..
283 '\d ECHO 1\_s*' ..
284 'catch /fail/\_s*' ..
285 '\d JUMP -> \d\+\_s*' ..
286 '\d PUSH v:exception\_s*' ..
287 '\d PUSHS "fail"\_s*' ..
288 '\d COMPARESTRING =\~\_s*' ..
289 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
290 '\d CATCH\_s*' ..
291 'echo "no"\_s*' ..
292 '\d\+ PUSHS "no"\_s*' ..
293 '\d\+ ECHO 1\_s*' ..
294 'finally\_s*' ..
295 'throw "end"\_s*' ..
296 '\d\+ PUSHS "end"\_s*' ..
297 '\d\+ THROW\_s*' ..
298 'endtry\_s*' ..
299 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200300 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100301enddef
302
303def s:ScriptFuncNew()
304 let ll = [1, "two", 333]
305 let dd = #{one: 1, two: "val"}
306enddef
307
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100308def Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100309 let res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200310 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
311 'let ll = \[1, "two", 333\]\_s*' ..
312 '\d PUSHNR 1\_s*' ..
313 '\d PUSHS "two"\_s*' ..
314 '\d PUSHNR 333\_s*' ..
315 '\d NEWLIST size 3\_s*' ..
316 '\d STORE $0\_s*' ..
317 'let dd = #{one: 1, two: "val"}\_s*' ..
318 '\d PUSHS "one"\_s*' ..
319 '\d PUSHNR 1\_s*' ..
320 '\d PUSHS "two"\_s*' ..
321 '\d PUSHS "val"\_s*' ..
322 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200323 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100324enddef
325
Bram Moolenaar6e949782020-04-13 17:21:00 +0200326def FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100327 echo arg
328enddef
329
330func UserFunc()
331 echo 'nothing'
332endfunc
333
334func UserFuncWithArg(arg)
335 echo a:arg
336endfunc
337
338def s:ScriptFuncCall(): string
339 changenr()
340 char2nr("abc")
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100341 Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100342 FuncWithArg(343)
343 ScriptFuncNew()
344 s:ScriptFuncNew()
345 UserFunc()
346 UserFuncWithArg("foo")
347 let FuncRef = function("UserFunc")
348 FuncRef()
349 let FuncRefWithArg = function("UserFuncWithArg")
350 FuncRefWithArg("bar")
351 return "yes"
352enddef
353
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100354def Test_disassemble_call()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100355 let res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200356 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
357 'changenr()\_s*' ..
358 '\d BCALL changenr(argc 0)\_s*' ..
359 '\d DROP\_s*' ..
360 'char2nr("abc")\_s*' ..
361 '\d PUSHS "abc"\_s*' ..
362 '\d BCALL char2nr(argc 1)\_s*' ..
363 '\d DROP\_s*' ..
364 'Test_disassemble_new()\_s*' ..
365 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
366 '\d DROP\_s*' ..
367 'FuncWithArg(343)\_s*' ..
368 '\d\+ PUSHNR 343\_s*' ..
369 '\d\+ DCALL FuncWithArg(argc 1)\_s*' ..
370 '\d\+ DROP\_s*' ..
371 'ScriptFuncNew()\_s*' ..
372 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
373 '\d\+ DROP\_s*' ..
374 's:ScriptFuncNew()\_s*' ..
375 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
376 '\d\+ DROP\_s*' ..
377 'UserFunc()\_s*' ..
378 '\d\+ UCALL UserFunc(argc 0)\_s*' ..
379 '\d\+ DROP\_s*' ..
380 'UserFuncWithArg("foo")\_s*' ..
381 '\d\+ PUSHS "foo"\_s*' ..
382 '\d\+ UCALL UserFuncWithArg(argc 1)\_s*' ..
383 '\d\+ DROP\_s*' ..
384 'let FuncRef = function("UserFunc")\_s*' ..
385 '\d\+ PUSHS "UserFunc"\_s*' ..
386 '\d\+ BCALL function(argc 1)\_s*' ..
387 '\d\+ STORE $0\_s*' ..
388 'FuncRef()\_s*' ..
389 '\d\+ LOAD $\d\_s*' ..
390 '\d\+ PCALL (argc 0)\_s*' ..
391 '\d\+ DROP\_s*' ..
392 'let FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
393 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
394 '\d\+ BCALL function(argc 1)\_s*' ..
395 '\d\+ STORE $1\_s*' ..
396 'FuncRefWithArg("bar")\_s*' ..
397 '\d\+ PUSHS "bar"\_s*' ..
398 '\d\+ LOAD $\d\_s*' ..
399 '\d\+ PCALL (argc 1)\_s*' ..
400 '\d\+ DROP\_s*' ..
401 'return "yes"\_s*' ..
402 '\d\+ PUSHS "yes"\_s*' ..
403 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200404 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100405enddef
406
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200407def s:CreateRefs()
408 let local = 'a'
409 def Append(arg: string)
410 local ..= arg
411 enddef
412 g:Append = Append
413 def Get(): string
414 return local
415 enddef
416 g:Get = Get
417enddef
418
419def Test_disassemble_closure()
420 CreateRefs()
421 let res = execute('disass g:Append')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200422 assert_match('<lambda>\d\_s*' ..
423 'local ..= arg\_s*' ..
424 '\d LOADOUTER $0\_s*' ..
425 '\d LOAD arg\[-1\]\_s*' ..
426 '\d CONCAT\_s*' ..
427 '\d STOREOUTER $0\_s*' ..
428 '\d PUSHNR 0\_s*' ..
429 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200430 res)
431
432 res = execute('disass g:Get')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200433 assert_match('<lambda>\d\_s*' ..
434 'return local\_s*' ..
435 '\d LOADOUTER $0\_s*' ..
436 '\d RETURN',
Bram Moolenaarb68b3462020-05-06 21:06:30 +0200437 res)
438
439 unlet g:Append
440 unlet g:Get
441enddef
442
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100443
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200444def EchoArg(arg: string): string
445 return arg
446enddef
447def RefThis(): func
448 return function('EchoArg')
449enddef
450def s:ScriptPCall()
451 RefThis()("text")
452enddef
453
454def Test_disassemble_pcall()
455 let res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200456 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
457 'RefThis()("text")\_s*' ..
458 '\d DCALL RefThis(argc 0)\_s*' ..
459 '\d PUSHS "text"\_s*' ..
460 '\d PCALL top (argc 1)\_s*' ..
461 '\d PCALL end\_s*' ..
462 '\d DROP\_s*' ..
463 '\d PUSHNR 0\_s*' ..
464 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200465 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200466enddef
467
468
Bram Moolenaara26b9702020-04-18 19:53:28 +0200469def s:FuncWithForwardCall(): string
470 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100471enddef
472
473def DefinedLater(arg: string): string
474 return arg
475enddef
476
477def Test_disassemble_update_instr()
Bram Moolenaara26b9702020-04-18 19:53:28 +0200478 let res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200479 assert_match('FuncWithForwardCall\_s*' ..
480 'return g:DefinedLater("yes")\_s*' ..
481 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200482 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200483 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200484 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100485
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200486 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100487 assert_equal('yes', FuncWithForwardCall())
488
Bram Moolenaara26b9702020-04-18 19:53:28 +0200489 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200490 assert_match('FuncWithForwardCall\_s*' ..
491 'return g:DefinedLater("yes")\_s*' ..
492 '\d PUSHS "yes"\_s*' ..
493 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200494 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200495 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100496enddef
497
498
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100499def FuncWithDefault(arg: string = 'default'): string
500 return arg
501enddef
502
503def Test_disassemble_call_default()
504 let res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200505 assert_match('FuncWithDefault\_s*' ..
506 '\d PUSHS "default"\_s*' ..
507 '\d STORE arg\[-1]\_s*' ..
508 'return arg\_s*' ..
509 '\d LOAD arg\[-1]\_s*' ..
510 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200511 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +0100512enddef
513
514
Bram Moolenaar158906c2020-02-06 20:39:45 +0100515def HasEval()
516 if has("eval")
517 echo "yes"
518 else
519 echo "no"
520 endif
521enddef
522
523def HasNothing()
524 if has("nothing")
525 echo "yes"
526 else
527 echo "no"
528 endif
529enddef
530
531def HasSomething()
532 if has("nothing")
533 echo "nothing"
534 elseif has("something")
535 echo "something"
536 elseif has("eval")
537 echo "eval"
538 elseif has("less")
539 echo "less"
540 endif
541enddef
542
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100543def Test_disassemble_const_expr()
Bram Moolenaar158906c2020-02-06 20:39:45 +0100544 assert_equal("\nyes", execute('call HasEval()'))
545 let instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200546 assert_match('HasEval\_s*' ..
547 'if has("eval")\_s*' ..
548 'echo "yes"\_s*' ..
549 '\d PUSHS "yes"\_s*' ..
550 '\d ECHO 1\_s*' ..
551 'else\_s*' ..
552 'echo "no"\_s*' ..
553 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200554 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100555 assert_notmatch('JUMP', instr)
556
557 assert_equal("\nno", execute('call HasNothing()'))
558 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200559 assert_match('HasNothing\_s*' ..
560 'if has("nothing")\_s*' ..
561 'echo "yes"\_s*' ..
562 'else\_s*' ..
563 'echo "no"\_s*' ..
564 '\d PUSHS "no"\_s*' ..
565 '\d ECHO 1\_s*' ..
566 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200567 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100568 assert_notmatch('PUSHS "yes"', instr)
569 assert_notmatch('JUMP', instr)
570
571 assert_equal("\neval", execute('call HasSomething()'))
572 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200573 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200574 'if has("nothing")\_s*' ..
575 'echo "nothing"\_s*' ..
576 'elseif has("something")\_s*' ..
577 'echo "something"\_s*' ..
578 'elseif has("eval")\_s*' ..
579 'echo "eval"\_s*' ..
580 '\d PUSHS "eval"\_s*' ..
581 '\d ECHO 1\_s*' ..
582 'elseif has("less").*' ..
583 'echo "less"\_s*' ..
584 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200585 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +0100586 assert_notmatch('PUSHS "nothing"', instr)
587 assert_notmatch('PUSHS "something"', instr)
588 assert_notmatch('PUSHS "less"', instr)
589 assert_notmatch('JUMP', instr)
590enddef
591
Bram Moolenaarefd88552020-06-18 20:50:10 +0200592def ReturnInIf(): string
593 if g:cond
594 return "yes"
595 else
596 return "no"
597 endif
598enddef
599
600def Test_disassemble_return_in_if()
601 let instr = execute('disassemble ReturnInIf')
602 assert_match('ReturnInIf\_s*' ..
603 'if g:cond\_s*' ..
604 '0 LOADG g:cond\_s*' ..
605 '1 JUMP_IF_FALSE -> 4\_s*' ..
606 'return "yes"\_s*' ..
607 '2 PUSHS "yes"\_s*' ..
608 '3 RETURN\_s*' ..
609 'else\_s*' ..
610 ' return "no"\_s*' ..
611 '4 PUSHS "no"\_s*' ..
612 '5 RETURN$',
613 instr)
614enddef
615
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100616def WithFunc()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200617 let Funky1: func
618 let Funky2: func = function("len")
619 let Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100620enddef
621
622def Test_disassemble_function()
623 let instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200624 assert_match('WithFunc\_s*' ..
625 'let Funky1: func\_s*' ..
626 '0 PUSHFUNC "\[none]"\_s*' ..
627 '1 STORE $0\_s*' ..
628 'let Funky2: func = function("len")\_s*' ..
629 '2 PUSHS "len"\_s*' ..
630 '3 BCALL function(argc 1)\_s*' ..
631 '4 STORE $1\_s*' ..
632 'let Party2: func = funcref("UserFunc")\_s*' ..
633 '\d PUSHS "UserFunc"\_s*' ..
634 '\d BCALL funcref(argc 1)\_s*' ..
635 '\d STORE $2\_s*' ..
636 '\d PUSHNR 0\_s*' ..
637 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200638 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100639enddef
640
641if has('channel')
642 def WithChannel()
643 let job1: job
644 let job2: job = job_start("donothing")
645 let chan1: channel
646 enddef
647endif
648
649def Test_disassemble_channel()
650 CheckFeature channel
651
652 let instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200653 assert_match('WithChannel\_s*' ..
654 'let job1: job\_s*' ..
655 '\d PUSHJOB "no process"\_s*' ..
656 '\d STORE $0\_s*' ..
657 'let job2: job = job_start("donothing")\_s*' ..
658 '\d PUSHS "donothing"\_s*' ..
659 '\d BCALL job_start(argc 1)\_s*' ..
660 '\d STORE $1\_s*' ..
661 'let chan1: channel\_s*' ..
662 '\d PUSHCHANNEL 0\_s*' ..
663 '\d STORE $2\_s*' ..
664 '\d PUSHNR 0\_s*' ..
665 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200666 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +0100667enddef
668
Bram Moolenaar777770f2020-02-06 21:27:08 +0100669def WithLambda(): string
670 let F = {a -> "X" .. a .. "X"}
671 return F("x")
672enddef
673
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100674def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100675 assert_equal("XxX", WithLambda())
676 let instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200677 assert_match('WithLambda\_s*' ..
678 'let F = {a -> "X" .. a .. "X"}\_s*' ..
679 '\d FUNCREF <lambda>\d\+ $1\_s*' ..
680 '\d STORE $0\_s*' ..
681 'return F("x")\_s*' ..
682 '\d PUSHS "x"\_s*' ..
683 '\d LOAD $0\_s*' ..
684 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +0200685 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200686 instr)
Bram Moolenaarbfd65582020-07-13 18:18:00 +0200687
688 let name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
689 instr = execute('disassemble ' .. name)
690 assert_match('<lambda>\d\+\_s*' ..
691 'return "X" .. a .. "X"\_s*' ..
692 '\d PUSHS "X"\_s*' ..
693 '\d LOAD arg\[-1\]\_s*' ..
694 '\d 2STRING stack\[-1\]\_s*' ..
695 '\d CONCAT\_s*' ..
696 '\d PUSHS "X"\_s*' ..
697 '\d CONCAT\_s*' ..
698 '\d RETURN',
699 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100700enddef
701
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200702def NestedOuter()
703 def g:Inner()
704 echomsg "inner"
705 enddef
706enddef
707
708def Test_nested_func()
709 let instr = execute('disassemble NestedOuter')
710 assert_match('NestedOuter\_s*' ..
711 'def g:Inner()\_s*' ..
712 'echomsg "inner"\_s*' ..
713 'enddef\_s*' ..
714 '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
715 '\d PUSHNR 0\_s*' ..
716 '\d RETURN',
717 instr)
718enddef
719
Bram Moolenaar6e949782020-04-13 17:21:00 +0200720def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100721 if arg == 1 && arg != 2 || arg == 4
722 return 'yes'
723 endif
724 return 'no'
725enddef
726
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100727def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100728 assert_equal("yes", AndOr(1))
729 assert_equal("no", AndOr(2))
730 assert_equal("yes", AndOr(4))
731 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200732 assert_match('AndOr\_s*' ..
733 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
734 '\d LOAD arg\[-1]\_s*' ..
735 '\d PUSHNR 1\_s*' ..
736 '\d COMPAREANY ==\_s*' ..
737 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
738 '\d LOAD arg\[-1]\_s*' ..
739 '\d PUSHNR 2\_s*' ..
740 '\d COMPAREANY !=\_s*' ..
741 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
742 '\d LOAD arg\[-1]\_s*' ..
743 '\d\+ PUSHNR 4\_s*' ..
744 '\d\+ COMPAREANY ==\_s*' ..
745 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200746 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100747enddef
748
Bram Moolenaar04d05222020-02-06 22:06:54 +0100749def ForLoop(): list<number>
750 let res: list<number>
751 for i in range(3)
752 res->add(i)
753 endfor
754 return res
755enddef
756
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100757def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100758 assert_equal([0, 1, 2], ForLoop())
759 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200760 assert_match('ForLoop\_s*' ..
761 'let res: list<number>\_s*' ..
762 '\d NEWLIST size 0\_s*' ..
763 '\d STORE $0\_s*' ..
764 'for i in range(3)\_s*' ..
765 '\d STORE -1 in $1\_s*' ..
766 '\d PUSHNR 3\_s*' ..
767 '\d BCALL range(argc 1)\_s*' ..
768 '\d FOR $1 -> \d\+\_s*' ..
769 '\d STORE $2\_s*' ..
770 'res->add(i)\_s*' ..
771 '\d LOAD $0\_s*' ..
772 '\d LOAD $2\_s*' ..
773 '\d\+ BCALL add(argc 2)\_s*' ..
774 '\d\+ DROP\_s*' ..
775 'endfor\_s*' ..
776 '\d\+ JUMP -> \d\+\_s*' ..
777 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200778 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100779enddef
780
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200781def ForLoopEval(): string
782 let res = ""
783 for str in eval('["one", "two"]')
784 res ..= str
785 endfor
786 return res
787enddef
788
789def Test_disassemble_for_loop_eval()
790 assert_equal('onetwo', ForLoopEval())
791 let instr = execute('disassemble ForLoopEval')
792 assert_match('ForLoopEval\_s*' ..
793 'let res = ""\_s*' ..
794 '\d PUSHS ""\_s*' ..
795 '\d STORE $0\_s*' ..
796 'for str in eval(''\["one", "two"\]'')\_s*' ..
797 '\d STORE -1 in $1\_s*' ..
798 '\d PUSHS "\["one", "two"\]"\_s*' ..
799 '\d BCALL eval(argc 1)\_s*' ..
800 '\d CHECKTYPE list stack\[-1\]\_s*' ..
801 '\d FOR $1 -> \d\+\_s*' ..
802 '\d STORE $2\_s*' ..
803 'res ..= str\_s*' ..
804 '\d\+ LOAD $0\_s*' ..
805 '\d\+ LOAD $2\_s*' ..
806 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
807 '\d\+ CONCAT\_s*' ..
808 '\d\+ STORE $0\_s*' ..
809 'endfor\_s*' ..
810 '\d\+ JUMP -> 6\_s*' ..
811 '\d\+ DROP\_s*' ..
812 'return res\_s*' ..
813 '\d\+ LOAD $0\_s*' ..
814 '\d\+ RETURN',
815 instr)
816enddef
817
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100818let g:number = 42
819
Bram Moolenaar64d662d2020-08-09 19:02:50 +0200820def TypeCast()
821 let l: list<number> = [23, <number>g:number]
822enddef
823
824def Test_disassemble_typecast()
825 let instr = execute('disassemble TypeCast')
826 assert_match('TypeCast.*' ..
827 'let l: list<number> = \[23, <number>g:number\].*' ..
828 '\d PUSHNR 23\_s*' ..
829 '\d LOADG g:number\_s*' ..
830 '\d CHECKTYPE number stack\[-1\]\_s*' ..
831 '\d NEWLIST size 2\_s*' ..
832 '\d STORE $0\_s*' ..
833 '\d PUSHNR 0\_s*' ..
834 '\d RETURN\_s*',
835 instr)
836enddef
837
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100838def Computing()
839 let nr = 3
840 let nrres = nr + 7
841 nrres = nr - 7
842 nrres = nr * 7
843 nrres = nr / 7
844 nrres = nr % 7
845
846 let anyres = g:number + 7
847 anyres = g:number - 7
848 anyres = g:number * 7
849 anyres = g:number / 7
850 anyres = g:number % 7
851
852 if has('float')
853 let fl = 3.0
854 let flres = fl + 7.0
855 flres = fl - 7.0
856 flres = fl * 7.0
857 flres = fl / 7.0
858 endif
859enddef
860
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100861def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100862 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200863 assert_match('Computing.*' ..
864 'let nr = 3.*' ..
865 '\d STORE 3 in $0.*' ..
866 'let nrres = nr + 7.*' ..
867 '\d LOAD $0.*' ..
868 '\d PUSHNR 7.*' ..
869 '\d OPNR +.*' ..
870 '\d STORE $1.*' ..
871 'nrres = nr - 7.*' ..
872 '\d OPNR -.*' ..
873 'nrres = nr \* 7.*' ..
874 '\d OPNR \*.*' ..
875 'nrres = nr / 7.*' ..
876 '\d OPNR /.*' ..
877 'nrres = nr % 7.*' ..
878 '\d OPNR %.*' ..
879 'let anyres = g:number + 7.*' ..
880 '\d LOADG g:number.*' ..
881 '\d PUSHNR 7.*' ..
882 '\d OPANY +.*' ..
883 '\d STORE $2.*' ..
884 'anyres = g:number - 7.*' ..
885 '\d OPANY -.*' ..
886 'anyres = g:number \* 7.*' ..
887 '\d OPANY \*.*' ..
888 'anyres = g:number / 7.*' ..
889 '\d OPANY /.*' ..
890 'anyres = g:number % 7.*' ..
891 '\d OPANY %.*',
892 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100893 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200894 assert_match('Computing.*' ..
895 'let fl = 3.0.*' ..
896 '\d PUSHF 3.0.*' ..
897 '\d STORE $3.*' ..
898 'let flres = fl + 7.0.*' ..
899 '\d LOAD $3.*' ..
900 '\d PUSHF 7.0.*' ..
901 '\d OPFLOAT +.*' ..
902 '\d STORE $4.*' ..
903 'flres = fl - 7.0.*' ..
904 '\d OPFLOAT -.*' ..
905 'flres = fl \* 7.0.*' ..
906 '\d OPFLOAT \*.*' ..
907 'flres = fl / 7.0.*' ..
908 '\d OPFLOAT /.*',
909 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100910 endif
911enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100912
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100913def AddListBlob()
914 let reslist = [1, 2] + [3, 4]
915 let resblob = 0z1122 + 0z3344
916enddef
917
918def Test_disassemble_add_list_blob()
919 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200920 assert_match('AddListBlob.*' ..
921 'let reslist = \[1, 2] + \[3, 4].*' ..
922 '\d PUSHNR 1.*' ..
923 '\d PUSHNR 2.*' ..
924 '\d NEWLIST size 2.*' ..
925 '\d PUSHNR 3.*' ..
926 '\d PUSHNR 4.*' ..
927 '\d NEWLIST size 2.*' ..
928 '\d ADDLIST.*' ..
929 '\d STORE $.*.*' ..
930 'let resblob = 0z1122 + 0z3344.*' ..
931 '\d PUSHBLOB 0z1122.*' ..
932 '\d PUSHBLOB 0z3344.*' ..
933 '\d ADDBLOB.*' ..
934 '\d STORE $.*',
935 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100936enddef
937
938let g:aa = 'aa'
939def ConcatString(): string
940 let res = g:aa .. "bb"
941 return res
942enddef
943
944def Test_disassemble_concat()
945 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200946 assert_match('ConcatString.*' ..
947 'let res = g:aa .. "bb".*' ..
948 '\d LOADG g:aa.*' ..
949 '\d PUSHS "bb".*' ..
950 '\d 2STRING stack\[-2].*' ..
951 '\d CONCAT.*' ..
952 '\d STORE $.*',
953 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100954 assert_equal('aabb', ConcatString())
955enddef
956
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200957def StringIndex(): number
958 let s = "abcd"
959 let res = s[1]
960 return res
961enddef
962
963def Test_disassemble_string_index()
964 let instr = execute('disassemble StringIndex')
965 assert_match('StringIndex\_s*' ..
966 'let s = "abcd"\_s*' ..
967 '\d PUSHS "abcd"\_s*' ..
968 '\d STORE $0\_s*' ..
969 'let res = s\[1]\_s*' ..
970 '\d LOAD $0\_s*' ..
971 '\d PUSHNR 1\_s*' ..
972 '\d STRINDEX\_s*' ..
973 '\d STORE $1\_s*',
974 instr)
975 assert_equal('b', StringIndex())
976enddef
977
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100978def ListIndex(): number
979 let l = [1, 2, 3]
980 let res = l[1]
981 return res
982enddef
983
984def Test_disassemble_list_index()
985 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200986 assert_match('ListIndex\_s*' ..
987 'let l = \[1, 2, 3]\_s*' ..
988 '\d PUSHNR 1\_s*' ..
989 '\d PUSHNR 2\_s*' ..
990 '\d PUSHNR 3\_s*' ..
991 '\d NEWLIST size 3\_s*' ..
992 '\d STORE $0\_s*' ..
993 'let res = l\[1]\_s*' ..
994 '\d LOAD $0\_s*' ..
995 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200996 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200997 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200998 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100999 assert_equal(2, ListIndex())
1000enddef
1001
1002def DictMember(): number
1003 let d = #{item: 1}
1004 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001005 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001006 return res
1007enddef
1008
1009def Test_disassemble_dict_member()
1010 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001011 assert_match('DictMember\_s*' ..
1012 'let d = #{item: 1}\_s*' ..
1013 '\d PUSHS "item"\_s*' ..
1014 '\d PUSHNR 1\_s*' ..
1015 '\d NEWDICT size 1\_s*' ..
1016 '\d STORE $0\_s*' ..
1017 'let res = d.item\_s*' ..
1018 '\d\+ LOAD $0\_s*' ..
1019 '\d\+ MEMBER item\_s*' ..
1020 '\d\+ STORE $1\_s*' ..
1021 'res = d\["item"\]\_s*' ..
1022 '\d\+ LOAD $0\_s*' ..
1023 '\d\+ PUSHS "item"\_s*' ..
1024 '\d\+ MEMBER\_s*' ..
1025 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001026 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001027 call assert_equal(1, DictMember())
1028enddef
1029
1030def NegateNumber(): number
1031 let nr = 9
1032 let plus = +nr
1033 let res = -nr
1034 return res
1035enddef
1036
1037def Test_disassemble_negate_number()
1038 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001039 assert_match('NegateNumber\_s*' ..
1040 'let nr = 9\_s*' ..
1041 '\d STORE 9 in $0\_s*' ..
1042 'let plus = +nr\_s*' ..
1043 '\d LOAD $0\_s*' ..
1044 '\d CHECKNR\_s*' ..
1045 '\d STORE $1\_s*' ..
1046 'let res = -nr\_s*' ..
1047 '\d LOAD $0\_s*' ..
1048 '\d NEGATENR\_s*' ..
1049 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001050 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001051 call assert_equal(-9, NegateNumber())
1052enddef
1053
1054def InvertBool(): bool
1055 let flag = true
1056 let invert = !flag
1057 let res = !!flag
1058 return res
1059enddef
1060
1061def Test_disassemble_invert_bool()
1062 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001063 assert_match('InvertBool\_s*' ..
1064 'let flag = true\_s*' ..
1065 '\d PUSH v:true\_s*' ..
1066 '\d STORE $0\_s*' ..
1067 'let invert = !flag\_s*' ..
1068 '\d LOAD $0\_s*' ..
1069 '\d INVERT (!val)\_s*' ..
1070 '\d STORE $1\_s*' ..
1071 'let res = !!flag\_s*' ..
1072 '\d LOAD $0\_s*' ..
1073 '\d 2BOOL (!!val)\_s*' ..
1074 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001075 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001076 call assert_equal(true, InvertBool())
1077enddef
1078
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001079def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001080 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001081 ['true == isFalse', 'COMPAREBOOL =='],
1082 ['true != isFalse', 'COMPAREBOOL !='],
1083 ['v:none == isNull', 'COMPARESPECIAL =='],
1084 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001085
Bram Moolenaara5565e42020-05-09 15:44:01 +02001086 ['111 == aNumber', 'COMPARENR =='],
1087 ['111 != aNumber', 'COMPARENR !='],
1088 ['111 > aNumber', 'COMPARENR >'],
1089 ['111 < aNumber', 'COMPARENR <'],
1090 ['111 >= aNumber', 'COMPARENR >='],
1091 ['111 <= aNumber', 'COMPARENR <='],
1092 ['111 =~ aNumber', 'COMPARENR =\~'],
1093 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001094
Bram Moolenaara5565e42020-05-09 15:44:01 +02001095 ['"xx" != aString', 'COMPARESTRING !='],
1096 ['"xx" > aString', 'COMPARESTRING >'],
1097 ['"xx" < aString', 'COMPARESTRING <'],
1098 ['"xx" >= aString', 'COMPARESTRING >='],
1099 ['"xx" <= aString', 'COMPARESTRING <='],
1100 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1101 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1102 ['"xx" is aString', 'COMPARESTRING is'],
1103 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001104
Bram Moolenaara5565e42020-05-09 15:44:01 +02001105 ['0z11 == aBlob', 'COMPAREBLOB =='],
1106 ['0z11 != aBlob', 'COMPAREBLOB !='],
1107 ['0z11 is aBlob', 'COMPAREBLOB is'],
1108 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001109
Bram Moolenaara5565e42020-05-09 15:44:01 +02001110 ['[1, 2] == aList', 'COMPARELIST =='],
1111 ['[1, 2] != aList', 'COMPARELIST !='],
1112 ['[1, 2] is aList', 'COMPARELIST is'],
1113 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001114
Bram Moolenaara5565e42020-05-09 15:44:01 +02001115 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1116 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1117 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1118 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001119
1120 ['{->33} == {->44}', 'COMPAREFUNC =='],
1121 ['{->33} != {->44}', 'COMPAREFUNC !='],
1122 ['{->33} is {->44}', 'COMPAREFUNC is'],
1123 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1124
1125 ['77 == g:xx', 'COMPAREANY =='],
1126 ['77 != g:xx', 'COMPAREANY !='],
1127 ['77 > g:xx', 'COMPAREANY >'],
1128 ['77 < g:xx', 'COMPAREANY <'],
1129 ['77 >= g:xx', 'COMPAREANY >='],
1130 ['77 <= g:xx', 'COMPAREANY <='],
1131 ['77 =~ g:xx', 'COMPAREANY =\~'],
1132 ['77 !~ g:xx', 'COMPAREANY !\~'],
1133 ['77 is g:xx', 'COMPAREANY is'],
1134 ['77 isnot g:xx', 'COMPAREANY isnot'],
1135 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001136 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001137 if has('float')
1138 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001139 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1140 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1141 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1142 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1143 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1144 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1145 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1146 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001147 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001148 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001149 endif
1150
1151 let nr = 1
1152 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001153 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001154 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001155 ' let isFalse = false',
1156 ' let isNull = v:null',
1157 ' let aNumber = 222',
1158 ' let aString = "yy"',
1159 ' let aBlob = 0z22',
1160 ' let aList = [3, 4]',
1161 ' let aDict = #{x: 2}',
1162 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001163 ' if ' .. case[0],
1164 ' echo 42'
1165 ' endif',
1166 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001167 source Xdisassemble
1168 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001169 assert_match('TestCase' .. nr .. '.*' ..
1170 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1171 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001172 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001173 '\d ' .. case[1] .. '.*' ..
1174 '\d JUMP_IF_FALSE -> \d\+.*',
1175 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001176
1177 nr += 1
1178 endfor
1179
Bram Moolenaar22da5592020-03-19 14:52:20 +01001180 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001181enddef
1182
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001183def Test_disassemble_compare_const()
1184 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001185 ['"xx" == "yy"', false],
1186 ['"aa" == "aa"', true],
1187 ['has("eval") ? true : false', true],
1188 ['has("asdf") ? true : false', false],
1189 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001190
1191 let nr = 1
1192 for case in cases
1193 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001194 ' if ' .. case[0],
1195 ' echo 42'
1196 ' endif',
1197 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001198 source Xdisassemble
1199 let instr = execute('disassemble TestCase' .. nr)
1200 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001201 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001202 assert_match('TestCase' .. nr .. '.*' ..
1203 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1204 '\d PUSHNR 42.*' ..
1205 '\d ECHO 1.*' ..
1206 '\d PUSHNR 0.*' ..
1207 '\d RETURN.*',
1208 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001209 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001210 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001211 assert_match('TestCase' .. nr .. '.*' ..
1212 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1213 'echo 42[ \n]*' ..
1214 'endif[ \n]*' ..
1215 '\s*\d PUSHNR 0.*' ..
1216 '\d RETURN.*',
1217 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001218 endif
1219
1220 nr += 1
1221 endfor
1222
1223 delete('Xdisassemble')
1224enddef
1225
Bram Moolenaarad39c092020-02-26 18:23:43 +01001226def s:Execute()
1227 execute 'help vim9.txt'
1228 let cmd = 'help vim9.txt'
1229 execute cmd
1230 let tag = 'vim9.txt'
1231 execute 'help ' .. tag
1232enddef
1233
1234def Test_disassemble_execute()
1235 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001236 assert_match('\<SNR>\d*_Execute\_s*' ..
1237 "execute 'help vim9.txt'\\_s*" ..
1238 '\d PUSHS "help vim9.txt"\_s*' ..
1239 '\d EXECUTE 1\_s*' ..
1240 "let cmd = 'help vim9.txt'\\_s*" ..
1241 '\d PUSHS "help vim9.txt"\_s*' ..
1242 '\d STORE $0\_s*' ..
1243 'execute cmd\_s*' ..
1244 '\d LOAD $0\_s*' ..
1245 '\d EXECUTE 1\_s*' ..
1246 "let tag = 'vim9.txt'\\_s*" ..
1247 '\d PUSHS "vim9.txt"\_s*' ..
1248 '\d STORE $1\_s*' ..
1249 "execute 'help ' .. tag\\_s*" ..
1250 '\d\+ PUSHS "help "\_s*' ..
1251 '\d\+ LOAD $1\_s*' ..
1252 '\d\+ CONCAT\_s*' ..
1253 '\d\+ EXECUTE 1\_s*' ..
1254 '\d\+ PUSHNR 0\_s*' ..
1255 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001256 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001257enddef
1258
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001259def s:Echomsg()
1260 echomsg 'some' 'message'
1261 echoerr 'went' .. 'wrong'
1262enddef
1263
1264def Test_disassemble_echomsg()
1265 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001266 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1267 "echomsg 'some' 'message'\\_s*" ..
1268 '\d PUSHS "some"\_s*' ..
1269 '\d PUSHS "message"\_s*' ..
1270 '\d ECHOMSG 2\_s*' ..
1271 "echoerr 'went' .. 'wrong'\\_s*" ..
1272 '\d PUSHS "wentwrong"\_s*' ..
1273 '\d ECHOERR 1\_s*' ..
1274 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001275 '\d RETURN',
1276 res)
1277enddef
1278
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001279def SomeStringArg(arg: string)
1280 echo arg
1281enddef
1282
1283def SomeAnyArg(arg: any)
1284 echo arg
1285enddef
1286
1287def SomeStringArgAndReturn(arg: string): string
1288 return arg
1289enddef
1290
1291def Test_display_func()
1292 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001293 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1294 '\d *echo arg.*' ..
1295 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001296 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001297
1298 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001299 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1300 '\d *echo arg\_s*' ..
1301 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001302 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001303
1304 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001305 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1306 '\d *return arg\_s*' ..
1307 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001308 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001309enddef
1310
Bram Moolenaar09689a02020-05-09 22:50:08 +02001311def Test_vim9script_forward_func()
1312 let lines =<< trim END
1313 vim9script
1314 def FuncOne(): string
1315 return FuncTwo()
1316 enddef
1317 def FuncTwo(): string
1318 return 'two'
1319 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001320 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001321 END
1322 writefile(lines, 'Xdisassemble')
1323 source Xdisassemble
1324
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001325 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001326 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1327 'return FuncTwo()\_s*' ..
1328 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001329 '\d RETURN',
1330 g:res_FuncOne)
1331
1332 delete('Xdisassemble')
1333 unlet g:res_FuncOne
1334enddef
1335
Bram Moolenaar61a89812020-05-07 16:58:17 +02001336def s:ConcatStrings(): string
1337 return 'one' .. 'two' .. 'three'
1338enddef
1339
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001340def s:ComputeConst(): number
1341 return 2 + 3 * 4 / 6 + 7
1342enddef
1343
Bram Moolenaar1c747212020-05-09 18:28:34 +02001344def s:ComputeConstParen(): number
1345 return ((2 + 4) * (8 / 2)) / (3 + 4)
1346enddef
1347
Bram Moolenaar61a89812020-05-07 16:58:17 +02001348def Test_simplify_const_expr()
1349 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001350 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1351 "return 'one' .. 'two' .. 'three'\\_s*" ..
1352 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001353 '\d RETURN',
1354 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001355
1356 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001357 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1358 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1359 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001360 '\d RETURN',
1361 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001362
1363 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001364 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1365 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1366 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001367 '\d RETURN',
1368 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001369enddef
1370
Bram Moolenaar389df252020-07-09 21:20:47 +02001371def s:CallAppend()
1372 eval "some text"->append(2)
1373enddef
1374
1375def Test_shuffle()
1376 let res = execute('disass s:CallAppend')
1377 assert_match('<SNR>\d*_CallAppend\_s*' ..
1378 'eval "some text"->append(2)\_s*' ..
1379 '\d PUSHS "some text"\_s*' ..
1380 '\d PUSHNR 2\_s*' ..
1381 '\d SHUFFLE 2 up 1\_s*' ..
1382 '\d BCALL append(argc 2)\_s*' ..
1383 '\d DROP\_s*' ..
1384 '\d PUSHNR 0\_s*' ..
1385 '\d RETURN',
1386 res)
1387enddef
1388
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001389" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker