blob: e98ab75afae6505e928158be7bc4a42153b0b6c2 [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
Bram Moolenaar62aec932022-01-29 21:45:34 +00004import './vim9.vim' as v9
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01005
Bram Moolenaar62aec932022-01-29 21:45:34 +00006func s:NotCompiled()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01007 echo "not"
8endfunc
9
10let s:scriptvar = 4
11let g:globalvar = 'g'
Bram Moolenaard3aac292020-04-19 14:32:17 +020012let b:buffervar = 'b'
13let w:windowvar = 'w'
14let t:tabpagevar = 't'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010015
16def s:ScriptFuncLoad(arg: string)
Bram Moolenaarac564082020-09-27 19:05:33 +020017 var local = 1
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010018 buffers
Bram Moolenaare4984292020-12-13 14:19:25 +010019 echo
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010020 echo arg
21 echo local
Bram Moolenaar8a1c1012020-05-07 14:07:25 +020022 echo &lines
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010023 echo v:version
24 echo s:scriptvar
25 echo g:globalvar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020026 echo get(g:, "global")
Bram Moolenaar03290b82020-12-19 16:30:44 +010027 echo g:auto#var
Bram Moolenaard3aac292020-04-19 14:32:17 +020028 echo b:buffervar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020029 echo get(b:, "buffer")
Bram Moolenaard3aac292020-04-19 14:32:17 +020030 echo w:windowvar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020031 echo get(w:, "window")
Bram Moolenaard3aac292020-04-19 14:32:17 +020032 echo t:tabpagevar
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020033 echo get(t:, "tab")
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010034 echo &tabstop
35 echo $ENVVAR
36 echo @z
37enddef
38
Bram Moolenaarf2460a32020-02-07 22:09:54 +010039def Test_disassemble_load()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010040 assert_fails('disass NoFunc', 'E1061:')
Bram Moolenaar451c2e32020-08-15 16:33:28 +020041 assert_fails('disass NotCompiled', 'E1091:')
Bram Moolenaar21456cd2020-02-13 21:29:32 +010042 assert_fails('disass', 'E471:')
43 assert_fails('disass [', 'E475:')
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +020044 assert_fails('disass 234', 'E129:')
45 assert_fails('disass <XX>foo', 'E129:')
Bram Moolenaarf79d9dd2022-05-21 15:39:02 +010046 assert_fails('disass Test_disassemble_load burp', 'E488:')
47 assert_fails('disass debug debug Test_disassemble_load', 'E488:')
48 assert_fails('disass profile profile Test_disassemble_load', 'E488:')
Bram Moolenaar5cab73f2020-02-06 19:25:19 +010049
Bram Moolenaarac564082020-09-27 19:05:33 +020050 var res = execute('disass s:ScriptFuncLoad')
Bram Moolenaar675f7162020-04-12 22:53:54 +020051 assert_match('<SNR>\d*_ScriptFuncLoad.*' ..
Bram Moolenaare4984292020-12-13 14:19:25 +010052 'buffers\_s*' ..
53 '\d\+ EXEC \+buffers\_s*' ..
54 'echo\_s*' ..
55 'echo arg\_s*' ..
56 '\d\+ LOAD arg\[-1\]\_s*' ..
57 '\d\+ ECHO 1\_s*' ..
58 'echo local\_s*' ..
59 '\d\+ LOAD $0\_s*' ..
60 '\d\+ ECHO 1\_s*' ..
61 'echo &lines\_s*' ..
62 '\d\+ LOADOPT &lines\_s*' ..
63 '\d\+ ECHO 1\_s*' ..
64 'echo v:version\_s*' ..
65 '\d\+ LOADV v:version\_s*' ..
66 '\d\+ ECHO 1\_s*' ..
67 'echo s:scriptvar\_s*' ..
68 '\d\+ LOADS s:scriptvar from .*test_vim9_disassemble.vim\_s*' ..
69 '\d\+ ECHO 1\_s*' ..
70 'echo g:globalvar\_s*' ..
71 '\d\+ LOADG g:globalvar\_s*' ..
72 '\d\+ ECHO 1\_s*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020073 'echo get(g:, "global")\_s*' ..
74 '\d\+ LOAD g:\_s*' ..
75 '\d\+ PUSHS "global"\_s*' ..
Bram Moolenaar03290b82020-12-19 16:30:44 +010076 '\d\+ BCALL get(argc 2)\_s*' ..
77 '\d\+ ECHO 1\_s*' ..
78 'echo g:auto#var\_s*' ..
79 '\d\+ LOADAUTO g:auto#var\_s*' ..
80 '\d\+ ECHO 1\_s*' ..
81 'echo b:buffervar\_s*' ..
82 '\d\+ LOADB b:buffervar\_s*' ..
83 '\d\+ ECHO 1\_s*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020084 'echo get(b:, "buffer")\_s*' ..
85 '\d\+ LOAD b:\_s*' ..
86 '\d\+ PUSHS "buffer"\_s*' ..
87 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020088 ' LOADW w:windowvar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020089 'echo get(w:, "window")\_s*' ..
90 '\d\+ LOAD w:\_s*' ..
91 '\d\+ PUSHS "window"\_s*' ..
92 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +020093 ' LOADT t:tabpagevar.*' ..
Bram Moolenaar2f8ce0a2020-07-19 19:47:35 +020094 'echo get(t:, "tab")\_s*' ..
95 '\d\+ LOAD t:\_s*' ..
96 '\d\+ PUSHS "tab"\_s*' ..
97 '\d\+ BCALL get(argc 2).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +020098 ' LOADENV $ENVVAR.*' ..
99 ' LOADREG @z.*',
100 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100101enddef
102
Bram Moolenaarcfe435d2020-04-25 20:02:55 +0200103def s:EditExpand()
Bram Moolenaarac564082020-09-27 19:05:33 +0200104 var filename = "file"
105 var filenr = 123
Bram Moolenaarcfe435d2020-04-25 20:02:55 +0200106 edit the`=filename``=filenr`.txt
107enddef
108
109def Test_disassemble_exec_expr()
Bram Moolenaarac564082020-09-27 19:05:33 +0200110 var res = execute('disass s:EditExpand')
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200111 assert_match('<SNR>\d*_EditExpand\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200112 ' var filename = "file"\_s*' ..
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200113 '\d PUSHS "file"\_s*' ..
114 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200115 ' var filenr = 123\_s*' ..
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200116 '\d STORE 123 in $1\_s*' ..
117 ' edit the`=filename``=filenr`.txt\_s*' ..
118 '\d PUSHS "edit the"\_s*' ..
119 '\d LOAD $0\_s*' ..
120 '\d LOAD $1\_s*' ..
121 '\d 2STRING stack\[-1\]\_s*' ..
122 '\d\+ PUSHS ".txt"\_s*' ..
123 '\d\+ EXECCONCAT 4\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200124 '\d\+ RETURN void',
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200125 res)
126enddef
127
Bram Moolenaar20677332021-06-06 17:02:53 +0200128if has('python3')
129 def s:PyHeredoc()
130 python3 << EOF
131 print('hello')
132EOF
133 enddef
134
135 def Test_disassemble_python_heredoc()
136 var res = execute('disass s:PyHeredoc')
137 assert_match('<SNR>\d*_PyHeredoc.*' ..
138 " python3 << EOF^@ print('hello')^@EOF\\_s*" ..
139 '\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200140 '\d RETURN void',
Bram Moolenaar20677332021-06-06 17:02:53 +0200141 res)
142 enddef
143endif
144
Bram Moolenaar4c137212021-04-19 16:48:48 +0200145def s:Substitute()
146 var expr = "abc"
147 :%s/a/\=expr/&g#c
148enddef
149
150def Test_disassemble_substitute()
151 var res = execute('disass s:Substitute')
152 assert_match('<SNR>\d*_Substitute.*' ..
153 ' var expr = "abc"\_s*' ..
154 '\d PUSHS "abc"\_s*' ..
155 '\d STORE $0\_s*' ..
156 ' :%s/a/\\=expr/&g#c\_s*' ..
157 '\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
158 ' 0 LOAD $0\_s*' ..
159 ' -------------\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200160 '\d RETURN void',
Bram Moolenaar4c137212021-04-19 16:48:48 +0200161 res)
162enddef
163
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200164
165def s:SearchPair()
166 var col = 8
167 searchpair("{", "", "}", "", "col('.') > col")
168enddef
169
170def Test_disassemble_seachpair()
171 var res = execute('disass s:SearchPair')
172 assert_match('<SNR>\d*_SearchPair.*' ..
173 ' var col = 8\_s*' ..
174 '\d STORE 8 in $0\_s*' ..
175 ' searchpair("{", "", "}", "", "col(''.'') > col")\_s*' ..
176 '\d PUSHS "{"\_s*' ..
177 '\d PUSHS ""\_s*' ..
178 '\d PUSHS "}"\_s*' ..
179 '\d PUSHS ""\_s*' ..
180 '\d INSTR\_s*' ..
181 ' 0 PUSHS "."\_s*' ..
182 ' 1 BCALL col(argc 1)\_s*' ..
183 ' 2 LOAD $0\_s*' ..
184 ' 3 COMPARENR >\_s*' ..
185 ' -------------\_s*' ..
186 '\d BCALL searchpair(argc 5)\_s*' ..
187 '\d DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200188 '\d RETURN void',
Bram Moolenaarf18332f2021-05-07 17:55:55 +0200189 res)
190enddef
191
192
LemonBoyf3b48952022-05-05 13:53:03 +0100193def s:SubstituteExpr()
194 substitute('a', 'b', '\=123', 'g')
195enddef
196
197def Test_disassemble_substitute_expr()
198 var res = execute('disass s:SubstituteExpr')
199 assert_match('<SNR>\d*_SubstituteExpr.*' ..
200 'substitute(''a'', ''b'', ''\\=123'', ''g'')\_s*' ..
201 '\d PUSHS "a"\_s*' ..
202 '\d PUSHS "b"\_s*' ..
203 '\d INSTR\_s*' ..
204 ' 0 PUSHNR 123\_s*' ..
205 ' -------------\_s*' ..
206 '\d PUSHS "g"\_s*' ..
207 '\d BCALL substitute(argc 4)\_s*' ..
208 '\d DROP\_s*' ..
209 '\d RETURN void',
210 res)
211enddef
212
Bram Moolenaar2d1c57e2021-04-19 20:50:03 +0200213def s:RedirVar()
214 var result: string
215 redir =>> result
216 echo "text"
217 redir END
218enddef
219
220def Test_disassemble_redir_var()
221 var res = execute('disass s:RedirVar')
222 assert_match('<SNR>\d*_RedirVar.*' ..
223 ' var result: string\_s*' ..
224 '\d PUSHS "\[NULL\]"\_s*' ..
225 '\d STORE $0\_s*' ..
226 ' redir =>> result\_s*' ..
227 '\d REDIR\_s*' ..
228 ' echo "text"\_s*' ..
229 '\d PUSHS "text"\_s*' ..
230 '\d ECHO 1\_s*' ..
231 ' redir END\_s*' ..
232 '\d LOAD $0\_s*' ..
233 '\d REDIR END\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +0100234 '\d CONCAT size 2\_s*' ..
Bram Moolenaar2d1c57e2021-04-19 20:50:03 +0200235 '\d STORE $0\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200236 '\d RETURN void',
Bram Moolenaar2d1c57e2021-04-19 20:50:03 +0200237 res)
238enddef
239
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200240def s:Cexpr()
241 var errors = "list of errors"
242 cexpr errors
243enddef
244
245def Test_disassemble_cexpr()
John Marriott45377e22025-03-27 18:12:32 +0100246 CheckFeature quickfix
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200247 var res = execute('disass s:Cexpr')
248 assert_match('<SNR>\d*_Cexpr.*' ..
249 ' var errors = "list of errors"\_s*' ..
250 '\d PUSHS "list of errors"\_s*' ..
251 '\d STORE $0\_s*' ..
252 ' cexpr errors\_s*' ..
253 '\d CEXPR pre cexpr\_s*' ..
254 '\d LOAD $0\_s*' ..
255 '\d CEXPR core cexpr "cexpr errors"\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200256 '\d RETURN void',
Bram Moolenaar5f7d4c02021-05-05 21:31:39 +0200257 res)
258enddef
259
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200260def s:YankRange()
261 norm! m[jjm]
262 :'[,']yank
263enddef
264
265def Test_disassemble_yank_range()
Bram Moolenaarac564082020-09-27 19:05:33 +0200266 var res = execute('disass s:YankRange')
Bram Moolenaar7c5ad342020-08-12 15:48:55 +0200267 assert_match('<SNR>\d*_YankRange.*' ..
268 ' norm! m\[jjm\]\_s*' ..
269 '\d EXEC norm! m\[jjm\]\_s*' ..
270 ' :''\[,''\]yank\_s*' ..
271 '\d EXEC :''\[,''\]yank\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200272 '\d RETURN void',
Bram Moolenaarcfe435d2020-04-25 20:02:55 +0200273 res)
274enddef
275
Bram Moolenaarc3516f72020-09-08 22:45:35 +0200276def s:PutExpr()
277 :3put ="text"
278enddef
279
280def Test_disassemble_put_expr()
Bram Moolenaarac564082020-09-27 19:05:33 +0200281 var res = execute('disass s:PutExpr')
Bram Moolenaarc3516f72020-09-08 22:45:35 +0200282 assert_match('<SNR>\d*_PutExpr.*' ..
283 ' :3put ="text"\_s*' ..
284 '\d PUSHS "text"\_s*' ..
285 '\d PUT = 3\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200286 '\d RETURN void',
Bram Moolenaarc3516f72020-09-08 22:45:35 +0200287 res)
288enddef
289
64-bitmane08f10a2025-03-18 22:14:34 +0100290def s:IputExpr()
291 :3iput ="text"
292enddef
293
294def Test_disassemble_iput_expr()
295 var res = execute('disass s:IputExpr')
296 assert_match('<SNR>\d*_IputExpr.*' ..
297 ' :3iput ="text"\_s*' ..
298 '\d PUSHS "text"\_s*' ..
299 '\d IPUT = 3\_s*' ..
300 '\d RETURN void',
301 res)
302enddef
303
Bram Moolenaar08597872020-12-10 19:43:40 +0100304def s:PutRange()
305 :$-2put a
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100306 :$-3put! b
Bram Moolenaar08597872020-12-10 19:43:40 +0100307enddef
308
309def Test_disassemble_put_range()
310 var res = execute('disass s:PutRange')
311 assert_match('<SNR>\d*_PutRange.*' ..
312 ' :$-2put a\_s*' ..
313 '\d RANGE $-2\_s*' ..
314 '\d PUT a range\_s*' ..
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100315
316 ' :$-3put! b\_s*' ..
317 '\d RANGE $-3\_s*' ..
318 '\d PUT b above range\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200319 '\d RETURN void',
Bram Moolenaar08597872020-12-10 19:43:40 +0100320 res)
321enddef
322
64-bitmane08f10a2025-03-18 22:14:34 +0100323def s:IputRange()
324 :$-2iput a
325 :$-3iput! b
326enddef
327
328def Test_disassemble_iput_range()
329 var res = execute('disass s:IputRange')
330 assert_match('<SNR>\d*_IputRange.*' ..
331 ' :$-2iput a\_s*' ..
332 '\d RANGE $-2\_s*' ..
333 '\d IPUT a range\_s*' ..
334
335 ' :$-3iput! b\_s*' ..
336 '\d RANGE $-3\_s*' ..
337 '\d IPUT b above range\_s*' ..
338 '\d RETURN void',
339 res)
340enddef
341
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100342def s:ScriptFuncPush()
Bram Moolenaarac564082020-09-27 19:05:33 +0200343 var localbool = true
344 var localspec = v:none
345 var localblob = 0z1234
Bram Moolenaar73e28dc2022-09-17 21:08:33 +0100346 var localfloat = 1.234
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100347enddef
348
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100349def Test_disassemble_push()
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +0100350 mkdir('Xdisdir/autoload', 'pR')
Bram Moolenaar06b77222022-01-25 15:51:56 +0000351 var save_rtp = &rtp
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100352 exe 'set rtp^=' .. getcwd() .. '/Xdisdir'
Bram Moolenaar06b77222022-01-25 15:51:56 +0000353
354 var lines =<< trim END
355 vim9script
356 END
Bram Moolenaar3b0d70f2022-08-29 22:31:20 +0100357 writefile(lines, 'Xdisdir/autoload/autoscript.vim')
Bram Moolenaar06b77222022-01-25 15:51:56 +0000358
359 lines =<< trim END
360 vim9script
361 import autoload 'autoscript.vim'
362
Bram Moolenaara749a422022-02-12 19:52:25 +0000363 def AutoloadFunc()
Bram Moolenaar06b77222022-01-25 15:51:56 +0000364 &operatorfunc = autoscript.Opfunc
365 enddef
366
Bram Moolenaara749a422022-02-12 19:52:25 +0000367 var res = execute('disass AutoloadFunc')
Bram Moolenaar06b77222022-01-25 15:51:56 +0000368 assert_match('<SNR>\d*_AutoloadFunc.*' ..
369 '&operatorfunc = autoscript.Opfunc\_s*' ..
370 '0 AUTOLOAD autoscript#Opfunc\_s*' ..
371 '1 STOREFUNCOPT &operatorfunc\_s*' ..
372 '2 RETURN void',
373 res)
374 END
Bram Moolenaar62aec932022-01-29 21:45:34 +0000375 v9.CheckScriptSuccess(lines)
Bram Moolenaar06b77222022-01-25 15:51:56 +0000376
Bram Moolenaar06b77222022-01-25 15:51:56 +0000377 &rtp = save_rtp
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100378enddef
379
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +0100380def Test_disassemble_import_autoload()
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +0100381 writefile(['vim9script'], 'XimportAL.vim', 'D')
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +0100382
383 var lines =<< trim END
384 vim9script
385 import autoload './XimportAL.vim'
386
387 def AutoloadFunc()
388 echo XimportAL.SomeFunc()
389 echo XimportAL.someVar
390 XimportAL.someVar = "yes"
391 enddef
392
393 var res = execute('disass AutoloadFunc')
394 assert_match('<SNR>\d*_AutoloadFunc.*' ..
395 'echo XimportAL.SomeFunc()\_s*' ..
Bram Moolenaar17125182022-03-30 21:57:50 +0100396 '\d SOURCE .*/testdir/XimportAL.vim\_s*' ..
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +0100397 '\d PUSHFUNC "<80><fd>R\d\+_SomeFunc"\_s*' ..
398 '\d PCALL top (argc 0)\_s*' ..
399 '\d PCALL end\_s*' ..
400 '\d ECHO 1\_s*' ..
401
402 'echo XimportAL.someVar\_s*' ..
403 '\d SOURCE .*/testdir/XimportAL.vim\_s*' ..
404 '\d LOADEXPORT s:someVar from .*/testdir/XimportAL.vim\_s*' ..
405 '\d ECHO 1\_s*' ..
406
407 'XimportAL.someVar = "yes"\_s*' ..
408 '\d\+ PUSHS "yes"\_s*' ..
409 '\d\+ SOURCE .*/testdir/XimportAL.vim\_s*' ..
410 '\d\+ STOREEXPORT someVar in .*/testdir/XimportAL.vim\_s*' ..
411
412 '\d\+ RETURN void',
413 res)
414 END
415 v9.CheckScriptSuccess(lines)
Bram Moolenaarc0ceeeb2022-03-30 21:12:27 +0100416enddef
417
Ernie Rael3f821d62024-04-24 20:07:50 +0200418def Test_disassemble_import_autoload_autoload()
419 mkdir('Xauto_auto/autoload', 'pR')
420 var lines =<< trim END
421 vim9script
422 export const val = 11
423 END
424 writefile(lines, 'Xauto_auto/autoload/Xauto_vars_f1.vim')
425
426 lines =<< trim END
427 vim9script
428
429 import autoload './Xauto_auto/autoload/Xauto_vars_f1.vim' as f1
430 def F()
431 f1.val = 13
432 enddef
433 var res = execute('disass F')
434
435 assert_match('<SNR>\d*_F.*' ..
436 'f1.val = 13\_s*' ..
437 '\d PUSHNR 13\_s*' ..
438 '\d SOURCE .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
439 '\d STOREEXPORT val in .*/Xauto_auto/autoload/Xauto_vars_f1.vim\_s*' ..
440 '\d RETURN void',
441 res)
442 END
443 v9.CheckScriptSuccess(lines)
444enddef
445
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100446def s:ScriptFuncStore()
Bram Moolenaarac564082020-09-27 19:05:33 +0200447 var localnr = 1
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100448 localnr = 2
Bram Moolenaarac564082020-09-27 19:05:33 +0200449 var localstr = 'abc'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100450 localstr = 'xyz'
451 v:char = 'abc'
452 s:scriptvar = 'sv'
453 g:globalvar = 'gv'
Bram Moolenaar03290b82020-12-19 16:30:44 +0100454 g:auto#var = 'av'
Bram Moolenaard3aac292020-04-19 14:32:17 +0200455 b:buffervar = 'bv'
456 w:windowvar = 'wv'
457 t:tabpagevar = 'tv'
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100458 &tabstop = 8
Bram Moolenaardcb53be2021-12-09 14:23:43 +0000459 &opfunc = (t) => len(t)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100460 $ENVVAR = 'ev'
461 @z = 'rv'
462enddef
463
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100464def Test_disassemble_store()
Bram Moolenaarac564082020-09-27 19:05:33 +0200465 var res = execute('disass s:ScriptFuncStore')
Bram Moolenaar675f7162020-04-12 22:53:54 +0200466 assert_match('<SNR>\d*_ScriptFuncStore.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200467 'var localnr = 1.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200468 'localnr = 2.*' ..
469 ' STORE 2 in $0.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200470 'var localstr = ''abc''.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200471 'localstr = ''xyz''.*' ..
472 ' STORE $1.*' ..
473 'v:char = ''abc''.*' ..
474 'STOREV v:char.*' ..
475 's:scriptvar = ''sv''.*' ..
476 ' STORES s:scriptvar in .*test_vim9_disassemble.vim.*' ..
477 'g:globalvar = ''gv''.*' ..
478 ' STOREG g:globalvar.*' ..
Bram Moolenaar03290b82020-12-19 16:30:44 +0100479 'g:auto#var = ''av''.*' ..
480 ' STOREAUTO g:auto#var.*' ..
Bram Moolenaard3aac292020-04-19 14:32:17 +0200481 'b:buffervar = ''bv''.*' ..
482 ' STOREB b:buffervar.*' ..
483 'w:windowvar = ''wv''.*' ..
484 ' STOREW w:windowvar.*' ..
485 't:tabpagevar = ''tv''.*' ..
486 ' STORET t:tabpagevar.*' ..
Bram Moolenaardcb53be2021-12-09 14:23:43 +0000487 '&tabstop = 8\_s*' ..
488 '\d\+ PUSHNR 8\_s*' ..
489 '\d\+ STOREOPT &tabstop\_s*' ..
490 '&opfunc = (t) => len(t)\_s*' ..
491 '\d\+ FUNCREF <lambda>\d\+\_s*' ..
492 '\d\+ STOREFUNCOPT &opfunc\_s*' ..
493 '$ENVVAR = ''ev''\_s*' ..
494 '\d\+ PUSHS "ev"\_s*' ..
495 '\d\+ STOREENV $ENVVAR\_s*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +0200496 '@z = ''rv''.*' ..
Bram Moolenaardcb53be2021-12-09 14:23:43 +0000497 '\d\+ STOREREG @z.*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200498 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100499enddef
500
Bram Moolenaarcb790402020-05-15 20:53:00 +0200501def s:ScriptFuncStoreMember()
Bram Moolenaarac564082020-09-27 19:05:33 +0200502 var locallist: list<number> = []
Bram Moolenaarcb790402020-05-15 20:53:00 +0200503 locallist[0] = 123
Bram Moolenaarac564082020-09-27 19:05:33 +0200504 var localdict: dict<number> = {}
Bram Moolenaarcb790402020-05-15 20:53:00 +0200505 localdict["a"] = 456
Bram Moolenaar51e93322021-04-17 20:44:56 +0200506 var localblob: blob = 0z1122
507 localblob[1] = 33
Bram Moolenaarcb790402020-05-15 20:53:00 +0200508enddef
509
510def Test_disassemble_store_member()
Bram Moolenaarac564082020-09-27 19:05:33 +0200511 var res = execute('disass s:ScriptFuncStoreMember')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200512 assert_match('<SNR>\d*_ScriptFuncStoreMember\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200513 'var locallist: list<number> = []\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200514 '\d NEWLIST size 0\_s*' ..
Bram Moolenaaraa210a32021-01-02 15:41:03 +0100515 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200516 '\d STORE $0\_s*' ..
517 'locallist\[0\] = 123\_s*' ..
518 '\d PUSHNR 123\_s*' ..
519 '\d PUSHNR 0\_s*' ..
520 '\d LOAD $0\_s*' ..
Bram Moolenaar51e93322021-04-17 20:44:56 +0200521 '\d STOREINDEX list\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200522 'var localdict: dict<number> = {}\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200523 '\d NEWDICT size 0\_s*' ..
Bram Moolenaaraa210a32021-01-02 15:41:03 +0100524 '\d SETTYPE dict<number>\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200525 '\d STORE $1\_s*' ..
526 'localdict\["a"\] = 456\_s*' ..
527 '\d\+ PUSHNR 456\_s*' ..
528 '\d\+ PUSHS "a"\_s*' ..
529 '\d\+ LOAD $1\_s*' ..
Bram Moolenaar51e93322021-04-17 20:44:56 +0200530 '\d\+ STOREINDEX dict\_s*' ..
531 'var localblob: blob = 0z1122\_s*' ..
532 '\d\+ PUSHBLOB 0z1122\_s*' ..
533 '\d\+ STORE $2\_s*' ..
534 'localblob\[1\] = 33\_s*' ..
535 '\d\+ PUSHNR 33\_s*' ..
536 '\d\+ PUSHNR 1\_s*' ..
537 '\d\+ LOAD $2\_s*' ..
538 '\d\+ STOREINDEX blob\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200539 '\d\+ RETURN void',
Bram Moolenaarcb790402020-05-15 20:53:00 +0200540 res)
541enddef
542
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +0000543if has('job')
544 def s:StoreNull()
545 var ss = null_string
546 var bb = null_blob
547 var dd = null_dict
548 var ll = null_list
549 var Ff = null_function
550 var Pp = null_partial
551 var jj = null_job
552 var cc = null_channel
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +0200553 var oo = null_object
554 var nc = null_class
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +0000555 enddef
556
557 def Test_disassemble_assign_null()
558 var res = execute('disass s:StoreNull')
559 assert_match('<SNR>\d*_StoreNull\_s*' ..
560 'var ss = null_string\_s*' ..
561 '\d\+ PUSHS "\[NULL\]"\_s*' ..
562 '\d\+ STORE $\d\_s*' ..
563
564 'var bb = null_blob\_s*' ..
565 '\d\+ PUSHBLOB 0z\_s*' ..
566 '\d\+ STORE $\d\_s*' ..
567
568 'var dd = null_dict\_s*' ..
Bram Moolenaarec15b1c2022-03-27 16:29:53 +0100569 '\d\+ NEWDICT size -1\_s*' ..
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +0000570 '\d\+ STORE $\d\_s*' ..
571
572 'var ll = null_list\_s*' ..
Bram Moolenaarec15b1c2022-03-27 16:29:53 +0100573 '\d\+ NEWLIST size -1\_s*' ..
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +0000574 '\d\+ STORE $\d\_s*' ..
575
576 'var Ff = null_function\_s*' ..
577 '\d\+ PUSHFUNC "\[none\]"\_s*' ..
578 '\d\+ STORE $\d\_s*' ..
579
580 'var Pp = null_partial\_s*' ..
581 '\d\+ NEWPARTIAL\_s*' ..
582 '\d\+ STORE $\d\_s*' ..
583
584 'var jj = null_job\_s*' ..
585 '\d\+ PUSHJOB "no process"\_s*' ..
586 '\d\+ STORE $\d\_s*' ..
587
588 'var cc = null_channel\_s*' ..
589 '\d\+ PUSHCHANNEL 0\_s*' ..
590 '\d\+ STORE $\d\_s*' ..
591
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +0200592 'var oo = null_object\_s*' ..
593 '\d\+ PUSHOBJ null\_s*' ..
594 '\d\+ STORE $\d\_s*' ..
595
596 'var nc = null_class\_s*' ..
597 '\d\+ PUSHCLASS null\_s*' ..
598 '\d\+ STORE $\d\_s*' ..
599
Bram Moolenaar8acb9cc2022-03-08 13:18:55 +0000600 '\d\+ RETURN void',
601 res)
602 enddef
603endif
604
Bram Moolenaar4f5e3972020-12-21 17:30:50 +0100605def s:ScriptFuncStoreIndex()
606 var d = {dd: {}}
607 d.dd[0] = 0
608enddef
609
610def Test_disassemble_store_index()
611 var res = execute('disass s:ScriptFuncStoreIndex')
612 assert_match('<SNR>\d*_ScriptFuncStoreIndex\_s*' ..
613 'var d = {dd: {}}\_s*' ..
614 '\d PUSHS "dd"\_s*' ..
615 '\d NEWDICT size 0\_s*' ..
616 '\d NEWDICT size 1\_s*' ..
Yegappan Lakshmanan66897192023-12-05 15:51:50 +0100617 '\d SETTYPE dict<dict<any>>\_s*' ..
Bram Moolenaar4f5e3972020-12-21 17:30:50 +0100618 '\d STORE $0\_s*' ..
619 'd.dd\[0\] = 0\_s*' ..
620 '\d PUSHNR 0\_s*' ..
621 '\d PUSHNR 0\_s*' ..
622 '\d LOAD $0\_s*' ..
623 '\d MEMBER dd\_s*' ..
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +0200624 '\d\+ USEDICT\_s*' ..
625 '\d\+ STOREINDEX any\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200626 '\d\+ RETURN void',
Bram Moolenaar4f5e3972020-12-21 17:30:50 +0100627 res)
628enddef
629
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200630def s:ListAssign()
Bram Moolenaarac564082020-09-27 19:05:33 +0200631 var x: string
632 var y: string
633 var l: list<any>
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200634 [x, y; l] = g:stringlist
635enddef
636
637def Test_disassemble_list_assign()
Bram Moolenaarac564082020-09-27 19:05:33 +0200638 var res = execute('disass s:ListAssign')
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200639 assert_match('<SNR>\d*_ListAssign\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200640 'var x: string\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200641 '\d PUSHS "\[NULL\]"\_s*' ..
642 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200643 'var y: string\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200644 '\d PUSHS "\[NULL\]"\_s*' ..
645 '\d STORE $1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200646 'var l: list<any>\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200647 '\d NEWLIST size 0\_s*' ..
648 '\d STORE $2\_s*' ..
649 '\[x, y; l\] = g:stringlist\_s*' ..
650 '\d LOADG g:stringlist\_s*' ..
Bram Moolenaar5e654232020-09-16 15:22:00 +0200651 '\d CHECKTYPE list<any> stack\[-1\]\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200652 '\d CHECKLEN >= 2\_s*' ..
653 '\d\+ ITEM 0\_s*' ..
Bram Moolenaarbd3a9d22022-05-17 16:12:39 +0100654 '\d\+ CHECKTYPE string stack\[-1\] var 1\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200655 '\d\+ STORE $0\_s*' ..
656 '\d\+ ITEM 1\_s*' ..
Bram Moolenaarbd3a9d22022-05-17 16:12:39 +0100657 '\d\+ CHECKTYPE string stack\[-1\] var 2\_s*' ..
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200658 '\d\+ STORE $1\_s*' ..
659 '\d\+ SLICE 2\_s*' ..
660 '\d\+ STORE $2\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200661 '\d\+ RETURN void',
Bram Moolenaar0779fab2020-06-18 22:18:18 +0200662 res)
663enddef
664
Bram Moolenaar035bd1c2021-06-21 19:44:11 +0200665def s:ListAssignWithOp()
666 var a = 2
667 var b = 3
668 [a, b] += [4, 5]
669enddef
670
671def Test_disassemble_list_assign_with_op()
672 var res = execute('disass s:ListAssignWithOp')
673 assert_match('<SNR>\d*_ListAssignWithOp\_s*' ..
674 'var a = 2\_s*' ..
675 '\d STORE 2 in $0\_s*' ..
676 'var b = 3\_s*' ..
677 '\d STORE 3 in $1\_s*' ..
678 '\[a, b\] += \[4, 5\]\_s*' ..
679 '\d\+ PUSHNR 4\_s*' ..
680 '\d\+ PUSHNR 5\_s*' ..
681 '\d\+ NEWLIST size 2\_s*' ..
Bram Moolenaar035bd1c2021-06-21 19:44:11 +0200682 '\d\+ LOAD $0\_s*' ..
683 '\d\+ ITEM 0 with op\_s*' ..
684 '\d\+ OPNR +\_s*' ..
685 '\d\+ STORE $0\_s*' ..
686 '\d\+ LOAD $1\_s*' ..
687 '\d\+ ITEM 1 with op\_s*' ..
688 '\d\+ OPNR +\_s*' ..
689 '\d\+ STORE $1\_s*' ..
690 '\d\+ DROP\_s*' ..
691 '\d\+ RETURN void',
692 res)
693enddef
694
Bram Moolenaar1dcae592020-10-19 19:02:42 +0200695def s:ListAdd()
696 var l: list<number> = []
697 add(l, 123)
698 add(l, g:aNumber)
699enddef
700
701def Test_disassemble_list_add()
702 var res = execute('disass s:ListAdd')
703 assert_match('<SNR>\d*_ListAdd\_s*' ..
704 'var l: list<number> = []\_s*' ..
705 '\d NEWLIST size 0\_s*' ..
Bram Moolenaaraa210a32021-01-02 15:41:03 +0100706 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaar1dcae592020-10-19 19:02:42 +0200707 '\d STORE $0\_s*' ..
708 'add(l, 123)\_s*' ..
709 '\d LOAD $0\_s*' ..
710 '\d PUSHNR 123\_s*' ..
711 '\d LISTAPPEND\_s*' ..
712 '\d DROP\_s*' ..
713 'add(l, g:aNumber)\_s*' ..
714 '\d LOAD $0\_s*' ..
715 '\d\+ LOADG g:aNumber\_s*' ..
716 '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
717 '\d\+ LISTAPPEND\_s*' ..
718 '\d\+ DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200719 '\d\+ RETURN void',
Bram Moolenaar1dcae592020-10-19 19:02:42 +0200720 res)
721enddef
722
Bram Moolenaar80b0e5e2020-10-19 20:45:36 +0200723def s:BlobAdd()
724 var b: blob = 0z
725 add(b, 123)
726 add(b, g:aNumber)
727enddef
728
729def Test_disassemble_blob_add()
730 var res = execute('disass s:BlobAdd')
731 assert_match('<SNR>\d*_BlobAdd\_s*' ..
732 'var b: blob = 0z\_s*' ..
733 '\d PUSHBLOB 0z\_s*' ..
734 '\d STORE $0\_s*' ..
735 'add(b, 123)\_s*' ..
736 '\d LOAD $0\_s*' ..
737 '\d PUSHNR 123\_s*' ..
738 '\d BLOBAPPEND\_s*' ..
739 '\d DROP\_s*' ..
740 'add(b, g:aNumber)\_s*' ..
741 '\d LOAD $0\_s*' ..
742 '\d\+ LOADG g:aNumber\_s*' ..
743 '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
744 '\d\+ BLOBAPPEND\_s*' ..
745 '\d\+ DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200746 '\d\+ RETURN void',
Bram Moolenaar80b0e5e2020-10-19 20:45:36 +0200747 res)
748enddef
749
Bram Moolenaarf62d7392021-04-14 12:40:00 +0200750def s:BlobIndexSlice()
751 var b: blob = 0z112233
752 echo b[1]
753 echo b[1 : 2]
754enddef
755
756def Test_disassemble_blob_index_slice()
757 var res = execute('disass s:BlobIndexSlice')
758 assert_match('<SNR>\d*_BlobIndexSlice\_s*' ..
759 'var b: blob = 0z112233\_s*' ..
760 '\d PUSHBLOB 0z112233\_s*' ..
761 '\d STORE $0\_s*' ..
762 'echo b\[1\]\_s*' ..
763 '\d LOAD $0\_s*' ..
764 '\d PUSHNR 1\_s*' ..
765 '\d BLOBINDEX\_s*' ..
766 '\d ECHO 1\_s*' ..
767 'echo b\[1 : 2\]\_s*' ..
768 '\d LOAD $0\_s*' ..
769 '\d PUSHNR 1\_s*' ..
770 '\d\+ PUSHNR 2\_s*' ..
771 '\d\+ BLOBSLICE\_s*' ..
772 '\d\+ ECHO 1\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +0200773 '\d\+ RETURN void',
Bram Moolenaarf62d7392021-04-14 12:40:00 +0200774 res)
775enddef
776
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200777def s:ScriptFuncUnlet()
778 g:somevar = "value"
779 unlet g:somevar
780 unlet! g:somevar
Bram Moolenaar7bdaea62020-04-19 18:27:26 +0200781 unlet $SOMEVAR
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100782
783 var l = [1, 2, 3]
784 unlet l[2]
785 unlet l[0 : 1]
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200786enddef
787
788def Test_disassemble_unlet()
Bram Moolenaarac564082020-09-27 19:05:33 +0200789 var res = execute('disass s:ScriptFuncUnlet')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200790 assert_match('<SNR>\d*_ScriptFuncUnlet\_s*' ..
791 'g:somevar = "value"\_s*' ..
792 '\d PUSHS "value"\_s*' ..
793 '\d STOREG g:somevar\_s*' ..
794 'unlet g:somevar\_s*' ..
795 '\d UNLET g:somevar\_s*' ..
796 'unlet! g:somevar\_s*' ..
797 '\d UNLET! g:somevar\_s*' ..
798 'unlet $SOMEVAR\_s*' ..
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100799 '\d UNLETENV $SOMEVAR\_s*' ..
800
801 'var l = \[1, 2, 3]\_s*' ..
802 '\d\+ PUSHNR 1\_s*' ..
803 '\d\+ PUSHNR 2\_s*' ..
804 '\d\+ PUSHNR 3\_s*' ..
805 '\d\+ NEWLIST size 3\_s*' ..
806 '\d\+ SETTYPE list<number>\_s*' ..
807 '\d\+ STORE $0\_s*' ..
808
809 'unlet l\[2]\_s*' ..
810 '\d\+ PUSHNR 2\_s*' ..
811 '\d\+ LOAD $0\_s*' ..
812 '\d\+ UNLETINDEX\_s*' ..
813
814 'unlet l\[0 : 1]\_s*' ..
815 '\d\+ PUSHNR 0\_s*' ..
816 '\d\+ PUSHNR 1\_s*' ..
817 '\d\+ LOAD $0\_s*' ..
818 '\d\+ UNLETRANGE\_s*',
Bram Moolenaard72c1bf2020-04-19 16:28:59 +0200819 res)
820enddef
821
Bram Moolenaaraacc9662021-08-13 19:40:51 +0200822def s:LockLocal()
823 var d = {a: 1}
824 lockvar d.a
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100825 const nr = 22
Bram Moolenaaraacc9662021-08-13 19:40:51 +0200826enddef
827
Bram Moolenaare88c6b72022-02-15 15:37:11 +0000828def Test_disassemble_lock_local()
Bram Moolenaaraacc9662021-08-13 19:40:51 +0200829 var res = execute('disass s:LockLocal')
830 assert_match('<SNR>\d*_LockLocal\_s*' ..
831 'var d = {a: 1}\_s*' ..
832 '\d PUSHS "a"\_s*' ..
833 '\d PUSHNR 1\_s*' ..
834 '\d NEWDICT size 1\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +0000835 '\d SETTYPE dict<number>\_s*' ..
Bram Moolenaaraacc9662021-08-13 19:40:51 +0200836 '\d STORE $0\_s*' ..
837 'lockvar d.a\_s*' ..
838 '\d LOAD $0\_s*' ..
Bram Moolenaarf6ced982022-04-28 12:00:49 +0100839 '\d LOCKUNLOCK lockvar 2 d.a\_s*' ..
840
841 'const nr = 22\_s*' ..
842 '\d\+ PUSHNR 22\_s*' ..
843 '\d\+ LOCKCONST\_s*' ..
844 '\d\+ STORE $1',
Bram Moolenaaraacc9662021-08-13 19:40:51 +0200845 res)
846enddef
847
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100848def s:ScriptFuncTry()
849 try
Bram Moolenaarcb790402020-05-15 20:53:00 +0200850 echo "yes"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100851 catch /fail/
Bram Moolenaarcb790402020-05-15 20:53:00 +0200852 echo "no"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100853 finally
Bram Moolenaarcb790402020-05-15 20:53:00 +0200854 throw "end"
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100855 endtry
856enddef
857
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100858def Test_disassemble_try()
Bram Moolenaarac564082020-09-27 19:05:33 +0200859 var res = execute('disass s:ScriptFuncTry')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200860 assert_match('<SNR>\d*_ScriptFuncTry\_s*' ..
861 'try\_s*' ..
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100862 '\d TRY catch -> \d\+, finally -> \d\+, endtry -> \d\+\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200863 'echo "yes"\_s*' ..
864 '\d PUSHS "yes"\_s*' ..
865 '\d ECHO 1\_s*' ..
866 'catch /fail/\_s*' ..
867 '\d JUMP -> \d\+\_s*' ..
868 '\d PUSH v:exception\_s*' ..
869 '\d PUSHS "fail"\_s*' ..
870 '\d COMPARESTRING =\~\_s*' ..
871 '\d JUMP_IF_FALSE -> \d\+\_s*' ..
872 '\d CATCH\_s*' ..
873 'echo "no"\_s*' ..
874 '\d\+ PUSHS "no"\_s*' ..
875 '\d\+ ECHO 1\_s*' ..
876 'finally\_s*' ..
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +0100877 '\d\+ FINALLY\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200878 'throw "end"\_s*' ..
879 '\d\+ PUSHS "end"\_s*' ..
880 '\d\+ THROW\_s*' ..
881 'endtry\_s*' ..
882 '\d\+ ENDTRY',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200883 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100884enddef
885
886def s:ScriptFuncNew()
Bram Moolenaarac564082020-09-27 19:05:33 +0200887 var ll = [1, "two", 333]
Bram Moolenaare0de1712020-12-02 17:36:54 +0100888 var dd = {one: 1, two: "val"}
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100889enddef
890
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100891def Test_disassemble_new()
Bram Moolenaarac564082020-09-27 19:05:33 +0200892 var res = execute('disass s:ScriptFuncNew')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200893 assert_match('<SNR>\d*_ScriptFuncNew\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200894 'var ll = \[1, "two", 333\]\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200895 '\d PUSHNR 1\_s*' ..
896 '\d PUSHS "two"\_s*' ..
897 '\d PUSHNR 333\_s*' ..
898 '\d NEWLIST size 3\_s*' ..
899 '\d STORE $0\_s*' ..
Bram Moolenaare0de1712020-12-02 17:36:54 +0100900 'var dd = {one: 1, two: "val"}\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200901 '\d PUSHS "one"\_s*' ..
902 '\d PUSHNR 1\_s*' ..
903 '\d PUSHS "two"\_s*' ..
904 '\d PUSHS "val"\_s*' ..
905 '\d NEWDICT size 2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200906 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100907enddef
908
Bram Moolenaar62aec932022-01-29 21:45:34 +0000909def s:FuncWithArg(arg: any)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100910 echo arg
911enddef
912
Bram Moolenaar62aec932022-01-29 21:45:34 +0000913func s:UserFunc()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100914 echo 'nothing'
915endfunc
916
Bram Moolenaar62aec932022-01-29 21:45:34 +0000917func s:UserFuncWithArg(arg)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100918 echo a:arg
919endfunc
920
921def s:ScriptFuncCall(): string
922 changenr()
923 char2nr("abc")
Bram Moolenaar62aec932022-01-29 21:45:34 +0000924 g:Test_disassemble_new()
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100925 FuncWithArg(343)
926 ScriptFuncNew()
927 s:ScriptFuncNew()
928 UserFunc()
929 UserFuncWithArg("foo")
Bram Moolenaarac564082020-09-27 19:05:33 +0200930 var FuncRef = function("UserFunc")
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100931 FuncRef()
Bram Moolenaarac564082020-09-27 19:05:33 +0200932 var FuncRefWithArg = function("UserFuncWithArg")
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100933 FuncRefWithArg("bar")
934 return "yes"
935enddef
936
Bram Moolenaarf2460a32020-02-07 22:09:54 +0100937def Test_disassemble_call()
Bram Moolenaarac564082020-09-27 19:05:33 +0200938 var res = execute('disass s:ScriptFuncCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +0200939 assert_match('<SNR>\d\+_ScriptFuncCall\_s*' ..
940 'changenr()\_s*' ..
941 '\d BCALL changenr(argc 0)\_s*' ..
942 '\d DROP\_s*' ..
943 'char2nr("abc")\_s*' ..
944 '\d PUSHS "abc"\_s*' ..
945 '\d BCALL char2nr(argc 1)\_s*' ..
946 '\d DROP\_s*' ..
Bram Moolenaar62aec932022-01-29 21:45:34 +0000947 'g:Test_disassemble_new()\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200948 '\d DCALL Test_disassemble_new(argc 0)\_s*' ..
949 '\d DROP\_s*' ..
950 'FuncWithArg(343)\_s*' ..
951 '\d\+ PUSHNR 343\_s*' ..
Bram Moolenaar62aec932022-01-29 21:45:34 +0000952 '\d\+ DCALL <SNR>\d\+_FuncWithArg(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200953 '\d\+ DROP\_s*' ..
954 'ScriptFuncNew()\_s*' ..
955 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
956 '\d\+ DROP\_s*' ..
957 's:ScriptFuncNew()\_s*' ..
958 '\d\+ DCALL <SNR>\d\+_ScriptFuncNew(argc 0)\_s*' ..
959 '\d\+ DROP\_s*' ..
960 'UserFunc()\_s*' ..
Bram Moolenaar62aec932022-01-29 21:45:34 +0000961 '\d\+ UCALL <80><fd>R\d\+_UserFunc(argc 0)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200962 '\d\+ DROP\_s*' ..
963 'UserFuncWithArg("foo")\_s*' ..
964 '\d\+ PUSHS "foo"\_s*' ..
Bram Moolenaar62aec932022-01-29 21:45:34 +0000965 '\d\+ UCALL <80><fd>R\d\+_UserFuncWithArg(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200966 '\d\+ DROP\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200967 'var FuncRef = function("UserFunc")\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200968 '\d\+ PUSHS "UserFunc"\_s*' ..
969 '\d\+ BCALL function(argc 1)\_s*' ..
970 '\d\+ STORE $0\_s*' ..
971 'FuncRef()\_s*' ..
972 '\d\+ LOAD $\d\_s*' ..
973 '\d\+ PCALL (argc 0)\_s*' ..
974 '\d\+ DROP\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +0200975 'var FuncRefWithArg = function("UserFuncWithArg")\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +0200976 '\d\+ PUSHS "UserFuncWithArg"\_s*' ..
977 '\d\+ BCALL function(argc 1)\_s*' ..
978 '\d\+ STORE $1\_s*' ..
979 'FuncRefWithArg("bar")\_s*' ..
980 '\d\+ PUSHS "bar"\_s*' ..
981 '\d\+ LOAD $\d\_s*' ..
982 '\d\+ PCALL (argc 1)\_s*' ..
983 '\d\+ DROP\_s*' ..
984 'return "yes"\_s*' ..
985 '\d\+ PUSHS "yes"\_s*' ..
986 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +0200987 res)
Bram Moolenaar5cab73f2020-02-06 19:25:19 +0100988enddef
989
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +0200990
991def s:CreateRefs()
992 var local = 'a'
993 def Append(arg: string)
994 local ..= arg
995 enddef
996 g:Append = Append
997 def Get(): string
998 return local
999 enddef
1000 g:Get = Get
1001enddef
1002
1003def Test_disassemble_closure()
1004 CreateRefs()
1005 var res = execute('disass g:Append')
1006 assert_match('<lambda>\d\_s*' ..
1007 'local ..= arg\_s*' ..
Bram Moolenaarab360522021-01-10 14:02:28 +01001008 '\d LOADOUTER level 1 $0\_s*' ..
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001009 '\d LOAD arg\[-1\]\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01001010 '\d CONCAT size 2\_s*' ..
Bram Moolenaarab360522021-01-10 14:02:28 +01001011 '\d STOREOUTER level 1 $0\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001012 '\d RETURN void',
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001013 res)
1014
1015 res = execute('disass g:Get')
1016 assert_match('<lambda>\d\_s*' ..
1017 'return local\_s*' ..
Bram Moolenaarab360522021-01-10 14:02:28 +01001018 '\d LOADOUTER level 1 $0\_s*' ..
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001019 '\d RETURN',
1020 res)
1021
1022 unlet g:Append
1023 unlet g:Get
1024enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001025
Bram Moolenaar95e4dd82022-04-27 22:15:40 +01001026def s:ClosureArg(arg: string)
1027 var Ref = () => arg .. "x"
1028enddef
1029
1030def Test_disassemble_closure_arg()
1031 var res = execute('disass s:ClosureArg')
1032 assert_match('<SNR>\d\+_ClosureArg\_s*' ..
1033 'var Ref = () => arg .. "x"\_s*' ..
1034 '\d FUNCREF <lambda>\d\+',
1035 res)
1036 var lres = execute('disass ' .. matchstr(res, '<lambda>\d\+'))
1037 assert_match('<lambda>\d\+\_s*' ..
1038 'return arg .. "x"\_s*' ..
1039 '\d LOADOUTER level 1 arg\[-1]\_s*' ..
1040 '\d PUSHS "x"\_s*' ..
1041 '\d CONCAT size 2\_s*' ..
1042 '\d RETURN',
1043 lres)
1044enddef
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001045
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001046def s:ClosureInLoop()
1047 for i in range(5)
1048 var ii = i
1049 continue
1050 break
1051 if g:val
1052 return
1053 endif
1054 g:Ref = () => ii
1055 continue
1056 break
1057 if g:val
1058 return
1059 endif
1060 endfor
1061enddef
1062
1063" Mainly check that ENDLOOP is only produced after a closure was created.
1064def Test_disassemble_closure_in_loop()
1065 var res = execute('disass s:ClosureInLoop')
1066 assert_match('<SNR>\d\+_ClosureInLoop\_s*' ..
1067 'for i in range(5)\_s*' ..
1068 '\d\+ STORE -1 in $0\_s*' ..
1069 '\d\+ PUSHNR 5\_s*' ..
1070 '\d\+ BCALL range(argc 1)\_s*' ..
1071 '\d\+ FOR $0 -> \d\+\_s*' ..
1072 '\d\+ STORE $2\_s*' ..
1073
1074 'var ii = i\_s*' ..
1075 '\d\+ LOAD $2\_s*' ..
1076 '\d\+ STORE $3\_s*' ..
1077
1078 'continue\_s*' ..
1079 '\d\+ JUMP -> \d\+\_s*' ..
1080
1081 'break\_s*' ..
1082 '\d\+ JUMP -> \d\+\_s*' ..
1083
1084 'if g:val\_s*' ..
1085 '\d\+ LOADG g:val\_s*' ..
1086 '\d\+ COND2BOOL\_s*' ..
1087 '\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
1088
1089 ' return\_s*' ..
1090 '\d\+ PUSHNR 0\_s*' ..
1091 '\d\+ RETURN\_s*' ..
1092
1093 'endif\_s*' ..
1094 'g:Ref = () => ii\_s*' ..
Julio B1fa22e32024-04-18 22:05:12 +02001095 '\d\+ FUNCREF <lambda>\d\+ vars $3-$3\_s*' ..
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001096 '\d\+ STOREG g:Ref\_s*' ..
1097
1098 'continue\_s*' ..
Bram Moolenaarcc341812022-09-19 15:54:34 +01001099 '\d\+ ENDLOOP ref $1 save $3-$3 depth 0\_s*' ..
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001100 '\d\+ JUMP -> \d\+\_s*' ..
1101
1102 'break\_s*' ..
Bram Moolenaarcc341812022-09-19 15:54:34 +01001103 '\d\+ ENDLOOP ref $1 save $3-$3 depth 0\_s*' ..
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001104 '\d\+ JUMP -> \d\+\_s*' ..
1105
1106 'if g:val\_s*' ..
1107 '\d\+ LOADG g:val\_s*' ..
1108 '\d\+ COND2BOOL\_s*' ..
1109 '\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
1110
1111 ' return\_s*' ..
1112 '\d\+ PUSHNR 0\_s*' ..
Bram Moolenaarcc341812022-09-19 15:54:34 +01001113 '\d\+ ENDLOOP ref $1 save $3-$3 depth 0\_s*' ..
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001114 '\d\+ RETURN\_s*' ..
1115
1116 'endif\_s*' ..
1117 'endfor\_s*' ..
Bram Moolenaarcc341812022-09-19 15:54:34 +01001118 '\d\+ ENDLOOP ref $1 save $3-$3 depth 0\_s*' ..
Bram Moolenaar8abb5842022-09-17 12:39:58 +01001119 '\d\+ JUMP -> \d\+\_s*' ..
1120 '\d\+ DROP\_s*' ..
1121 '\d\+ RETURN void',
1122 res)
1123enddef
1124
Bram Moolenaarbd5da372020-03-31 23:13:10 +02001125def EchoArg(arg: string): string
1126 return arg
1127enddef
Bram Moolenaar62aec932022-01-29 21:45:34 +00001128def s:RefThis(): func
Bram Moolenaarbd5da372020-03-31 23:13:10 +02001129 return function('EchoArg')
1130enddef
1131def s:ScriptPCall()
1132 RefThis()("text")
1133enddef
1134
1135def Test_disassemble_pcall()
Bram Moolenaarac564082020-09-27 19:05:33 +02001136 var res = execute('disass s:ScriptPCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001137 assert_match('<SNR>\d\+_ScriptPCall\_s*' ..
1138 'RefThis()("text")\_s*' ..
Bram Moolenaar62aec932022-01-29 21:45:34 +00001139 '\d DCALL <SNR>\d\+_RefThis(argc 0)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001140 '\d PUSHS "text"\_s*' ..
1141 '\d PCALL top (argc 1)\_s*' ..
1142 '\d PCALL end\_s*' ..
1143 '\d DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001144 '\d RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001145 res)
Bram Moolenaarbd5da372020-03-31 23:13:10 +02001146enddef
1147
1148
Bram Moolenaara26b9702020-04-18 19:53:28 +02001149def s:FuncWithForwardCall(): string
1150 return g:DefinedLater("yes")
Bram Moolenaar7eeefd42020-02-26 21:24:23 +01001151enddef
1152
1153def DefinedLater(arg: string): string
1154 return arg
1155enddef
1156
1157def Test_disassemble_update_instr()
Bram Moolenaarac564082020-09-27 19:05:33 +02001158 var res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001159 assert_match('FuncWithForwardCall\_s*' ..
1160 'return g:DefinedLater("yes")\_s*' ..
1161 '\d PUSHS "yes"\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +02001162 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001163 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001164 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +01001165
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02001166 # Calling the function will change UCALL into the faster DCALL
Bram Moolenaar7eeefd42020-02-26 21:24:23 +01001167 assert_equal('yes', FuncWithForwardCall())
1168
Bram Moolenaara26b9702020-04-18 19:53:28 +02001169 res = execute('disass s:FuncWithForwardCall')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001170 assert_match('FuncWithForwardCall\_s*' ..
1171 'return g:DefinedLater("yes")\_s*' ..
1172 '\d PUSHS "yes"\_s*' ..
1173 '\d DCALL DefinedLater(argc 1)\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001174 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001175 res)
Bram Moolenaar7eeefd42020-02-26 21:24:23 +01001176enddef
1177
1178
Bram Moolenaar9ce47ec2021-04-20 22:16:39 +02001179def FuncWithDefault(l: number, arg: string = "default", nr = 77): string
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001180 return arg .. nr
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001181enddef
1182
1183def Test_disassemble_call_default()
Bram Moolenaarac564082020-09-27 19:05:33 +02001184 var res = execute('disass FuncWithDefault')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001185 assert_match('FuncWithDefault\_s*' ..
Bram Moolenaar9ce47ec2021-04-20 22:16:39 +02001186 ' arg = "default"\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001187 '\d JUMP_IF_ARG_SET arg\[-2\] -> 3\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001188 '\d PUSHS "default"\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001189 '\d STORE arg\[-2]\_s*' ..
Bram Moolenaar9ce47ec2021-04-20 22:16:39 +02001190 ' nr = 77\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001191 '3 JUMP_IF_ARG_SET arg\[-1\] -> 6\_s*' ..
1192 '\d PUSHNR 77\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001193 '\d STORE arg\[-1]\_s*' ..
Bram Moolenaar9ce47ec2021-04-20 22:16:39 +02001194 ' return arg .. nr\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001195 '6 LOAD arg\[-2]\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001196 '\d LOAD arg\[-1]\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001197 '\d 2STRING stack\[-1]\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01001198 '\d\+ CONCAT size 2\_s*' ..
Bram Moolenaar38a3bfa2021-03-29 22:14:55 +02001199 '\d\+ RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001200 res)
Bram Moolenaar8ed04582020-02-22 19:07:28 +01001201enddef
1202
1203
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001204def s:HasEval()
Bram Moolenaar158906c2020-02-06 20:39:45 +01001205 if has("eval")
1206 echo "yes"
1207 else
1208 echo "no"
1209 endif
1210enddef
1211
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001212def s:HasNothing()
Bram Moolenaar158906c2020-02-06 20:39:45 +01001213 if has("nothing")
1214 echo "yes"
1215 else
1216 echo "no"
1217 endif
1218enddef
1219
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001220def s:HasSomething()
Bram Moolenaar158906c2020-02-06 20:39:45 +01001221 if has("nothing")
1222 echo "nothing"
1223 elseif has("something")
1224 echo "something"
1225 elseif has("eval")
1226 echo "eval"
1227 elseif has("less")
1228 echo "less"
1229 endif
1230enddef
1231
Bram Moolenaar848fadd2022-01-30 15:28:30 +00001232def s:HasGuiRunning()
Bram Moolenaar8cebd432020-11-08 12:49:47 +01001233 if has("gui_running")
1234 echo "yes"
1235 else
1236 echo "no"
1237 endif
1238enddef
1239
LemonBoy58f331a2022-04-02 21:59:06 +01001240def s:LenConstant(): number
1241 return len("foo") + len("fighters")
1242enddef
1243
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001244def Test_disassemble_const_expr()
LemonBoy58f331a2022-04-02 21:59:06 +01001245 var instr = execute('disassemble LenConstant')
1246 assert_match('LenConstant\_s*' ..
1247 'return len("foo") + len("fighters")\_s*' ..
1248 '\d PUSHNR 11\_s*',
1249 instr)
1250 assert_notmatch('BCALL len', instr)
1251
Bram Moolenaard2c61702020-09-06 15:58:36 +02001252 assert_equal("\nyes", execute('HasEval()'))
LemonBoy58f331a2022-04-02 21:59:06 +01001253 instr = execute('disassemble HasEval')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001254 assert_match('HasEval\_s*' ..
1255 'if has("eval")\_s*' ..
1256 'echo "yes"\_s*' ..
1257 '\d PUSHS "yes"\_s*' ..
1258 '\d ECHO 1\_s*' ..
1259 'else\_s*' ..
1260 'echo "no"\_s*' ..
1261 'endif\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001262 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +01001263 assert_notmatch('JUMP', instr)
1264
Bram Moolenaard2c61702020-09-06 15:58:36 +02001265 assert_equal("\nno", execute('HasNothing()'))
Bram Moolenaar158906c2020-02-06 20:39:45 +01001266 instr = execute('disassemble HasNothing')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001267 assert_match('HasNothing\_s*' ..
1268 'if has("nothing")\_s*' ..
1269 'echo "yes"\_s*' ..
1270 'else\_s*' ..
1271 'echo "no"\_s*' ..
1272 '\d PUSHS "no"\_s*' ..
1273 '\d ECHO 1\_s*' ..
1274 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001275 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +01001276 assert_notmatch('PUSHS "yes"', instr)
1277 assert_notmatch('JUMP', instr)
1278
Bram Moolenaard2c61702020-09-06 15:58:36 +02001279 assert_equal("\neval", execute('HasSomething()'))
Bram Moolenaar158906c2020-02-06 20:39:45 +01001280 instr = execute('disassemble HasSomething')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001281 assert_match('HasSomething.*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001282 'if has("nothing")\_s*' ..
1283 'echo "nothing"\_s*' ..
1284 'elseif has("something")\_s*' ..
1285 'echo "something"\_s*' ..
1286 'elseif has("eval")\_s*' ..
1287 'echo "eval"\_s*' ..
1288 '\d PUSHS "eval"\_s*' ..
1289 '\d ECHO 1\_s*' ..
1290 'elseif has("less").*' ..
1291 'echo "less"\_s*' ..
1292 'endif',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001293 instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +01001294 assert_notmatch('PUSHS "nothing"', instr)
1295 assert_notmatch('PUSHS "something"', instr)
1296 assert_notmatch('PUSHS "less"', instr)
1297 assert_notmatch('JUMP', instr)
Bram Moolenaar8cebd432020-11-08 12:49:47 +01001298
1299 var result: string
1300 var instr_expected: string
1301 if has('gui')
1302 if has('gui_running')
1303 # GUI already running, always returns "yes"
1304 result = "\nyes"
1305 instr_expected = 'HasGuiRunning.*' ..
1306 'if has("gui_running")\_s*' ..
1307 ' echo "yes"\_s*' ..
1308 '\d PUSHS "yes"\_s*' ..
1309 '\d ECHO 1\_s*' ..
1310 'else\_s*' ..
1311 ' echo "no"\_s*' ..
1312 'endif'
1313 else
1314 result = "\nno"
1315 if has('unix')
1316 # GUI not running but can start later, call has()
1317 instr_expected = 'HasGuiRunning.*' ..
1318 'if has("gui_running")\_s*' ..
1319 '\d PUSHS "gui_running"\_s*' ..
1320 '\d BCALL has(argc 1)\_s*' ..
Bram Moolenaaraf8ea0d2021-04-11 18:24:46 +02001321 '\d COND2BOOL\_s*' ..
Bram Moolenaar8cebd432020-11-08 12:49:47 +01001322 '\d JUMP_IF_FALSE -> \d\_s*' ..
1323 ' echo "yes"\_s*' ..
1324 '\d PUSHS "yes"\_s*' ..
1325 '\d ECHO 1\_s*' ..
1326 'else\_s*' ..
1327 '\d JUMP -> \d\_s*' ..
1328 ' echo "no"\_s*' ..
1329 '\d PUSHS "no"\_s*' ..
1330 '\d ECHO 1\_s*' ..
1331 'endif'
1332 else
1333 # GUI not running, always return "no"
1334 instr_expected = 'HasGuiRunning.*' ..
1335 'if has("gui_running")\_s*' ..
1336 ' echo "yes"\_s*' ..
1337 'else\_s*' ..
1338 ' echo "no"\_s*' ..
1339 '\d PUSHS "no"\_s*' ..
1340 '\d ECHO 1\_s*' ..
1341 'endif'
1342 endif
1343 endif
1344 else
1345 # GUI not supported, always return "no"
1346 result = "\nno"
1347 instr_expected = 'HasGuiRunning.*' ..
1348 'if has("gui_running")\_s*' ..
1349 ' echo "yes"\_s*' ..
1350 'else\_s*' ..
1351 ' echo "no"\_s*' ..
1352 '\d PUSHS "no"\_s*' ..
1353 '\d ECHO 1\_s*' ..
1354 'endif'
1355 endif
1356
1357 assert_equal(result, execute('HasGuiRunning()'))
1358 instr = execute('disassemble HasGuiRunning')
1359 assert_match(instr_expected, instr)
Bram Moolenaar158906c2020-02-06 20:39:45 +01001360enddef
1361
Bram Moolenaarefd88552020-06-18 20:50:10 +02001362def ReturnInIf(): string
Bram Moolenaar8e02faf2020-11-18 16:35:02 +01001363 if 1 < 0
1364 return "maybe"
1365 endif
Bram Moolenaarefd88552020-06-18 20:50:10 +02001366 if g:cond
1367 return "yes"
1368 else
1369 return "no"
1370 endif
1371enddef
1372
1373def Test_disassemble_return_in_if()
Bram Moolenaarac564082020-09-27 19:05:33 +02001374 var instr = execute('disassemble ReturnInIf')
Bram Moolenaarefd88552020-06-18 20:50:10 +02001375 assert_match('ReturnInIf\_s*' ..
Bram Moolenaar8e02faf2020-11-18 16:35:02 +01001376 'if 1 < 0\_s*' ..
1377 ' return "maybe"\_s*' ..
1378 'endif\_s*' ..
Bram Moolenaarefd88552020-06-18 20:50:10 +02001379 'if g:cond\_s*' ..
1380 '0 LOADG g:cond\_s*' ..
Bram Moolenaarea2d4072020-11-12 12:08:51 +01001381 '1 COND2BOOL\_s*' ..
1382 '2 JUMP_IF_FALSE -> 5\_s*' ..
Bram Moolenaarefd88552020-06-18 20:50:10 +02001383 'return "yes"\_s*' ..
Bram Moolenaarea2d4072020-11-12 12:08:51 +01001384 '3 PUSHS "yes"\_s*' ..
1385 '4 RETURN\_s*' ..
Bram Moolenaarefd88552020-06-18 20:50:10 +02001386 'else\_s*' ..
1387 ' return "no"\_s*' ..
Bram Moolenaarea2d4072020-11-12 12:08:51 +01001388 '5 PUSHS "no"\_s*' ..
1389 '6 RETURN$',
Bram Moolenaarefd88552020-06-18 20:50:10 +02001390 instr)
1391enddef
1392
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01001393def WithFunc()
Bram Moolenaarac564082020-09-27 19:05:33 +02001394 var Funky1: func
1395 var Funky2: func = function("len")
1396 var Party2: func = funcref("UserFunc")
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01001397enddef
1398
1399def Test_disassemble_function()
Bram Moolenaarac564082020-09-27 19:05:33 +02001400 var instr = execute('disassemble WithFunc')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001401 assert_match('WithFunc\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001402 'var Funky1: func\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001403 '0 PUSHFUNC "\[none]"\_s*' ..
1404 '1 STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001405 'var Funky2: func = function("len")\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001406 '2 PUSHS "len"\_s*' ..
1407 '3 BCALL function(argc 1)\_s*' ..
1408 '4 STORE $1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001409 'var Party2: func = funcref("UserFunc")\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001410 '\d PUSHS "UserFunc"\_s*' ..
1411 '\d BCALL funcref(argc 1)\_s*' ..
1412 '\d STORE $2\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001413 '\d RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001414 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01001415enddef
1416
1417if has('channel')
1418 def WithChannel()
Bram Moolenaarac564082020-09-27 19:05:33 +02001419 var job1: job
1420 var job2: job = job_start("donothing")
1421 var chan1: channel
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01001422 enddef
1423endif
1424
1425def Test_disassemble_channel()
1426 CheckFeature channel
1427
Bram Moolenaarac564082020-09-27 19:05:33 +02001428 var instr = execute('disassemble WithChannel')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001429 assert_match('WithChannel\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001430 'var job1: job\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001431 '\d PUSHJOB "no process"\_s*' ..
1432 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001433 'var job2: job = job_start("donothing")\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001434 '\d PUSHS "donothing"\_s*' ..
1435 '\d BCALL job_start(argc 1)\_s*' ..
1436 '\d STORE $1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001437 'var chan1: channel\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001438 '\d PUSHCHANNEL 0\_s*' ..
1439 '\d STORE $2\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001440 '\d RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001441 instr)
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +01001442enddef
1443
Bram Moolenaar62aec932022-01-29 21:45:34 +00001444def s:WithLambda(): string
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001445 var F = (a) => "X" .. a .. "X"
Bram Moolenaar777770f2020-02-06 21:27:08 +01001446 return F("x")
1447enddef
1448
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001449def Test_disassemble_lambda()
Bram Moolenaar777770f2020-02-06 21:27:08 +01001450 assert_equal("XxX", WithLambda())
Bram Moolenaarac564082020-09-27 19:05:33 +02001451 var instr = execute('disassemble WithLambda')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001452 assert_match('WithLambda\_s*' ..
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001453 'var F = (a) => "X" .. a .. "X"\_s*' ..
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001454 '\d FUNCREF <lambda>\d\+\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001455 '\d STORE $0\_s*' ..
1456 'return F("x")\_s*' ..
1457 '\d PUSHS "x"\_s*' ..
1458 '\d LOAD $0\_s*' ..
1459 '\d PCALL (argc 1)\_s*' ..
Bram Moolenaar822ba242020-05-24 23:00:18 +02001460 '\d RETURN',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001461 instr)
Bram Moolenaarbfd65582020-07-13 18:18:00 +02001462
Bram Moolenaarac564082020-09-27 19:05:33 +02001463 var name = substitute(instr, '.*\(<lambda>\d\+\).*', '\1', '')
Bram Moolenaarbfd65582020-07-13 18:18:00 +02001464 instr = execute('disassemble ' .. name)
1465 assert_match('<lambda>\d\+\_s*' ..
1466 'return "X" .. a .. "X"\_s*' ..
1467 '\d PUSHS "X"\_s*' ..
1468 '\d LOAD arg\[-1\]\_s*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +02001469 '\d 2STRING_ANY stack\[-1\]\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01001470 '\d CONCAT size 2\_s*' ..
Bram Moolenaarbfd65582020-07-13 18:18:00 +02001471 '\d PUSHS "X"\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01001472 '\d CONCAT size 2\_s*' ..
Bram Moolenaarbfd65582020-07-13 18:18:00 +02001473 '\d RETURN',
1474 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +01001475enddef
1476
Bram Moolenaar62aec932022-01-29 21:45:34 +00001477def s:LambdaWithType(): number
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001478 var Ref = (a: number) => a + 10
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001479 return Ref(g:value)
1480enddef
1481
1482def Test_disassemble_lambda_with_type()
1483 g:value = 5
1484 assert_equal(15, LambdaWithType())
1485 var instr = execute('disassemble LambdaWithType')
1486 assert_match('LambdaWithType\_s*' ..
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01001487 'var Ref = (a: number) => a + 10\_s*' ..
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001488 '\d FUNCREF <lambda>\d\+\_s*' ..
1489 '\d STORE $0\_s*' ..
1490 'return Ref(g:value)\_s*' ..
1491 '\d LOADG g:value\_s*' ..
1492 '\d LOAD $0\_s*' ..
Bram Moolenaare32e5162021-01-21 20:21:29 +01001493 '\d CHECKTYPE number stack\[-2\] arg 1\_s*' ..
Bram Moolenaarb4d16cb2020-11-05 18:45:46 +01001494 '\d PCALL (argc 1)\_s*' ..
1495 '\d RETURN',
1496 instr)
1497enddef
1498
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001499def NestedOuter()
1500 def g:Inner()
1501 echomsg "inner"
1502 enddef
1503enddef
1504
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001505def Test_disassemble_nested_func()
Bram Moolenaarac564082020-09-27 19:05:33 +02001506 var instr = execute('disassemble NestedOuter')
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001507 assert_match('NestedOuter\_s*' ..
1508 'def g:Inner()\_s*' ..
1509 'echomsg "inner"\_s*' ..
1510 'enddef\_s*' ..
1511 '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001512 '\d RETURN void',
Bram Moolenaar38ddf332020-07-31 22:05:04 +02001513 instr)
1514enddef
1515
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001516def NestedDefList()
1517 def
1518 def Info
1519 def /Info
1520 def /Info/
1521enddef
1522
Bram Moolenaar8863bda2021-03-17 18:42:08 +01001523def Test_disassemble_nested_def_list()
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001524 var instr = execute('disassemble NestedDefList')
1525 assert_match('NestedDefList\_s*' ..
1526 'def\_s*' ..
1527 '\d DEF \_s*' ..
1528 'def Info\_s*' ..
1529 '\d DEF Info\_s*' ..
1530 'def /Info\_s*' ..
1531 '\d DEF /Info\_s*' ..
1532 'def /Info/\_s*' ..
1533 '\d DEF /Info/\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001534 '\d RETURN void',
Bram Moolenaar6abdcf82020-11-22 18:15:44 +01001535 instr)
1536enddef
1537
Bram Moolenaar62aec932022-01-29 21:45:34 +00001538def s:AndOr(arg: any): string
Bram Moolenaar777770f2020-02-06 21:27:08 +01001539 if arg == 1 && arg != 2 || arg == 4
1540 return 'yes'
1541 endif
1542 return 'no'
1543enddef
1544
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001545def Test_disassemble_and_or()
Bram Moolenaar777770f2020-02-06 21:27:08 +01001546 assert_equal("yes", AndOr(1))
1547 assert_equal("no", AndOr(2))
1548 assert_equal("yes", AndOr(4))
Bram Moolenaarac564082020-09-27 19:05:33 +02001549 var instr = execute('disassemble AndOr')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001550 assert_match('AndOr\_s*' ..
1551 'if arg == 1 && arg != 2 || arg == 4\_s*' ..
1552 '\d LOAD arg\[-1]\_s*' ..
1553 '\d PUSHNR 1\_s*' ..
1554 '\d COMPAREANY ==\_s*' ..
Bram Moolenaar2bb26582020-10-03 22:52:39 +02001555 '\d JUMP_IF_COND_FALSE -> \d\+\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001556 '\d LOAD arg\[-1]\_s*' ..
1557 '\d PUSHNR 2\_s*' ..
1558 '\d COMPAREANY !=\_s*' ..
Bram Moolenaar2bb26582020-10-03 22:52:39 +02001559 '\d JUMP_IF_COND_TRUE -> \d\+\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001560 '\d LOAD arg\[-1]\_s*' ..
1561 '\d\+ PUSHNR 4\_s*' ..
1562 '\d\+ COMPAREANY ==\_s*' ..
1563 '\d\+ JUMP_IF_FALSE -> \d\+',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001564 instr)
Bram Moolenaar777770f2020-02-06 21:27:08 +01001565enddef
1566
Bram Moolenaar62aec932022-01-29 21:45:34 +00001567def s:AndConstant(arg: any): string
Bram Moolenaar1a7ee4d2021-09-16 16:15:07 +02001568 if true && arg
1569 return "yes"
1570 endif
1571 if false && arg
1572 return "never"
1573 endif
1574 return "no"
1575enddef
1576
1577def Test_disassemble_and_constant()
1578 assert_equal("yes", AndConstant(1))
1579 assert_equal("no", AndConstant(false))
1580 var instr = execute('disassemble AndConstant')
1581 assert_match('AndConstant\_s*' ..
1582 'if true && arg\_s*' ..
1583 '0 LOAD arg\[-1\]\_s*' ..
1584 '1 COND2BOOL\_s*' ..
1585 '2 JUMP_IF_FALSE -> 5\_s*' ..
1586 'return "yes"\_s*' ..
1587 '3 PUSHS "yes"\_s*' ..
1588 '4 RETURN\_s*' ..
1589 'endif\_s*' ..
1590 'if false && arg\_s*' ..
1591 'return "never"\_s*' ..
1592 'endif\_s*' ..
1593 'return "no"\_s*' ..
1594 '5 PUSHS "no"\_s*' ..
1595 '6 RETURN',
1596 instr)
1597enddef
1598
Bram Moolenaar62aec932022-01-29 21:45:34 +00001599def s:ForLoop(): list<number>
Bram Moolenaarac564082020-09-27 19:05:33 +02001600 var res: list<number>
Bram Moolenaar04d05222020-02-06 22:06:54 +01001601 for i in range(3)
1602 res->add(i)
1603 endfor
1604 return res
1605enddef
1606
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001607def Test_disassemble_for_loop()
Bram Moolenaar04d05222020-02-06 22:06:54 +01001608 assert_equal([0, 1, 2], ForLoop())
Bram Moolenaarac564082020-09-27 19:05:33 +02001609 var instr = execute('disassemble ForLoop')
Bram Moolenaarcb790402020-05-15 20:53:00 +02001610 assert_match('ForLoop\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001611 'var res: list<number>\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001612 '\d NEWLIST size 0\_s*' ..
Bram Moolenaaraa210a32021-01-02 15:41:03 +01001613 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001614 '\d STORE $0\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001615
Bram Moolenaarcb790402020-05-15 20:53:00 +02001616 'for i in range(3)\_s*' ..
1617 '\d STORE -1 in $1\_s*' ..
1618 '\d PUSHNR 3\_s*' ..
1619 '\d BCALL range(argc 1)\_s*' ..
1620 '\d FOR $1 -> \d\+\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001621 '\d STORE $3\_s*' ..
1622
Bram Moolenaarcb790402020-05-15 20:53:00 +02001623 'res->add(i)\_s*' ..
1624 '\d LOAD $0\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001625 '\d LOAD $3\_s*' ..
Bram Moolenaar1dcae592020-10-19 19:02:42 +02001626 '\d\+ LISTAPPEND\_s*' ..
Bram Moolenaarcb790402020-05-15 20:53:00 +02001627 '\d\+ DROP\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001628
Bram Moolenaarcb790402020-05-15 20:53:00 +02001629 'endfor\_s*' ..
1630 '\d\+ JUMP -> \d\+\_s*' ..
1631 '\d\+ DROP',
Bram Moolenaar675f7162020-04-12 22:53:54 +02001632 instr)
Bram Moolenaar04d05222020-02-06 22:06:54 +01001633enddef
1634
Bram Moolenaar62aec932022-01-29 21:45:34 +00001635def s:ForLoopEval(): string
Bram Moolenaarac564082020-09-27 19:05:33 +02001636 var res = ""
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001637 for str in eval('["one", "two"]')
1638 res ..= str
1639 endfor
1640 return res
1641enddef
1642
1643def Test_disassemble_for_loop_eval()
1644 assert_equal('onetwo', ForLoopEval())
Bram Moolenaarac564082020-09-27 19:05:33 +02001645 var instr = execute('disassemble ForLoopEval')
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001646 assert_match('ForLoopEval\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001647 'var res = ""\_s*' ..
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001648 '\d PUSHS ""\_s*' ..
1649 '\d STORE $0\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001650
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001651 'for str in eval(''\["one", "two"\]'')\_s*' ..
1652 '\d STORE -1 in $1\_s*' ..
1653 '\d PUSHS "\["one", "two"\]"\_s*' ..
1654 '\d BCALL eval(argc 1)\_s*' ..
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001655 '\d FOR $1 -> \d\+\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001656 '\d STORE $3\_s*' ..
1657
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001658 'res ..= str\_s*' ..
1659 '\d\+ LOAD $0\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001660 '\d\+ LOAD $3\_s*' ..
Bram Moolenaarf5d52c92021-07-31 22:51:10 +02001661 '\d 2STRING_ANY stack\[-1\]\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01001662 '\d\+ CONCAT size 2\_s*' ..
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001663 '\d\+ STORE $0\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001664
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001665 'endfor\_s*' ..
Bram Moolenaar74e54fc2021-03-26 20:41:29 +01001666 '\d\+ JUMP -> 5\_s*' ..
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001667 '\d\+ DROP\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001668
Bram Moolenaar0ad3e892020-07-05 21:38:11 +02001669 'return res\_s*' ..
1670 '\d\+ LOAD $0\_s*' ..
1671 '\d\+ RETURN',
1672 instr)
1673enddef
1674
Bram Moolenaar62aec932022-01-29 21:45:34 +00001675def s:ForLoopUnpack()
Bram Moolenaar792f7862020-11-23 08:31:18 +01001676 for [x1, x2] in [[1, 2], [3, 4]]
1677 echo x1 x2
1678 endfor
1679enddef
1680
1681def Test_disassemble_for_loop_unpack()
1682 var instr = execute('disassemble ForLoopUnpack')
1683 assert_match('ForLoopUnpack\_s*' ..
1684 'for \[x1, x2\] in \[\[1, 2\], \[3, 4\]\]\_s*' ..
1685 '\d\+ STORE -1 in $0\_s*' ..
1686 '\d\+ PUSHNR 1\_s*' ..
1687 '\d\+ PUSHNR 2\_s*' ..
1688 '\d\+ NEWLIST size 2\_s*' ..
1689 '\d\+ PUSHNR 3\_s*' ..
1690 '\d\+ PUSHNR 4\_s*' ..
1691 '\d\+ NEWLIST size 2\_s*' ..
1692 '\d\+ NEWLIST size 2\_s*' ..
1693 '\d\+ FOR $0 -> 16\_s*' ..
1694 '\d\+ UNPACK 2\_s*' ..
Bram Moolenaar792f7862020-11-23 08:31:18 +01001695 '\d\+ STORE $2\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001696 '\d\+ STORE $3\_s*' ..
1697
Bram Moolenaar792f7862020-11-23 08:31:18 +01001698 'echo x1 x2\_s*' ..
Bram Moolenaar792f7862020-11-23 08:31:18 +01001699 '\d\+ LOAD $2\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001700 '\d\+ LOAD $3\_s*' ..
Bram Moolenaar792f7862020-11-23 08:31:18 +01001701 '\d\+ ECHO 2\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001702
Bram Moolenaar792f7862020-11-23 08:31:18 +01001703 'endfor\_s*' ..
1704 '\d\+ JUMP -> 8\_s*' ..
1705 '\d\+ DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001706 '\d\+ RETURN void',
Bram Moolenaar792f7862020-11-23 08:31:18 +01001707 instr)
1708enddef
1709
Bram Moolenaar62aec932022-01-29 21:45:34 +00001710def s:ForLoopContinue()
Bram Moolenaarc150c092021-02-13 15:02:46 +01001711 for nr in [1, 2]
1712 try
1713 echo "ok"
1714 try
1715 echo "deeper"
1716 catch
1717 continue
1718 endtry
1719 catch
1720 echo "not ok"
1721 endtry
1722 endfor
1723enddef
1724
1725def Test_disassemble_for_loop_continue()
1726 var instr = execute('disassemble ForLoopContinue')
1727 assert_match('ForLoopContinue\_s*' ..
1728 'for nr in \[1, 2]\_s*' ..
1729 '0 STORE -1 in $0\_s*' ..
1730 '1 PUSHNR 1\_s*' ..
1731 '2 PUSHNR 2\_s*' ..
1732 '3 NEWLIST size 2\_s*' ..
1733 '4 FOR $0 -> 22\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001734 '5 STORE $2\_s*' ..
1735
Bram Moolenaarc150c092021-02-13 15:02:46 +01001736 'try\_s*' ..
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +01001737 '6 TRY catch -> 17, endtry -> 20\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001738
Bram Moolenaarc150c092021-02-13 15:02:46 +01001739 'echo "ok"\_s*' ..
1740 '7 PUSHS "ok"\_s*' ..
1741 '8 ECHO 1\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001742
Bram Moolenaarc150c092021-02-13 15:02:46 +01001743 'try\_s*' ..
Bram Moolenaar7e82c5f2021-02-21 21:32:45 +01001744 '9 TRY catch -> 13, endtry -> 15\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001745
Bram Moolenaarc150c092021-02-13 15:02:46 +01001746 'echo "deeper"\_s*' ..
1747 '10 PUSHS "deeper"\_s*' ..
1748 '11 ECHO 1\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001749
Bram Moolenaarc150c092021-02-13 15:02:46 +01001750 'catch\_s*' ..
1751 '12 JUMP -> 15\_s*' ..
1752 '13 CATCH\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001753
Bram Moolenaarc150c092021-02-13 15:02:46 +01001754 'continue\_s*' ..
1755 '14 TRY-CONTINUE 2 levels -> 4\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001756
Bram Moolenaarc150c092021-02-13 15:02:46 +01001757 'endtry\_s*' ..
1758 '15 ENDTRY\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001759
Bram Moolenaarc150c092021-02-13 15:02:46 +01001760 'catch\_s*' ..
1761 '16 JUMP -> 20\_s*' ..
1762 '17 CATCH\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001763
Bram Moolenaarc150c092021-02-13 15:02:46 +01001764 'echo "not ok"\_s*' ..
1765 '18 PUSHS "not ok"\_s*' ..
1766 '19 ECHO 1\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001767
Bram Moolenaarc150c092021-02-13 15:02:46 +01001768 'endtry\_s*' ..
1769 '20 ENDTRY\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01001770
Bram Moolenaarc150c092021-02-13 15:02:46 +01001771 'endfor\_s*' ..
1772 '21 JUMP -> 4\_s*' ..
1773 '\d\+ DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001774 '\d\+ RETURN void',
Bram Moolenaarc150c092021-02-13 15:02:46 +01001775 instr)
1776enddef
1777
Bram Moolenaarc2a4b352020-02-06 22:41:16 +01001778let g:number = 42
1779
Bram Moolenaar62aec932022-01-29 21:45:34 +00001780def s:TypeCast()
Bram Moolenaarac564082020-09-27 19:05:33 +02001781 var l: list<number> = [23, <number>g:number]
Bram Moolenaar64d662d2020-08-09 19:02:50 +02001782enddef
1783
1784def Test_disassemble_typecast()
Bram Moolenaarac564082020-09-27 19:05:33 +02001785 var instr = execute('disassemble TypeCast')
Bram Moolenaar64d662d2020-08-09 19:02:50 +02001786 assert_match('TypeCast.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001787 'var l: list<number> = \[23, <number>g:number\].*' ..
Bram Moolenaar64d662d2020-08-09 19:02:50 +02001788 '\d PUSHNR 23\_s*' ..
1789 '\d LOADG g:number\_s*' ..
1790 '\d CHECKTYPE number stack\[-1\]\_s*' ..
1791 '\d NEWLIST size 2\_s*' ..
Bram Moolenaaraa210a32021-01-02 15:41:03 +01001792 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaar64d662d2020-08-09 19:02:50 +02001793 '\d STORE $0\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02001794 '\d RETURN void\_s*',
Bram Moolenaar64d662d2020-08-09 19:02:50 +02001795 instr)
1796enddef
1797
LemonBoy50d48542024-07-04 17:03:17 +02001798def Test_disassemble_object_cast()
1799 # Downcasting.
1800 var lines =<< trim END
1801 vim9script
1802 class A
1803 endclass
1804 class B extends A
1805 var mylen: number
1806 endclass
1807 def F(o: A): number
1808 return (<B>o).mylen
1809 enddef
1810
1811 g:instr = execute('disassemble F')
1812 END
1813 v9.CheckScriptSuccess(lines)
1814 assert_match('\<SNR>\d*_F\_s*' ..
1815 'return (<B>o).mylen\_s*' ..
1816 '0 LOAD arg\[-1\]\_s*' ..
1817 '1 CHECKTYPE object<B> stack\[-1\]\_s*' ..
1818 '2 OBJ_MEMBER 0\_s*' ..
1819 '3 RETURN\_s*',
1820 g:instr)
1821
1822 # Upcasting.
1823 lines =<< trim END
1824 vim9script
1825 class A
1826 var mylen: number
1827 endclass
1828 class B extends A
1829 endclass
1830 def F(o: B): number
1831 return (<A>o).mylen
1832 enddef
1833
1834 g:instr = execute('disassemble F')
1835 END
1836 v9.CheckScriptSuccess(lines)
1837 assert_match('\<SNR>\d*_F\_s*' ..
1838 'return (<A>o).mylen\_s*' ..
1839 '0 LOAD arg\[-1\]\_s*' ..
1840 '1 OBJ_MEMBER 0\_s*' ..
1841 '2 RETURN\_s*',
1842 g:instr)
1843
1844 # Casting, type is not statically known.
1845 lines =<< trim END
1846 vim9script
1847 class A
1848 endclass
1849 class B extends A
1850 endclass
1851 def F(o: any): any
1852 return <A>o
1853 enddef
1854
1855 g:instr = execute('disassemble F')
1856 END
1857 v9.CheckScriptSuccess(lines)
1858 assert_match('\<SNR>\d*_F\_s*' ..
1859 'return <A>o\_s*' ..
1860 '0 LOAD arg\[-1\]\_s*' ..
1861 '1 CHECKTYPE object<A> stack\[-1\]\_s*' ..
1862 '2 RETURN\_s*',
1863 g:instr)
1864enddef
1865
Bram Moolenaar62aec932022-01-29 21:45:34 +00001866def s:Computing()
Bram Moolenaarac564082020-09-27 19:05:33 +02001867 var nr = 3
1868 var nrres = nr + 7
Bram Moolenaarc2a4b352020-02-06 22:41:16 +01001869 nrres = nr - 7
1870 nrres = nr * 7
1871 nrres = nr / 7
1872 nrres = nr % 7
1873
Bram Moolenaarac564082020-09-27 19:05:33 +02001874 var anyres = g:number + 7
Bram Moolenaarc2a4b352020-02-06 22:41:16 +01001875 anyres = g:number - 7
1876 anyres = g:number * 7
1877 anyres = g:number / 7
1878 anyres = g:number % 7
1879
Bram Moolenaar73e28dc2022-09-17 21:08:33 +01001880 var fl = 3.0
1881 var flres = fl + 7.0
1882 flres = fl - 7.0
1883 flres = fl * 7.0
1884 flres = fl / 7.0
Bram Moolenaarc2a4b352020-02-06 22:41:16 +01001885enddef
1886
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001887def Test_disassemble_computing()
Bram Moolenaarac564082020-09-27 19:05:33 +02001888 var instr = execute('disassemble Computing')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001889 assert_match('Computing.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001890 'var nr = 3.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001891 '\d STORE 3 in $0.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001892 'var nrres = nr + 7.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001893 '\d LOAD $0.*' ..
1894 '\d PUSHNR 7.*' ..
1895 '\d OPNR +.*' ..
1896 '\d STORE $1.*' ..
1897 'nrres = nr - 7.*' ..
1898 '\d OPNR -.*' ..
1899 'nrres = nr \* 7.*' ..
1900 '\d OPNR \*.*' ..
1901 'nrres = nr / 7.*' ..
1902 '\d OPNR /.*' ..
1903 'nrres = nr % 7.*' ..
1904 '\d OPNR %.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001905 'var anyres = g:number + 7.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001906 '\d LOADG g:number.*' ..
1907 '\d PUSHNR 7.*' ..
1908 '\d OPANY +.*' ..
1909 '\d STORE $2.*' ..
1910 'anyres = g:number - 7.*' ..
1911 '\d OPANY -.*' ..
1912 'anyres = g:number \* 7.*' ..
1913 '\d OPANY \*.*' ..
1914 'anyres = g:number / 7.*' ..
1915 '\d OPANY /.*' ..
1916 'anyres = g:number % 7.*' ..
1917 '\d OPANY %.*',
1918 instr)
Bram Moolenaar73e28dc2022-09-17 21:08:33 +01001919 assert_match('Computing.*' ..
1920 'var fl = 3.0.*' ..
1921 '\d PUSHF 3.0.*' ..
1922 '\d STORE $3.*' ..
1923 'var flres = fl + 7.0.*' ..
1924 '\d LOAD $3.*' ..
1925 '\d PUSHF 7.0.*' ..
1926 '\d OPFLOAT +.*' ..
1927 '\d STORE $4.*' ..
1928 'flres = fl - 7.0.*' ..
1929 '\d OPFLOAT -.*' ..
1930 'flres = fl \* 7.0.*' ..
1931 '\d OPFLOAT \*.*' ..
1932 'flres = fl / 7.0.*' ..
1933 '\d OPFLOAT /.*',
1934 instr)
Bram Moolenaarc2a4b352020-02-06 22:41:16 +01001935enddef
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01001936
Bram Moolenaar62aec932022-01-29 21:45:34 +00001937def s:AddListBlob()
Bram Moolenaarac564082020-09-27 19:05:33 +02001938 var reslist = [1, 2] + [3, 4]
1939 var resblob = 0z1122 + 0z3344
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001940enddef
1941
1942def Test_disassemble_add_list_blob()
Bram Moolenaarac564082020-09-27 19:05:33 +02001943 var instr = execute('disassemble AddListBlob')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001944 assert_match('AddListBlob.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001945 'var reslist = \[1, 2] + \[3, 4].*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001946 '\d PUSHNR 1.*' ..
1947 '\d PUSHNR 2.*' ..
1948 '\d NEWLIST size 2.*' ..
1949 '\d PUSHNR 3.*' ..
1950 '\d PUSHNR 4.*' ..
1951 '\d NEWLIST size 2.*' ..
1952 '\d ADDLIST.*' ..
1953 '\d STORE $.*.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001954 'var resblob = 0z1122 + 0z3344.*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001955 '\d PUSHBLOB 0z1122.*' ..
1956 '\d PUSHBLOB 0z3344.*' ..
1957 '\d ADDBLOB.*' ..
1958 '\d STORE $.*',
1959 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001960enddef
1961
1962let g:aa = 'aa'
Bram Moolenaar62aec932022-01-29 21:45:34 +00001963def s:ConcatString(): string
Bram Moolenaarac564082020-09-27 19:05:33 +02001964 var res = g:aa .. "bb"
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001965 return res
1966enddef
1967
1968def Test_disassemble_concat()
Bram Moolenaarac564082020-09-27 19:05:33 +02001969 var instr = execute('disassemble ConcatString')
Bram Moolenaar675f7162020-04-12 22:53:54 +02001970 assert_match('ConcatString.*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001971 'var res = g:aa .. "bb".*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001972 '\d LOADG g:aa.*' ..
1973 '\d PUSHS "bb".*' ..
Bram Moolenaar418f1df2020-08-12 21:34:49 +02001974 '\d 2STRING_ANY stack\[-2].*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02001975 '\d CONCAT.*' ..
1976 '\d STORE $.*',
1977 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01001978 assert_equal('aabb', ConcatString())
1979enddef
1980
Bram Moolenaar62aec932022-01-29 21:45:34 +00001981def s:StringIndex(): string
Bram Moolenaarac564082020-09-27 19:05:33 +02001982 var s = "abcd"
1983 var res = s[1]
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001984 return res
1985enddef
1986
1987def Test_disassemble_string_index()
Bram Moolenaarac564082020-09-27 19:05:33 +02001988 var instr = execute('disassemble StringIndex')
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001989 assert_match('StringIndex\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001990 'var s = "abcd"\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001991 '\d PUSHS "abcd"\_s*' ..
1992 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02001993 'var res = s\[1]\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02001994 '\d LOAD $0\_s*' ..
1995 '\d PUSHNR 1\_s*' ..
1996 '\d STRINDEX\_s*' ..
1997 '\d STORE $1\_s*',
1998 instr)
1999 assert_equal('b', StringIndex())
2000enddef
2001
Bram Moolenaar62aec932022-01-29 21:45:34 +00002002def s:StringSlice(): string
Bram Moolenaarac564082020-09-27 19:05:33 +02002003 var s = "abcd"
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002004 var res = s[1 : 8]
Bram Moolenaared591872020-08-15 22:14:53 +02002005 return res
2006enddef
2007
2008def Test_disassemble_string_slice()
Bram Moolenaarac564082020-09-27 19:05:33 +02002009 var instr = execute('disassemble StringSlice')
Bram Moolenaared591872020-08-15 22:14:53 +02002010 assert_match('StringSlice\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002011 'var s = "abcd"\_s*' ..
Bram Moolenaared591872020-08-15 22:14:53 +02002012 '\d PUSHS "abcd"\_s*' ..
2013 '\d STORE $0\_s*' ..
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002014 'var res = s\[1 : 8]\_s*' ..
Bram Moolenaared591872020-08-15 22:14:53 +02002015 '\d LOAD $0\_s*' ..
2016 '\d PUSHNR 1\_s*' ..
2017 '\d PUSHNR 8\_s*' ..
2018 '\d STRSLICE\_s*' ..
2019 '\d STORE $1\_s*',
2020 instr)
2021 assert_equal('bcd', StringSlice())
2022enddef
2023
Bram Moolenaar62aec932022-01-29 21:45:34 +00002024def s:ListIndex(): number
Bram Moolenaarac564082020-09-27 19:05:33 +02002025 var l = [1, 2, 3]
2026 var res = l[1]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002027 return res
2028enddef
2029
2030def Test_disassemble_list_index()
Bram Moolenaarac564082020-09-27 19:05:33 +02002031 var instr = execute('disassemble ListIndex')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002032 assert_match('ListIndex\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002033 'var l = \[1, 2, 3]\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002034 '\d PUSHNR 1\_s*' ..
2035 '\d PUSHNR 2\_s*' ..
2036 '\d PUSHNR 3\_s*' ..
2037 '\d NEWLIST size 3\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +00002038 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002039 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002040 'var res = l\[1]\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002041 '\d LOAD $0\_s*' ..
2042 '\d PUSHNR 1\_s*' ..
Bram Moolenaar747f11a2020-07-19 18:38:37 +02002043 '\d LISTINDEX\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002044 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002045 instr)
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002046 assert_equal(2, ListIndex())
2047enddef
2048
Bram Moolenaar62aec932022-01-29 21:45:34 +00002049def s:ListSlice(): list<number>
Bram Moolenaarac564082020-09-27 19:05:33 +02002050 var l = [1, 2, 3]
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002051 var res = l[1 : 8]
Bram Moolenaared591872020-08-15 22:14:53 +02002052 return res
2053enddef
2054
2055def Test_disassemble_list_slice()
Bram Moolenaarac564082020-09-27 19:05:33 +02002056 var instr = execute('disassemble ListSlice')
Bram Moolenaared591872020-08-15 22:14:53 +02002057 assert_match('ListSlice\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002058 'var l = \[1, 2, 3]\_s*' ..
Bram Moolenaared591872020-08-15 22:14:53 +02002059 '\d PUSHNR 1\_s*' ..
2060 '\d PUSHNR 2\_s*' ..
2061 '\d PUSHNR 3\_s*' ..
2062 '\d NEWLIST size 3\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +00002063 '\d SETTYPE list<number>\_s*' ..
Bram Moolenaared591872020-08-15 22:14:53 +02002064 '\d STORE $0\_s*' ..
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002065 'var res = l\[1 : 8]\_s*' ..
Bram Moolenaared591872020-08-15 22:14:53 +02002066 '\d LOAD $0\_s*' ..
2067 '\d PUSHNR 1\_s*' ..
2068 '\d PUSHNR 8\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +00002069 '\d\+ LISTSLICE\_s*' ..
2070 '\d\+ SETTYPE list<number>\_s*' ..
2071 '\d\+ STORE $1\_s*',
Bram Moolenaared591872020-08-15 22:14:53 +02002072 instr)
2073 assert_equal([2, 3], ListSlice())
2074enddef
2075
Bram Moolenaar62aec932022-01-29 21:45:34 +00002076def s:DictMember(): number
Bram Moolenaare0de1712020-12-02 17:36:54 +01002077 var d = {item: 1}
Bram Moolenaarac564082020-09-27 19:05:33 +02002078 var res = d.item
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002079 res = d["item"]
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002080 return res
2081enddef
2082
2083def Test_disassemble_dict_member()
Bram Moolenaarac564082020-09-27 19:05:33 +02002084 var instr = execute('disassemble DictMember')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002085 assert_match('DictMember\_s*' ..
Bram Moolenaare0de1712020-12-02 17:36:54 +01002086 'var d = {item: 1}\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002087 '\d PUSHS "item"\_s*' ..
2088 '\d PUSHNR 1\_s*' ..
2089 '\d NEWDICT size 1\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +00002090 '\d SETTYPE dict<number>\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002091 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002092 'var res = d.item\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002093 '\d\+ LOAD $0\_s*' ..
2094 '\d\+ MEMBER item\_s*' ..
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02002095 '\d\+ USEDICT\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002096 '\d\+ STORE $1\_s*' ..
2097 'res = d\["item"\]\_s*' ..
2098 '\d\+ LOAD $0\_s*' ..
2099 '\d\+ PUSHS "item"\_s*' ..
2100 '\d\+ MEMBER\_s*' ..
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02002101 '\d\+ USEDICT\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002102 '\d\+ STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002103 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02002104 assert_equal(1, DictMember())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002105enddef
2106
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002107let somelist = [1, 2, 3, 4, 5]
Bram Moolenaar62aec932022-01-29 21:45:34 +00002108def s:AnyIndex(): number
Bram Moolenaarac564082020-09-27 19:05:33 +02002109 var res = g:somelist[2]
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002110 return res
2111enddef
2112
2113def Test_disassemble_any_index()
Bram Moolenaarac564082020-09-27 19:05:33 +02002114 var instr = execute('disassemble AnyIndex')
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002115 assert_match('AnyIndex\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002116 'var res = g:somelist\[2\]\_s*' ..
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002117 '\d LOADG g:somelist\_s*' ..
2118 '\d PUSHNR 2\_s*' ..
2119 '\d ANYINDEX\_s*' ..
2120 '\d STORE $0\_s*' ..
2121 'return res\_s*' ..
2122 '\d LOAD $0\_s*' ..
2123 '\d CHECKTYPE number stack\[-1\]\_s*' ..
2124 '\d RETURN',
2125 instr)
2126 assert_equal(3, AnyIndex())
2127enddef
2128
Bram Moolenaar62aec932022-01-29 21:45:34 +00002129def s:AnySlice(): list<number>
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002130 var res = g:somelist[1 : 3]
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002131 return res
2132enddef
2133
2134def Test_disassemble_any_slice()
Bram Moolenaarac564082020-09-27 19:05:33 +02002135 var instr = execute('disassemble AnySlice')
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002136 assert_match('AnySlice\_s*' ..
Bram Moolenaarde4f95b2020-12-30 20:39:21 +01002137 'var res = g:somelist\[1 : 3\]\_s*' ..
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002138 '\d LOADG g:somelist\_s*' ..
2139 '\d PUSHNR 1\_s*' ..
2140 '\d PUSHNR 3\_s*' ..
2141 '\d ANYSLICE\_s*' ..
2142 '\d STORE $0\_s*' ..
2143 'return res\_s*' ..
2144 '\d LOAD $0\_s*' ..
Bram Moolenaar5e654232020-09-16 15:22:00 +02002145 '\d CHECKTYPE list<number> stack\[-1\]\_s*' ..
Bram Moolenaarcc673e72020-08-16 17:33:35 +02002146 '\d RETURN',
2147 instr)
2148 assert_equal([2, 3, 4], AnySlice())
2149enddef
2150
Bram Moolenaar62aec932022-01-29 21:45:34 +00002151def s:NegateNumber(): number
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +02002152 g:nr = 9
2153 var plus = +g:nr
2154 var minus = -g:nr
2155 return minus
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002156enddef
2157
2158def Test_disassemble_negate_number()
Bram Moolenaarac564082020-09-27 19:05:33 +02002159 var instr = execute('disassemble NegateNumber')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002160 assert_match('NegateNumber\_s*' ..
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +02002161 'g:nr = 9\_s*' ..
2162 '\d PUSHNR 9\_s*' ..
2163 '\d STOREG g:nr\_s*' ..
2164 'var plus = +g:nr\_s*' ..
2165 '\d LOADG g:nr\_s*' ..
2166 '\d CHECKTYPE number stack\[-1\]\_s*' ..
2167 '\d STORE $0\_s*' ..
2168 'var minus = -g:nr\_s*' ..
2169 '\d LOADG g:nr\_s*' ..
2170 '\d CHECKTYPE number stack\[-1\]\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002171 '\d NEGATENR\_s*' ..
Bram Moolenaarcd6b4f32021-08-15 20:36:28 +02002172 '\d STORE $1\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002173 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02002174 assert_equal(-9, NegateNumber())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002175enddef
2176
Bram Moolenaar62aec932022-01-29 21:45:34 +00002177def s:InvertBool(): bool
Bram Moolenaarac564082020-09-27 19:05:33 +02002178 var flag = true
2179 var invert = !flag
2180 var res = !!flag
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002181 return res
2182enddef
2183
2184def Test_disassemble_invert_bool()
Bram Moolenaarac564082020-09-27 19:05:33 +02002185 var instr = execute('disassemble InvertBool')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002186 assert_match('InvertBool\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002187 'var flag = true\_s*' ..
Bram Moolenaara8b8af12021-01-01 15:11:04 +01002188 '\d PUSH true\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002189 '\d STORE $0\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002190 'var invert = !flag\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002191 '\d LOAD $0\_s*' ..
Bram Moolenaar5fa9b242021-06-04 21:00:32 +02002192 '\d INVERT -1 (!val)\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002193 '\d STORE $1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002194 'var res = !!flag\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002195 '\d LOAD $0\_s*' ..
Bram Moolenaar5fa9b242021-06-04 21:00:32 +02002196 '\d 2BOOL -1 (!!val)\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002197 '\d STORE $2\_s*',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002198 instr)
Bram Moolenaard2c61702020-09-06 15:58:36 +02002199 assert_equal(true, InvertBool())
Bram Moolenaaree2e52a2020-02-19 14:17:18 +01002200enddef
2201
Bram Moolenaar62aec932022-01-29 21:45:34 +00002202def s:ReturnBool(): bool
Bram Moolenaar1a7ee4d2021-09-16 16:15:07 +02002203 var one = 1
2204 var zero = 0
Bram Moolenaar5cd64792021-12-25 18:23:24 +00002205 var none: number
Bram Moolenaar1a7ee4d2021-09-16 16:15:07 +02002206 var name: bool = one && zero || one
Bram Moolenaar2bb26582020-10-03 22:52:39 +02002207 return name
Bram Moolenaar4ed124c2020-09-09 20:03:46 +02002208enddef
2209
2210def Test_disassemble_return_bool()
Bram Moolenaarac564082020-09-27 19:05:33 +02002211 var instr = execute('disassemble ReturnBool')
Bram Moolenaar4ed124c2020-09-09 20:03:46 +02002212 assert_match('ReturnBool\_s*' ..
Bram Moolenaar1a7ee4d2021-09-16 16:15:07 +02002213 'var one = 1\_s*' ..
2214 '0 STORE 1 in $0\_s*' ..
2215 'var zero = 0\_s*' ..
Bram Moolenaar5cd64792021-12-25 18:23:24 +00002216 'var none: number\_s*' ..
Bram Moolenaar1a7ee4d2021-09-16 16:15:07 +02002217 'var name: bool = one && zero || one\_s*' ..
Bram Moolenaar5cd64792021-12-25 18:23:24 +00002218 '1 LOAD $0\_s*' ..
2219 '2 COND2BOOL\_s*' ..
2220 '3 JUMP_IF_COND_FALSE -> 6\_s*' ..
2221 '4 LOAD $1\_s*' ..
2222 '5 COND2BOOL\_s*' ..
2223 '6 JUMP_IF_COND_TRUE -> 9\_s*' ..
2224 '7 LOAD $0\_s*' ..
2225 '8 COND2BOOL\_s*' ..
2226 '9 STORE $3\_s*' ..
Bram Moolenaar2bb26582020-10-03 22:52:39 +02002227 'return name\_s*' ..
Bram Moolenaar94722c52023-01-28 19:19:03 +00002228 '\d\+ LOAD $3\_s*' ..
Bram Moolenaarea2d4072020-11-12 12:08:51 +01002229 '\d\+ RETURN',
Bram Moolenaar4ed124c2020-09-09 20:03:46 +02002230 instr)
2231 assert_equal(true, InvertBool())
2232enddef
2233
Bram Moolenaar62aec932022-01-29 21:45:34 +00002234def s:AutoInit()
Bram Moolenaarfb9dcb02021-12-25 22:00:49 +00002235 var t: number
2236 t = 1
2237 t = 0
2238enddef
2239
2240def Test_disassemble_auto_init()
2241 var instr = execute('disassemble AutoInit')
2242 assert_match('AutoInit\_s*' ..
2243 'var t: number\_s*' ..
2244 't = 1\_s*' ..
2245 '\d STORE 1 in $0\_s*' ..
2246 't = 0\_s*' ..
2247 '\d STORE 0 in $0\_s*' ..
2248 '\d\+ RETURN void',
2249 instr)
2250enddef
2251
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002252def Test_disassemble_compare()
Bram Moolenaarac564082020-09-27 19:05:33 +02002253 var cases = [
Bram Moolenaara5565e42020-05-09 15:44:01 +02002254 ['true == isFalse', 'COMPAREBOOL =='],
2255 ['true != isFalse', 'COMPAREBOOL !='],
2256 ['v:none == isNull', 'COMPARESPECIAL =='],
2257 ['v:none != isNull', 'COMPARESPECIAL !='],
Bram Moolenaar7a222242022-03-01 19:23:24 +00002258 ['"text" == isNull', 'COMPARENULL =='],
2259 ['"text" != isNull', 'COMPARENULL !='],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002260
Bram Moolenaara5565e42020-05-09 15:44:01 +02002261 ['111 == aNumber', 'COMPARENR =='],
2262 ['111 != aNumber', 'COMPARENR !='],
2263 ['111 > aNumber', 'COMPARENR >'],
2264 ['111 < aNumber', 'COMPARENR <'],
2265 ['111 >= aNumber', 'COMPARENR >='],
2266 ['111 <= aNumber', 'COMPARENR <='],
2267 ['111 =~ aNumber', 'COMPARENR =\~'],
2268 ['111 !~ aNumber', 'COMPARENR !\~'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002269
Bram Moolenaara5565e42020-05-09 15:44:01 +02002270 ['"xx" != aString', 'COMPARESTRING !='],
2271 ['"xx" > aString', 'COMPARESTRING >'],
2272 ['"xx" < aString', 'COMPARESTRING <'],
2273 ['"xx" >= aString', 'COMPARESTRING >='],
2274 ['"xx" <= aString', 'COMPARESTRING <='],
2275 ['"xx" =~ aString', 'COMPARESTRING =\~'],
2276 ['"xx" !~ aString', 'COMPARESTRING !\~'],
2277 ['"xx" is aString', 'COMPARESTRING is'],
2278 ['"xx" isnot aString', 'COMPARESTRING isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002279
Bram Moolenaara5565e42020-05-09 15:44:01 +02002280 ['0z11 == aBlob', 'COMPAREBLOB =='],
2281 ['0z11 != aBlob', 'COMPAREBLOB !='],
2282 ['0z11 is aBlob', 'COMPAREBLOB is'],
2283 ['0z11 isnot aBlob', 'COMPAREBLOB isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002284
Bram Moolenaara5565e42020-05-09 15:44:01 +02002285 ['[1, 2] == aList', 'COMPARELIST =='],
2286 ['[1, 2] != aList', 'COMPARELIST !='],
2287 ['[1, 2] is aList', 'COMPARELIST is'],
2288 ['[1, 2] isnot aList', 'COMPARELIST isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002289
Bram Moolenaare0de1712020-12-02 17:36:54 +01002290 ['{a: 1} == aDict', 'COMPAREDICT =='],
2291 ['{a: 1} != aDict', 'COMPAREDICT !='],
2292 ['{a: 1} is aDict', 'COMPAREDICT is'],
2293 ['{a: 1} isnot aDict', 'COMPAREDICT isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002294
Bram Moolenaar2949cfd2020-12-31 21:28:47 +01002295 ['(() => 33) == (() => 44)', 'COMPAREFUNC =='],
2296 ['(() => 33) != (() => 44)', 'COMPAREFUNC !='],
2297 ['(() => 33) is (() => 44)', 'COMPAREFUNC is'],
2298 ['(() => 33) isnot (() => 44)', 'COMPAREFUNC isnot'],
Bram Moolenaar675f7162020-04-12 22:53:54 +02002299
2300 ['77 == g:xx', 'COMPAREANY =='],
2301 ['77 != g:xx', 'COMPAREANY !='],
2302 ['77 > g:xx', 'COMPAREANY >'],
2303 ['77 < g:xx', 'COMPAREANY <'],
2304 ['77 >= g:xx', 'COMPAREANY >='],
2305 ['77 <= g:xx', 'COMPAREANY <='],
2306 ['77 =~ g:xx', 'COMPAREANY =\~'],
2307 ['77 !~ g:xx', 'COMPAREANY !\~'],
2308 ['77 is g:xx', 'COMPAREANY is'],
2309 ['77 isnot g:xx', 'COMPAREANY isnot'],
2310 ]
Bram Moolenaarac564082020-09-27 19:05:33 +02002311 var floatDecl = ''
Bram Moolenaar73e28dc2022-09-17 21:08:33 +01002312 cases->extend([
2313 ['1.1 == aFloat', 'COMPAREFLOAT =='],
2314 ['1.1 != aFloat', 'COMPAREFLOAT !='],
2315 ['1.1 > aFloat', 'COMPAREFLOAT >'],
2316 ['1.1 < aFloat', 'COMPAREFLOAT <'],
2317 ['1.1 >= aFloat', 'COMPAREFLOAT >='],
2318 ['1.1 <= aFloat', 'COMPAREFLOAT <='],
2319 ['1.1 =~ aFloat', 'COMPAREFLOAT =\~'],
2320 ['1.1 !~ aFloat', 'COMPAREFLOAT !\~'],
2321 ])
2322 floatDecl = 'var aFloat = 2.2'
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002323
Bram Moolenaarac564082020-09-27 19:05:33 +02002324 var nr = 1
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002325 for case in cases
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002326 # declare local variables to get a non-constant with the right type
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002327 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaarac564082020-09-27 19:05:33 +02002328 ' var isFalse = false',
2329 ' var isNull = v:null',
2330 ' var aNumber = 222',
2331 ' var aString = "yy"',
2332 ' var aBlob = 0z22',
2333 ' var aList = [3, 4]',
Bram Moolenaare0de1712020-12-02 17:36:54 +01002334 ' var aDict = {x: 2}',
Bram Moolenaara5565e42020-05-09 15:44:01 +02002335 floatDecl,
Bram Moolenaar675f7162020-04-12 22:53:54 +02002336 ' if ' .. case[0],
Bram Moolenaar2984ed32022-08-20 14:51:17 +01002337 ' echo 42',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002338 ' endif',
2339 'enddef'], 'Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002340 source Xdisassemble
Bram Moolenaarac564082020-09-27 19:05:33 +02002341 var instr = execute('disassemble TestCase' .. nr)
Bram Moolenaar675f7162020-04-12 22:53:54 +02002342 assert_match('TestCase' .. nr .. '.*' ..
2343 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
2344 '\d \(PUSH\|FUNCREF\).*' ..
Bram Moolenaara5565e42020-05-09 15:44:01 +02002345 '\d \(PUSH\|FUNCREF\|LOAD\).*' ..
Bram Moolenaar675f7162020-04-12 22:53:54 +02002346 '\d ' .. case[1] .. '.*' ..
2347 '\d JUMP_IF_FALSE -> \d\+.*',
2348 instr)
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002349
2350 nr += 1
2351 endfor
2352
Bram Moolenaar22da5592020-03-19 14:52:20 +01002353 delete('Xdisassemble')
Bram Moolenaarf2460a32020-02-07 22:09:54 +01002354enddef
2355
Bram Moolenaar92f26c22020-10-03 20:17:30 +02002356def s:FalsyOp()
2357 echo g:flag ?? "yes"
2358 echo [] ?? "empty list"
2359 echo "" ?? "empty string"
2360enddef
2361
Dominique Pelle81b573d2022-03-22 21:14:55 +00002362def Test_disassemble_falsy_op()
Bram Moolenaar92f26c22020-10-03 20:17:30 +02002363 var res = execute('disass s:FalsyOp')
2364 assert_match('\<SNR>\d*_FalsyOp\_s*' ..
2365 'echo g:flag ?? "yes"\_s*' ..
2366 '0 LOADG g:flag\_s*' ..
2367 '1 JUMP_AND_KEEP_IF_TRUE -> 3\_s*' ..
2368 '2 PUSHS "yes"\_s*' ..
2369 '3 ECHO 1\_s*' ..
2370 'echo \[\] ?? "empty list"\_s*' ..
2371 '4 NEWLIST size 0\_s*' ..
2372 '5 JUMP_AND_KEEP_IF_TRUE -> 7\_s*' ..
2373 '6 PUSHS "empty list"\_s*' ..
2374 '7 ECHO 1\_s*' ..
2375 'echo "" ?? "empty string"\_s*' ..
2376 '\d\+ PUSHS "empty string"\_s*' ..
2377 '\d\+ ECHO 1\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002378 '\d\+ RETURN void',
Bram Moolenaar92f26c22020-10-03 20:17:30 +02002379 res)
2380enddef
2381
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002382def Test_disassemble_compare_const()
Bram Moolenaarac564082020-09-27 19:05:33 +02002383 var cases = [
Bram Moolenaar675f7162020-04-12 22:53:54 +02002384 ['"xx" == "yy"', false],
2385 ['"aa" == "aa"', true],
2386 ['has("eval") ? true : false', true],
2387 ['has("asdf") ? true : false', false],
2388 ]
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002389
Bram Moolenaarac564082020-09-27 19:05:33 +02002390 var nr = 1
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002391 for case in cases
2392 writefile(['def TestCase' .. nr .. '()',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002393 ' if ' .. case[0],
Bram Moolenaar2984ed32022-08-20 14:51:17 +01002394 ' echo 42',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002395 ' endif',
2396 'enddef'], 'Xdisassemble')
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002397 source Xdisassemble
Bram Moolenaarac564082020-09-27 19:05:33 +02002398 var instr = execute('disassemble TestCase' .. nr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002399 if case[1]
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002400 # condition true, "echo 42" executed
Bram Moolenaar675f7162020-04-12 22:53:54 +02002401 assert_match('TestCase' .. nr .. '.*' ..
2402 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
2403 '\d PUSHNR 42.*' ..
2404 '\d ECHO 1.*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002405 '\d RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002406 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002407 else
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002408 # condition false, function just returns
Bram Moolenaar675f7162020-04-12 22:53:54 +02002409 assert_match('TestCase' .. nr .. '.*' ..
2410 'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
2411 'echo 42[ \n]*' ..
2412 'endif[ \n]*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002413 '\d RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002414 instr)
Bram Moolenaara4d4cf42020-04-02 13:50:27 +02002415 endif
2416
2417 nr += 1
2418 endfor
2419
2420 delete('Xdisassemble')
2421enddef
2422
Bram Moolenaarad39c092020-02-26 18:23:43 +01002423def s:Execute()
2424 execute 'help vim9.txt'
Bram Moolenaarac564082020-09-27 19:05:33 +02002425 var cmd = 'help vim9.txt'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002426 execute cmd
Bram Moolenaarac564082020-09-27 19:05:33 +02002427 var tag = 'vim9.txt'
Bram Moolenaarad39c092020-02-26 18:23:43 +01002428 execute 'help ' .. tag
2429enddef
2430
2431def Test_disassemble_execute()
Bram Moolenaarac564082020-09-27 19:05:33 +02002432 var res = execute('disass s:Execute')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002433 assert_match('\<SNR>\d*_Execute\_s*' ..
2434 "execute 'help vim9.txt'\\_s*" ..
2435 '\d PUSHS "help vim9.txt"\_s*' ..
2436 '\d EXECUTE 1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002437 "var cmd = 'help vim9.txt'\\_s*" ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002438 '\d PUSHS "help vim9.txt"\_s*' ..
2439 '\d STORE $0\_s*' ..
2440 'execute cmd\_s*' ..
2441 '\d LOAD $0\_s*' ..
2442 '\d EXECUTE 1\_s*' ..
Bram Moolenaarac564082020-09-27 19:05:33 +02002443 "var tag = 'vim9.txt'\\_s*" ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002444 '\d PUSHS "vim9.txt"\_s*' ..
2445 '\d STORE $1\_s*' ..
2446 "execute 'help ' .. tag\\_s*" ..
2447 '\d\+ PUSHS "help "\_s*' ..
2448 '\d\+ LOAD $1\_s*' ..
LemonBoy372bcce2022-04-25 12:43:20 +01002449 '\d\+ CONCAT size 2\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002450 '\d\+ EXECUTE 1\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002451 '\d\+ RETURN void',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002452 res)
Bram Moolenaarad39c092020-02-26 18:23:43 +01002453enddef
2454
Bram Moolenaare4eed8c2021-12-01 15:22:56 +00002455def s:OnlyRange()
2456 :$
2457 :123
2458 :'m
2459enddef
2460
2461def Test_disassemble_range_only()
2462 var res = execute('disass s:OnlyRange')
2463 assert_match('\<SNR>\d*_OnlyRange\_s*' ..
2464 ':$\_s*' ..
2465 '\d EXECRANGE $\_s*' ..
2466 ':123\_s*' ..
2467 '\d EXECRANGE 123\_s*' ..
2468 ':''m\_s*' ..
2469 '\d EXECRANGE ''m\_s*' ..
2470 '\d\+ RETURN void',
2471 res)
2472enddef
2473
Bram Moolenaarf6ced982022-04-28 12:00:49 +01002474def s:StoreRange()
2475 var l = [1, 2]
2476 l[0 : 1] = [7, 8]
2477enddef
2478
2479def Test_disassemble_store_range()
2480 var res = execute('disass s:StoreRange')
2481 assert_match('\<SNR>\d*_StoreRange\_s*' ..
2482 'var l = \[1, 2]\_s*' ..
2483 '\d PUSHNR 1\_s*' ..
2484 '\d PUSHNR 2\_s*' ..
2485 '\d NEWLIST size 2\_s*' ..
2486 '\d SETTYPE list<number>\_s*' ..
2487 '\d STORE $0\_s*' ..
2488
2489 'l\[0 : 1] = \[7, 8]\_s*' ..
2490 '\d\+ PUSHNR 7\_s*' ..
2491 '\d\+ PUSHNR 8\_s*' ..
2492 '\d\+ NEWLIST size 2\_s*' ..
2493 '\d\+ PUSHNR 0\_s*' ..
2494 '\d\+ PUSHNR 1\_s*' ..
2495 '\d\+ LOAD $0\_s*' ..
2496 '\d\+ STORERANGE\_s*' ..
2497 '\d\+ RETURN void',
2498 res)
2499enddef
2500
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002501def s:Echomsg()
2502 echomsg 'some' 'message'
Bram Moolenaar7de62622021-08-07 15:05:47 +02002503 echoconsole 'nothing'
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002504 echoerr 'went' .. 'wrong'
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002505 var local = 'window'
2506 echowin 'in' local
Bram Moolenaarbdc09a12022-10-07 14:31:45 +01002507 :5echowin 'five'
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002508enddef
2509
2510def Test_disassemble_echomsg()
Bram Moolenaarac564082020-09-27 19:05:33 +02002511 var res = execute('disass s:Echomsg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002512 assert_match('\<SNR>\d*_Echomsg\_s*' ..
2513 "echomsg 'some' 'message'\\_s*" ..
2514 '\d PUSHS "some"\_s*' ..
2515 '\d PUSHS "message"\_s*' ..
2516 '\d ECHOMSG 2\_s*' ..
Bram Moolenaar7de62622021-08-07 15:05:47 +02002517 "echoconsole 'nothing'\\_s*" ..
2518 '\d PUSHS "nothing"\_s*' ..
2519 '\d ECHOCONSOLE 1\_s*' ..
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002520 "echoerr 'went' .. 'wrong'\\_s*" ..
2521 '\d PUSHS "wentwrong"\_s*' ..
2522 '\d ECHOERR 1\_s*' ..
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002523 "var local = 'window'\\_s*" ..
2524 '\d\+ PUSHS "window"\_s*' ..
2525 '\d\+ STORE $0\_s*' ..
2526 "echowin 'in' local\\_s*" ..
2527 '\d\+ PUSHS "in"\_s*' ..
2528 '\d\+ LOAD $0\_s*' ..
2529 '\d\+ ECHOWINDOW 2\_s*' ..
Bram Moolenaarbdc09a12022-10-07 14:31:45 +01002530 ":5echowin 'five'\\_s*" ..
2531 '\d\+ PUSHS "five"\_s*' ..
2532 '\d\+ ECHOWINDOW 1 (5 sec)\_s*' ..
Bram Moolenaar7d7ad7b2022-09-01 16:00:53 +01002533 '\d\+ RETURN void',
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +02002534 res)
2535enddef
2536
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01002537def SomeStringArg(arg: string)
2538 echo arg
2539enddef
2540
2541def SomeAnyArg(arg: any)
2542 echo arg
2543enddef
2544
2545def SomeStringArgAndReturn(arg: string): string
2546 return arg
2547enddef
2548
2549def Test_display_func()
Bram Moolenaarac564082020-09-27 19:05:33 +02002550 var res1 = execute('function SomeStringArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002551 assert_match('.* def SomeStringArg(arg: string)\_s*' ..
2552 '\d *echo arg.*' ..
2553 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002554 res1)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01002555
Bram Moolenaarac564082020-09-27 19:05:33 +02002556 var res2 = execute('function SomeAnyArg')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002557 assert_match('.* def SomeAnyArg(arg: any)\_s*' ..
2558 '\d *echo arg\_s*' ..
2559 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002560 res2)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01002561
Bram Moolenaarac564082020-09-27 19:05:33 +02002562 var res3 = execute('function SomeStringArgAndReturn')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002563 assert_match('.* def SomeStringArgAndReturn(arg: string): string\_s*' ..
2564 '\d *return arg\_s*' ..
2565 ' *enddef',
Bram Moolenaar675f7162020-04-12 22:53:54 +02002566 res3)
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +01002567enddef
2568
Bram Moolenaar09689a02020-05-09 22:50:08 +02002569def Test_vim9script_forward_func()
Bram Moolenaarac564082020-09-27 19:05:33 +02002570 var lines =<< trim END
Bram Moolenaar09689a02020-05-09 22:50:08 +02002571 vim9script
2572 def FuncOne(): string
2573 return FuncTwo()
2574 enddef
2575 def FuncTwo(): string
2576 return 'two'
2577 enddef
Bram Moolenaar67979662020-06-20 22:50:47 +02002578 g:res_FuncOne = execute('disass FuncOne')
Bram Moolenaar09689a02020-05-09 22:50:08 +02002579 END
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01002580 writefile(lines, 'Xdisassemble', 'D')
Bram Moolenaar09689a02020-05-09 22:50:08 +02002581 source Xdisassemble
2582
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +02002583 # check that the first function calls the second with DCALL
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002584 assert_match('\<SNR>\d*_FuncOne\_s*' ..
2585 'return FuncTwo()\_s*' ..
2586 '\d DCALL <SNR>\d\+_FuncTwo(argc 0)\_s*' ..
Bram Moolenaar09689a02020-05-09 22:50:08 +02002587 '\d RETURN',
2588 g:res_FuncOne)
2589
Bram Moolenaar09689a02020-05-09 22:50:08 +02002590 unlet g:res_FuncOne
2591enddef
2592
Bram Moolenaar61a89812020-05-07 16:58:17 +02002593def s:ConcatStrings(): string
2594 return 'one' .. 'two' .. 'three'
2595enddef
2596
Bram Moolenaar7d131b02020-05-08 19:10:34 +02002597def s:ComputeConst(): number
2598 return 2 + 3 * 4 / 6 + 7
2599enddef
2600
Bram Moolenaar1c747212020-05-09 18:28:34 +02002601def s:ComputeConstParen(): number
2602 return ((2 + 4) * (8 / 2)) / (3 + 4)
2603enddef
2604
Bram Moolenaar61a89812020-05-07 16:58:17 +02002605def Test_simplify_const_expr()
Bram Moolenaarac564082020-09-27 19:05:33 +02002606 var res = execute('disass s:ConcatStrings')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002607 assert_match('<SNR>\d*_ConcatStrings\_s*' ..
2608 "return 'one' .. 'two' .. 'three'\\_s*" ..
2609 '\d PUSHS "onetwothree"\_s*' ..
Bram Moolenaar61a89812020-05-07 16:58:17 +02002610 '\d RETURN',
2611 res)
Bram Moolenaar7d131b02020-05-08 19:10:34 +02002612
2613 res = execute('disass s:ComputeConst')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002614 assert_match('<SNR>\d*_ComputeConst\_s*' ..
2615 'return 2 + 3 \* 4 / 6 + 7\_s*' ..
2616 '\d PUSHNR 11\_s*' ..
Bram Moolenaar7d131b02020-05-08 19:10:34 +02002617 '\d RETURN',
2618 res)
Bram Moolenaar1c747212020-05-09 18:28:34 +02002619
2620 res = execute('disass s:ComputeConstParen')
Bram Moolenaar4902ab12020-05-15 19:21:31 +02002621 assert_match('<SNR>\d*_ComputeConstParen\_s*' ..
2622 'return ((2 + 4) \* (8 / 2)) / (3 + 4)\_s*' ..
2623 '\d PUSHNR 3\>\_s*' ..
Bram Moolenaar1c747212020-05-09 18:28:34 +02002624 '\d RETURN',
2625 res)
Bram Moolenaar61a89812020-05-07 16:58:17 +02002626enddef
2627
Bram Moolenaar389df252020-07-09 21:20:47 +02002628def s:CallAppend()
2629 eval "some text"->append(2)
2630enddef
2631
2632def Test_shuffle()
Bram Moolenaarac564082020-09-27 19:05:33 +02002633 var res = execute('disass s:CallAppend')
Bram Moolenaar389df252020-07-09 21:20:47 +02002634 assert_match('<SNR>\d*_CallAppend\_s*' ..
2635 'eval "some text"->append(2)\_s*' ..
2636 '\d PUSHS "some text"\_s*' ..
2637 '\d PUSHNR 2\_s*' ..
2638 '\d SHUFFLE 2 up 1\_s*' ..
2639 '\d BCALL append(argc 2)\_s*' ..
2640 '\d DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002641 '\d RETURN void',
Bram Moolenaar389df252020-07-09 21:20:47 +02002642 res)
2643enddef
2644
Bram Moolenaarf4c6e1e2020-10-23 18:02:32 +02002645
2646def s:SilentMessage()
2647 silent echomsg "text"
2648 silent! echoerr "error"
2649enddef
2650
2651def Test_silent()
2652 var res = execute('disass s:SilentMessage')
2653 assert_match('<SNR>\d*_SilentMessage\_s*' ..
2654 'silent echomsg "text"\_s*' ..
Bram Moolenaar02194d22020-10-24 23:08:38 +02002655 '\d CMDMOD silent\_s*' ..
Bram Moolenaarf4c6e1e2020-10-23 18:02:32 +02002656 '\d PUSHS "text"\_s*' ..
2657 '\d ECHOMSG 1\_s*' ..
Bram Moolenaar02194d22020-10-24 23:08:38 +02002658 '\d CMDMOD_REV\_s*' ..
Bram Moolenaarf4c6e1e2020-10-23 18:02:32 +02002659 'silent! echoerr "error"\_s*' ..
Bram Moolenaar02194d22020-10-24 23:08:38 +02002660 '\d CMDMOD silent!\_s*' ..
Bram Moolenaarf4c6e1e2020-10-23 18:02:32 +02002661 '\d PUSHS "error"\_s*' ..
2662 '\d ECHOERR 1\_s*' ..
Bram Moolenaar02194d22020-10-24 23:08:38 +02002663 '\d CMDMOD_REV\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002664 '\d\+ RETURN void',
Bram Moolenaara91a7132021-03-25 21:12:15 +01002665 res)
2666enddef
2667
2668def s:SilentIf()
2669 silent if 4 == g:five
2670 silent elseif 4 == g:five
Bram Moolenaarfa984412021-03-25 22:15:28 +01002671 endif
Bram Moolenaara91a7132021-03-25 21:12:15 +01002672enddef
2673
2674def Test_silent_if()
2675 var res = execute('disass s:SilentIf')
2676 assert_match('<SNR>\d*_SilentIf\_s*' ..
2677 'silent if 4 == g:five\_s*' ..
2678 '\d\+ CMDMOD silent\_s*' ..
2679 '\d\+ PUSHNR 4\_s*' ..
2680 '\d\+ LOADG g:five\_s*' ..
2681 '\d\+ COMPAREANY ==\_s*' ..
2682 '\d\+ CMDMOD_REV\_s*' ..
2683 '\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
2684 'silent elseif 4 == g:five\_s*' ..
2685 '\d\+ JUMP -> \d\+\_s*' ..
2686 '\d\+ CMDMOD silent\_s*' ..
2687 '\d\+ PUSHNR 4\_s*' ..
2688 '\d\+ LOADG g:five\_s*' ..
2689 '\d\+ COMPAREANY ==\_s*' ..
2690 '\d\+ CMDMOD_REV\_s*' ..
2691 '\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
Bram Moolenaarfa984412021-03-25 22:15:28 +01002692 'endif\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002693 '\d\+ RETURN void',
Bram Moolenaara91a7132021-03-25 21:12:15 +01002694 res)
2695enddef
2696
2697def s:SilentFor()
2698 silent for i in [0]
Bram Moolenaarfa984412021-03-25 22:15:28 +01002699 endfor
Bram Moolenaara91a7132021-03-25 21:12:15 +01002700enddef
2701
2702def Test_silent_for()
2703 var res = execute('disass s:SilentFor')
2704 assert_match('<SNR>\d*_SilentFor\_s*' ..
2705 'silent for i in \[0\]\_s*' ..
2706 '\d CMDMOD silent\_s*' ..
2707 '\d STORE -1 in $0\_s*' ..
2708 '\d PUSHNR 0\_s*' ..
2709 '\d NEWLIST size 1\_s*' ..
2710 '\d CMDMOD_REV\_s*' ..
2711 '5 FOR $0 -> 8\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002712 '\d STORE $2\_s*' ..
2713
Bram Moolenaarfa984412021-03-25 22:15:28 +01002714 'endfor\_s*' ..
Bram Moolenaara91a7132021-03-25 21:12:15 +01002715 '\d JUMP -> 5\_s*' ..
2716 '8 DROP\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002717 '\d RETURN void\_s*',
Bram Moolenaara91a7132021-03-25 21:12:15 +01002718 res)
2719enddef
2720
2721def s:SilentWhile()
2722 silent while g:not
Bram Moolenaarfa984412021-03-25 22:15:28 +01002723 endwhile
Bram Moolenaara91a7132021-03-25 21:12:15 +01002724enddef
2725
2726def Test_silent_while()
2727 var res = execute('disass s:SilentWhile')
2728 assert_match('<SNR>\d*_SilentWhile\_s*' ..
2729 'silent while g:not\_s*' ..
2730 '0 CMDMOD silent\_s*' ..
2731 '\d LOADG g:not\_s*' ..
2732 '\d COND2BOOL\_s*' ..
2733 '\d CMDMOD_REV\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002734 '\d WHILE $0 -> 6\_s*' ..
Bram Moolenaara91a7132021-03-25 21:12:15 +01002735
Bram Moolenaarfa984412021-03-25 22:15:28 +01002736 'endwhile\_s*' ..
Bram Moolenaara91a7132021-03-25 21:12:15 +01002737 '\d JUMP -> 0\_s*' ..
Bram Moolenaarf57b43c2021-06-15 22:13:27 +02002738 '6 RETURN void\_s*',
Bram Moolenaara91a7132021-03-25 21:12:15 +01002739 res)
2740enddef
2741
2742def s:SilentReturn(): string
2743 silent return "done"
2744enddef
2745
2746def Test_silent_return()
2747 var res = execute('disass s:SilentReturn')
2748 assert_match('<SNR>\d*_SilentReturn\_s*' ..
2749 'silent return "done"\_s*' ..
2750 '\d CMDMOD silent\_s*' ..
2751 '\d PUSHS "done"\_s*' ..
2752 '\d CMDMOD_REV\_s*' ..
2753 '\d RETURN',
Bram Moolenaarf4c6e1e2020-10-23 18:02:32 +02002754 res)
2755enddef
2756
Bram Moolenaarb2049902021-01-24 12:53:53 +01002757def s:Profiled(): string
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002758 # comment
Bram Moolenaarb2049902021-01-24 12:53:53 +01002759 echo "profiled"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002760 # comment
Bram Moolenaar26d71162021-06-14 21:08:56 +02002761 var some = "some text"
Bram Moolenaarb2049902021-01-24 12:53:53 +01002762 return "done"
2763enddef
2764
2765def Test_profiled()
Bram Moolenaarf002a412021-01-24 13:34:18 +01002766 if !has('profile')
2767 MissingFeature 'profile'
2768 endif
Bram Moolenaare99d4222021-06-13 14:01:26 +02002769 var res = execute('disass profile s:Profiled')
Bram Moolenaarb2049902021-01-24 12:53:53 +01002770 assert_match('<SNR>\d*_Profiled\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002771 '# comment\_s*' ..
Bram Moolenaarb2049902021-01-24 12:53:53 +01002772 'echo "profiled"\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002773 '\d PROFILE START line 2\_s*' ..
Bram Moolenaarb2049902021-01-24 12:53:53 +01002774 '\d PUSHS "profiled"\_s*' ..
2775 '\d ECHO 1\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002776 '# comment\_s*' ..
Bram Moolenaar26d71162021-06-14 21:08:56 +02002777 'var some = "some text"\_s*' ..
Bram Moolenaarced68a02021-01-24 17:53:47 +01002778 '\d PROFILE END\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002779 '\d PROFILE START line 4\_s*' ..
Bram Moolenaar26d71162021-06-14 21:08:56 +02002780 '\d PUSHS "some text"\_s*' ..
2781 '\d STORE $0\_s*' ..
2782 'return "done"\_s*' ..
2783 '\d PROFILE END\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002784 '\d PROFILE START line 5\_s*' ..
Bram Moolenaarb2049902021-01-24 12:53:53 +01002785 '\d PUSHS "done"\_s*' ..
Bram Moolenaar26d71162021-06-14 21:08:56 +02002786 '\d\+ RETURN\_s*' ..
2787 '\d\+ PROFILE END',
Bram Moolenaarb2049902021-01-24 12:53:53 +01002788 res)
2789enddef
2790
Bram Moolenaare99d4222021-06-13 14:01:26 +02002791def Test_debugged()
2792 var res = execute('disass debug s:Profiled')
2793 assert_match('<SNR>\d*_Profiled\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002794 '# comment\_s*' ..
Bram Moolenaare99d4222021-06-13 14:01:26 +02002795 'echo "profiled"\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002796 '\d DEBUG line 1-2 varcount 0\_s*' ..
Bram Moolenaare99d4222021-06-13 14:01:26 +02002797 '\d PUSHS "profiled"\_s*' ..
2798 '\d ECHO 1\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002799 '# comment\_s*' ..
Bram Moolenaar26d71162021-06-14 21:08:56 +02002800 'var some = "some text"\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002801 '\d DEBUG line 3-4 varcount 0\_s*' ..
Bram Moolenaar26d71162021-06-14 21:08:56 +02002802 '\d PUSHS "some text"\_s*' ..
2803 '\d STORE $0\_s*' ..
Bram Moolenaare99d4222021-06-13 14:01:26 +02002804 'return "done"\_s*' ..
Bram Moolenaar8cec9272021-06-23 20:20:53 +02002805 '\d DEBUG line 5-5 varcount 1\_s*' ..
Bram Moolenaare99d4222021-06-13 14:01:26 +02002806 '\d PUSHS "done"\_s*' ..
2807 '\d RETURN\_s*',
2808 res)
2809enddef
2810
Bram Moolenaar90770b72021-11-30 20:57:38 +00002811def s:ElseifConstant()
2812 if g:value
2813 echo "one"
2814 elseif true
2815 echo "true"
2816 elseif false
2817 echo "false"
2818 endif
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002819 if 0
2820 echo "yes"
2821 elseif 0
2822 echo "no"
2823 endif
Bram Moolenaar90770b72021-11-30 20:57:38 +00002824enddef
2825
2826def Test_debug_elseif_constant()
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002827 var res = execute('disass debug s:ElseifConstant')
Bram Moolenaar90770b72021-11-30 20:57:38 +00002828 assert_match('<SNR>\d*_ElseifConstant\_s*' ..
2829 'if g:value\_s*' ..
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002830 '0 DEBUG line 1-1 varcount 0\_s*' ..
2831 '1 LOADG g:value\_s*' ..
2832 '2 COND2BOOL\_s*' ..
2833 '3 JUMP_IF_FALSE -> 8\_s*' ..
Bram Moolenaar90770b72021-11-30 20:57:38 +00002834 'echo "one"\_s*' ..
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002835 '4 DEBUG line 2-2 varcount 0\_s*' ..
2836 '5 PUSHS "one"\_s*' ..
2837 '6 ECHO 1\_s*' ..
Bram Moolenaar90770b72021-11-30 20:57:38 +00002838 'elseif true\_s*' ..
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002839 '7 JUMP -> 12\_s*' ..
2840 '8 DEBUG line 3-3 varcount 0\_s*' ..
Bram Moolenaar90770b72021-11-30 20:57:38 +00002841 'echo "true"\_s*' ..
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002842 '9 DEBUG line 4-4 varcount 0\_s*' ..
2843 '10 PUSHS "true"\_s*' ..
2844 '11 ECHO 1\_s*' ..
Bram Moolenaar90770b72021-11-30 20:57:38 +00002845 'elseif false\_s*' ..
2846 'echo "false"\_s*' ..
2847 'endif\_s*' ..
Bram Moolenaar1b5f7a62021-12-21 13:30:42 +00002848 'if 0\_s*' ..
2849 '12 DEBUG line 8-8 varcount 0\_s*' ..
2850 'echo "yes"\_s*' ..
2851 'elseif 0\_s*' ..
2852 '13 DEBUG line 11-10 varcount 0\_s*' ..
2853 'echo "no"\_s*' ..
2854 'endif\_s*' ..
2855 '14 RETURN void*',
Bram Moolenaar90770b72021-11-30 20:57:38 +00002856 res)
2857enddef
2858
Bram Moolenaar093165c2021-08-22 13:35:31 +02002859def s:DebugElseif()
2860 var b = false
2861 if b
2862 eval 1 + 0
2863 silent elseif !b
2864 eval 2 + 0
2865 endif
2866enddef
2867
2868def Test_debug_elseif()
2869 var res = execute('disass debug s:DebugElseif')
2870 assert_match('<SNR>\d*_DebugElseif\_s*' ..
2871 'var b = false\_s*' ..
2872 '0 DEBUG line 1-1 varcount 0\_s*' ..
2873 '1 PUSH false\_s*' ..
2874 '2 STORE $0\_s*' ..
2875
2876 'if b\_s*' ..
2877 '3 DEBUG line 2-2 varcount 1\_s*' ..
2878 '4 LOAD $0\_s*' ..
2879 '5 JUMP_IF_FALSE -> 10\_s*' ..
2880
2881 'eval 1 + 0\_s*' ..
2882 '6 DEBUG line 3-3 varcount 1\_s*' ..
2883 '7 PUSHNR 1\_s*' ..
2884 '8 DROP\_s*' ..
2885
2886 'silent elseif !b\_s*' ..
2887 '9 JUMP -> 20\_s*' ..
2888 '10 CMDMOD silent\_s*' ..
2889 '11 DEBUG line 4-4 varcount 1\_s*' ..
2890 '12 LOAD $0\_s*' ..
2891 '13 INVERT -1 (!val)\_s*' ..
2892 '14 CMDMOD_REV\_s*' ..
2893 '15 JUMP_IF_FALSE -> 20\_s*' ..
2894
2895 'eval 2 + 0\_s*' ..
2896 '16 DEBUG line 5-5 varcount 1\_s*' ..
2897 '17 PUSHNR 2\_s*' ..
2898 '18 DROP\_s*' ..
2899
2900 'endif\_s*' ..
2901 '19 DEBUG line 6-6 varcount 1\_s*' ..
2902 '20 RETURN void*',
2903 res)
2904enddef
2905
Bram Moolenaar2b4ecc22022-01-02 14:08:18 +00002906def s:DebugFor()
2907 echo "hello"
2908 for a in [0]
2909 echo a
2910 endfor
2911enddef
2912
2913def Test_debug_for()
2914 var res = execute('disass debug s:DebugFor')
2915 assert_match('<SNR>\d*_DebugFor\_s*' ..
2916 'echo "hello"\_s*' ..
2917 '0 DEBUG line 1-1 varcount 0\_s*' ..
2918 '1 PUSHS "hello"\_s*' ..
2919 '2 ECHO 1\_s*' ..
2920
2921 'for a in \[0\]\_s*' ..
2922 '3 DEBUG line 2-2 varcount 0\_s*' ..
2923 '4 STORE -1 in $0\_s*' ..
2924 '5 PUSHNR 0\_s*' ..
2925 '6 NEWLIST size 1\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002926 '7 DEBUG line 2-2 varcount 3\_s*' ..
Bram Moolenaar2b4ecc22022-01-02 14:08:18 +00002927 '8 FOR $0 -> 15\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002928 '9 STORE $2\_s*' ..
Bram Moolenaar2b4ecc22022-01-02 14:08:18 +00002929
2930 'echo a\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002931 '10 DEBUG line 3-3 varcount 3\_s*' ..
2932 '11 LOAD $2\_s*' ..
Bram Moolenaar2b4ecc22022-01-02 14:08:18 +00002933 '12 ECHO 1\_s*' ..
2934
2935 'endfor\_s*' ..
Bram Moolenaarb46c0832022-09-15 17:19:37 +01002936 '13 DEBUG line 4-4 varcount 3\_s*' ..
Bram Moolenaar2b4ecc22022-01-02 14:08:18 +00002937 '14 JUMP -> 7\_s*' ..
2938 '15 DROP\_s*' ..
2939 '16 RETURN void*',
2940 res)
2941enddef
2942
Bram Moolenaar21ebb082022-02-04 21:58:58 +00002943def s:TryCatch()
2944 try
2945 echo "try"
2946 catch /error/
2947 echo "caught"
2948 endtry
2949enddef
2950
2951def Test_debug_try_catch()
2952 var res = execute('disass debug s:TryCatch')
2953 assert_match('<SNR>\d*_TryCatch\_s*' ..
2954 'try\_s*' ..
2955 '0 DEBUG line 1-1 varcount 0\_s*' ..
2956 '1 TRY catch -> 7, endtry -> 17\_s*' ..
2957 'echo "try"\_s*' ..
2958 '2 DEBUG line 2-2 varcount 0\_s*' ..
2959 '3 PUSHS "try"\_s*' ..
2960 '4 ECHO 1\_s*' ..
2961 'catch /error/\_s*' ..
2962 '5 DEBUG line 3-3 varcount 0\_s*' ..
2963 '6 JUMP -> 17\_s*' ..
2964 '7 DEBUG line 4-3 varcount 0\_s*' ..
2965 '8 PUSH v:exception\_s*' ..
2966 '9 PUSHS "error"\_s*' ..
2967 '10 COMPARESTRING =\~\_s*' ..
2968 '11 JUMP_IF_FALSE -> 17\_s*' ..
2969 '12 CATCH\_s*' ..
2970 'echo "caught"\_s*' ..
2971 '13 DEBUG line 4-4 varcount 0\_s*' ..
2972 '14 PUSHS "caught"\_s*' ..
2973 '15 ECHO 1\_s*' ..
2974 'endtry\_s*' ..
2975 '16 DEBUG line 5-5 varcount 0\_s*' ..
2976 '17 ENDTRY\_s*' ..
2977 '\d\+ RETURN void',
2978 res)
2979enddef
2980
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002981func s:Legacy() dict
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02002982 echo 'legacy'
2983endfunc
2984
2985def s:UseMember()
2986 var d = {func: Legacy}
2987 var v = d.func()
2988enddef
2989
2990def Test_disassemble_dict_stack()
2991 var res = execute('disass s:UseMember')
2992 assert_match('<SNR>\d*_UseMember\_s*' ..
2993 'var d = {func: Legacy}\_s*' ..
2994 '\d PUSHS "func"\_s*' ..
Bram Moolenaar848fadd2022-01-30 15:28:30 +00002995 '\d PUSHFUNC "<80><fd>R\d\+_Legacy"\_s*' ..
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02002996 '\d NEWDICT size 1\_s*' ..
Bram Moolenaare88c6b72022-02-15 15:37:11 +00002997 '\d SETTYPE dict<func(...): any>\_s*' ..
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02002998 '\d STORE $0\_s*' ..
2999
3000 'var v = d.func()\_s*' ..
3001 '\d LOAD $0\_s*' ..
3002 '\d MEMBER func\_s*' ..
3003 '\d PCALL top (argc 0)\_s*' ..
3004 '\d PCALL end\_s*' ..
3005 '\d CLEARDICT\_s*' ..
3006 '\d\+ STORE $1\_s*' ..
3007 '\d\+ RETURN void*',
3008 res)
3009enddef
3010
Bram Moolenaar95e4dd82022-04-27 22:15:40 +01003011def s:RetLegacy(): string
3012 legacy return "yes"
3013enddef
3014
3015def Test_disassemble_return_legacy()
3016 var res = execute('disass s:RetLegacy')
3017 assert_match('<SNR>\d*_RetLegacy\_s*' ..
3018 'legacy return "yes"\_s*' ..
3019 '\d CMDMOD legacy\_s*' ..
3020 '\d EVAL legacy "yes"\_s*' ..
3021 '\d CHECKTYPE string stack\[-1]\_s*' ..
3022 '\d CMDMOD_REV\_s*' ..
3023 '\d RETURN',
3024 res)
3025enddef
3026
Bram Moolenaarf62d7392021-04-14 12:40:00 +02003027def s:EchoMessages()
3028 echohl ErrorMsg | echom v:exception | echohl NONE
3029enddef
3030
3031def Test_disassemble_nextcmd()
3032 # splitting commands and removing trailing blanks should not change the line
3033 var res = execute('disass s:EchoMessages')
3034 assert_match('<SNR>\d*_EchoMessages\_s*' ..
3035 'echohl ErrorMsg | echom v:exception | echohl NONE',
3036 res)
3037enddef
3038
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003039def Test_disassemble_after_reload()
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01003040 var lines =<< trim END
3041 vim9script
3042 if exists('g:ThisFunc')
3043 finish
3044 endif
3045 var name: any
3046 def g:ThisFunc(): number
3047 g:name = name
3048 return 0
3049 enddef
3050 def g:ThatFunc(): number
3051 name = g:name
3052 return 0
3053 enddef
3054 END
3055 lines->writefile('Xreload.vim', 'D')
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003056
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01003057 source Xreload.vim
3058 g:ThisFunc()
3059 g:ThatFunc()
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003060
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01003061 source Xreload.vim
3062 var res = execute('disass g:ThisFunc')
3063 assert_match('ThisFunc\_s*' ..
3064 'g:name = name\_s*' ..
3065 '\d LOADSCRIPT \[deleted\] from .*/Xreload.vim\_s*' ..
3066 '\d STOREG g:name\_s*' ..
3067 'return 0\_s*' ..
3068 '\d PUSHNR 0\_s*' ..
3069 '\d RETURN\_s*',
3070 res)
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003071
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01003072 res = execute('disass g:ThatFunc')
3073 assert_match('ThatFunc\_s*' ..
3074 'name = g:name\_s*' ..
3075 '\d LOADG g:name\_s*' ..
3076 '\d STORESCRIPT \[deleted\] in .*/Xreload.vim\_s*' ..
3077 'return 0\_s*' ..
3078 '\d PUSHNR 0\_s*' ..
3079 '\d RETURN\_s*',
3080 res)
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003081
Bram Moolenaar0e9bdad2022-10-15 20:06:33 +01003082 delfunc g:ThisFunc
3083 delfunc g:ThatFunc
Bram Moolenaar6db660b2021-08-01 14:08:54 +02003084enddef
3085
LemonBoy2eaef102022-05-06 13:14:50 +01003086def s:MakeString(x: number): string
3087 return $"x={x} x^2={x * x}"
3088enddef
Bram Moolenaar7cd24222021-01-12 18:58:39 +01003089
LemonBoy2eaef102022-05-06 13:14:50 +01003090def Test_disassemble_string_interp()
3091 var instr = execute('disassemble s:MakeString')
3092 assert_match('MakeString\_s*' ..
3093 'return $"x={x} x^2={x \* x}"\_s*' ..
3094 '0 PUSHS "x="\_s*' ..
3095 '1 LOAD arg\[-1\]\_s*' ..
3096 '2 2STRING stack\[-1\]\_s*' ..
3097 '3 PUSHS " x^2="\_s*' ..
3098 '4 LOAD arg\[-1\]\_s*' ..
3099 '5 LOAD arg\[-1\]\_s*' ..
3100 '6 OPNR \*\_s*' ..
3101 '7 2STRING stack\[-1\]\_s*' ..
3102 '8 CONCAT size 4\_s*' ..
3103 '9 RETURN\_s*',
3104 instr)
3105enddef
Bram Moolenaarb1b6f4d2021-09-13 18:25:54 +02003106
Yegappan Lakshmanana061f342022-05-22 19:13:49 +01003107def BitShift()
3108 var a = 1 << 2
3109 var b = 8 >> 1
3110 var c = a << b
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003111 var d = b >> a
Yegappan Lakshmanana061f342022-05-22 19:13:49 +01003112enddef
3113
3114def Test_disassemble_bitshift()
3115 var instr = execute('disassemble BitShift')
3116 assert_match('BitShift\_s*' ..
3117 'var a = 1 << 2\_s*' ..
3118 '0 STORE 4 in $0\_s*' ..
3119 'var b = 8 >> 1\_s*' ..
3120 '1 STORE 4 in $1\_s*' ..
3121 'var c = a << b\_s*' ..
3122 '2 LOAD $0\_s*' ..
3123 '3 LOAD $1\_s*' ..
3124 '4 OPNR <<\_s*' ..
3125 '5 STORE $2\_s*' ..
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003126 'var d = b >> a\_s*' ..
Yegappan Lakshmanana061f342022-05-22 19:13:49 +01003127 '6 LOAD $1\_s*' ..
3128 '7 LOAD $0\_s*' ..
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003129 '8 OPNR >>\_s*' ..
Yegappan Lakshmanana061f342022-05-22 19:13:49 +01003130 '9 STORE $3\_s*' ..
3131 '10 RETURN void', instr)
3132enddef
3133
Bram Moolenaar1d84f762022-09-03 21:35:53 +01003134def s:OneDefer()
3135 defer delete("file")
3136enddef
3137
3138def Test_disassemble_defer()
3139 var instr = execute('disassemble s:OneDefer')
3140 assert_match('OneDefer\_s*' ..
3141 'defer delete("file")\_s*' ..
3142 '\d PUSHFUNC "delete"\_s*' ..
3143 '\d PUSHS "file"\_s*' ..
3144 '\d DEFER 1 args\_s*' ..
3145 '\d RETURN\_s*',
3146 instr)
3147enddef
3148
Bram Moolenaar38f1ab32023-02-21 20:09:46 +00003149def Test_disassemble_class_function()
3150 var lines =<< trim END
3151 vim9script
3152
3153 class Cl
3154 static def Fc(): string
3155 return "x"
3156 enddef
3157 endclass
3158
3159 g:instr = execute('disassemble Cl.Fc')
3160 END
3161 v9.CheckScriptSuccess(lines)
3162 assert_match('Fc\_s*' ..
3163 'return "x"\_s*' ..
3164 '\d PUSHS "x"\_s*' ..
3165 '\d RETURN\_s*',
3166 g:instr)
3167
3168 lines =<< trim END
3169 vim9script
3170
3171 class Cl
3172 def Fo(): string
3173 return "y"
3174 enddef
3175 endclass
3176
3177 g:instr = execute('disassemble Cl.Fo')
3178 END
3179 v9.CheckScriptSuccess(lines)
3180 assert_match('Fo\_s*' ..
3181 'return "y"\_s*' ..
3182 '\d PUSHS "y"\_s*' ..
3183 '\d RETURN\_s*',
3184 g:instr)
3185
3186 unlet g:instr
3187enddef
3188
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003189" Disassemble instructions for using an interface with static and regular member
3190" variables.
3191def Test_disassemble_interface_static_member()
3192 var lines =<< trim END
3193 vim9script
3194 interface I
Doug Kearns74da0ee2023-12-14 20:26:26 +01003195 var o_var: number
3196 var o_var2: number
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003197 endinterface
3198
3199 class C implements I
Doug Kearns74da0ee2023-12-14 20:26:26 +01003200 public static var s_var: number
3201 var o_var: number
3202 public static var s_var2: number
3203 var o_var2: number
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003204 endclass
3205
3206 def F1(i: I)
3207 var x: number
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003208 x = i.o_var
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003209 x = i.o_var2
3210 enddef
3211
3212 def F2(o: C)
3213 var x: number
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003214 x = o.o_var
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003215 x = o.o_var2
3216 enddef
3217
3218 g:instr1 = execute('disassemble F1')
3219 g:instr2 = execute('disassemble F2')
3220 END
3221 v9.CheckScriptSuccess(lines)
3222 assert_match('<SNR>\d*_F1\_s*' ..
3223 'var x: number\_s*' ..
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003224 'x = i.o_var\_s*' ..
Yegappan Lakshmanan04054052023-09-10 18:12:56 +02003225 '0 LOAD arg\[-1\]\_s*' ..
3226 '1 ITF_MEMBER 0 on I\_s*' ..
3227 '2 STORE $0\_s*' ..
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003228 'x = i.o_var2\_s*' ..
Yegappan Lakshmanan04054052023-09-10 18:12:56 +02003229 '3 LOAD arg\[-1\]\_s*' ..
3230 '4 ITF_MEMBER 1 on I\_s*' ..
3231 '5 STORE $0\_s*' ..
3232 '6 RETURN void\_s*',
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003233 g:instr1)
3234 assert_match('<SNR>\d*_F2\_s*' ..
3235 'var x: number\_s*' ..
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003236 'x = o.o_var\_s*' ..
Yegappan Lakshmanan04054052023-09-10 18:12:56 +02003237 '0 LOAD arg\[-1\]\_s*' ..
3238 '1 OBJ_MEMBER 0\_s*' ..
3239 '2 STORE $0\_s*' ..
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003240 'x = o.o_var2\_s*' ..
Yegappan Lakshmanan04054052023-09-10 18:12:56 +02003241 '3 LOAD arg\[-1\]\_s*' ..
3242 '4 OBJ_MEMBER 1\_s*' ..
3243 '5 STORE $0\_s*' ..
3244 '6 RETURN void',
Yegappan Lakshmanan28a60f82023-09-05 20:42:18 +02003245 g:instr2)
3246
3247 unlet g:instr1
3248 unlet g:instr2
3249enddef
3250
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003251" Disassemble instructions for loading and storing class variables
3252def Test_disassemble_class_variable()
3253 var lines =<< trim END
3254 vim9script
3255
3256 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003257 public static var val = 10
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003258 def Foo(): number
3259 val = 20
3260 return val
3261 enddef
3262 endclass
3263
3264 g:instr = execute('disassemble A.Foo')
3265 END
3266 v9.CheckScriptSuccess(lines)
3267 assert_match('Foo\_s*' ..
3268 'val = 20\_s*' ..
3269 '0 PUSHNR 20\_s*' ..
3270 '1 STORE CLASSMEMBER A.val\_s*' ..
3271 'return val\_s*' ..
3272 '2 LOAD CLASSMEMBER A.val\_s*' ..
3273 '3 RETURN', g:instr)
3274
3275 unlet g:instr
3276enddef
3277
3278" Disassemble instructions for METHODCALL
3279def Test_disassemble_methodcall()
3280 var lines =<< trim END
3281 vim9script
3282 interface A
3283 def Foo()
3284 endinterface
3285 def Bar(a: A)
3286 a.Foo()
3287 enddef
3288 g:instr = execute('disassemble Bar')
3289 END
3290 v9.CheckScriptSuccess(lines)
3291 assert_match('<SNR>\d*_Bar\_s*' ..
3292 'a.Foo()\_s*' ..
3293 '0 LOAD arg\[-1\]\_s*' ..
3294 '1 METHODCALL A.Foo(argc 0)\_s*' ..
3295 '2 DROP\_s*' ..
3296 '3 RETURN void', g:instr)
3297
3298 unlet g:instr
3299enddef
3300
3301" Disassemble instructions for ISN_JUMP_IF_ARG_NOT_SET
3302def Test_disassemble_ifargnotset()
3303 var lines =<< trim END
3304 vim9script
3305 class A
Doug Kearns74da0ee2023-12-14 20:26:26 +01003306 var val: number = 10
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003307 endclass
3308 g:instr = execute('disassemble A.new')
3309 END
3310 v9.CheckScriptSuccess(lines)
3311 assert_match('new\_s*' ..
3312 '0 NEW A size \d\+\_s*' ..
3313 '1 PUSHNR 10\_s*' ..
3314 '2 STORE_THIS 0\_s*' ..
3315 'ifargisset 0 this.val = val\_s*' ..
3316 '3 JUMP_IF_ARG_NOT_SET arg\[-1\] -> 8\_s*' ..
3317 '4 LOAD arg\[-1\]\_s*' ..
3318 '5 PUSHNR 0\_s*' ..
3319 '6 LOAD $0\_s*' ..
3320 '7 STOREINDEX object\_s*' ..
3321 '8 RETURN object', g:instr)
3322
3323 unlet g:instr
3324enddef
3325
Ernie Raele75fde62023-12-21 17:18:54 +01003326" Disassemble instructions for ISN_COMPAREOBJECT
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003327def Test_disassemble_compare_class_object()
3328 var lines =<< trim END
3329 vim9script
3330 class A
3331 endclass
3332 class B
3333 endclass
3334 def Foo(a: A, b: B)
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003335 if a == b
3336 endif
3337 enddef
3338 g:instr = execute('disassemble Foo')
3339 END
3340 v9.CheckScriptSuccess(lines)
3341 assert_match('<SNR>\d*_Foo\_s*' ..
Ernie Raele75fde62023-12-21 17:18:54 +01003342 'if a == b\_s*' ..
3343 '0 LOAD arg\[-2\]\_s*' ..
3344 '1 LOAD arg\[-1\]\_s*' ..
3345 '2 COMPAREOBJECT ==\_s*' ..
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003346 '3 JUMP_IF_FALSE -> 4\_s*' ..
3347 'endif\_s*' ..
Ernie Raele75fde62023-12-21 17:18:54 +01003348 '4 RETURN void', g:instr)
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003349 unlet g:instr
3350enddef
3351
3352" Disassemble instructions for ISN_CHECKTYPE with a float|number
3353def Test_checktype_float()
3354 var lines =<< trim END
3355 vim9script
3356 def Foo()
3357 var f: float = 0.0
3358 var a: any
3359 f += a
3360 enddef
3361 g:instr = execute('disassemble Foo')
3362 END
3363 v9.CheckScriptSuccess(lines)
3364 assert_match('<SNR>\d*_Foo\_s*' ..
3365 'var f: float = 0.0\_s*' ..
3366 '0 PUSHF 0.0\_s*' ..
3367 '1 STORE $0\_s*' ..
3368 'var a: any\_s*' ..
3369 'f += a\_s*' ..
3370 '2 LOAD $0\_s*' ..
3371 '3 LOAD $1\_s*' ..
3372 '4 CHECKTYPE float|number stack\[-1\]\_s*' ..
3373 '5 OPANY +\_s*' ..
3374 '6 STORE $0\_s*' ..
3375 '7 RETURN void', g:instr)
3376 unlet g:instr
3377enddef
3378
3379" Disassemble instructions for ISN_FUNCREF with a class
3380def Test_funcref_with_class()
3381 var lines =<< trim END
3382 vim9script
3383 class A
3384 def Foo()
3385 enddef
3386 endclass
3387 class B extends A
3388 def Foo()
3389 enddef
3390 endclass
3391 def Bar(a: A)
3392 defer a.Foo()
3393 enddef
3394 g:instr = execute('disassemble Bar')
3395 END
3396 v9.CheckScriptSuccess(lines)
3397 assert_match('<SNR>\d*_Bar\_s*' ..
3398 'defer a.Foo()\_s*' ..
3399 '0 LOAD arg\[-1\]\_s*' ..
3400 '1 FUNCREF A.Foo\_s*' ..
Yegappan Lakshmananf3eac692023-10-17 11:00:45 +02003401 '2 DEFER 0 args\_s*' ..
Yegappan Lakshmananf4ee1cb2023-10-09 17:57:27 +02003402 '3 RETURN void', g:instr)
3403 unlet g:instr
3404enddef
3405
Yegappan Lakshmanand3eae7b2024-03-03 16:26:58 +01003406" Disassemble instructions for calls to a string() function in an object
3407def Test_disassemble_object_string()
3408 var lines =<< trim END
3409 vim9script
3410 class A
3411 def string(): string
3412 return 'A'
3413 enddef
3414 endclass
3415 def Bar()
3416 var a = A.new()
3417 var s = string(a)
3418 s = string(A)
3419 enddef
3420 g:instr = execute('disassemble Bar')
3421 END
3422 v9.CheckScriptSuccess(lines)
3423 assert_match('<SNR>\d*_Bar\_s*' ..
3424 'var a = A.new()\_s*' ..
3425 '0 DCALL new(argc 0)\_s*' ..
3426 '1 STORE $0\_s*' ..
3427 'var s = string(a)\_s*' ..
3428 '2 LOAD $0\_s*' ..
3429 '3 METHODCALL A.string(argc 0)\_s*' ..
3430 '4 STORE $1\_s*' ..
3431 's = string(A)\_s*' ..
3432 '5 LOADSCRIPT A-0 from .*\_s*' ..
3433 '6 BCALL string(argc 1)\_s*' ..
3434 '7 STORE $1\_s*' ..
3435 '8 RETURN void', g:instr)
3436 unlet g:instr
3437
3438 # Use the default string() function for a class
3439 lines =<< trim END
3440 vim9script
3441 class A
3442 endclass
3443 def Bar()
3444 var a = A.new()
3445 var s = string(a)
3446 s = string(A)
3447 enddef
3448 g:instr = execute('disassemble Bar')
3449 END
3450 v9.CheckScriptSuccess(lines)
3451 assert_match('<SNR>\d*_Bar\_s*' ..
3452 'var a = A.new()\_s*' ..
3453 '0 DCALL new(argc 0)\_s*' ..
3454 '1 STORE $0\_s*' ..
3455 'var s = string(a)\_s*' ..
3456 '2 LOAD $0\_s*' ..
3457 '3 BCALL string(argc 1)\_s*' ..
3458 '4 STORE $1\_s*' ..
3459 's = string(A)\_s*' ..
3460 '5 LOADSCRIPT A-0 from .*\_s*' ..
3461 '6 BCALL string(argc 1)\_s*' ..
3462 '7 STORE $1\_s*' ..
3463 '8 RETURN void', g:instr)
3464 unlet g:instr
3465enddef
3466
3467" Disassemble instructions for calls to a empty() function in an object
3468def Test_disassemble_object_empty()
3469 var lines =<< trim END
3470 vim9script
3471 class A
3472 def empty(): bool
3473 return true
3474 enddef
3475 endclass
3476 def Bar()
3477 var a = A.new()
3478 var s = empty(a)
3479 enddef
3480 g:instr = execute('disassemble Bar')
3481 END
3482 v9.CheckScriptSuccess(lines)
3483 assert_match('<SNR>\d*_Bar\_s*' ..
3484 'var a = A.new()\_s*' ..
3485 '0 DCALL new(argc 0)\_s*' ..
3486 '1 STORE $0\_s*' ..
3487 'var s = empty(a)\_s*' ..
3488 '2 LOAD $0\_s*' ..
3489 '3 METHODCALL A.empty(argc 0)\_s*' ..
3490 '4 STORE $1\_s*' ..
3491 '5 RETURN void', g:instr)
3492 unlet g:instr
3493
3494 # Use the default empty() function for a class
3495 lines =<< trim END
3496 vim9script
3497 class A
3498 endclass
3499 def Bar()
3500 var a = A.new()
3501 var s = empty(a)
3502 enddef
3503 g:instr = execute('disassemble Bar')
3504 END
3505 v9.CheckScriptSuccess(lines)
3506 assert_match('<SNR>\d*_Bar\_s*' ..
3507 'var a = A.new()\_s*' ..
3508 '0 DCALL new(argc 0)\_s*' ..
3509 '1 STORE $0\_s*' ..
3510 'var s = empty(a)\_s*' ..
3511 '2 LOAD $0\_s*' ..
3512 '3 BCALL empty(argc 1)\_s*' ..
3513 '4 STORE $1\_s*' ..
3514 '5 RETURN void', g:instr)
3515 unlet g:instr
3516enddef
3517
3518" Disassemble instructions for calls to a len() function in an object
3519def Test_disassemble_object_len()
3520 var lines =<< trim END
3521 vim9script
3522 class A
3523 def len(): number
3524 return 10
3525 enddef
3526 endclass
3527 def Bar()
3528 var a = A.new()
3529 var s = len(a)
3530 enddef
3531 g:instr = execute('disassemble Bar')
3532 END
3533 v9.CheckScriptSuccess(lines)
3534 assert_match('<SNR>\d*_Bar\_s*' ..
3535 'var a = A.new()\_s*' ..
3536 '0 DCALL new(argc 0)\_s*' ..
3537 '1 STORE $0\_s*' ..
3538 'var s = len(a)\_s*' ..
3539 '2 LOAD $0\_s*' ..
3540 '3 METHODCALL A.len(argc 0)\_s*' ..
3541 '4 STORE $1\_s*' ..
3542 '5 RETURN void', g:instr)
3543 unlet g:instr
3544
3545 # Use the default len() function for a class
3546 lines =<< trim END
3547 vim9script
3548 class A
3549 endclass
3550 def Bar()
3551 var a = A.new()
3552 var s = len(a)
3553 enddef
3554 g:instr = execute('disassemble Bar')
3555 END
3556 v9.CheckScriptSuccess(lines)
3557 assert_match('<SNR>\d*_Bar\_s*' ..
3558 'var a = A.new()\_s*' ..
3559 '0 DCALL new(argc 0)\_s*' ..
3560 '1 STORE $0\_s*' ..
3561 'var s = len(a)\_s*' ..
3562 '2 LOAD $0\_s*' ..
3563 '3 BCALL len(argc 1)\_s*' ..
3564 '4 STORE $1\_s*' ..
3565 '5 RETURN void', g:instr)
3566 unlet g:instr
3567enddef
3568
Yegappan Lakshmanand990bf02024-03-22 19:56:17 +01003569" Disassemble instructions for using a compound operator in a closure
3570def Test_disassemble_compound_op_in_closure()
3571 var lines =<< trim END
3572 vim9script
3573 class A
3574 var foo: number = 1
3575 def Foo(): func
3576 var Fn = () => {
3577 this.foo += 1
3578 }
3579 return Fn
3580 enddef
3581 endclass
3582 var a = A.new()
3583 var Lambda = a.Foo()
3584 var num = matchstr(string(Lambda), '\d\+')
3585 g:instr = execute($'disassemble <lambda>{num}')
3586 END
3587 v9.CheckScriptSuccess(lines)
3588 assert_match('<lambda>\d\+\_s*' ..
3589 'this.foo += 1\_s*' ..
3590 '0 LOADOUTER level 0 $0\_s*' ..
3591 '1 OBJ_MEMBER 0\_s*' ..
3592 '2 PUSHNR 1\_s*' ..
3593 '3 OPNR +\_s*' ..
3594 '4 PUSHNR 0\_s*' ..
3595 '5 LOADOUTER level 0 $0\_s*' ..
3596 '6 STOREINDEX object\_s*' ..
3597 '7 RETURN void', g:instr)
3598 unlet g:instr
3599enddef
3600
LemonBoyf4af3312024-07-04 13:43:12 +02003601def Test_disassemble_member_initializer()
3602 var lines =<< trim END
3603 vim9script
3604 class A
3605 var l: list<string> = []
3606 var d: dict<string> = {}
3607 endclass
3608 g:instr = execute('disassemble A.new')
3609 END
3610 v9.CheckScriptSuccess(lines)
3611 # Ensure SETTYPE is emitted and that matches the declared type.
3612 assert_match('new\_s*' ..
3613 '0 NEW A size \d\+\_s*' ..
3614 '1 NEWLIST size 0\_s*' ..
3615 '2 SETTYPE list<string>\_s*' ..
3616 '3 STORE_THIS 0\_s*' ..
3617 '4 NEWDICT size 0\_s*' ..
3618 '5 SETTYPE dict<string>\_s*' ..
3619 '6 STORE_THIS 1', g:instr)
3620 unlet g:instr
3621enddef
3622
Yegappan Lakshmananc10342d2025-01-11 09:39:01 +01003623" Disassemble the code generated for accessing a interface member variable
3624def Test_disassemble_interface_variable_access()
3625 var lines =<< trim END
3626 vim9script
3627 interface IX
3628 var F: func(): string
3629 endinterface
3630
3631 def Foo(ix: IX): string
3632 return ix.F()
3633 enddef
3634
3635 g:instr = execute('disassemble Foo')
3636 END
3637 v9.CheckScriptSuccess(lines)
3638 assert_match('<SNR>\d\+_Foo\_s*' ..
3639 'return ix.F()\_s*' ..
3640 '0 LOAD arg\[-1\]\_s*' ..
3641 '1 ITF_MEMBER 0 on IX\_s*' ..
3642 '2 PCALL top (argc 0)\_s*' ..
3643 '3 PCALL end\_s*' ..
3644 '4 RETURN', g:instr)
3645 unlet g:instr
3646enddef
3647
Yegappan Lakshmanan6289f912025-01-14 17:13:36 +01003648" Disassemble the code generated for accessing a script-local funcref
3649def Test_disassemble_using_script_local_funcref()
3650 var lines =<< trim END
3651 vim9script
3652 def Noop()
3653 enddef
3654 export var Setup = Noop
3655 export def Run()
3656 Setup()
3657 enddef
3658 g:instr = execute('disassemble Run')
3659 END
3660 v9.CheckScriptSuccess(lines)
3661 assert_match('<SNR>\d\+_Run\_s*' ..
3662 'Setup()\_s*' ..
3663 '0 LOADSCRIPT Setup-0 from .*\_s*' ..
3664 '1 PCALL (argc 0)\_s*' ..
3665 '2 DROP\_s*' ..
3666 '3 RETURN void\_s*', g:instr)
3667 unlet g:instr
3668enddef
3669
Yegappan Lakshmanan16f2d3a2025-02-24 19:23:43 +01003670" Disassemble the code generated for using a script local variable
3671" in an instance variable initialization expression
3672def Test_disassemble_using_script_local_var_in_obj_init()
3673 var lines =<< trim END
3674 vim9script
3675 const DEFAULT = 'default-obj_key'
3676 export class ObjKey
3677 const unique_object_id3 = DEFAULT
3678 endclass
3679 END
3680 writefile(lines, 'Xscriptlocalobjinit.vim', 'D')
3681 lines =<< trim END
3682 vim9script
3683 import './Xscriptlocalobjinit.vim' as obj_key
3684
3685 class C1 extends obj_key.ObjKey
3686 endclass
3687 g:instr = execute('disassemble C1.new')
3688 END
3689 v9.CheckScriptSuccess(lines)
3690 assert_match('new\_s*' ..
3691 '0 NEW C1 size \d\+\_s*' ..
3692 '1 SCRIPTCTX_SET .*/Xscriptlocalobjinit.vim\_s*' ..
3693 '2 LOADSCRIPT DEFAULT-0 from .*/Xscriptlocalobjinit.vim\_s*' ..
3694 '3 SCRIPTCTX_SET .*\_s*' ..
3695 '4 STORE_THIS 0', g:instr)
3696 unlet g:instr
3697enddef
3698
Yegappan Lakshmanan9cb865e2025-03-23 16:42:16 +01003699" Disassemble the code generated for indexing a tuple
3700def Test_disassemble_tuple_indexing()
3701 var lines =<< trim END
3702 vim9script
3703 def Fn(): tuple<...list<number>>
3704 var t = (5, 6, 7)
3705 var i = t[2]
3706 var j = t[1 : 2]
3707 return t
3708 enddef
3709 g:instr = execute('disassemble Fn')
3710 END
3711 v9.CheckScriptSuccess(lines)
3712 assert_match('<SNR>\d\+_Fn\_s*' ..
3713 'var t = (5, 6, 7)\_s*' ..
3714 '0 PUSHNR 5\_s*' ..
3715 '1 PUSHNR 6\_s*' ..
3716 '2 PUSHNR 7\_s*' ..
3717 '3 NEWTUPLE size 3\_s*' ..
3718 '4 SETTYPE tuple<number, number, number>\_s*' ..
3719 '5 STORE $0\_s*' ..
3720 'var i = t\[2\]\_s*' ..
3721 '6 LOAD $0\_s*' ..
3722 '7 PUSHNR 2\_s*' ..
3723 '8 TUPLEINDEX\_s*' ..
3724 '9 STORE $1\_s*' ..
3725 'var j = t\[1 : 2\]\_s*' ..
3726 '10 LOAD $0\_s*' ..
3727 '11 PUSHNR 1\_s*' ..
3728 '12 PUSHNR 2\_s*' ..
3729 '13 TUPLESLICE\_s*' ..
3730 '14 SETTYPE tuple<number, number, number>\_s*' ..
3731 '15 STORE $2\_s*' ..
3732 'return t\_s*' ..
3733 '16 LOAD $0\_s*' ..
3734 '17 RETURN', g:instr)
3735 unlet g:instr
3736enddef
3737
3738" Disassemble the code generated for assigning a tuple to a default value
3739def Test_disassemble_tuple_default_value()
3740 var lines =<< trim END
3741 vim9script
3742 def Fn()
3743 var t: tuple<number>
3744 enddef
3745 g:instr = execute('disassemble Fn')
3746 END
3747 v9.CheckScriptSuccess(lines)
3748 assert_match('<SNR>\d\+_Fn\_s*' ..
3749 'var t: tuple<number>\_s*' ..
3750 '0 NEWTUPLE size 0\_s*' ..
3751 '1 SETTYPE tuple<number>\_s*' ..
3752 '2 STORE $0\_s*' ..
3753 '3 RETURN void', g:instr)
3754 unlet g:instr
3755enddef
3756
3757" Disassemble the code generated for comparing tuples
3758def Test_disassemble_tuple_compare()
3759 var lines =<< trim END
3760 vim9script
3761 def Fn()
3762 var t1 = (1, 2)
3763 var t2 = t1
3764 var x = t1 == t2
3765 enddef
3766 g:instr = execute('disassemble Fn')
3767 END
3768 v9.CheckScriptSuccess(lines)
3769 assert_match('<SNR>\d\+_Fn\_s*' ..
3770 'var t1 = (1, 2)\_s*' ..
3771 '0 PUSHNR 1\_s*' ..
3772 '1 PUSHNR 2\_s*' ..
3773 '2 NEWTUPLE size 2\_s*' ..
3774 '3 SETTYPE tuple<number, number>\_s*' ..
3775 '4 STORE $0\_s*' ..
3776 'var t2 = t1\_s*' ..
3777 '5 LOAD $0\_s*' ..
3778 '6 SETTYPE tuple<number, number>\_s*' ..
3779 '7 STORE $1\_s*' ..
3780 'var x = t1 == t2\_s*' ..
3781 '8 LOAD $0\_s*' ..
3782 '9 LOAD $1\_s*' ..
3783 '10 COMPARETUPLE ==\_s*' ..
3784 '11 STORE $2\_s*' ..
3785 '12 RETURN void', g:instr)
3786 unlet g:instr
3787enddef
3788
3789" Disassemble the code generated for concatenating tuples
3790def Test_disassemble_tuple_concatenate()
3791 var lines =<< trim END
3792 vim9script
3793 def Fn()
3794 var t1 = (1,) + (2,)
3795 enddef
3796 g:instr = execute('disassemble Fn')
3797 END
3798 v9.CheckScriptSuccess(lines)
3799 assert_match('<SNR>\d\+_Fn\_s*' ..
3800 'var t1 = (1,) + (2,)\_s*' ..
3801 '0 PUSHNR 1\_s*' ..
3802 '1 NEWTUPLE size 1\_s*' ..
3803 '2 PUSHNR 2\_s*' ..
3804 '3 NEWTUPLE size 1\_s*' ..
3805 '4 ADDTUPLE\_s*' ..
3806 '5 SETTYPE tuple<number, number>\_s*' ..
3807 '6 STORE $0\_s*' ..
3808 '7 RETURN void', g:instr)
3809 unlet g:instr
3810enddef
3811
3812" Disassemble the code generated for a constant tupe
3813def Test_disassemble_tuple_const()
3814 var lines =<< trim END
3815 vim9script
3816 def Fn()
3817 const t = (1, 2, 3)
3818 var x = t[1 : 2]
3819 enddef
3820 g:instr = execute('disassemble Fn')
3821 END
3822 v9.CheckScriptSuccess(lines)
3823 assert_match('<SNR>\d\+_Fn\_s*' ..
3824 'const t = (1, 2, 3)\_s*' ..
3825 '0 PUSHNR 1\_s*' ..
3826 '1 PUSHNR 2\_s*' ..
3827 '2 PUSHNR 3\_s*' ..
3828 '3 NEWTUPLE size 3\_s*' ..
3829 '4 LOCKCONST\_s*' ..
3830 '5 SETTYPE tuple<number, number, number>\_s*' ..
3831 '6 STORE $0\_s*' ..
3832 'var x = t\[1 : 2\]\_s*' ..
3833 '7 LOAD $0\_s*' ..
3834 '8 PUSHNR 1\_s*' ..
3835 '9 PUSHNR 2\_s*' ..
3836 '10 TUPLESLICE\_s*' ..
3837 '11 SETTYPE tuple<number, number, number>\_s*' ..
3838 '12 STORE $1\_s*' ..
3839 '13 RETURN void', g:instr)
3840 unlet g:instr
3841enddef
3842
3843" Disassemble the code generated for setting the type when using a tuple in an
3844" assignment
3845def Test_disassemble_assign_tuple_set_type()
3846 var lines =<< trim END
3847 vim9script
3848 def Fn()
3849 var x = (1,)
3850 enddef
3851 g:instr = execute('disassemble Fn')
3852 END
3853 v9.CheckScriptSuccess(lines)
3854 assert_match('<SNR>\d\+_Fn\_s*' ..
3855 'var x = (1,)\_s*' ..
3856 '0 PUSHNR 1\_s*' ..
3857 '1 NEWTUPLE size 1\_s*' ..
3858 '2 SETTYPE tuple<number>\_s*' ..
3859 '3 STORE $0\_s*' ..
3860 '4 RETURN void', g:instr)
3861
3862 lines =<< trim END
3863 vim9script
3864 def Fn()
3865 var x = ()
3866 enddef
3867 g:instr = execute('disassemble Fn')
3868 END
3869 v9.CheckScriptSuccess(lines)
3870 assert_match('<SNR>\d\+_Fn\_s*' ..
3871 'var x = ()\_s*' ..
3872 '0 NEWTUPLE size 0\_s*' ..
3873 '1 STORE $0\_s*' ..
3874 '2 RETURN void', g:instr)
3875
3876 unlet g:instr
3877enddef
3878
Bram Moolenaar5cab73f2020-02-06 19:25:19 +01003879" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker