blob: 98a9e207e5a80df548ebfa52a612c20d3167182d [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 Moolenaar6e949782020-04-13 17:21:00 +0200702def AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +0100703 if arg == 1 && arg != 2 || arg == 4
704 return 'yes'
705 endif
706 return 'no'
707enddef
708
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100709def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +0100710 assert_equal("yes", AndOr(1))
711 assert_equal("no", AndOr(2))
712 assert_equal("yes", AndOr(4))
713 let instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200714 assert_match('AndOr\_s*' ..
715 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
716 '\d LOAD arg\[-1]\_s*' ..
717 '\d PUSHNR 1\_s*' ..
718 '\d COMPAREANY ==\_s*' ..
719 '\d JUMP_AND_KEEP_IF_FALSE -> \d\+\_s*' ..
720 '\d LOAD arg\[-1]\_s*' ..
721 '\d PUSHNR 2\_s*' ..
722 '\d COMPAREANY !=\_s*' ..
723 '\d JUMP_AND_KEEP_IF_TRUE -> \d\+\_s*' ..
724 '\d LOAD arg\[-1]\_s*' ..
725 '\d\+ PUSHNR 4\_s*' ..
726 '\d\+ COMPAREANY ==\_s*' ..
727 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200728 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +0100729enddef
730
Bram Moolenaar04d05222020-02-06 22:06:54 +0100731def ForLoop(): list<number>
732 let res: list<number>
733 for i in range(3)
734 res->add(i)
735 endfor
736 return res
737enddef
738
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100739def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +0100740 assert_equal([0, 1, 2], ForLoop())
741 let instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200742 assert_match('ForLoop\_s*' ..
743 'let res: list<number>\_s*' ..
744 '\d NEWLIST size 0\_s*' ..
745 '\d STORE $0\_s*' ..
746 'for i in range(3)\_s*' ..
747 '\d STORE -1 in $1\_s*' ..
748 '\d PUSHNR 3\_s*' ..
749 '\d BCALL range(argc 1)\_s*' ..
750 '\d FOR $1 -> \d\+\_s*' ..
751 '\d STORE $2\_s*' ..
752 'res->add(i)\_s*' ..
753 '\d LOAD $0\_s*' ..
754 '\d LOAD $2\_s*' ..
755 '\d\+ BCALL add(argc 2)\_s*' ..
756 '\d\+ DROP\_s*' ..
757 'endfor\_s*' ..
758 '\d\+ JUMP -> \d\+\_s*' ..
759 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200760 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +0100761enddef
762
Bram Moolenaar0ad3e892020-07-05 21:38:11 +0200763def ForLoopEval(): string
764 let res = ""
765 for str in eval('["one", "two"]')
766 res ..= str
767 endfor
768 return res
769enddef
770
771def Test_disassemble_for_loop_eval()
772 assert_equal('onetwo', ForLoopEval())
773 let instr = execute('disassemble ForLoopEval')
774 assert_match('ForLoopEval\_s*' ..
775 'let res = ""\_s*' ..
776 '\d PUSHS ""\_s*' ..
777 '\d STORE $0\_s*' ..
778 'for str in eval(''\["one", "two"\]'')\_s*' ..
779 '\d STORE -1 in $1\_s*' ..
780 '\d PUSHS "\["one", "two"\]"\_s*' ..
781 '\d BCALL eval(argc 1)\_s*' ..
782 '\d CHECKTYPE list stack\[-1\]\_s*' ..
783 '\d FOR $1 -> \d\+\_s*' ..
784 '\d STORE $2\_s*' ..
785 'res ..= str\_s*' ..
786 '\d\+ LOAD $0\_s*' ..
787 '\d\+ LOAD $2\_s*' ..
788 '\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
789 '\d\+ CONCAT\_s*' ..
790 '\d\+ STORE $0\_s*' ..
791 'endfor\_s*' ..
792 '\d\+ JUMP -> 6\_s*' ..
793 '\d\+ DROP\_s*' ..
794 'return res\_s*' ..
795 '\d\+ LOAD $0\_s*' ..
796 '\d\+ RETURN',
797 instr)
798enddef
799
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100800let g:number = 42
801
802def Computing()
803 let nr = 3
804 let nrres = nr + 7
805 nrres = nr - 7
806 nrres = nr * 7
807 nrres = nr / 7
808 nrres = nr % 7
809
810 let anyres = g:number + 7
811 anyres = g:number - 7
812 anyres = g:number * 7
813 anyres = g:number / 7
814 anyres = g:number % 7
815
816 if has('float')
817 let fl = 3.0
818 let flres = fl + 7.0
819 flres = fl - 7.0
820 flres = fl * 7.0
821 flres = fl / 7.0
822 endif
823enddef
824
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100825def Test_disassemble_computing()
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100826 let instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200827 assert_match('Computing.*' ..
828 'let nr = 3.*' ..
829 '\d STORE 3 in $0.*' ..
830 'let nrres = nr + 7.*' ..
831 '\d LOAD $0.*' ..
832 '\d PUSHNR 7.*' ..
833 '\d OPNR +.*' ..
834 '\d STORE $1.*' ..
835 'nrres = nr - 7.*' ..
836 '\d OPNR -.*' ..
837 'nrres = nr \* 7.*' ..
838 '\d OPNR \*.*' ..
839 'nrres = nr / 7.*' ..
840 '\d OPNR /.*' ..
841 'nrres = nr % 7.*' ..
842 '\d OPNR %.*' ..
843 'let anyres = g:number + 7.*' ..
844 '\d LOADG g:number.*' ..
845 '\d PUSHNR 7.*' ..
846 '\d OPANY +.*' ..
847 '\d STORE $2.*' ..
848 'anyres = g:number - 7.*' ..
849 '\d OPANY -.*' ..
850 'anyres = g:number \* 7.*' ..
851 '\d OPANY \*.*' ..
852 'anyres = g:number / 7.*' ..
853 '\d OPANY /.*' ..
854 'anyres = g:number % 7.*' ..
855 '\d OPANY %.*',
856 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100857 if has('float')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200858 assert_match('Computing.*' ..
859 'let fl = 3.0.*' ..
860 '\d PUSHF 3.0.*' ..
861 '\d STORE $3.*' ..
862 'let flres = fl + 7.0.*' ..
863 '\d LOAD $3.*' ..
864 '\d PUSHF 7.0.*' ..
865 '\d OPFLOAT +.*' ..
866 '\d STORE $4.*' ..
867 'flres = fl - 7.0.*' ..
868 '\d OPFLOAT -.*' ..
869 'flres = fl \* 7.0.*' ..
870 '\d OPFLOAT \*.*' ..
871 'flres = fl / 7.0.*' ..
872 '\d OPFLOAT /.*',
873 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +0100874 endif
875enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100876
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100877def AddListBlob()
878 let reslist = [1, 2] + [3, 4]
879 let resblob = 0z1122 + 0z3344
880enddef
881
882def Test_disassemble_add_list_blob()
883 let instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200884 assert_match('AddListBlob.*' ..
885 'let reslist = \[1, 2] + \[3, 4].*' ..
886 '\d PUSHNR 1.*' ..
887 '\d PUSHNR 2.*' ..
888 '\d NEWLIST size 2.*' ..
889 '\d PUSHNR 3.*' ..
890 '\d PUSHNR 4.*' ..
891 '\d NEWLIST size 2.*' ..
892 '\d ADDLIST.*' ..
893 '\d STORE $.*.*' ..
894 'let resblob = 0z1122 + 0z3344.*' ..
895 '\d PUSHBLOB 0z1122.*' ..
896 '\d PUSHBLOB 0z3344.*' ..
897 '\d ADDBLOB.*' ..
898 '\d STORE $.*',
899 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100900enddef
901
902let g:aa = 'aa'
903def ConcatString(): string
904 let res = g:aa .. "bb"
905 return res
906enddef
907
908def Test_disassemble_concat()
909 let instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200910 assert_match('ConcatString.*' ..
911 'let res = g:aa .. "bb".*' ..
912 '\d LOADG g:aa.*' ..
913 '\d PUSHS "bb".*' ..
914 '\d 2STRING stack\[-2].*' ..
915 '\d CONCAT.*' ..
916 '\d STORE $.*',
917 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100918 assert_equal('aabb', ConcatString())
919enddef
920
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200921def StringIndex(): number
922 let s = "abcd"
923 let res = s[1]
924 return res
925enddef
926
927def Test_disassemble_string_index()
928 let instr = execute('disassemble StringIndex')
929 assert_match('StringIndex\_s*' ..
930 'let s = "abcd"\_s*' ..
931 '\d PUSHS "abcd"\_s*' ..
932 '\d STORE $0\_s*' ..
933 'let res = s\[1]\_s*' ..
934 '\d LOAD $0\_s*' ..
935 '\d PUSHNR 1\_s*' ..
936 '\d STRINDEX\_s*' ..
937 '\d STORE $1\_s*',
938 instr)
939 assert_equal('b', StringIndex())
940enddef
941
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100942def ListIndex(): number
943 let l = [1, 2, 3]
944 let res = l[1]
945 return res
946enddef
947
948def Test_disassemble_list_index()
949 let instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200950 assert_match('ListIndex\_s*' ..
951 'let l = \[1, 2, 3]\_s*' ..
952 '\d PUSHNR 1\_s*' ..
953 '\d PUSHNR 2\_s*' ..
954 '\d PUSHNR 3\_s*' ..
955 '\d NEWLIST size 3\_s*' ..
956 '\d STORE $0\_s*' ..
957 'let res = l\[1]\_s*' ..
958 '\d LOAD $0\_s*' ..
959 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +0200960 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200961 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200962 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100963 assert_equal(2, ListIndex())
964enddef
965
966def DictMember(): number
967 let d = #{item: 1}
968 let res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200969 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100970 return res
971enddef
972
973def Test_disassemble_dict_member()
974 let instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +0200975 assert_match('DictMember\_s*' ..
976 'let d = #{item: 1}\_s*' ..
977 '\d PUSHS "item"\_s*' ..
978 '\d PUSHNR 1\_s*' ..
979 '\d NEWDICT size 1\_s*' ..
980 '\d STORE $0\_s*' ..
981 'let res = d.item\_s*' ..
982 '\d\+ LOAD $0\_s*' ..
983 '\d\+ MEMBER item\_s*' ..
984 '\d\+ STORE $1\_s*' ..
985 'res = d\["item"\]\_s*' ..
986 '\d\+ LOAD $0\_s*' ..
987 '\d\+ PUSHS "item"\_s*' ..
988 '\d\+ MEMBER\_s*' ..
989 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200990 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +0100991 call assert_equal(1, DictMember())
992enddef
993
994def NegateNumber(): number
995 let nr = 9
996 let plus = +nr
997 let res = -nr
998 return res
999enddef
1000
1001def Test_disassemble_negate_number()
1002 let instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001003 assert_match('NegateNumber\_s*' ..
1004 'let nr = 9\_s*' ..
1005 '\d STORE 9 in $0\_s*' ..
1006 'let plus = +nr\_s*' ..
1007 '\d LOAD $0\_s*' ..
1008 '\d CHECKNR\_s*' ..
1009 '\d STORE $1\_s*' ..
1010 'let res = -nr\_s*' ..
1011 '\d LOAD $0\_s*' ..
1012 '\d NEGATENR\_s*' ..
1013 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001014 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001015 call assert_equal(-9, NegateNumber())
1016enddef
1017
1018def InvertBool(): bool
1019 let flag = true
1020 let invert = !flag
1021 let res = !!flag
1022 return res
1023enddef
1024
1025def Test_disassemble_invert_bool()
1026 let instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001027 assert_match('InvertBool\_s*' ..
1028 'let flag = true\_s*' ..
1029 '\d PUSH v:true\_s*' ..
1030 '\d STORE $0\_s*' ..
1031 'let invert = !flag\_s*' ..
1032 '\d LOAD $0\_s*' ..
1033 '\d INVERT (!val)\_s*' ..
1034 '\d STORE $1\_s*' ..
1035 'let res = !!flag\_s*' ..
1036 '\d LOAD $0\_s*' ..
1037 '\d 2BOOL (!!val)\_s*' ..
1038 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001039 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001040 call assert_equal(true, InvertBool())
1041enddef
1042
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001043def Test_disassemble_compare()
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001044 let cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02001045 ['true == isFalse', 'COMPAREBOOL =='],
1046 ['true != isFalse', 'COMPAREBOOL !='],
1047 ['v:none == isNull', 'COMPARESPECIAL =='],
1048 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001049
Bram Moolenaara5565e42020-05-09 15:44:01 +02001050 ['111 == aNumber', 'COMPARENR =='],
1051 ['111 != aNumber', 'COMPARENR !='],
1052 ['111 > aNumber', 'COMPARENR >'],
1053 ['111 < aNumber', 'COMPARENR <'],
1054 ['111 >= aNumber', 'COMPARENR >='],
1055 ['111 <= aNumber', 'COMPARENR <='],
1056 ['111 =~ aNumber', 'COMPARENR =\~'],
1057 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001058
Bram Moolenaara5565e42020-05-09 15:44:01 +02001059 ['"xx" != aString', 'COMPARESTRING !='],
1060 ['"xx" > aString', 'COMPARESTRING >'],
1061 ['"xx" < aString', 'COMPARESTRING <'],
1062 ['"xx" >= aString', 'COMPARESTRING >='],
1063 ['"xx" <= aString', 'COMPARESTRING <='],
1064 ['"xx" =~ aString', 'COMPARESTRING =\~'],
1065 ['"xx" !~ aString', 'COMPARESTRING !\~'],
1066 ['"xx" is aString', 'COMPARESTRING is'],
1067 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001068
Bram Moolenaara5565e42020-05-09 15:44:01 +02001069 ['0z11 == aBlob', 'COMPAREBLOB =='],
1070 ['0z11 != aBlob', 'COMPAREBLOB !='],
1071 ['0z11 is aBlob', 'COMPAREBLOB is'],
1072 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001073
Bram Moolenaara5565e42020-05-09 15:44:01 +02001074 ['[1, 2] == aList', 'COMPARELIST =='],
1075 ['[1, 2] != aList', 'COMPARELIST !='],
1076 ['[1, 2] is aList', 'COMPARELIST is'],
1077 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001078
Bram Moolenaara5565e42020-05-09 15:44:01 +02001079 ['#{a: 1} == aDict', 'COMPAREDICT =='],
1080 ['#{a: 1} != aDict', 'COMPAREDICT !='],
1081 ['#{a: 1} is aDict', 'COMPAREDICT is'],
1082 ['#{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001083
1084 ['{->33} == {->44}', 'COMPAREFUNC =='],
1085 ['{->33} != {->44}', 'COMPAREFUNC !='],
1086 ['{->33} is {->44}', 'COMPAREFUNC is'],
1087 ['{->33} isnot {->44}', 'COMPAREFUNC isnot'],
1088
1089 ['77 == g:xx', 'COMPAREANY =='],
1090 ['77 != g:xx', 'COMPAREANY !='],
1091 ['77 > g:xx', 'COMPAREANY >'],
1092 ['77 < g:xx', 'COMPAREANY <'],
1093 ['77 >= g:xx', 'COMPAREANY >='],
1094 ['77 <= g:xx', 'COMPAREANY <='],
1095 ['77 =~ g:xx', 'COMPAREANY =\~'],
1096 ['77 !~ g:xx', 'COMPAREANY !\~'],
1097 ['77 is g:xx', 'COMPAREANY is'],
1098 ['77 isnot g:xx', 'COMPAREANY isnot'],
1099 ]
Bram Moolenaara5565e42020-05-09 15:44:01 +02001100 let floatDecl = ''
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001101 if has('float')
1102 cases->extend([
Bram Moolenaara5565e42020-05-09 15:44:01 +02001103 ['1.1 == aFloat', 'COMPAREFLOAT =='],
1104 ['1.1 != aFloat', 'COMPAREFLOAT !='],
1105 ['1.1 > aFloat', 'COMPAREFLOAT >'],
1106 ['1.1 < aFloat', 'COMPAREFLOAT <'],
1107 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
1108 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
1109 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
1110 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02001111 ])
Bram Moolenaara5565e42020-05-09 15:44:01 +02001112 floatDecl = 'let aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001113 endif
1114
1115 let nr = 1
1116 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001117 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001118 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaara5565e42020-05-09 15:44:01 +02001119 ' let isFalse = false',
1120 ' let isNull = v:null',
1121 ' let aNumber = 222',
1122 ' let aString = "yy"',
1123 ' let aBlob = 0z22',
1124 ' let aList = [3, 4]',
1125 ' let aDict = #{x: 2}',
1126 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02001127 ' if ' .. case[0],
1128 ' echo 42'
1129 ' endif',
1130 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001131 source Xdisassemble
1132 let instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02001133 assert_match('TestCase' .. nr .. '.*' ..
1134 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1135 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02001136 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001137 '\d ' .. case[1] .. '.*' ..
1138 '\d JUMP_IF_FALSE -> \d\+.*',
1139 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001140
1141 nr += 1
1142 endfor
1143
Bram Moolenaar22da5592020-03-19 14:52:20 +01001144 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001145enddef
1146
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001147def Test_disassemble_compare_const()
1148 let cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02001149 ['"xx" == "yy"', false],
1150 ['"aa" == "aa"', true],
1151 ['has("eval") ? true : false', true],
1152 ['has("asdf") ? true : false', false],
1153 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001154
1155 let nr = 1
1156 for case in cases
1157 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001158 ' if ' .. case[0],
1159 ' echo 42'
1160 ' endif',
1161 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001162 source Xdisassemble
1163 let instr = execute('disassemble TestCase' .. nr)
1164 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001165 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02001166 assert_match('TestCase' .. nr .. '.*' ..
1167 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
1168 '\d PUSHNR 42.*' ..
1169 '\d ECHO 1.*' ..
1170 '\d PUSHNR 0.*' ..
1171 '\d RETURN.*',
1172 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001173 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001174 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02001175 assert_match('TestCase' .. nr .. '.*' ..
1176 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
1177 'echo 42[ \n]*' ..
1178 'endif[ \n]*' ..
1179 '\s*\d PUSHNR 0.*' ..
1180 '\d RETURN.*',
1181 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02001182 endif
1183
1184 nr += 1
1185 endfor
1186
1187 delete('Xdisassemble')
1188enddef
1189
Bram Moolenaarad39c092020-02-26 18:23:43 +01001190def s:Execute()
1191 execute 'help vim9.txt'
1192 let cmd = 'help vim9.txt'
1193 execute cmd
1194 let tag = 'vim9.txt'
1195 execute 'help ' .. tag
1196enddef
1197
1198def Test_disassemble_execute()
1199 let res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001200 assert_match('\<SNR>\d*_Execute\_s*' ..
1201 "execute 'help vim9.txt'\\_s*" ..
1202 '\d PUSHS "help vim9.txt"\_s*' ..
1203 '\d EXECUTE 1\_s*' ..
1204 "let cmd = 'help vim9.txt'\\_s*" ..
1205 '\d PUSHS "help vim9.txt"\_s*' ..
1206 '\d STORE $0\_s*' ..
1207 'execute cmd\_s*' ..
1208 '\d LOAD $0\_s*' ..
1209 '\d EXECUTE 1\_s*' ..
1210 "let tag = 'vim9.txt'\\_s*" ..
1211 '\d PUSHS "vim9.txt"\_s*' ..
1212 '\d STORE $1\_s*' ..
1213 "execute 'help ' .. tag\\_s*" ..
1214 '\d\+ PUSHS "help "\_s*' ..
1215 '\d\+ LOAD $1\_s*' ..
1216 '\d\+ CONCAT\_s*' ..
1217 '\d\+ EXECUTE 1\_s*' ..
1218 '\d\+ PUSHNR 0\_s*' ..
1219 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001220 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01001221enddef
1222
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001223def s:Echomsg()
1224 echomsg 'some' 'message'
1225 echoerr 'went' .. 'wrong'
1226enddef
1227
1228def Test_disassemble_echomsg()
1229 let res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001230 assert_match('\<SNR>\d*_Echomsg\_s*' ..
1231 "echomsg 'some' 'message'\\_s*" ..
1232 '\d PUSHS "some"\_s*' ..
1233 '\d PUSHS "message"\_s*' ..
1234 '\d ECHOMSG 2\_s*' ..
1235 "echoerr 'went' .. 'wrong'\\_s*" ..
1236 '\d PUSHS "wentwrong"\_s*' ..
1237 '\d ECHOERR 1\_s*' ..
1238 '\d PUSHNR 0\_s*' ..
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02001239 '\d RETURN',
1240 res)
1241enddef
1242
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001243def SomeStringArg(arg: string)
1244 echo arg
1245enddef
1246
1247def SomeAnyArg(arg: any)
1248 echo arg
1249enddef
1250
1251def SomeStringArgAndReturn(arg: string): string
1252 return arg
1253enddef
1254
1255def Test_display_func()
1256 let res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001257 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
1258 '\d *echo arg.*' ..
1259 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001260 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001261
1262 let res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001263 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
1264 '\d *echo arg\_s*' ..
1265 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001266 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001267
1268 let res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001269 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
1270 '\d *return arg\_s*' ..
1271 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001272 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01001273enddef
1274
Bram Moolenaar09689a02020-05-09 22:50:08 +02001275def Test_vim9script_forward_func()
1276 let lines =<< trim END
1277 vim9script
1278 def FuncOne(): string
1279 return FuncTwo()
1280 enddef
1281 def FuncTwo(): string
1282 return 'two'
1283 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02001284 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02001285 END
1286 writefile(lines, 'Xdisassemble')
1287 source Xdisassemble
1288
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001289 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001290 assert_match('\<SNR>\d*_FuncOne\_s*' ..
1291 'return FuncTwo()\_s*' ..
1292 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02001293 '\d RETURN',
1294 g:res_FuncOne)
1295
1296 delete('Xdisassemble')
1297 unlet g:res_FuncOne
1298enddef
1299
Bram Moolenaar61a89812020-05-07 16:58:17 +02001300def s:ConcatStrings(): string
1301 return 'one' .. 'two' .. 'three'
1302enddef
1303
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001304def s:ComputeConst(): number
1305 return 2 + 3 * 4 / 6 + 7
1306enddef
1307
Bram Moolenaar1c747212020-05-09 18:28:34 +02001308def s:ComputeConstParen(): number
1309 return ((2 + 4) * (8 / 2)) / (3 + 4)
1310enddef
1311
Bram Moolenaar61a89812020-05-07 16:58:17 +02001312def Test_simplify_const_expr()
1313 let res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001314 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
1315 "return 'one' .. 'two' .. 'three'\\_s*" ..
1316 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02001317 '\d RETURN',
1318 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001319
1320 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001321 assert_match('<SNR>\d*_ComputeConst\_s*' ..
1322 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
1323 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02001324 '\d RETURN',
1325 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02001326
1327 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02001328 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
1329 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
1330 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02001331 '\d RETURN',
1332 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02001333enddef
1334
Bram Moolenaar389df252020-07-09 21:20:47 +02001335def s:CallAppend()
1336 eval "some text"->append(2)
1337enddef
1338
1339def Test_shuffle()
1340 let res = execute('disass s:CallAppend')
1341 assert_match('<SNR>\d*_CallAppend\_s*' ..
1342 'eval "some text"->append(2)\_s*' ..
1343 '\d PUSHS "some text"\_s*' ..
1344 '\d PUSHNR 2\_s*' ..
1345 '\d SHUFFLE 2 up 1\_s*' ..
1346 '\d BCALL append(argc 2)\_s*' ..
1347 '\d DROP\_s*' ..
1348 '\d PUSHNR 0\_s*' ..
1349 '\d RETURN',
1350 res)
1351enddef
1352
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001353" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker