blob: 4f2265475453ca0f6abe8405a09b646b0cf795cf [file] [log] [blame]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001/* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * vim9execute.c: execute Vim9 script instructions
12 */
13
14#define USING_FLOAT_STUFF
15#include "vim.h"
16
17#if defined(FEAT_EVAL) || defined(PROTO)
18
19#ifdef VMS
20# include <float.h>
21#endif
22
23#include "vim9.h"
24
25// Structure put on ec_trystack when ISN_TRY is encountered.
26typedef struct {
27 int tcd_frame; // ec_frame when ISN_TRY was encountered
28 int tcd_catch_idx; // instruction of the first catch
29 int tcd_finally_idx; // instruction of the finally block
30 int tcd_caught; // catch block entered
31 int tcd_return; // when TRUE return from end of :finally
32} trycmd_T;
33
34
35// A stack is used to store:
36// - arguments passed to a :def function
37// - info about the calling function, to use when returning
38// - local variables
39// - temporary values
40//
41// In detail (FP == Frame Pointer):
42// arg1 first argument from caller (if present)
43// arg2 second argument from caller (if present)
44// extra_arg1 any missing optional argument default value
45// FP -> cur_func calling function
46// current previous instruction pointer
47// frame_ptr previous Frame Pointer
48// var1 space for local variable
49// var2 space for local variable
50// .... fixed space for max. number of local variables
51// temp temporary values
52// .... flexible space for temporary values (can grow big)
53
54/*
55 * Execution context.
56 */
57typedef struct {
58 garray_T ec_stack; // stack of typval_T values
59 int ec_frame; // index in ec_stack: context of ec_dfunc_idx
60
61 garray_T ec_trystack; // stack of trycmd_T values
62 int ec_in_catch; // when TRUE in catch or finally block
63
64 int ec_dfunc_idx; // current function index
65 isn_T *ec_instr; // array with instructions
66 int ec_iidx; // index in ec_instr: instruction to execute
67} ectx_T;
68
69// Get pointer to item relative to the bottom of the stack, -1 is the last one.
70#define STACK_TV_BOT(idx) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_stack.ga_len + idx)
71
72/*
Bram Moolenaar170fcfc2020-02-06 17:51:35 +010073 * Return the number of arguments, including optional arguments and any vararg.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010074 */
75 static int
76ufunc_argcount(ufunc_T *ufunc)
77{
78 return ufunc->uf_args.ga_len + (ufunc->uf_va_name != NULL ? 1 : 0);
79}
80
81/*
Bram Moolenaar170fcfc2020-02-06 17:51:35 +010082 * Set the instruction index, depending on omitted arguments, where the default
83 * values are to be computed. If all optional arguments are present, start
84 * with the function body.
85 * The expression evaluation is at the start of the instructions:
86 * 0 -> EVAL default1
87 * STORE arg[-2]
88 * 1 -> EVAL default2
89 * STORE arg[-1]
90 * 2 -> function body
91 */
92 static void
93init_instr_idx(ufunc_T *ufunc, int argcount, ectx_T *ectx)
94{
95 if (ufunc->uf_def_args.ga_len == 0)
96 ectx->ec_iidx = 0;
97 else
98 {
99 int defcount = ufunc->uf_args.ga_len - argcount;
100
101 // If there is a varargs argument defcount can be negative, no defaults
102 // to evaluate then.
103 if (defcount < 0)
104 defcount = 0;
105 ectx->ec_iidx = ufunc->uf_def_arg_idx[
106 ufunc->uf_def_args.ga_len - defcount];
107 }
108}
109
110/*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100111 * Call compiled function "cdf_idx" from compiled code.
112 *
113 * Stack has:
114 * - current arguments (already there)
115 * - omitted optional argument (default values) added here
116 * - stack frame:
117 * - pointer to calling function
118 * - Index of next instruction in calling function
119 * - previous frame pointer
120 * - reserved space for local variables
121 */
122 static int
123call_dfunc(int cdf_idx, int argcount, ectx_T *ectx)
124{
125 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
126 ufunc_T *ufunc = dfunc->df_ufunc;
127 int optcount = ufunc_argcount(ufunc) - argcount;
128 int idx;
129
130 if (dfunc->df_deleted)
131 {
132 emsg_funcname(e_func_deleted, ufunc->uf_name);
133 return FAIL;
134 }
135
136 if (ga_grow(&ectx->ec_stack, optcount + 3 + dfunc->df_varcount) == FAIL)
137 return FAIL;
138
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100139 if (optcount < 0)
140 {
141 emsg("argument count wrong?");
142 return FAIL;
143 }
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100144
145 // Reserve space for omitted optional arguments, filled in soon.
146 // Also any empty varargs argument.
147 ectx->ec_stack.ga_len += optcount;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100148
149 // Store current execution state in stack frame for ISN_RETURN.
150 // TODO: If the actual number of arguments doesn't match what the called
151 // function expects things go bad.
152 STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
153 STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
154 STACK_TV_BOT(2)->vval.v_number = ectx->ec_frame;
155 ectx->ec_frame = ectx->ec_stack.ga_len;
156
157 // Initialize local variables
158 for (idx = 0; idx < dfunc->df_varcount; ++idx)
159 STACK_TV_BOT(STACK_FRAME_SIZE + idx)->v_type = VAR_UNKNOWN;
160 ectx->ec_stack.ga_len += STACK_FRAME_SIZE + dfunc->df_varcount;
161
162 // Set execution state to the start of the called function.
163 ectx->ec_dfunc_idx = cdf_idx;
164 ectx->ec_instr = dfunc->df_instr;
165 estack_push_ufunc(ETYPE_UFUNC, dfunc->df_ufunc, 1);
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100166
167 // Decide where to start execution, handles optional arguments.
168 init_instr_idx(ufunc, argcount, ectx);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100169
170 return OK;
171}
172
173// Get pointer to item in the stack.
174#define STACK_TV(idx) (((typval_T *)ectx->ec_stack.ga_data) + idx)
175
176/*
177 * Return from the current function.
178 */
179 static void
180func_return(ectx_T *ectx)
181{
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100182 int idx;
183 dfunc_T *dfunc;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100184 int top;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100185
186 // execution context goes one level up
187 estack_pop();
188
189 // Clear the local variables and temporary values, but not
190 // the return value.
191 for (idx = ectx->ec_frame + STACK_FRAME_SIZE;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100192 idx < ectx->ec_stack.ga_len - 1; ++idx)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100193 clear_tv(STACK_TV(idx));
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100194
195 // Clear the arguments.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100196 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100197 top = ectx->ec_frame - ufunc_argcount(dfunc->df_ufunc);
198 for (idx = top; idx < ectx->ec_frame; ++idx)
199 clear_tv(STACK_TV(idx));
200
201 // Restore the previous frame.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100202 ectx->ec_dfunc_idx = STACK_TV(ectx->ec_frame)->vval.v_number;
203 ectx->ec_iidx = STACK_TV(ectx->ec_frame + 1)->vval.v_number;
204 ectx->ec_frame = STACK_TV(ectx->ec_frame + 2)->vval.v_number;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100205 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
206 ectx->ec_instr = dfunc->df_instr;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100207
208 // Reset the stack to the position before the call, move the return value
209 // to the top of the stack.
210 idx = ectx->ec_stack.ga_len - 1;
211 ectx->ec_stack.ga_len = top + 1;
212 *STACK_TV_BOT(-1) = *STACK_TV(idx);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100213}
214
215#undef STACK_TV
216
217/*
218 * Prepare arguments and rettv for calling a builtin or user function.
219 */
220 static int
221call_prepare(int argcount, typval_T *argvars, ectx_T *ectx)
222{
223 int idx;
224 typval_T *tv;
225
226 // Move arguments from bottom of the stack to argvars[] and add terminator.
227 for (idx = 0; idx < argcount; ++idx)
228 argvars[idx] = *STACK_TV_BOT(idx - argcount);
229 argvars[argcount].v_type = VAR_UNKNOWN;
230
231 // Result replaces the arguments on the stack.
232 if (argcount > 0)
233 ectx->ec_stack.ga_len -= argcount - 1;
234 else if (ga_grow(&ectx->ec_stack, 1) == FAIL)
235 return FAIL;
236 else
237 ++ectx->ec_stack.ga_len;
238
239 // Default return value is zero.
240 tv = STACK_TV_BOT(-1);
241 tv->v_type = VAR_NUMBER;
242 tv->vval.v_number = 0;
243
244 return OK;
245}
246
247/*
248 * Call a builtin function by index.
249 */
250 static int
251call_bfunc(int func_idx, int argcount, ectx_T *ectx)
252{
253 typval_T argvars[MAX_FUNC_ARGS];
254 int idx;
255
256 if (call_prepare(argcount, argvars, ectx) == FAIL)
257 return FAIL;
258
259 // Call the builtin function.
260 call_internal_func_by_idx(func_idx, argvars, STACK_TV_BOT(-1));
261
262 // Clear the arguments.
263 for (idx = 0; idx < argcount; ++idx)
264 clear_tv(&argvars[idx]);
265 return OK;
266}
267
268/*
269 * Execute a user defined function.
270 */
271 static int
272call_ufunc(ufunc_T *ufunc, int argcount, ectx_T *ectx)
273{
274 typval_T argvars[MAX_FUNC_ARGS];
275 funcexe_T funcexe;
276 int error;
277 int idx;
278
279 if (ufunc->uf_dfunc_idx >= 0)
280 // The function has been compiled, can call it quickly.
281 return call_dfunc(ufunc->uf_dfunc_idx, argcount, ectx);
282
283 if (call_prepare(argcount, argvars, ectx) == FAIL)
284 return FAIL;
285 vim_memset(&funcexe, 0, sizeof(funcexe));
286 funcexe.evaluate = TRUE;
287
288 // Call the user function. Result goes in last position on the stack.
289 // TODO: add selfdict if there is one
290 error = call_user_func_check(ufunc, argcount, argvars,
291 STACK_TV_BOT(-1), &funcexe, NULL);
292
293 // Clear the arguments.
294 for (idx = 0; idx < argcount; ++idx)
295 clear_tv(&argvars[idx]);
296
297 if (error != FCERR_NONE)
298 {
299 user_func_error(error, ufunc->uf_name);
300 return FAIL;
301 }
302 return OK;
303}
304
305/*
306 * Execute a function by "name".
307 * This can be a builtin function or a user function.
308 * Returns FAIL if not found without an error message.
309 */
310 static int
311call_by_name(char_u *name, int argcount, ectx_T *ectx)
312{
313 ufunc_T *ufunc;
314
315 if (builtin_function(name, -1))
316 {
317 int func_idx = find_internal_func(name);
318
319 if (func_idx < 0)
320 return FAIL;
321 if (check_internal_func(func_idx, argcount) == FAIL)
322 return FAIL;
323 return call_bfunc(func_idx, argcount, ectx);
324 }
325
326 ufunc = find_func(name, NULL);
327 if (ufunc != NULL)
328 return call_ufunc(ufunc, argcount, ectx);
329
330 return FAIL;
331}
332
333 static int
334call_partial(typval_T *tv, int argcount, ectx_T *ectx)
335{
336 char_u *name;
337 int called_emsg_before = called_emsg;
338
339 if (tv->v_type == VAR_PARTIAL)
340 {
341 partial_T *pt = tv->vval.v_partial;
342
343 if (pt->pt_func != NULL)
344 return call_ufunc(pt->pt_func, argcount, ectx);
345 name = pt->pt_name;
346 }
347 else
348 name = tv->vval.v_string;
349 if (call_by_name(name, argcount, ectx) == FAIL)
350 {
351 if (called_emsg == called_emsg_before)
352 semsg(_(e_unknownfunc), name);
353 return FAIL;
354 }
355 return OK;
356}
357
358/*
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100359 * Store "tv" in variable "name".
360 * This is for s: and g: variables.
361 */
362 static void
363store_var(char_u *name, typval_T *tv)
364{
365 funccal_entry_T entry;
366
367 save_funccal(&entry);
368 set_var_const(name, NULL, tv, FALSE, 0);
369 restore_funccal();
370}
371
372/*
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100373 * Execute a function by "name".
374 * This can be a builtin function, user function or a funcref.
375 */
376 static int
377call_eval_func(char_u *name, int argcount, ectx_T *ectx)
378{
379 int called_emsg_before = called_emsg;
380
381 if (call_by_name(name, argcount, ectx) == FAIL
382 && called_emsg == called_emsg_before)
383 {
384 // "name" may be a variable that is a funcref or partial
385 // if find variable
386 // call_partial()
387 // else
388 // semsg(_(e_unknownfunc), name);
389 emsg("call_eval_func(partial) not implemented yet");
390 return FAIL;
391 }
392 return OK;
393}
394
395/*
396 * Call a "def" function from old Vim script.
397 * Return OK or FAIL.
398 */
399 int
400call_def_function(
401 ufunc_T *ufunc,
402 int argc, // nr of arguments
403 typval_T *argv, // arguments
404 typval_T *rettv) // return value
405{
406 ectx_T ectx; // execution context
407 int initial_frame_ptr;
408 typval_T *tv;
409 int idx;
410 int ret = FAIL;
411 dfunc_T *dfunc;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100412 int defcount = ufunc->uf_args.ga_len - argc;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100413
414// Get pointer to item in the stack.
415#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
416
417// Get pointer to item at the bottom of the stack, -1 is the bottom.
418#undef STACK_TV_BOT
419#define STACK_TV_BOT(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_stack.ga_len + idx)
420
421// Get pointer to local variable on the stack.
422#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame + STACK_FRAME_SIZE + idx)
423
424 vim_memset(&ectx, 0, sizeof(ectx));
425 ga_init2(&ectx.ec_stack, sizeof(typval_T), 500);
426 if (ga_grow(&ectx.ec_stack, 20) == FAIL)
427 goto failed;
428 ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx;
429
430 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
431
432 // Put arguments on the stack.
433 for (idx = 0; idx < argc; ++idx)
434 {
435 copy_tv(&argv[idx], STACK_TV_BOT(0));
436 ++ectx.ec_stack.ga_len;
437 }
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100438 // Make space for omitted arguments, will store default value below.
439 if (defcount > 0)
440 for (idx = 0; idx < defcount; ++idx)
441 {
442 STACK_TV_BOT(0)->v_type = VAR_UNKNOWN;
443 ++ectx.ec_stack.ga_len;
444 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100445
446 // Frame pointer points to just after arguments.
447 ectx.ec_frame = ectx.ec_stack.ga_len;
448 initial_frame_ptr = ectx.ec_frame;
449
450 // dummy frame entries
451 for (idx = 0; idx < STACK_FRAME_SIZE; ++idx)
452 {
453 STACK_TV(ectx.ec_stack.ga_len)->v_type = VAR_UNKNOWN;
454 ++ectx.ec_stack.ga_len;
455 }
456
457 // Reserve space for local variables.
458 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
459 for (idx = 0; idx < dfunc->df_varcount; ++idx)
460 STACK_TV_VAR(idx)->v_type = VAR_UNKNOWN;
461 ectx.ec_stack.ga_len += dfunc->df_varcount;
462
463 ectx.ec_instr = dfunc->df_instr;
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100464
465 // Decide where to start execution, handles optional arguments.
466 init_instr_idx(ufunc, argc, &ectx);
467
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100468 for (;;)
469 {
470 isn_T *iptr;
471 trycmd_T *trycmd = NULL;
472
473 if (did_throw && !ectx.ec_in_catch)
474 {
475 garray_T *trystack = &ectx.ec_trystack;
476
477 // An exception jumps to the first catch, finally, or returns from
478 // the current function.
479 if (trystack->ga_len > 0)
480 trycmd = ((trycmd_T *)trystack->ga_data) + trystack->ga_len - 1;
481 if (trycmd != NULL && trycmd->tcd_frame == ectx.ec_frame)
482 {
483 // jump to ":catch" or ":finally"
484 ectx.ec_in_catch = TRUE;
485 ectx.ec_iidx = trycmd->tcd_catch_idx;
486 }
487 else
488 {
489 // not inside try or need to return from current functions.
490 if (ectx.ec_frame == initial_frame_ptr)
491 {
492 // At the toplevel we are done. Push a dummy return value.
493 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
494 goto failed;
495 tv = STACK_TV_BOT(0);
496 tv->v_type = VAR_NUMBER;
497 tv->vval.v_number = 0;
498 ++ectx.ec_stack.ga_len;
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100499 need_rethrow = TRUE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100500 goto done;
501 }
502
503 func_return(&ectx);
504 }
505 continue;
506 }
507
508 iptr = &ectx.ec_instr[ectx.ec_iidx++];
509 switch (iptr->isn_type)
510 {
511 // execute Ex command line
512 case ISN_EXEC:
513 do_cmdline_cmd(iptr->isn_arg.string);
514 break;
515
516 // execute :echo {string} ...
517 case ISN_ECHO:
518 {
519 int count = iptr->isn_arg.echo.echo_count;
520 int atstart = TRUE;
521 int needclr = TRUE;
522
523 for (idx = 0; idx < count; ++idx)
524 {
525 tv = STACK_TV_BOT(idx - count);
526 echo_one(tv, iptr->isn_arg.echo.echo_with_white,
527 &atstart, &needclr);
528 clear_tv(tv);
529 }
Bram Moolenaare0807ea2020-02-20 22:18:06 +0100530 if (needclr)
531 msg_clr_eos();
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100532 ectx.ec_stack.ga_len -= count;
533 }
534 break;
535
Bram Moolenaarad39c092020-02-26 18:23:43 +0100536 // execute :execute {string} ...
537 case ISN_EXECUTE:
538 {
539 int count = iptr->isn_arg.number;
540 garray_T ga;
541 char_u buf[NUMBUFLEN];
542 char_u *p;
543 int len;
544 int failed = FALSE;
545
546 ga_init2(&ga, 1, 80);
547 for (idx = 0; idx < count; ++idx)
548 {
549 tv = STACK_TV_BOT(idx - count);
550 if (tv->v_type == VAR_CHANNEL || tv->v_type == VAR_JOB)
551 {
552 emsg(_(e_inval_string));
553 break;
554 }
555 else
556 p = tv_get_string_buf(tv, buf);
557
558 len = (int)STRLEN(p);
559 if (ga_grow(&ga, len + 2) == FAIL)
560 failed = TRUE;
561 else
562 {
563 if (ga.ga_len > 0)
564 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
565 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
566 ga.ga_len += len;
567 }
568 clear_tv(tv);
569 }
570 ectx.ec_stack.ga_len -= count;
571
572 if (!failed && ga.ga_data != NULL)
573 do_cmdline_cmd((char_u *)ga.ga_data);
574 ga_clear(&ga);
575 }
576 break;
577
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100578 // load local variable or argument
579 case ISN_LOAD:
580 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
581 goto failed;
582 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0));
583 ++ectx.ec_stack.ga_len;
584 break;
585
586 // load v: variable
587 case ISN_LOADV:
588 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
589 goto failed;
590 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0));
591 ++ectx.ec_stack.ga_len;
592 break;
593
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100594 // load s: variable in Vim9 script
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100595 case ISN_LOADSCRIPT:
596 {
597 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +0100598 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100599 svar_T *sv;
600
601 sv = ((svar_T *)si->sn_var_vals.ga_data)
602 + iptr->isn_arg.script.script_idx;
603 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
604 goto failed;
605 copy_tv(sv->sv_tv, STACK_TV_BOT(0));
606 ++ectx.ec_stack.ga_len;
607 }
608 break;
609
610 // load s: variable in old script
611 case ISN_LOADS:
612 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100613 hashtab_T *ht = &SCRIPT_VARS(
614 iptr->isn_arg.loadstore.ls_sid);
615 char_u *name = iptr->isn_arg.loadstore.ls_name;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100616 dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE);
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100617
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100618 if (di == NULL)
619 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100620 semsg(_(e_undefvar), name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100621 goto failed;
622 }
623 else
624 {
625 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
626 goto failed;
627 copy_tv(&di->di_tv, STACK_TV_BOT(0));
628 ++ectx.ec_stack.ga_len;
629 }
630 }
631 break;
632
633 // load g: variable
634 case ISN_LOADG:
635 {
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100636 dictitem_T *di = find_var_in_ht(get_globvar_ht(), 0,
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100637 iptr->isn_arg.string, TRUE);
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100638
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100639 if (di == NULL)
640 {
641 semsg(_("E121: Undefined variable: g:%s"),
642 iptr->isn_arg.string);
643 goto failed;
644 }
645 else
646 {
647 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
648 goto failed;
649 copy_tv(&di->di_tv, STACK_TV_BOT(0));
650 ++ectx.ec_stack.ga_len;
651 }
652 }
653 break;
654
655 // load &option
656 case ISN_LOADOPT:
657 {
658 typval_T optval;
659 char_u *name = iptr->isn_arg.string;
660
661 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
662 goto failed;
Bram Moolenaar58ceca52020-01-28 22:46:22 +0100663 if (get_option_tv(&name, &optval, TRUE) == FAIL)
664 goto failed;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100665 *STACK_TV_BOT(0) = optval;
666 ++ectx.ec_stack.ga_len;
667 }
668 break;
669
670 // load $ENV
671 case ISN_LOADENV:
672 {
673 typval_T optval;
674 char_u *name = iptr->isn_arg.string;
675
676 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
677 goto failed;
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100678 // name is always valid, checked when compiling
679 (void)get_env_tv(&name, &optval, TRUE);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100680 *STACK_TV_BOT(0) = optval;
681 ++ectx.ec_stack.ga_len;
682 }
683 break;
684
685 // load @register
686 case ISN_LOADREG:
687 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
688 goto failed;
689 tv = STACK_TV_BOT(0);
690 tv->v_type = VAR_STRING;
691 tv->vval.v_string = get_reg_contents(
692 iptr->isn_arg.number, GREG_EXPR_SRC);
693 ++ectx.ec_stack.ga_len;
694 break;
695
696 // store local variable
697 case ISN_STORE:
698 --ectx.ec_stack.ga_len;
699 tv = STACK_TV_VAR(iptr->isn_arg.number);
700 clear_tv(tv);
701 *tv = *STACK_TV_BOT(0);
702 break;
703
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100704 // store s: variable in old script
705 case ISN_STORES:
706 {
707 hashtab_T *ht = &SCRIPT_VARS(
708 iptr->isn_arg.loadstore.ls_sid);
709 char_u *name = iptr->isn_arg.loadstore.ls_name;
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100710 dictitem_T *di = find_var_in_ht(ht, 0, name + 2, TRUE);
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100711
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100712 --ectx.ec_stack.ga_len;
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100713 if (di == NULL)
714 store_var(iptr->isn_arg.string, STACK_TV_BOT(0));
715 else
716 {
717 clear_tv(&di->di_tv);
718 di->di_tv = *STACK_TV_BOT(0);
719 }
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100720 }
721 break;
722
723 // store script-local variable in Vim9 script
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100724 case ISN_STORESCRIPT:
725 {
Bram Moolenaar21b9e972020-01-26 19:26:46 +0100726 scriptitem_T *si = SCRIPT_ITEM(
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100727 iptr->isn_arg.script.script_sid);
728 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
729 + iptr->isn_arg.script.script_idx;
730
731 --ectx.ec_stack.ga_len;
732 clear_tv(sv->sv_tv);
733 *sv->sv_tv = *STACK_TV_BOT(0);
734 }
735 break;
736
737 // store option
738 case ISN_STOREOPT:
739 {
740 long n = 0;
741 char_u *s = NULL;
742 char *msg;
743
744 --ectx.ec_stack.ga_len;
745 tv = STACK_TV_BOT(0);
746 if (tv->v_type == VAR_STRING)
Bram Moolenaar97a2af32020-01-28 22:52:48 +0100747 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100748 s = tv->vval.v_string;
Bram Moolenaar97a2af32020-01-28 22:52:48 +0100749 if (s == NULL)
750 s = (char_u *)"";
751 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100752 else if (tv->v_type == VAR_NUMBER)
753 n = tv->vval.v_number;
754 else
755 {
756 emsg(_("E1051: Expected string or number"));
757 goto failed;
758 }
759 msg = set_option_value(iptr->isn_arg.storeopt.so_name,
760 n, s, iptr->isn_arg.storeopt.so_flags);
761 if (msg != NULL)
762 {
763 emsg(_(msg));
764 goto failed;
765 }
766 clear_tv(tv);
767 }
768 break;
769
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100770 // store $ENV
771 case ISN_STOREENV:
772 --ectx.ec_stack.ga_len;
773 vim_setenv_ext(iptr->isn_arg.string,
774 tv_get_string(STACK_TV_BOT(0)));
775 break;
776
777 // store @r
778 case ISN_STOREREG:
779 {
780 int reg = iptr->isn_arg.number;
781
782 --ectx.ec_stack.ga_len;
Bram Moolenaar401d9ff2020-02-19 18:14:44 +0100783 tv = STACK_TV_BOT(0);
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100784 write_reg_contents(reg == '@' ? '"' : reg,
Bram Moolenaar401d9ff2020-02-19 18:14:44 +0100785 tv_get_string(tv), -1, FALSE);
786 clear_tv(tv);
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100787 }
788 break;
789
790 // store v: variable
791 case ISN_STOREV:
792 --ectx.ec_stack.ga_len;
793 if (set_vim_var_tv(iptr->isn_arg.number, STACK_TV_BOT(0))
794 == FAIL)
795 goto failed;
796 break;
797
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100798 // store g: variable
799 case ISN_STOREG:
800 {
801 dictitem_T *di;
802
803 --ectx.ec_stack.ga_len;
804 di = find_var_in_ht(get_globvar_ht(), 0,
Bram Moolenaar401d9ff2020-02-19 18:14:44 +0100805 iptr->isn_arg.string + 2, TRUE);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100806 if (di == NULL)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +0100807 store_var(iptr->isn_arg.string, STACK_TV_BOT(0));
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100808 else
809 {
810 clear_tv(&di->di_tv);
811 di->di_tv = *STACK_TV_BOT(0);
812 }
813 }
814 break;
815
816 // store number in local variable
817 case ISN_STORENR:
818 tv = STACK_TV_VAR(iptr->isn_arg.storenr.str_idx);
819 clear_tv(tv);
820 tv->v_type = VAR_NUMBER;
821 tv->vval.v_number = iptr->isn_arg.storenr.str_val;
822 break;
823
824 // push constant
825 case ISN_PUSHNR:
826 case ISN_PUSHBOOL:
827 case ISN_PUSHSPEC:
828 case ISN_PUSHF:
829 case ISN_PUSHS:
830 case ISN_PUSHBLOB:
831 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
832 goto failed;
833 tv = STACK_TV_BOT(0);
834 ++ectx.ec_stack.ga_len;
835 switch (iptr->isn_type)
836 {
837 case ISN_PUSHNR:
838 tv->v_type = VAR_NUMBER;
839 tv->vval.v_number = iptr->isn_arg.number;
840 break;
841 case ISN_PUSHBOOL:
842 tv->v_type = VAR_BOOL;
843 tv->vval.v_number = iptr->isn_arg.number;
844 break;
845 case ISN_PUSHSPEC:
846 tv->v_type = VAR_SPECIAL;
847 tv->vval.v_number = iptr->isn_arg.number;
848 break;
849#ifdef FEAT_FLOAT
850 case ISN_PUSHF:
851 tv->v_type = VAR_FLOAT;
852 tv->vval.v_float = iptr->isn_arg.fnumber;
853 break;
854#endif
855 case ISN_PUSHBLOB:
856 blob_copy(iptr->isn_arg.blob, tv);
857 break;
858 default:
859 tv->v_type = VAR_STRING;
860 tv->vval.v_string = vim_strsave(iptr->isn_arg.string);
861 }
862 break;
863
864 // create a list from items on the stack; uses a single allocation
865 // for the list header and the items
866 case ISN_NEWLIST:
867 {
868 int count = iptr->isn_arg.number;
869 list_T *list = list_alloc_with_items(count);
870
871 if (list == NULL)
872 goto failed;
873 for (idx = 0; idx < count; ++idx)
874 list_set_item(list, idx, STACK_TV_BOT(idx - count));
875
876 if (count > 0)
877 ectx.ec_stack.ga_len -= count - 1;
878 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
879 goto failed;
880 else
881 ++ectx.ec_stack.ga_len;
882 tv = STACK_TV_BOT(-1);
883 tv->v_type = VAR_LIST;
884 tv->vval.v_list = list;
885 ++list->lv_refcount;
886 }
887 break;
888
889 // create a dict from items on the stack
890 case ISN_NEWDICT:
891 {
892 int count = iptr->isn_arg.number;
893 dict_T *dict = dict_alloc();
894 dictitem_T *item;
895
896 if (dict == NULL)
897 goto failed;
898 for (idx = 0; idx < count; ++idx)
899 {
900 // check key type is VAR_STRING
901 tv = STACK_TV_BOT(2 * (idx - count));
902 item = dictitem_alloc(tv->vval.v_string);
903 clear_tv(tv);
904 if (item == NULL)
905 goto failed;
906 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
907 item->di_tv.v_lock = 0;
908 if (dict_add(dict, item) == FAIL)
909 goto failed;
910 }
911
912 if (count > 0)
913 ectx.ec_stack.ga_len -= 2 * count - 1;
914 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
915 goto failed;
916 else
917 ++ectx.ec_stack.ga_len;
918 tv = STACK_TV_BOT(-1);
919 tv->v_type = VAR_DICT;
920 tv->vval.v_dict = dict;
921 ++dict->dv_refcount;
922 }
923 break;
924
925 // call a :def function
926 case ISN_DCALL:
927 if (call_dfunc(iptr->isn_arg.dfunc.cdf_idx,
928 iptr->isn_arg.dfunc.cdf_argcount,
929 &ectx) == FAIL)
930 goto failed;
931 break;
932
933 // call a builtin function
934 case ISN_BCALL:
935 SOURCING_LNUM = iptr->isn_lnum;
936 if (call_bfunc(iptr->isn_arg.bfunc.cbf_idx,
937 iptr->isn_arg.bfunc.cbf_argcount,
938 &ectx) == FAIL)
939 goto failed;
940 break;
941
942 // call a funcref or partial
943 case ISN_PCALL:
944 {
945 cpfunc_T *pfunc = &iptr->isn_arg.pfunc;
946 int r;
947 typval_T partial;
948
949 SOURCING_LNUM = iptr->isn_lnum;
950 if (pfunc->cpf_top)
951 {
952 // funcref is above the arguments
953 tv = STACK_TV_BOT(-pfunc->cpf_argcount - 1);
954 }
955 else
956 {
957 // Get the funcref from the stack.
958 --ectx.ec_stack.ga_len;
959 partial = *STACK_TV_BOT(0);
960 tv = &partial;
961 }
962 r = call_partial(tv, pfunc->cpf_argcount, &ectx);
963 if (tv == &partial)
964 clear_tv(&partial);
965 if (r == FAIL)
966 goto failed;
967
968 if (pfunc->cpf_top)
969 {
970 // Get the funcref from the stack, overwrite with the
971 // return value.
972 clear_tv(tv);
973 --ectx.ec_stack.ga_len;
974 *STACK_TV_BOT(-1) = *STACK_TV_BOT(0);
975 }
976 }
977 break;
978
979 // call a user defined function or funcref/partial
980 case ISN_UCALL:
981 {
982 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
983
984 SOURCING_LNUM = iptr->isn_lnum;
985 if (call_eval_func(cufunc->cuf_name,
986 cufunc->cuf_argcount, &ectx) == FAIL)
987 goto failed;
988 }
989 break;
990
991 // return from a :def function call
992 case ISN_RETURN:
993 {
Bram Moolenaar8cbd6df2020-01-28 22:59:45 +0100994 garray_T *trystack = &ectx.ec_trystack;
995
996 if (trystack->ga_len > 0)
997 trycmd = ((trycmd_T *)trystack->ga_data)
998 + trystack->ga_len - 1;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100999 if (trycmd != NULL && trycmd->tcd_frame == ectx.ec_frame
1000 && trycmd->tcd_finally_idx != 0)
1001 {
1002 // jump to ":finally"
1003 ectx.ec_iidx = trycmd->tcd_finally_idx;
1004 trycmd->tcd_return = TRUE;
1005 }
1006 else
1007 {
1008 // Restore previous function. If the frame pointer
1009 // is zero then there is none and we are done.
1010 if (ectx.ec_frame == initial_frame_ptr)
1011 goto done;
1012
1013 func_return(&ectx);
1014 }
1015 }
1016 break;
1017
1018 // push a function reference to a compiled function
1019 case ISN_FUNCREF:
1020 {
1021 partial_T *pt = NULL;
1022
1023 pt = ALLOC_CLEAR_ONE(partial_T);
1024 if (pt == NULL)
1025 goto failed;
1026 dfunc = ((dfunc_T *)def_functions.ga_data)
1027 + iptr->isn_arg.number;
1028 pt->pt_func = dfunc->df_ufunc;
1029 pt->pt_refcount = 1;
1030 ++dfunc->df_ufunc->uf_refcount;
1031
1032 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
1033 goto failed;
1034 tv = STACK_TV_BOT(0);
1035 ++ectx.ec_stack.ga_len;
1036 tv->vval.v_partial = pt;
1037 tv->v_type = VAR_PARTIAL;
1038 }
1039 break;
1040
1041 // jump if a condition is met
1042 case ISN_JUMP:
1043 {
1044 jumpwhen_T when = iptr->isn_arg.jump.jump_when;
1045 int jump = TRUE;
1046
1047 if (when != JUMP_ALWAYS)
1048 {
1049 tv = STACK_TV_BOT(-1);
1050 jump = tv2bool(tv);
1051 if (when == JUMP_IF_FALSE
1052 || when == JUMP_AND_KEEP_IF_FALSE)
1053 jump = !jump;
Bram Moolenaar777770f2020-02-06 21:27:08 +01001054 if (when == JUMP_IF_FALSE || !jump)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001055 {
1056 // drop the value from the stack
1057 clear_tv(tv);
1058 --ectx.ec_stack.ga_len;
1059 }
1060 }
1061 if (jump)
1062 ectx.ec_iidx = iptr->isn_arg.jump.jump_where;
1063 }
1064 break;
1065
1066 // top of a for loop
1067 case ISN_FOR:
1068 {
1069 list_T *list = STACK_TV_BOT(-1)->vval.v_list;
1070 typval_T *idxtv =
1071 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx);
1072
1073 // push the next item from the list
1074 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
1075 goto failed;
1076 if (++idxtv->vval.v_number >= list->lv_len)
1077 // past the end of the list, jump to "endfor"
1078 ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
1079 else if (list->lv_first == &range_list_item)
1080 {
1081 // non-materialized range() list
1082 tv = STACK_TV_BOT(0);
1083 tv->v_type = VAR_NUMBER;
1084 tv->vval.v_number = list_find_nr(
1085 list, idxtv->vval.v_number, NULL);
1086 ++ectx.ec_stack.ga_len;
1087 }
1088 else
1089 {
1090 listitem_T *li = list_find(list, idxtv->vval.v_number);
1091
1092 if (li == NULL)
1093 goto failed;
1094 copy_tv(&li->li_tv, STACK_TV_BOT(0));
1095 ++ectx.ec_stack.ga_len;
1096 }
1097 }
1098 break;
1099
1100 // start of ":try" block
1101 case ISN_TRY:
1102 {
1103 if (ga_grow(&ectx.ec_trystack, 1) == FAIL)
1104 goto failed;
1105 trycmd = ((trycmd_T *)ectx.ec_trystack.ga_data)
1106 + ectx.ec_trystack.ga_len;
1107 ++ectx.ec_trystack.ga_len;
1108 ++trylevel;
1109 trycmd->tcd_frame = ectx.ec_frame;
1110 trycmd->tcd_catch_idx = iptr->isn_arg.try.try_catch;
1111 trycmd->tcd_finally_idx = iptr->isn_arg.try.try_finally;
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001112 trycmd->tcd_caught = FALSE;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001113 }
1114 break;
1115
1116 case ISN_PUSHEXC:
1117 if (current_exception == NULL)
1118 {
1119 iemsg("Evaluating catch while current_exception is NULL");
1120 goto failed;
1121 }
1122 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
1123 goto failed;
1124 tv = STACK_TV_BOT(0);
1125 ++ectx.ec_stack.ga_len;
1126 tv->v_type = VAR_STRING;
1127 tv->vval.v_string = vim_strsave(
1128 (char_u *)current_exception->value);
1129 break;
1130
1131 case ISN_CATCH:
1132 {
1133 garray_T *trystack = &ectx.ec_trystack;
1134
1135 if (trystack->ga_len > 0)
1136 {
1137 trycmd = ((trycmd_T *)trystack->ga_data)
1138 + trystack->ga_len - 1;
1139 trycmd->tcd_caught = TRUE;
1140 }
1141 did_emsg = got_int = did_throw = FALSE;
1142 catch_exception(current_exception);
1143 }
1144 break;
1145
1146 // end of ":try" block
1147 case ISN_ENDTRY:
1148 {
1149 garray_T *trystack = &ectx.ec_trystack;
1150
1151 if (trystack->ga_len > 0)
1152 {
1153 --trystack->ga_len;
1154 --trylevel;
1155 trycmd = ((trycmd_T *)trystack->ga_data)
1156 + trystack->ga_len;
Bram Moolenaarf575adf2020-02-20 20:41:06 +01001157 if (trycmd->tcd_caught && current_exception != NULL)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001158 {
1159 // discard the exception
1160 if (caught_stack == current_exception)
1161 caught_stack = caught_stack->caught;
1162 discard_current_exception();
1163 }
1164
1165 if (trycmd->tcd_return)
1166 {
1167 // Restore previous function. If the frame pointer
1168 // is zero then there is none and we are done.
1169 if (ectx.ec_frame == initial_frame_ptr)
1170 goto done;
1171
1172 func_return(&ectx);
1173 }
1174 }
1175 }
1176 break;
1177
1178 case ISN_THROW:
1179 --ectx.ec_stack.ga_len;
1180 tv = STACK_TV_BOT(0);
1181 if (throw_exception(tv->vval.v_string, ET_USER, NULL) == FAIL)
1182 {
1183 vim_free(tv->vval.v_string);
1184 goto failed;
1185 }
1186 did_throw = TRUE;
1187 break;
1188
1189 // compare with special values
1190 case ISN_COMPAREBOOL:
1191 case ISN_COMPARESPECIAL:
1192 {
1193 typval_T *tv1 = STACK_TV_BOT(-2);
1194 typval_T *tv2 = STACK_TV_BOT(-1);
1195 varnumber_T arg1 = tv1->vval.v_number;
1196 varnumber_T arg2 = tv2->vval.v_number;
1197 int res;
1198
1199 switch (iptr->isn_arg.op.op_type)
1200 {
1201 case EXPR_EQUAL: res = arg1 == arg2; break;
1202 case EXPR_NEQUAL: res = arg1 != arg2; break;
1203 default: res = 0; break;
1204 }
1205
1206 --ectx.ec_stack.ga_len;
1207 tv1->v_type = VAR_BOOL;
1208 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1209 }
1210 break;
1211
1212 // Operation with two number arguments
1213 case ISN_OPNR:
1214 case ISN_COMPARENR:
1215 {
1216 typval_T *tv1 = STACK_TV_BOT(-2);
1217 typval_T *tv2 = STACK_TV_BOT(-1);
1218 varnumber_T arg1 = tv1->vval.v_number;
1219 varnumber_T arg2 = tv2->vval.v_number;
1220 varnumber_T res;
1221
1222 switch (iptr->isn_arg.op.op_type)
1223 {
1224 case EXPR_MULT: res = arg1 * arg2; break;
1225 case EXPR_DIV: res = arg1 / arg2; break;
1226 case EXPR_REM: res = arg1 % arg2; break;
1227 case EXPR_SUB: res = arg1 - arg2; break;
1228 case EXPR_ADD: res = arg1 + arg2; break;
1229
1230 case EXPR_EQUAL: res = arg1 == arg2; break;
1231 case EXPR_NEQUAL: res = arg1 != arg2; break;
1232 case EXPR_GREATER: res = arg1 > arg2; break;
1233 case EXPR_GEQUAL: res = arg1 >= arg2; break;
1234 case EXPR_SMALLER: res = arg1 < arg2; break;
1235 case EXPR_SEQUAL: res = arg1 <= arg2; break;
1236 default: res = 0; break;
1237 }
1238
1239 --ectx.ec_stack.ga_len;
1240 if (iptr->isn_type == ISN_COMPARENR)
1241 {
1242 tv1->v_type = VAR_BOOL;
1243 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1244 }
1245 else
1246 tv1->vval.v_number = res;
1247 }
1248 break;
1249
1250 // Computation with two float arguments
1251 case ISN_OPFLOAT:
1252 case ISN_COMPAREFLOAT:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001253#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001254 {
1255 typval_T *tv1 = STACK_TV_BOT(-2);
1256 typval_T *tv2 = STACK_TV_BOT(-1);
1257 float_T arg1 = tv1->vval.v_float;
1258 float_T arg2 = tv2->vval.v_float;
1259 float_T res = 0;
1260 int cmp = FALSE;
1261
1262 switch (iptr->isn_arg.op.op_type)
1263 {
1264 case EXPR_MULT: res = arg1 * arg2; break;
1265 case EXPR_DIV: res = arg1 / arg2; break;
1266 case EXPR_SUB: res = arg1 - arg2; break;
1267 case EXPR_ADD: res = arg1 + arg2; break;
1268
1269 case EXPR_EQUAL: cmp = arg1 == arg2; break;
1270 case EXPR_NEQUAL: cmp = arg1 != arg2; break;
1271 case EXPR_GREATER: cmp = arg1 > arg2; break;
1272 case EXPR_GEQUAL: cmp = arg1 >= arg2; break;
1273 case EXPR_SMALLER: cmp = arg1 < arg2; break;
1274 case EXPR_SEQUAL: cmp = arg1 <= arg2; break;
1275 default: cmp = 0; break;
1276 }
1277 --ectx.ec_stack.ga_len;
1278 if (iptr->isn_type == ISN_COMPAREFLOAT)
1279 {
1280 tv1->v_type = VAR_BOOL;
1281 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1282 }
1283 else
1284 tv1->vval.v_float = res;
1285 }
Bram Moolenaara5d59532020-01-26 21:42:03 +01001286#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001287 break;
1288
1289 case ISN_COMPARELIST:
1290 {
1291 typval_T *tv1 = STACK_TV_BOT(-2);
1292 typval_T *tv2 = STACK_TV_BOT(-1);
1293 list_T *arg1 = tv1->vval.v_list;
1294 list_T *arg2 = tv2->vval.v_list;
1295 int cmp = FALSE;
1296 int ic = iptr->isn_arg.op.op_ic;
1297
1298 switch (iptr->isn_arg.op.op_type)
1299 {
1300 case EXPR_EQUAL: cmp =
1301 list_equal(arg1, arg2, ic, FALSE); break;
1302 case EXPR_NEQUAL: cmp =
1303 !list_equal(arg1, arg2, ic, FALSE); break;
1304 case EXPR_IS: cmp = arg1 == arg2; break;
1305 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1306 default: cmp = 0; break;
1307 }
1308 --ectx.ec_stack.ga_len;
1309 clear_tv(tv1);
1310 clear_tv(tv2);
1311 tv1->v_type = VAR_BOOL;
1312 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1313 }
1314 break;
1315
1316 case ISN_COMPAREBLOB:
1317 {
1318 typval_T *tv1 = STACK_TV_BOT(-2);
1319 typval_T *tv2 = STACK_TV_BOT(-1);
1320 blob_T *arg1 = tv1->vval.v_blob;
1321 blob_T *arg2 = tv2->vval.v_blob;
1322 int cmp = FALSE;
1323
1324 switch (iptr->isn_arg.op.op_type)
1325 {
1326 case EXPR_EQUAL: cmp = blob_equal(arg1, arg2); break;
1327 case EXPR_NEQUAL: cmp = !blob_equal(arg1, arg2); break;
1328 case EXPR_IS: cmp = arg1 == arg2; break;
1329 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1330 default: cmp = 0; break;
1331 }
1332 --ectx.ec_stack.ga_len;
1333 clear_tv(tv1);
1334 clear_tv(tv2);
1335 tv1->v_type = VAR_BOOL;
1336 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1337 }
1338 break;
1339
1340 // TODO: handle separately
1341 case ISN_COMPARESTRING:
1342 case ISN_COMPAREDICT:
1343 case ISN_COMPAREFUNC:
1344 case ISN_COMPAREPARTIAL:
1345 case ISN_COMPAREANY:
1346 {
1347 typval_T *tv1 = STACK_TV_BOT(-2);
1348 typval_T *tv2 = STACK_TV_BOT(-1);
1349 exptype_T exptype = iptr->isn_arg.op.op_type;
1350 int ic = iptr->isn_arg.op.op_ic;
1351
1352 typval_compare(tv1, tv2, exptype, ic);
1353 clear_tv(tv2);
1354 tv1->v_type = VAR_BOOL;
1355 tv1->vval.v_number = tv1->vval.v_number
1356 ? VVAL_TRUE : VVAL_FALSE;
1357 --ectx.ec_stack.ga_len;
1358 }
1359 break;
1360
1361 case ISN_ADDLIST:
1362 case ISN_ADDBLOB:
1363 {
1364 typval_T *tv1 = STACK_TV_BOT(-2);
1365 typval_T *tv2 = STACK_TV_BOT(-1);
1366
1367 if (iptr->isn_type == ISN_ADDLIST)
1368 eval_addlist(tv1, tv2);
1369 else
1370 eval_addblob(tv1, tv2);
1371 clear_tv(tv2);
1372 --ectx.ec_stack.ga_len;
1373 }
1374 break;
1375
1376 // Computation with two arguments of unknown type
1377 case ISN_OPANY:
1378 {
1379 typval_T *tv1 = STACK_TV_BOT(-2);
1380 typval_T *tv2 = STACK_TV_BOT(-1);
1381 varnumber_T n1, n2;
1382#ifdef FEAT_FLOAT
1383 float_T f1 = 0, f2 = 0;
1384#endif
1385 int error = FALSE;
1386
1387 if (iptr->isn_arg.op.op_type == EXPR_ADD)
1388 {
1389 if (tv1->v_type == VAR_LIST && tv2->v_type == VAR_LIST)
1390 {
1391 eval_addlist(tv1, tv2);
1392 clear_tv(tv2);
1393 --ectx.ec_stack.ga_len;
1394 break;
1395 }
1396 else if (tv1->v_type == VAR_BLOB
1397 && tv2->v_type == VAR_BLOB)
1398 {
1399 eval_addblob(tv1, tv2);
1400 clear_tv(tv2);
1401 --ectx.ec_stack.ga_len;
1402 break;
1403 }
1404 }
1405#ifdef FEAT_FLOAT
1406 if (tv1->v_type == VAR_FLOAT)
1407 {
1408 f1 = tv1->vval.v_float;
1409 n1 = 0;
1410 }
1411 else
1412#endif
1413 {
1414 n1 = tv_get_number_chk(tv1, &error);
1415 if (error)
1416 goto failed;
1417#ifdef FEAT_FLOAT
1418 if (tv2->v_type == VAR_FLOAT)
1419 f1 = n1;
1420#endif
1421 }
1422#ifdef FEAT_FLOAT
1423 if (tv2->v_type == VAR_FLOAT)
1424 {
1425 f2 = tv2->vval.v_float;
1426 n2 = 0;
1427 }
1428 else
1429#endif
1430 {
1431 n2 = tv_get_number_chk(tv2, &error);
1432 if (error)
1433 goto failed;
1434#ifdef FEAT_FLOAT
1435 if (tv1->v_type == VAR_FLOAT)
1436 f2 = n2;
1437#endif
1438 }
1439#ifdef FEAT_FLOAT
1440 // if there is a float on either side the result is a float
1441 if (tv1->v_type == VAR_FLOAT || tv2->v_type == VAR_FLOAT)
1442 {
1443 switch (iptr->isn_arg.op.op_type)
1444 {
1445 case EXPR_MULT: f1 = f1 * f2; break;
1446 case EXPR_DIV: f1 = f1 / f2; break;
1447 case EXPR_SUB: f1 = f1 - f2; break;
1448 case EXPR_ADD: f1 = f1 + f2; break;
1449 default: emsg(_(e_modulus)); goto failed;
1450 }
1451 clear_tv(tv1);
1452 clear_tv(tv2);
1453 tv1->v_type = VAR_FLOAT;
1454 tv1->vval.v_float = f1;
1455 --ectx.ec_stack.ga_len;
1456 }
1457 else
1458#endif
1459 {
1460 switch (iptr->isn_arg.op.op_type)
1461 {
1462 case EXPR_MULT: n1 = n1 * n2; break;
1463 case EXPR_DIV: n1 = num_divide(n1, n2); break;
1464 case EXPR_SUB: n1 = n1 - n2; break;
1465 case EXPR_ADD: n1 = n1 + n2; break;
1466 default: n1 = num_modulus(n1, n2); break;
1467 }
1468 clear_tv(tv1);
1469 clear_tv(tv2);
1470 tv1->v_type = VAR_NUMBER;
1471 tv1->vval.v_number = n1;
1472 --ectx.ec_stack.ga_len;
1473 }
1474 }
1475 break;
1476
1477 case ISN_CONCAT:
1478 {
1479 char_u *str1 = STACK_TV_BOT(-2)->vval.v_string;
1480 char_u *str2 = STACK_TV_BOT(-1)->vval.v_string;
1481 char_u *res;
1482
1483 res = concat_str(str1, str2);
1484 clear_tv(STACK_TV_BOT(-2));
1485 clear_tv(STACK_TV_BOT(-1));
1486 --ectx.ec_stack.ga_len;
1487 STACK_TV_BOT(-1)->vval.v_string = res;
1488 }
1489 break;
1490
1491 case ISN_INDEX:
1492 {
1493 list_T *list;
1494 varnumber_T n;
1495 listitem_T *li;
1496
1497 // list index: list is at stack-2, index at stack-1
1498 tv = STACK_TV_BOT(-2);
1499 if (tv->v_type != VAR_LIST)
1500 {
1501 emsg(_(e_listreq));
1502 goto failed;
1503 }
1504 list = tv->vval.v_list;
1505
1506 tv = STACK_TV_BOT(-1);
1507 if (tv->v_type != VAR_NUMBER)
1508 {
1509 emsg(_(e_number_exp));
1510 goto failed;
1511 }
1512 n = tv->vval.v_number;
1513 clear_tv(tv);
1514 if ((li = list_find(list, n)) == NULL)
1515 {
1516 semsg(_(e_listidx), n);
1517 goto failed;
1518 }
1519 --ectx.ec_stack.ga_len;
1520 clear_tv(STACK_TV_BOT(-1));
1521 copy_tv(&li->li_tv, STACK_TV_BOT(-1));
1522 }
1523 break;
1524
1525 // dict member with string key
1526 case ISN_MEMBER:
1527 {
1528 dict_T *dict;
1529 dictitem_T *di;
1530
1531 tv = STACK_TV_BOT(-1);
1532 if (tv->v_type != VAR_DICT || tv->vval.v_dict == NULL)
1533 {
1534 emsg(_(e_dictreq));
1535 goto failed;
1536 }
1537 dict = tv->vval.v_dict;
1538
1539 if ((di = dict_find(dict, iptr->isn_arg.string, -1))
1540 == NULL)
1541 {
1542 semsg(_(e_dictkey), iptr->isn_arg.string);
1543 goto failed;
1544 }
1545 clear_tv(tv);
1546 copy_tv(&di->di_tv, tv);
1547 }
1548 break;
1549
1550 case ISN_NEGATENR:
1551 tv = STACK_TV_BOT(-1);
1552 tv->vval.v_number = -tv->vval.v_number;
1553 break;
1554
1555 case ISN_CHECKNR:
1556 {
1557 int error = FALSE;
1558
1559 tv = STACK_TV_BOT(-1);
1560 if (check_not_string(tv) == FAIL)
1561 {
1562 --ectx.ec_stack.ga_len;
1563 goto failed;
1564 }
1565 (void)tv_get_number_chk(tv, &error);
1566 if (error)
1567 goto failed;
1568 }
1569 break;
1570
1571 case ISN_CHECKTYPE:
1572 {
1573 checktype_T *ct = &iptr->isn_arg.type;
1574
1575 tv = STACK_TV_BOT(ct->ct_off);
1576 if (tv->v_type != ct->ct_type)
1577 {
1578 semsg(_("E1029: Expected %s but got %s"),
1579 vartype_name(ct->ct_type),
1580 vartype_name(tv->v_type));
1581 goto failed;
1582 }
1583 }
1584 break;
1585
1586 case ISN_2BOOL:
1587 {
1588 int n;
1589
1590 tv = STACK_TV_BOT(-1);
1591 n = tv2bool(tv);
1592 if (iptr->isn_arg.number) // invert
1593 n = !n;
1594 clear_tv(tv);
1595 tv->v_type = VAR_BOOL;
1596 tv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
1597 }
1598 break;
1599
1600 case ISN_2STRING:
1601 {
1602 char_u *str;
1603
1604 tv = STACK_TV_BOT(iptr->isn_arg.number);
1605 if (tv->v_type != VAR_STRING)
1606 {
1607 str = typval_tostring(tv);
1608 clear_tv(tv);
1609 tv->v_type = VAR_STRING;
1610 tv->vval.v_string = str;
1611 }
1612 }
1613 break;
1614
1615 case ISN_DROP:
1616 --ectx.ec_stack.ga_len;
1617 clear_tv(STACK_TV_BOT(0));
1618 break;
1619 }
1620 }
1621
1622done:
1623 // function finished, get result from the stack.
1624 tv = STACK_TV_BOT(-1);
1625 *rettv = *tv;
1626 tv->v_type = VAR_UNKNOWN;
1627 ret = OK;
1628
1629failed:
1630 for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
1631 clear_tv(STACK_TV(idx));
1632 vim_free(ectx.ec_stack.ga_data);
1633 return ret;
1634}
1635
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001636/*
1637 * ":dissassemble".
Bram Moolenaar777770f2020-02-06 21:27:08 +01001638 * We don't really need this at runtime, but we do have tests that require it,
1639 * so always include this.
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001640 */
1641 void
1642ex_disassemble(exarg_T *eap)
1643{
Bram Moolenaar21456cd2020-02-13 21:29:32 +01001644 char_u *arg = eap->arg;
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001645 char_u *fname;
1646 ufunc_T *ufunc;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001647 dfunc_T *dfunc;
1648 isn_T *instr;
1649 int current;
1650 int line_idx = 0;
1651 int prev_current = 0;
1652
Bram Moolenaar21456cd2020-02-13 21:29:32 +01001653 fname = trans_function_name(&arg, FALSE,
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001654 TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL, NULL);
Bram Moolenaar21456cd2020-02-13 21:29:32 +01001655 if (fname == NULL)
1656 {
1657 semsg(_(e_invarg2), eap->arg);
1658 return;
1659 }
1660
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001661 ufunc = find_func(fname, NULL);
1662 vim_free(fname);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001663 if (ufunc == NULL)
1664 {
Bram Moolenaardf2ecdd2020-02-16 15:03:48 +01001665 semsg(_("E1061: Cannot find function %s"), eap->arg);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001666 return;
1667 }
1668 if (ufunc->uf_dfunc_idx < 0)
1669 {
Bram Moolenaardf2ecdd2020-02-16 15:03:48 +01001670 semsg(_("E1062: Function %s is not compiled"), eap->arg);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001671 return;
1672 }
1673 if (ufunc->uf_name_exp != NULL)
1674 msg((char *)ufunc->uf_name_exp);
1675 else
1676 msg((char *)ufunc->uf_name);
1677
1678 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
1679 instr = dfunc->df_instr;
1680 for (current = 0; current < dfunc->df_instr_count; ++current)
1681 {
1682 isn_T *iptr = &instr[current];
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001683 char *line;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001684
1685 while (line_idx < iptr->isn_lnum && line_idx < ufunc->uf_lines.ga_len)
1686 {
1687 if (current > prev_current)
1688 {
1689 msg_puts("\n\n");
1690 prev_current = current;
1691 }
Bram Moolenaarf2460a32020-02-07 22:09:54 +01001692 line = ((char **)ufunc->uf_lines.ga_data)[line_idx++];
1693 if (line != NULL)
1694 msg(line);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001695 }
1696
1697 switch (iptr->isn_type)
1698 {
1699 case ISN_EXEC:
1700 smsg("%4d EXEC %s", current, iptr->isn_arg.string);
1701 break;
1702 case ISN_ECHO:
1703 {
1704 echo_T *echo = &iptr->isn_arg.echo;
1705
1706 smsg("%4d %s %d", current,
1707 echo->echo_with_white ? "ECHO" : "ECHON",
1708 echo->echo_count);
1709 }
1710 break;
Bram Moolenaarad39c092020-02-26 18:23:43 +01001711 case ISN_EXECUTE:
1712 smsg("%4d EXECUTE %d", current, iptr->isn_arg.number);
1713 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001714 case ISN_LOAD:
1715 if (iptr->isn_arg.number < 0)
1716 smsg("%4d LOAD arg[%lld]", current,
1717 iptr->isn_arg.number + STACK_FRAME_SIZE);
1718 else
1719 smsg("%4d LOAD $%lld", current, iptr->isn_arg.number);
1720 break;
1721 case ISN_LOADV:
1722 smsg("%4d LOADV v:%s", current,
1723 get_vim_var_name(iptr->isn_arg.number));
1724 break;
1725 case ISN_LOADSCRIPT:
1726 {
1727 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001728 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001729 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1730 + iptr->isn_arg.script.script_idx;
1731
1732 smsg("%4d LOADSCRIPT %s from %s", current,
1733 sv->sv_name, si->sn_name);
1734 }
1735 break;
1736 case ISN_LOADS:
1737 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001738 scriptitem_T *si = SCRIPT_ITEM(
1739 iptr->isn_arg.loadstore.ls_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001740
1741 smsg("%4d LOADS s:%s from %s", current,
1742 iptr->isn_arg.string, si->sn_name);
1743 }
1744 break;
1745 case ISN_LOADG:
1746 smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
1747 break;
1748 case ISN_LOADOPT:
1749 smsg("%4d LOADOPT %s", current, iptr->isn_arg.string);
1750 break;
1751 case ISN_LOADENV:
1752 smsg("%4d LOADENV %s", current, iptr->isn_arg.string);
1753 break;
1754 case ISN_LOADREG:
1755 smsg("%4d LOADREG @%c", current, iptr->isn_arg.number);
1756 break;
1757
1758 case ISN_STORE:
Bram Moolenaar170fcfc2020-02-06 17:51:35 +01001759 if (iptr->isn_arg.number < 0)
1760 smsg("%4d STORE arg[%lld]", current,
1761 iptr->isn_arg.number + STACK_FRAME_SIZE);
1762 else
1763 smsg("%4d STORE $%lld", current, iptr->isn_arg.number);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001764 break;
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001765 case ISN_STOREV:
1766 smsg("%4d STOREV v:%s", current,
1767 get_vim_var_name(iptr->isn_arg.number));
1768 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001769 case ISN_STOREG:
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001770 smsg("%4d STOREG %s", current, iptr->isn_arg.string);
1771 break;
1772 case ISN_STORES:
1773 {
1774 scriptitem_T *si = SCRIPT_ITEM(
1775 iptr->isn_arg.loadstore.ls_sid);
1776
Bram Moolenaar0bbf7222020-02-19 22:31:48 +01001777 smsg("%4d STORES %s in %s", current,
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001778 iptr->isn_arg.string, si->sn_name);
1779 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001780 break;
1781 case ISN_STORESCRIPT:
1782 {
1783 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001784 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001785 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1786 + iptr->isn_arg.script.script_idx;
1787
1788 smsg("%4d STORESCRIPT %s in %s", current,
1789 sv->sv_name, si->sn_name);
1790 }
1791 break;
1792 case ISN_STOREOPT:
1793 smsg("%4d STOREOPT &%s", current,
1794 iptr->isn_arg.storeopt.so_name);
1795 break;
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001796 case ISN_STOREENV:
1797 smsg("%4d STOREENV $%s", current, iptr->isn_arg.string);
1798 break;
1799 case ISN_STOREREG:
1800 smsg("%4d STOREREG @%c", current, iptr->isn_arg.number);
1801 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001802 case ISN_STORENR:
1803 smsg("%4d STORE %lld in $%d", current,
1804 iptr->isn_arg.storenr.str_val,
1805 iptr->isn_arg.storenr.str_idx);
1806 break;
1807
1808 // constants
1809 case ISN_PUSHNR:
1810 smsg("%4d PUSHNR %lld", current, iptr->isn_arg.number);
1811 break;
1812 case ISN_PUSHBOOL:
1813 case ISN_PUSHSPEC:
1814 smsg("%4d PUSH %s", current,
1815 get_var_special_name(iptr->isn_arg.number));
1816 break;
1817 case ISN_PUSHF:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001818#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001819 smsg("%4d PUSHF %g", current, iptr->isn_arg.fnumber);
Bram Moolenaara5d59532020-01-26 21:42:03 +01001820#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001821 break;
1822 case ISN_PUSHS:
1823 smsg("%4d PUSHS \"%s\"", current, iptr->isn_arg.string);
1824 break;
1825 case ISN_PUSHBLOB:
1826 {
1827 char_u *r;
1828 char_u numbuf[NUMBUFLEN];
1829 char_u *tofree;
1830
1831 r = blob2string(iptr->isn_arg.blob, &tofree, numbuf);
Bram Moolenaarff80cb62020-02-05 22:10:05 +01001832 smsg("%4d PUSHBLOB %s", current, r);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001833 vim_free(tofree);
1834 }
1835 break;
1836 case ISN_PUSHEXC:
1837 smsg("%4d PUSH v:exception", current);
1838 break;
1839 case ISN_NEWLIST:
1840 smsg("%4d NEWLIST size %lld", current, iptr->isn_arg.number);
1841 break;
1842 case ISN_NEWDICT:
1843 smsg("%4d NEWDICT size %lld", current, iptr->isn_arg.number);
1844 break;
1845
1846 // function call
1847 case ISN_BCALL:
1848 {
1849 cbfunc_T *cbfunc = &iptr->isn_arg.bfunc;
1850
1851 smsg("%4d BCALL %s(argc %d)", current,
1852 internal_func_name(cbfunc->cbf_idx),
1853 cbfunc->cbf_argcount);
1854 }
1855 break;
1856 case ISN_DCALL:
1857 {
1858 cdfunc_T *cdfunc = &iptr->isn_arg.dfunc;
1859 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1860 + cdfunc->cdf_idx;
1861
1862 smsg("%4d DCALL %s(argc %d)", current,
1863 df->df_ufunc->uf_name_exp != NULL
1864 ? df->df_ufunc->uf_name_exp
1865 : df->df_ufunc->uf_name, cdfunc->cdf_argcount);
1866 }
1867 break;
1868 case ISN_UCALL:
1869 {
1870 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
1871
1872 smsg("%4d UCALL %s(argc %d)", current,
1873 cufunc->cuf_name, cufunc->cuf_argcount);
1874 }
1875 break;
1876 case ISN_PCALL:
1877 {
1878 cpfunc_T *cpfunc = &iptr->isn_arg.pfunc;
1879
1880 smsg("%4d PCALL%s (argc %d)", current,
1881 cpfunc->cpf_top ? " top" : "", cpfunc->cpf_argcount);
1882 }
1883 break;
1884 case ISN_RETURN:
1885 smsg("%4d RETURN", current);
1886 break;
1887 case ISN_FUNCREF:
1888 {
1889 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1890 + iptr->isn_arg.number;
1891
1892 smsg("%4d FUNCREF %s", current, df->df_ufunc->uf_name);
1893 }
1894 break;
1895
1896 case ISN_JUMP:
1897 {
1898 char *when = "?";
1899
1900 switch (iptr->isn_arg.jump.jump_when)
1901 {
1902 case JUMP_ALWAYS:
1903 when = "JUMP";
1904 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001905 case JUMP_AND_KEEP_IF_TRUE:
1906 when = "JUMP_AND_KEEP_IF_TRUE";
1907 break;
1908 case JUMP_IF_FALSE:
1909 when = "JUMP_IF_FALSE";
1910 break;
1911 case JUMP_AND_KEEP_IF_FALSE:
1912 when = "JUMP_AND_KEEP_IF_FALSE";
1913 break;
1914 }
1915 smsg("%4d %s -> %lld", current, when,
1916 iptr->isn_arg.jump.jump_where);
1917 }
1918 break;
1919
1920 case ISN_FOR:
1921 {
1922 forloop_T *forloop = &iptr->isn_arg.forloop;
1923
1924 smsg("%4d FOR $%d -> %d", current,
1925 forloop->for_idx, forloop->for_end);
1926 }
1927 break;
1928
1929 case ISN_TRY:
1930 {
1931 try_T *try = &iptr->isn_arg.try;
1932
1933 smsg("%4d TRY catch -> %d, finally -> %d", current,
1934 try->try_catch, try->try_finally);
1935 }
1936 break;
1937 case ISN_CATCH:
1938 // TODO
1939 smsg("%4d CATCH", current);
1940 break;
1941 case ISN_ENDTRY:
1942 smsg("%4d ENDTRY", current);
1943 break;
1944 case ISN_THROW:
1945 smsg("%4d THROW", current);
1946 break;
1947
1948 // expression operations on number
1949 case ISN_OPNR:
1950 case ISN_OPFLOAT:
1951 case ISN_OPANY:
1952 {
1953 char *what;
1954 char *ins;
1955
1956 switch (iptr->isn_arg.op.op_type)
1957 {
1958 case EXPR_MULT: what = "*"; break;
1959 case EXPR_DIV: what = "/"; break;
1960 case EXPR_REM: what = "%"; break;
1961 case EXPR_SUB: what = "-"; break;
1962 case EXPR_ADD: what = "+"; break;
1963 default: what = "???"; break;
1964 }
1965 switch (iptr->isn_type)
1966 {
1967 case ISN_OPNR: ins = "OPNR"; break;
1968 case ISN_OPFLOAT: ins = "OPFLOAT"; break;
1969 case ISN_OPANY: ins = "OPANY"; break;
1970 default: ins = "???"; break;
1971 }
1972 smsg("%4d %s %s", current, ins, what);
1973 }
1974 break;
1975
1976 case ISN_COMPAREBOOL:
1977 case ISN_COMPARESPECIAL:
1978 case ISN_COMPARENR:
1979 case ISN_COMPAREFLOAT:
1980 case ISN_COMPARESTRING:
1981 case ISN_COMPAREBLOB:
1982 case ISN_COMPARELIST:
1983 case ISN_COMPAREDICT:
1984 case ISN_COMPAREFUNC:
1985 case ISN_COMPAREPARTIAL:
1986 case ISN_COMPAREANY:
1987 {
1988 char *p;
1989 char buf[10];
1990 char *type;
1991
1992 switch (iptr->isn_arg.op.op_type)
1993 {
1994 case EXPR_EQUAL: p = "=="; break;
1995 case EXPR_NEQUAL: p = "!="; break;
1996 case EXPR_GREATER: p = ">"; break;
1997 case EXPR_GEQUAL: p = ">="; break;
1998 case EXPR_SMALLER: p = "<"; break;
1999 case EXPR_SEQUAL: p = "<="; break;
2000 case EXPR_MATCH: p = "=~"; break;
2001 case EXPR_IS: p = "is"; break;
2002 case EXPR_ISNOT: p = "isnot"; break;
2003 case EXPR_NOMATCH: p = "!~"; break;
2004 default: p = "???"; break;
2005 }
2006 STRCPY(buf, p);
2007 if (iptr->isn_arg.op.op_ic == TRUE)
2008 strcat(buf, "?");
2009 switch(iptr->isn_type)
2010 {
2011 case ISN_COMPAREBOOL: type = "COMPAREBOOL"; break;
2012 case ISN_COMPARESPECIAL:
2013 type = "COMPARESPECIAL"; break;
2014 case ISN_COMPARENR: type = "COMPARENR"; break;
2015 case ISN_COMPAREFLOAT: type = "COMPAREFLOAT"; break;
2016 case ISN_COMPARESTRING:
2017 type = "COMPARESTRING"; break;
2018 case ISN_COMPAREBLOB: type = "COMPAREBLOB"; break;
2019 case ISN_COMPARELIST: type = "COMPARELIST"; break;
2020 case ISN_COMPAREDICT: type = "COMPAREDICT"; break;
2021 case ISN_COMPAREFUNC: type = "COMPAREFUNC"; break;
2022 case ISN_COMPAREPARTIAL:
2023 type = "COMPAREPARTIAL"; break;
2024 case ISN_COMPAREANY: type = "COMPAREANY"; break;
2025 default: type = "???"; break;
2026 }
2027
2028 smsg("%4d %s %s", current, type, buf);
2029 }
2030 break;
2031
2032 case ISN_ADDLIST: smsg("%4d ADDLIST", current); break;
2033 case ISN_ADDBLOB: smsg("%4d ADDBLOB", current); break;
2034
2035 // expression operations
2036 case ISN_CONCAT: smsg("%4d CONCAT", current); break;
2037 case ISN_INDEX: smsg("%4d INDEX", current); break;
2038 case ISN_MEMBER: smsg("%4d MEMBER %s", current,
2039 iptr->isn_arg.string); break;
2040 case ISN_NEGATENR: smsg("%4d NEGATENR", current); break;
2041
2042 case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
2043 case ISN_CHECKTYPE: smsg("%4d CHECKTYPE %s stack[%d]", current,
2044 vartype_name(iptr->isn_arg.type.ct_type),
2045 iptr->isn_arg.type.ct_off);
2046 break;
2047 case ISN_2BOOL: if (iptr->isn_arg.number)
2048 smsg("%4d INVERT (!val)", current);
2049 else
2050 smsg("%4d 2BOOL (!!val)", current);
2051 break;
2052 case ISN_2STRING: smsg("%4d 2STRING stack[%d]", current,
2053 iptr->isn_arg.number);
2054 break;
2055
2056 case ISN_DROP: smsg("%4d DROP", current); break;
2057 }
2058 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01002059}
2060
2061/*
2062 * Return TRUE when "tv" is not falsey: non-zero, non-empty string, non-empty
2063 * list, etc. Mostly like what JavaScript does, except that empty list and
2064 * empty dictionary are FALSE.
2065 */
2066 int
2067tv2bool(typval_T *tv)
2068{
2069 switch (tv->v_type)
2070 {
2071 case VAR_NUMBER:
2072 return tv->vval.v_number != 0;
2073 case VAR_FLOAT:
2074#ifdef FEAT_FLOAT
2075 return tv->vval.v_float != 0.0;
2076#else
2077 break;
2078#endif
2079 case VAR_PARTIAL:
2080 return tv->vval.v_partial != NULL;
2081 case VAR_FUNC:
2082 case VAR_STRING:
2083 return tv->vval.v_string != NULL && *tv->vval.v_string != NUL;
2084 case VAR_LIST:
2085 return tv->vval.v_list != NULL && tv->vval.v_list->lv_len > 0;
2086 case VAR_DICT:
2087 return tv->vval.v_dict != NULL
2088 && tv->vval.v_dict->dv_hashtab.ht_used > 0;
2089 case VAR_BOOL:
2090 case VAR_SPECIAL:
2091 return tv->vval.v_number == VVAL_TRUE ? TRUE : FALSE;
2092 case VAR_JOB:
2093#ifdef FEAT_JOB_CHANNEL
2094 return tv->vval.v_job != NULL;
2095#else
2096 break;
2097#endif
2098 case VAR_CHANNEL:
2099#ifdef FEAT_JOB_CHANNEL
2100 return tv->vval.v_channel != NULL;
2101#else
2102 break;
2103#endif
2104 case VAR_BLOB:
2105 return tv->vval.v_blob != NULL && tv->vval.v_blob->bv_ga.ga_len > 0;
2106 case VAR_UNKNOWN:
2107 case VAR_VOID:
2108 break;
2109 }
2110 return FALSE;
2111}
2112
2113/*
2114 * If "tv" is a string give an error and return FAIL.
2115 */
2116 int
2117check_not_string(typval_T *tv)
2118{
2119 if (tv->v_type == VAR_STRING)
2120 {
2121 emsg(_("E1030: Using a String as a Number"));
2122 clear_tv(tv);
2123 return FAIL;
2124 }
2125 return OK;
2126}
2127
2128
2129#endif // FEAT_EVAL