blob: 6865ba1e24acb3a23807c815e7f0f93fdbe8763c [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/*
73 * Return the number of arguments, including any vararg.
74 */
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/*
82 * Call compiled function "cdf_idx" from compiled code.
83 *
84 * Stack has:
85 * - current arguments (already there)
86 * - omitted optional argument (default values) added here
87 * - stack frame:
88 * - pointer to calling function
89 * - Index of next instruction in calling function
90 * - previous frame pointer
91 * - reserved space for local variables
92 */
93 static int
94call_dfunc(int cdf_idx, int argcount, ectx_T *ectx)
95{
96 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
97 ufunc_T *ufunc = dfunc->df_ufunc;
98 int optcount = ufunc_argcount(ufunc) - argcount;
99 int idx;
100
101 if (dfunc->df_deleted)
102 {
103 emsg_funcname(e_func_deleted, ufunc->uf_name);
104 return FAIL;
105 }
106
107 if (ga_grow(&ectx->ec_stack, optcount + 3 + dfunc->df_varcount) == FAIL)
108 return FAIL;
109
110// TODO: Put omitted argument default values on the stack.
111 if (optcount > 0)
112 {
113 emsg("optional arguments not implemented yet");
114 return FAIL;
115 }
116 if (optcount < 0)
117 {
118 emsg("argument count wrong?");
119 return FAIL;
120 }
121// for (idx = argcount - dfunc->df_minarg;
122// idx < dfunc->df_maxarg; ++idx)
123// {
124// copy_tv(&dfunc->df_defarg[idx], STACK_TV_BOT(0));
125// ++ectx->ec_stack.ga_len;
126// }
127
128 // Store current execution state in stack frame for ISN_RETURN.
129 // TODO: If the actual number of arguments doesn't match what the called
130 // function expects things go bad.
131 STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
132 STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
133 STACK_TV_BOT(2)->vval.v_number = ectx->ec_frame;
134 ectx->ec_frame = ectx->ec_stack.ga_len;
135
136 // Initialize local variables
137 for (idx = 0; idx < dfunc->df_varcount; ++idx)
138 STACK_TV_BOT(STACK_FRAME_SIZE + idx)->v_type = VAR_UNKNOWN;
139 ectx->ec_stack.ga_len += STACK_FRAME_SIZE + dfunc->df_varcount;
140
141 // Set execution state to the start of the called function.
142 ectx->ec_dfunc_idx = cdf_idx;
143 ectx->ec_instr = dfunc->df_instr;
144 estack_push_ufunc(ETYPE_UFUNC, dfunc->df_ufunc, 1);
145 ectx->ec_iidx = 0;
146
147 return OK;
148}
149
150// Get pointer to item in the stack.
151#define STACK_TV(idx) (((typval_T *)ectx->ec_stack.ga_data) + idx)
152
153/*
154 * Return from the current function.
155 */
156 static void
157func_return(ectx_T *ectx)
158{
159 int ret_idx = ectx->ec_stack.ga_len - 1;
160 int idx;
161 dfunc_T *dfunc;
162
163 // execution context goes one level up
164 estack_pop();
165
166 // Clear the local variables and temporary values, but not
167 // the return value.
168 for (idx = ectx->ec_frame + STACK_FRAME_SIZE;
169 idx < ectx->ec_stack.ga_len - 1; ++idx)
170 clear_tv(STACK_TV(idx));
171 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
172 ectx->ec_stack.ga_len = ectx->ec_frame
173 - ufunc_argcount(dfunc->df_ufunc) + 1;
174 ectx->ec_dfunc_idx = STACK_TV(ectx->ec_frame)->vval.v_number;
175 ectx->ec_iidx = STACK_TV(ectx->ec_frame + 1)->vval.v_number;
176 ectx->ec_frame = STACK_TV(ectx->ec_frame + 2)->vval.v_number;
177 *STACK_TV_BOT(-1) = *STACK_TV(ret_idx);
178 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
179 ectx->ec_instr = dfunc->df_instr;
180}
181
182#undef STACK_TV
183
184/*
185 * Prepare arguments and rettv for calling a builtin or user function.
186 */
187 static int
188call_prepare(int argcount, typval_T *argvars, ectx_T *ectx)
189{
190 int idx;
191 typval_T *tv;
192
193 // Move arguments from bottom of the stack to argvars[] and add terminator.
194 for (idx = 0; idx < argcount; ++idx)
195 argvars[idx] = *STACK_TV_BOT(idx - argcount);
196 argvars[argcount].v_type = VAR_UNKNOWN;
197
198 // Result replaces the arguments on the stack.
199 if (argcount > 0)
200 ectx->ec_stack.ga_len -= argcount - 1;
201 else if (ga_grow(&ectx->ec_stack, 1) == FAIL)
202 return FAIL;
203 else
204 ++ectx->ec_stack.ga_len;
205
206 // Default return value is zero.
207 tv = STACK_TV_BOT(-1);
208 tv->v_type = VAR_NUMBER;
209 tv->vval.v_number = 0;
210
211 return OK;
212}
213
214/*
215 * Call a builtin function by index.
216 */
217 static int
218call_bfunc(int func_idx, int argcount, ectx_T *ectx)
219{
220 typval_T argvars[MAX_FUNC_ARGS];
221 int idx;
222
223 if (call_prepare(argcount, argvars, ectx) == FAIL)
224 return FAIL;
225
226 // Call the builtin function.
227 call_internal_func_by_idx(func_idx, argvars, STACK_TV_BOT(-1));
228
229 // Clear the arguments.
230 for (idx = 0; idx < argcount; ++idx)
231 clear_tv(&argvars[idx]);
232 return OK;
233}
234
235/*
236 * Execute a user defined function.
237 */
238 static int
239call_ufunc(ufunc_T *ufunc, int argcount, ectx_T *ectx)
240{
241 typval_T argvars[MAX_FUNC_ARGS];
242 funcexe_T funcexe;
243 int error;
244 int idx;
245
246 if (ufunc->uf_dfunc_idx >= 0)
247 // The function has been compiled, can call it quickly.
248 return call_dfunc(ufunc->uf_dfunc_idx, argcount, ectx);
249
250 if (call_prepare(argcount, argvars, ectx) == FAIL)
251 return FAIL;
252 vim_memset(&funcexe, 0, sizeof(funcexe));
253 funcexe.evaluate = TRUE;
254
255 // Call the user function. Result goes in last position on the stack.
256 // TODO: add selfdict if there is one
257 error = call_user_func_check(ufunc, argcount, argvars,
258 STACK_TV_BOT(-1), &funcexe, NULL);
259
260 // Clear the arguments.
261 for (idx = 0; idx < argcount; ++idx)
262 clear_tv(&argvars[idx]);
263
264 if (error != FCERR_NONE)
265 {
266 user_func_error(error, ufunc->uf_name);
267 return FAIL;
268 }
269 return OK;
270}
271
272/*
273 * Execute a function by "name".
274 * This can be a builtin function or a user function.
275 * Returns FAIL if not found without an error message.
276 */
277 static int
278call_by_name(char_u *name, int argcount, ectx_T *ectx)
279{
280 ufunc_T *ufunc;
281
282 if (builtin_function(name, -1))
283 {
284 int func_idx = find_internal_func(name);
285
286 if (func_idx < 0)
287 return FAIL;
288 if (check_internal_func(func_idx, argcount) == FAIL)
289 return FAIL;
290 return call_bfunc(func_idx, argcount, ectx);
291 }
292
293 ufunc = find_func(name, NULL);
294 if (ufunc != NULL)
295 return call_ufunc(ufunc, argcount, ectx);
296
297 return FAIL;
298}
299
300 static int
301call_partial(typval_T *tv, int argcount, ectx_T *ectx)
302{
303 char_u *name;
304 int called_emsg_before = called_emsg;
305
306 if (tv->v_type == VAR_PARTIAL)
307 {
308 partial_T *pt = tv->vval.v_partial;
309
310 if (pt->pt_func != NULL)
311 return call_ufunc(pt->pt_func, argcount, ectx);
312 name = pt->pt_name;
313 }
314 else
315 name = tv->vval.v_string;
316 if (call_by_name(name, argcount, ectx) == FAIL)
317 {
318 if (called_emsg == called_emsg_before)
319 semsg(_(e_unknownfunc), name);
320 return FAIL;
321 }
322 return OK;
323}
324
325/*
326 * Execute a function by "name".
327 * This can be a builtin function, user function or a funcref.
328 */
329 static int
330call_eval_func(char_u *name, int argcount, ectx_T *ectx)
331{
332 int called_emsg_before = called_emsg;
333
334 if (call_by_name(name, argcount, ectx) == FAIL
335 && called_emsg == called_emsg_before)
336 {
337 // "name" may be a variable that is a funcref or partial
338 // if find variable
339 // call_partial()
340 // else
341 // semsg(_(e_unknownfunc), name);
342 emsg("call_eval_func(partial) not implemented yet");
343 return FAIL;
344 }
345 return OK;
346}
347
348/*
349 * Call a "def" function from old Vim script.
350 * Return OK or FAIL.
351 */
352 int
353call_def_function(
354 ufunc_T *ufunc,
355 int argc, // nr of arguments
356 typval_T *argv, // arguments
357 typval_T *rettv) // return value
358{
359 ectx_T ectx; // execution context
360 int initial_frame_ptr;
361 typval_T *tv;
362 int idx;
363 int ret = FAIL;
364 dfunc_T *dfunc;
365
366// Get pointer to item in the stack.
367#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
368
369// Get pointer to item at the bottom of the stack, -1 is the bottom.
370#undef STACK_TV_BOT
371#define STACK_TV_BOT(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_stack.ga_len + idx)
372
373// Get pointer to local variable on the stack.
374#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame + STACK_FRAME_SIZE + idx)
375
376 vim_memset(&ectx, 0, sizeof(ectx));
377 ga_init2(&ectx.ec_stack, sizeof(typval_T), 500);
378 if (ga_grow(&ectx.ec_stack, 20) == FAIL)
379 goto failed;
380 ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx;
381
382 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
383
384 // Put arguments on the stack.
385 for (idx = 0; idx < argc; ++idx)
386 {
387 copy_tv(&argv[idx], STACK_TV_BOT(0));
388 ++ectx.ec_stack.ga_len;
389 }
390
391 // Frame pointer points to just after arguments.
392 ectx.ec_frame = ectx.ec_stack.ga_len;
393 initial_frame_ptr = ectx.ec_frame;
394
395 // dummy frame entries
396 for (idx = 0; idx < STACK_FRAME_SIZE; ++idx)
397 {
398 STACK_TV(ectx.ec_stack.ga_len)->v_type = VAR_UNKNOWN;
399 ++ectx.ec_stack.ga_len;
400 }
401
402 // Reserve space for local variables.
403 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
404 for (idx = 0; idx < dfunc->df_varcount; ++idx)
405 STACK_TV_VAR(idx)->v_type = VAR_UNKNOWN;
406 ectx.ec_stack.ga_len += dfunc->df_varcount;
407
408 ectx.ec_instr = dfunc->df_instr;
409 ectx.ec_iidx = 0;
410 for (;;)
411 {
412 isn_T *iptr;
413 trycmd_T *trycmd = NULL;
414
415 if (did_throw && !ectx.ec_in_catch)
416 {
417 garray_T *trystack = &ectx.ec_trystack;
418
419 // An exception jumps to the first catch, finally, or returns from
420 // the current function.
421 if (trystack->ga_len > 0)
422 trycmd = ((trycmd_T *)trystack->ga_data) + trystack->ga_len - 1;
423 if (trycmd != NULL && trycmd->tcd_frame == ectx.ec_frame)
424 {
425 // jump to ":catch" or ":finally"
426 ectx.ec_in_catch = TRUE;
427 ectx.ec_iidx = trycmd->tcd_catch_idx;
428 }
429 else
430 {
431 // not inside try or need to return from current functions.
432 if (ectx.ec_frame == initial_frame_ptr)
433 {
434 // At the toplevel we are done. Push a dummy return value.
435 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
436 goto failed;
437 tv = STACK_TV_BOT(0);
438 tv->v_type = VAR_NUMBER;
439 tv->vval.v_number = 0;
440 ++ectx.ec_stack.ga_len;
441 goto done;
442 }
443
444 func_return(&ectx);
445 }
446 continue;
447 }
448
449 iptr = &ectx.ec_instr[ectx.ec_iidx++];
450 switch (iptr->isn_type)
451 {
452 // execute Ex command line
453 case ISN_EXEC:
454 do_cmdline_cmd(iptr->isn_arg.string);
455 break;
456
457 // execute :echo {string} ...
458 case ISN_ECHO:
459 {
460 int count = iptr->isn_arg.echo.echo_count;
461 int atstart = TRUE;
462 int needclr = TRUE;
463
464 for (idx = 0; idx < count; ++idx)
465 {
466 tv = STACK_TV_BOT(idx - count);
467 echo_one(tv, iptr->isn_arg.echo.echo_with_white,
468 &atstart, &needclr);
469 clear_tv(tv);
470 }
471 ectx.ec_stack.ga_len -= count;
472 }
473 break;
474
475 // load local variable or argument
476 case ISN_LOAD:
477 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
478 goto failed;
479 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0));
480 ++ectx.ec_stack.ga_len;
481 break;
482
483 // load v: variable
484 case ISN_LOADV:
485 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
486 goto failed;
487 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0));
488 ++ectx.ec_stack.ga_len;
489 break;
490
491 // load s: variable in vim9script
492 case ISN_LOADSCRIPT:
493 {
494 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +0100495 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100496 svar_T *sv;
497
498 sv = ((svar_T *)si->sn_var_vals.ga_data)
499 + iptr->isn_arg.script.script_idx;
500 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
501 goto failed;
502 copy_tv(sv->sv_tv, STACK_TV_BOT(0));
503 ++ectx.ec_stack.ga_len;
504 }
505 break;
506
507 // load s: variable in old script
508 case ISN_LOADS:
509 {
510 hashtab_T *ht = &SCRIPT_VARS(iptr->isn_arg.loads.ls_sid);
511 char_u *name = iptr->isn_arg.loads.ls_name;
512 dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE);
513 if (di == NULL)
514 {
515 semsg(_("E121: Undefined variable: s:%s"), name);
516 goto failed;
517 }
518 else
519 {
520 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
521 goto failed;
522 copy_tv(&di->di_tv, STACK_TV_BOT(0));
523 ++ectx.ec_stack.ga_len;
524 }
525 }
526 break;
527
528 // load g: variable
529 case ISN_LOADG:
530 {
531 dictitem_T *di;
532
533 di = find_var_in_ht(get_globvar_ht(), 0,
534 iptr->isn_arg.string, TRUE);
535 if (di == NULL)
536 {
537 semsg(_("E121: Undefined variable: g:%s"),
538 iptr->isn_arg.string);
539 goto failed;
540 }
541 else
542 {
543 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
544 goto failed;
545 copy_tv(&di->di_tv, STACK_TV_BOT(0));
546 ++ectx.ec_stack.ga_len;
547 }
548 }
549 break;
550
551 // load &option
552 case ISN_LOADOPT:
553 {
554 typval_T optval;
555 char_u *name = iptr->isn_arg.string;
556
557 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
558 goto failed;
Bram Moolenaar58ceca52020-01-28 22:46:22 +0100559 if (get_option_tv(&name, &optval, TRUE) == FAIL)
560 goto failed;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100561 *STACK_TV_BOT(0) = optval;
562 ++ectx.ec_stack.ga_len;
563 }
564 break;
565
566 // load $ENV
567 case ISN_LOADENV:
568 {
569 typval_T optval;
570 char_u *name = iptr->isn_arg.string;
571
572 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
573 goto failed;
Bram Moolenaar07da94b2020-01-28 22:39:19 +0100574 if (get_env_tv(&name, &optval, TRUE) == FAIL)
575 {
576 semsg(_("E1060: Invalid environment variable name: %s"),
577 iptr->isn_arg.string);
578 goto failed;
579 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100580 *STACK_TV_BOT(0) = optval;
581 ++ectx.ec_stack.ga_len;
582 }
583 break;
584
585 // load @register
586 case ISN_LOADREG:
587 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
588 goto failed;
589 tv = STACK_TV_BOT(0);
590 tv->v_type = VAR_STRING;
591 tv->vval.v_string = get_reg_contents(
592 iptr->isn_arg.number, GREG_EXPR_SRC);
593 ++ectx.ec_stack.ga_len;
594 break;
595
596 // store local variable
597 case ISN_STORE:
598 --ectx.ec_stack.ga_len;
599 tv = STACK_TV_VAR(iptr->isn_arg.number);
600 clear_tv(tv);
601 *tv = *STACK_TV_BOT(0);
602 break;
603
604 // store script-local variable
605 case ISN_STORESCRIPT:
606 {
Bram Moolenaar21b9e972020-01-26 19:26:46 +0100607 scriptitem_T *si = SCRIPT_ITEM(
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100608 iptr->isn_arg.script.script_sid);
609 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
610 + iptr->isn_arg.script.script_idx;
611
612 --ectx.ec_stack.ga_len;
613 clear_tv(sv->sv_tv);
614 *sv->sv_tv = *STACK_TV_BOT(0);
615 }
616 break;
617
618 // store option
619 case ISN_STOREOPT:
620 {
621 long n = 0;
622 char_u *s = NULL;
623 char *msg;
624
625 --ectx.ec_stack.ga_len;
626 tv = STACK_TV_BOT(0);
627 if (tv->v_type == VAR_STRING)
628 s = tv->vval.v_string;
629 else if (tv->v_type == VAR_NUMBER)
630 n = tv->vval.v_number;
631 else
632 {
633 emsg(_("E1051: Expected string or number"));
634 goto failed;
635 }
636 msg = set_option_value(iptr->isn_arg.storeopt.so_name,
637 n, s, iptr->isn_arg.storeopt.so_flags);
638 if (msg != NULL)
639 {
640 emsg(_(msg));
641 goto failed;
642 }
643 clear_tv(tv);
644 }
645 break;
646
647 // store g: variable
648 case ISN_STOREG:
649 {
650 dictitem_T *di;
651
652 --ectx.ec_stack.ga_len;
653 di = find_var_in_ht(get_globvar_ht(), 0,
654 iptr->isn_arg.string, TRUE);
655 if (di == NULL)
656 {
657 funccal_entry_T entry;
658
659 save_funccal(&entry);
660 set_var_const(iptr->isn_arg.string, NULL,
661 STACK_TV_BOT(0), FALSE, 0);
662 restore_funccal();
663 }
664 else
665 {
666 clear_tv(&di->di_tv);
667 di->di_tv = *STACK_TV_BOT(0);
668 }
669 }
670 break;
671
672 // store number in local variable
673 case ISN_STORENR:
674 tv = STACK_TV_VAR(iptr->isn_arg.storenr.str_idx);
675 clear_tv(tv);
676 tv->v_type = VAR_NUMBER;
677 tv->vval.v_number = iptr->isn_arg.storenr.str_val;
678 break;
679
680 // push constant
681 case ISN_PUSHNR:
682 case ISN_PUSHBOOL:
683 case ISN_PUSHSPEC:
684 case ISN_PUSHF:
685 case ISN_PUSHS:
686 case ISN_PUSHBLOB:
687 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
688 goto failed;
689 tv = STACK_TV_BOT(0);
690 ++ectx.ec_stack.ga_len;
691 switch (iptr->isn_type)
692 {
693 case ISN_PUSHNR:
694 tv->v_type = VAR_NUMBER;
695 tv->vval.v_number = iptr->isn_arg.number;
696 break;
697 case ISN_PUSHBOOL:
698 tv->v_type = VAR_BOOL;
699 tv->vval.v_number = iptr->isn_arg.number;
700 break;
701 case ISN_PUSHSPEC:
702 tv->v_type = VAR_SPECIAL;
703 tv->vval.v_number = iptr->isn_arg.number;
704 break;
705#ifdef FEAT_FLOAT
706 case ISN_PUSHF:
707 tv->v_type = VAR_FLOAT;
708 tv->vval.v_float = iptr->isn_arg.fnumber;
709 break;
710#endif
711 case ISN_PUSHBLOB:
712 blob_copy(iptr->isn_arg.blob, tv);
713 break;
714 default:
715 tv->v_type = VAR_STRING;
716 tv->vval.v_string = vim_strsave(iptr->isn_arg.string);
717 }
718 break;
719
720 // create a list from items on the stack; uses a single allocation
721 // for the list header and the items
722 case ISN_NEWLIST:
723 {
724 int count = iptr->isn_arg.number;
725 list_T *list = list_alloc_with_items(count);
726
727 if (list == NULL)
728 goto failed;
729 for (idx = 0; idx < count; ++idx)
730 list_set_item(list, idx, STACK_TV_BOT(idx - count));
731
732 if (count > 0)
733 ectx.ec_stack.ga_len -= count - 1;
734 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
735 goto failed;
736 else
737 ++ectx.ec_stack.ga_len;
738 tv = STACK_TV_BOT(-1);
739 tv->v_type = VAR_LIST;
740 tv->vval.v_list = list;
741 ++list->lv_refcount;
742 }
743 break;
744
745 // create a dict from items on the stack
746 case ISN_NEWDICT:
747 {
748 int count = iptr->isn_arg.number;
749 dict_T *dict = dict_alloc();
750 dictitem_T *item;
751
752 if (dict == NULL)
753 goto failed;
754 for (idx = 0; idx < count; ++idx)
755 {
756 // check key type is VAR_STRING
757 tv = STACK_TV_BOT(2 * (idx - count));
758 item = dictitem_alloc(tv->vval.v_string);
759 clear_tv(tv);
760 if (item == NULL)
761 goto failed;
762 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
763 item->di_tv.v_lock = 0;
764 if (dict_add(dict, item) == FAIL)
765 goto failed;
766 }
767
768 if (count > 0)
769 ectx.ec_stack.ga_len -= 2 * count - 1;
770 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
771 goto failed;
772 else
773 ++ectx.ec_stack.ga_len;
774 tv = STACK_TV_BOT(-1);
775 tv->v_type = VAR_DICT;
776 tv->vval.v_dict = dict;
777 ++dict->dv_refcount;
778 }
779 break;
780
781 // call a :def function
782 case ISN_DCALL:
783 if (call_dfunc(iptr->isn_arg.dfunc.cdf_idx,
784 iptr->isn_arg.dfunc.cdf_argcount,
785 &ectx) == FAIL)
786 goto failed;
787 break;
788
789 // call a builtin function
790 case ISN_BCALL:
791 SOURCING_LNUM = iptr->isn_lnum;
792 if (call_bfunc(iptr->isn_arg.bfunc.cbf_idx,
793 iptr->isn_arg.bfunc.cbf_argcount,
794 &ectx) == FAIL)
795 goto failed;
796 break;
797
798 // call a funcref or partial
799 case ISN_PCALL:
800 {
801 cpfunc_T *pfunc = &iptr->isn_arg.pfunc;
802 int r;
803 typval_T partial;
804
805 SOURCING_LNUM = iptr->isn_lnum;
806 if (pfunc->cpf_top)
807 {
808 // funcref is above the arguments
809 tv = STACK_TV_BOT(-pfunc->cpf_argcount - 1);
810 }
811 else
812 {
813 // Get the funcref from the stack.
814 --ectx.ec_stack.ga_len;
815 partial = *STACK_TV_BOT(0);
816 tv = &partial;
817 }
818 r = call_partial(tv, pfunc->cpf_argcount, &ectx);
819 if (tv == &partial)
820 clear_tv(&partial);
821 if (r == FAIL)
822 goto failed;
823
824 if (pfunc->cpf_top)
825 {
826 // Get the funcref from the stack, overwrite with the
827 // return value.
828 clear_tv(tv);
829 --ectx.ec_stack.ga_len;
830 *STACK_TV_BOT(-1) = *STACK_TV_BOT(0);
831 }
832 }
833 break;
834
835 // call a user defined function or funcref/partial
836 case ISN_UCALL:
837 {
838 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
839
840 SOURCING_LNUM = iptr->isn_lnum;
841 if (call_eval_func(cufunc->cuf_name,
842 cufunc->cuf_argcount, &ectx) == FAIL)
843 goto failed;
844 }
845 break;
846
847 // return from a :def function call
848 case ISN_RETURN:
849 {
850 if (trycmd != NULL && trycmd->tcd_frame == ectx.ec_frame
851 && trycmd->tcd_finally_idx != 0)
852 {
853 // jump to ":finally"
854 ectx.ec_iidx = trycmd->tcd_finally_idx;
855 trycmd->tcd_return = TRUE;
856 }
857 else
858 {
859 // Restore previous function. If the frame pointer
860 // is zero then there is none and we are done.
861 if (ectx.ec_frame == initial_frame_ptr)
862 goto done;
863
864 func_return(&ectx);
865 }
866 }
867 break;
868
869 // push a function reference to a compiled function
870 case ISN_FUNCREF:
871 {
872 partial_T *pt = NULL;
873
874 pt = ALLOC_CLEAR_ONE(partial_T);
875 if (pt == NULL)
876 goto failed;
877 dfunc = ((dfunc_T *)def_functions.ga_data)
878 + iptr->isn_arg.number;
879 pt->pt_func = dfunc->df_ufunc;
880 pt->pt_refcount = 1;
881 ++dfunc->df_ufunc->uf_refcount;
882
883 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
884 goto failed;
885 tv = STACK_TV_BOT(0);
886 ++ectx.ec_stack.ga_len;
887 tv->vval.v_partial = pt;
888 tv->v_type = VAR_PARTIAL;
889 }
890 break;
891
892 // jump if a condition is met
893 case ISN_JUMP:
894 {
895 jumpwhen_T when = iptr->isn_arg.jump.jump_when;
896 int jump = TRUE;
897
898 if (when != JUMP_ALWAYS)
899 {
900 tv = STACK_TV_BOT(-1);
901 jump = tv2bool(tv);
902 if (when == JUMP_IF_FALSE
903 || when == JUMP_AND_KEEP_IF_FALSE)
904 jump = !jump;
905 if (when == JUMP_IF_FALSE || when == JUMP_IF_TRUE
906 || !jump)
907 {
908 // drop the value from the stack
909 clear_tv(tv);
910 --ectx.ec_stack.ga_len;
911 }
912 }
913 if (jump)
914 ectx.ec_iidx = iptr->isn_arg.jump.jump_where;
915 }
916 break;
917
918 // top of a for loop
919 case ISN_FOR:
920 {
921 list_T *list = STACK_TV_BOT(-1)->vval.v_list;
922 typval_T *idxtv =
923 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx);
924
925 // push the next item from the list
926 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
927 goto failed;
928 if (++idxtv->vval.v_number >= list->lv_len)
929 // past the end of the list, jump to "endfor"
930 ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
931 else if (list->lv_first == &range_list_item)
932 {
933 // non-materialized range() list
934 tv = STACK_TV_BOT(0);
935 tv->v_type = VAR_NUMBER;
936 tv->vval.v_number = list_find_nr(
937 list, idxtv->vval.v_number, NULL);
938 ++ectx.ec_stack.ga_len;
939 }
940 else
941 {
942 listitem_T *li = list_find(list, idxtv->vval.v_number);
943
944 if (li == NULL)
945 goto failed;
946 copy_tv(&li->li_tv, STACK_TV_BOT(0));
947 ++ectx.ec_stack.ga_len;
948 }
949 }
950 break;
951
952 // start of ":try" block
953 case ISN_TRY:
954 {
955 if (ga_grow(&ectx.ec_trystack, 1) == FAIL)
956 goto failed;
957 trycmd = ((trycmd_T *)ectx.ec_trystack.ga_data)
958 + ectx.ec_trystack.ga_len;
959 ++ectx.ec_trystack.ga_len;
960 ++trylevel;
961 trycmd->tcd_frame = ectx.ec_frame;
962 trycmd->tcd_catch_idx = iptr->isn_arg.try.try_catch;
963 trycmd->tcd_finally_idx = iptr->isn_arg.try.try_finally;
964 }
965 break;
966
967 case ISN_PUSHEXC:
968 if (current_exception == NULL)
969 {
970 iemsg("Evaluating catch while current_exception is NULL");
971 goto failed;
972 }
973 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
974 goto failed;
975 tv = STACK_TV_BOT(0);
976 ++ectx.ec_stack.ga_len;
977 tv->v_type = VAR_STRING;
978 tv->vval.v_string = vim_strsave(
979 (char_u *)current_exception->value);
980 break;
981
982 case ISN_CATCH:
983 {
984 garray_T *trystack = &ectx.ec_trystack;
985
986 if (trystack->ga_len > 0)
987 {
988 trycmd = ((trycmd_T *)trystack->ga_data)
989 + trystack->ga_len - 1;
990 trycmd->tcd_caught = TRUE;
991 }
992 did_emsg = got_int = did_throw = FALSE;
993 catch_exception(current_exception);
994 }
995 break;
996
997 // end of ":try" block
998 case ISN_ENDTRY:
999 {
1000 garray_T *trystack = &ectx.ec_trystack;
1001
1002 if (trystack->ga_len > 0)
1003 {
1004 --trystack->ga_len;
1005 --trylevel;
1006 trycmd = ((trycmd_T *)trystack->ga_data)
1007 + trystack->ga_len;
1008 if (trycmd->tcd_caught)
1009 {
1010 // discard the exception
1011 if (caught_stack == current_exception)
1012 caught_stack = caught_stack->caught;
1013 discard_current_exception();
1014 }
1015
1016 if (trycmd->tcd_return)
1017 {
1018 // Restore previous function. If the frame pointer
1019 // is zero then there is none and we are done.
1020 if (ectx.ec_frame == initial_frame_ptr)
1021 goto done;
1022
1023 func_return(&ectx);
1024 }
1025 }
1026 }
1027 break;
1028
1029 case ISN_THROW:
1030 --ectx.ec_stack.ga_len;
1031 tv = STACK_TV_BOT(0);
1032 if (throw_exception(tv->vval.v_string, ET_USER, NULL) == FAIL)
1033 {
1034 vim_free(tv->vval.v_string);
1035 goto failed;
1036 }
1037 did_throw = TRUE;
1038 break;
1039
1040 // compare with special values
1041 case ISN_COMPAREBOOL:
1042 case ISN_COMPARESPECIAL:
1043 {
1044 typval_T *tv1 = STACK_TV_BOT(-2);
1045 typval_T *tv2 = STACK_TV_BOT(-1);
1046 varnumber_T arg1 = tv1->vval.v_number;
1047 varnumber_T arg2 = tv2->vval.v_number;
1048 int res;
1049
1050 switch (iptr->isn_arg.op.op_type)
1051 {
1052 case EXPR_EQUAL: res = arg1 == arg2; break;
1053 case EXPR_NEQUAL: res = arg1 != arg2; break;
1054 default: res = 0; break;
1055 }
1056
1057 --ectx.ec_stack.ga_len;
1058 tv1->v_type = VAR_BOOL;
1059 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1060 }
1061 break;
1062
1063 // Operation with two number arguments
1064 case ISN_OPNR:
1065 case ISN_COMPARENR:
1066 {
1067 typval_T *tv1 = STACK_TV_BOT(-2);
1068 typval_T *tv2 = STACK_TV_BOT(-1);
1069 varnumber_T arg1 = tv1->vval.v_number;
1070 varnumber_T arg2 = tv2->vval.v_number;
1071 varnumber_T res;
1072
1073 switch (iptr->isn_arg.op.op_type)
1074 {
1075 case EXPR_MULT: res = arg1 * arg2; break;
1076 case EXPR_DIV: res = arg1 / arg2; break;
1077 case EXPR_REM: res = arg1 % arg2; break;
1078 case EXPR_SUB: res = arg1 - arg2; break;
1079 case EXPR_ADD: res = arg1 + arg2; break;
1080
1081 case EXPR_EQUAL: res = arg1 == arg2; break;
1082 case EXPR_NEQUAL: res = arg1 != arg2; break;
1083 case EXPR_GREATER: res = arg1 > arg2; break;
1084 case EXPR_GEQUAL: res = arg1 >= arg2; break;
1085 case EXPR_SMALLER: res = arg1 < arg2; break;
1086 case EXPR_SEQUAL: res = arg1 <= arg2; break;
1087 default: res = 0; break;
1088 }
1089
1090 --ectx.ec_stack.ga_len;
1091 if (iptr->isn_type == ISN_COMPARENR)
1092 {
1093 tv1->v_type = VAR_BOOL;
1094 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1095 }
1096 else
1097 tv1->vval.v_number = res;
1098 }
1099 break;
1100
1101 // Computation with two float arguments
1102 case ISN_OPFLOAT:
1103 case ISN_COMPAREFLOAT:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001104#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001105 {
1106 typval_T *tv1 = STACK_TV_BOT(-2);
1107 typval_T *tv2 = STACK_TV_BOT(-1);
1108 float_T arg1 = tv1->vval.v_float;
1109 float_T arg2 = tv2->vval.v_float;
1110 float_T res = 0;
1111 int cmp = FALSE;
1112
1113 switch (iptr->isn_arg.op.op_type)
1114 {
1115 case EXPR_MULT: res = arg1 * arg2; break;
1116 case EXPR_DIV: res = arg1 / arg2; break;
1117 case EXPR_SUB: res = arg1 - arg2; break;
1118 case EXPR_ADD: res = arg1 + arg2; break;
1119
1120 case EXPR_EQUAL: cmp = arg1 == arg2; break;
1121 case EXPR_NEQUAL: cmp = arg1 != arg2; break;
1122 case EXPR_GREATER: cmp = arg1 > arg2; break;
1123 case EXPR_GEQUAL: cmp = arg1 >= arg2; break;
1124 case EXPR_SMALLER: cmp = arg1 < arg2; break;
1125 case EXPR_SEQUAL: cmp = arg1 <= arg2; break;
1126 default: cmp = 0; break;
1127 }
1128 --ectx.ec_stack.ga_len;
1129 if (iptr->isn_type == ISN_COMPAREFLOAT)
1130 {
1131 tv1->v_type = VAR_BOOL;
1132 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1133 }
1134 else
1135 tv1->vval.v_float = res;
1136 }
Bram Moolenaara5d59532020-01-26 21:42:03 +01001137#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001138 break;
1139
1140 case ISN_COMPARELIST:
1141 {
1142 typval_T *tv1 = STACK_TV_BOT(-2);
1143 typval_T *tv2 = STACK_TV_BOT(-1);
1144 list_T *arg1 = tv1->vval.v_list;
1145 list_T *arg2 = tv2->vval.v_list;
1146 int cmp = FALSE;
1147 int ic = iptr->isn_arg.op.op_ic;
1148
1149 switch (iptr->isn_arg.op.op_type)
1150 {
1151 case EXPR_EQUAL: cmp =
1152 list_equal(arg1, arg2, ic, FALSE); break;
1153 case EXPR_NEQUAL: cmp =
1154 !list_equal(arg1, arg2, ic, FALSE); break;
1155 case EXPR_IS: cmp = arg1 == arg2; break;
1156 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1157 default: cmp = 0; break;
1158 }
1159 --ectx.ec_stack.ga_len;
1160 clear_tv(tv1);
1161 clear_tv(tv2);
1162 tv1->v_type = VAR_BOOL;
1163 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1164 }
1165 break;
1166
1167 case ISN_COMPAREBLOB:
1168 {
1169 typval_T *tv1 = STACK_TV_BOT(-2);
1170 typval_T *tv2 = STACK_TV_BOT(-1);
1171 blob_T *arg1 = tv1->vval.v_blob;
1172 blob_T *arg2 = tv2->vval.v_blob;
1173 int cmp = FALSE;
1174
1175 switch (iptr->isn_arg.op.op_type)
1176 {
1177 case EXPR_EQUAL: cmp = blob_equal(arg1, arg2); break;
1178 case EXPR_NEQUAL: cmp = !blob_equal(arg1, arg2); break;
1179 case EXPR_IS: cmp = arg1 == arg2; break;
1180 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1181 default: cmp = 0; break;
1182 }
1183 --ectx.ec_stack.ga_len;
1184 clear_tv(tv1);
1185 clear_tv(tv2);
1186 tv1->v_type = VAR_BOOL;
1187 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1188 }
1189 break;
1190
1191 // TODO: handle separately
1192 case ISN_COMPARESTRING:
1193 case ISN_COMPAREDICT:
1194 case ISN_COMPAREFUNC:
1195 case ISN_COMPAREPARTIAL:
1196 case ISN_COMPAREANY:
1197 {
1198 typval_T *tv1 = STACK_TV_BOT(-2);
1199 typval_T *tv2 = STACK_TV_BOT(-1);
1200 exptype_T exptype = iptr->isn_arg.op.op_type;
1201 int ic = iptr->isn_arg.op.op_ic;
1202
1203 typval_compare(tv1, tv2, exptype, ic);
1204 clear_tv(tv2);
1205 tv1->v_type = VAR_BOOL;
1206 tv1->vval.v_number = tv1->vval.v_number
1207 ? VVAL_TRUE : VVAL_FALSE;
1208 --ectx.ec_stack.ga_len;
1209 }
1210 break;
1211
1212 case ISN_ADDLIST:
1213 case ISN_ADDBLOB:
1214 {
1215 typval_T *tv1 = STACK_TV_BOT(-2);
1216 typval_T *tv2 = STACK_TV_BOT(-1);
1217
1218 if (iptr->isn_type == ISN_ADDLIST)
1219 eval_addlist(tv1, tv2);
1220 else
1221 eval_addblob(tv1, tv2);
1222 clear_tv(tv2);
1223 --ectx.ec_stack.ga_len;
1224 }
1225 break;
1226
1227 // Computation with two arguments of unknown type
1228 case ISN_OPANY:
1229 {
1230 typval_T *tv1 = STACK_TV_BOT(-2);
1231 typval_T *tv2 = STACK_TV_BOT(-1);
1232 varnumber_T n1, n2;
1233#ifdef FEAT_FLOAT
1234 float_T f1 = 0, f2 = 0;
1235#endif
1236 int error = FALSE;
1237
1238 if (iptr->isn_arg.op.op_type == EXPR_ADD)
1239 {
1240 if (tv1->v_type == VAR_LIST && tv2->v_type == VAR_LIST)
1241 {
1242 eval_addlist(tv1, tv2);
1243 clear_tv(tv2);
1244 --ectx.ec_stack.ga_len;
1245 break;
1246 }
1247 else if (tv1->v_type == VAR_BLOB
1248 && tv2->v_type == VAR_BLOB)
1249 {
1250 eval_addblob(tv1, tv2);
1251 clear_tv(tv2);
1252 --ectx.ec_stack.ga_len;
1253 break;
1254 }
1255 }
1256#ifdef FEAT_FLOAT
1257 if (tv1->v_type == VAR_FLOAT)
1258 {
1259 f1 = tv1->vval.v_float;
1260 n1 = 0;
1261 }
1262 else
1263#endif
1264 {
1265 n1 = tv_get_number_chk(tv1, &error);
1266 if (error)
1267 goto failed;
1268#ifdef FEAT_FLOAT
1269 if (tv2->v_type == VAR_FLOAT)
1270 f1 = n1;
1271#endif
1272 }
1273#ifdef FEAT_FLOAT
1274 if (tv2->v_type == VAR_FLOAT)
1275 {
1276 f2 = tv2->vval.v_float;
1277 n2 = 0;
1278 }
1279 else
1280#endif
1281 {
1282 n2 = tv_get_number_chk(tv2, &error);
1283 if (error)
1284 goto failed;
1285#ifdef FEAT_FLOAT
1286 if (tv1->v_type == VAR_FLOAT)
1287 f2 = n2;
1288#endif
1289 }
1290#ifdef FEAT_FLOAT
1291 // if there is a float on either side the result is a float
1292 if (tv1->v_type == VAR_FLOAT || tv2->v_type == VAR_FLOAT)
1293 {
1294 switch (iptr->isn_arg.op.op_type)
1295 {
1296 case EXPR_MULT: f1 = f1 * f2; break;
1297 case EXPR_DIV: f1 = f1 / f2; break;
1298 case EXPR_SUB: f1 = f1 - f2; break;
1299 case EXPR_ADD: f1 = f1 + f2; break;
1300 default: emsg(_(e_modulus)); goto failed;
1301 }
1302 clear_tv(tv1);
1303 clear_tv(tv2);
1304 tv1->v_type = VAR_FLOAT;
1305 tv1->vval.v_float = f1;
1306 --ectx.ec_stack.ga_len;
1307 }
1308 else
1309#endif
1310 {
1311 switch (iptr->isn_arg.op.op_type)
1312 {
1313 case EXPR_MULT: n1 = n1 * n2; break;
1314 case EXPR_DIV: n1 = num_divide(n1, n2); break;
1315 case EXPR_SUB: n1 = n1 - n2; break;
1316 case EXPR_ADD: n1 = n1 + n2; break;
1317 default: n1 = num_modulus(n1, n2); break;
1318 }
1319 clear_tv(tv1);
1320 clear_tv(tv2);
1321 tv1->v_type = VAR_NUMBER;
1322 tv1->vval.v_number = n1;
1323 --ectx.ec_stack.ga_len;
1324 }
1325 }
1326 break;
1327
1328 case ISN_CONCAT:
1329 {
1330 char_u *str1 = STACK_TV_BOT(-2)->vval.v_string;
1331 char_u *str2 = STACK_TV_BOT(-1)->vval.v_string;
1332 char_u *res;
1333
1334 res = concat_str(str1, str2);
1335 clear_tv(STACK_TV_BOT(-2));
1336 clear_tv(STACK_TV_BOT(-1));
1337 --ectx.ec_stack.ga_len;
1338 STACK_TV_BOT(-1)->vval.v_string = res;
1339 }
1340 break;
1341
1342 case ISN_INDEX:
1343 {
1344 list_T *list;
1345 varnumber_T n;
1346 listitem_T *li;
1347
1348 // list index: list is at stack-2, index at stack-1
1349 tv = STACK_TV_BOT(-2);
1350 if (tv->v_type != VAR_LIST)
1351 {
1352 emsg(_(e_listreq));
1353 goto failed;
1354 }
1355 list = tv->vval.v_list;
1356
1357 tv = STACK_TV_BOT(-1);
1358 if (tv->v_type != VAR_NUMBER)
1359 {
1360 emsg(_(e_number_exp));
1361 goto failed;
1362 }
1363 n = tv->vval.v_number;
1364 clear_tv(tv);
1365 if ((li = list_find(list, n)) == NULL)
1366 {
1367 semsg(_(e_listidx), n);
1368 goto failed;
1369 }
1370 --ectx.ec_stack.ga_len;
1371 clear_tv(STACK_TV_BOT(-1));
1372 copy_tv(&li->li_tv, STACK_TV_BOT(-1));
1373 }
1374 break;
1375
1376 // dict member with string key
1377 case ISN_MEMBER:
1378 {
1379 dict_T *dict;
1380 dictitem_T *di;
1381
1382 tv = STACK_TV_BOT(-1);
1383 if (tv->v_type != VAR_DICT || tv->vval.v_dict == NULL)
1384 {
1385 emsg(_(e_dictreq));
1386 goto failed;
1387 }
1388 dict = tv->vval.v_dict;
1389
1390 if ((di = dict_find(dict, iptr->isn_arg.string, -1))
1391 == NULL)
1392 {
1393 semsg(_(e_dictkey), iptr->isn_arg.string);
1394 goto failed;
1395 }
1396 clear_tv(tv);
1397 copy_tv(&di->di_tv, tv);
1398 }
1399 break;
1400
1401 case ISN_NEGATENR:
1402 tv = STACK_TV_BOT(-1);
1403 tv->vval.v_number = -tv->vval.v_number;
1404 break;
1405
1406 case ISN_CHECKNR:
1407 {
1408 int error = FALSE;
1409
1410 tv = STACK_TV_BOT(-1);
1411 if (check_not_string(tv) == FAIL)
1412 {
1413 --ectx.ec_stack.ga_len;
1414 goto failed;
1415 }
1416 (void)tv_get_number_chk(tv, &error);
1417 if (error)
1418 goto failed;
1419 }
1420 break;
1421
1422 case ISN_CHECKTYPE:
1423 {
1424 checktype_T *ct = &iptr->isn_arg.type;
1425
1426 tv = STACK_TV_BOT(ct->ct_off);
1427 if (tv->v_type != ct->ct_type)
1428 {
1429 semsg(_("E1029: Expected %s but got %s"),
1430 vartype_name(ct->ct_type),
1431 vartype_name(tv->v_type));
1432 goto failed;
1433 }
1434 }
1435 break;
1436
1437 case ISN_2BOOL:
1438 {
1439 int n;
1440
1441 tv = STACK_TV_BOT(-1);
1442 n = tv2bool(tv);
1443 if (iptr->isn_arg.number) // invert
1444 n = !n;
1445 clear_tv(tv);
1446 tv->v_type = VAR_BOOL;
1447 tv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
1448 }
1449 break;
1450
1451 case ISN_2STRING:
1452 {
1453 char_u *str;
1454
1455 tv = STACK_TV_BOT(iptr->isn_arg.number);
1456 if (tv->v_type != VAR_STRING)
1457 {
1458 str = typval_tostring(tv);
1459 clear_tv(tv);
1460 tv->v_type = VAR_STRING;
1461 tv->vval.v_string = str;
1462 }
1463 }
1464 break;
1465
1466 case ISN_DROP:
1467 --ectx.ec_stack.ga_len;
1468 clear_tv(STACK_TV_BOT(0));
1469 break;
1470 }
1471 }
1472
1473done:
1474 // function finished, get result from the stack.
1475 tv = STACK_TV_BOT(-1);
1476 *rettv = *tv;
1477 tv->v_type = VAR_UNKNOWN;
1478 ret = OK;
1479
1480failed:
1481 for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
1482 clear_tv(STACK_TV(idx));
1483 vim_free(ectx.ec_stack.ga_data);
1484 return ret;
1485}
1486
1487#define DISASSEMBLE 1
1488
1489/*
1490 * ":dissassemble".
1491 */
1492 void
1493ex_disassemble(exarg_T *eap)
1494{
1495#ifdef DISASSEMBLE
1496 ufunc_T *ufunc = find_func(eap->arg, NULL);
1497 dfunc_T *dfunc;
1498 isn_T *instr;
1499 int current;
1500 int line_idx = 0;
1501 int prev_current = 0;
1502
1503 if (ufunc == NULL)
1504 {
1505 semsg("Cannot find function %s", eap->arg);
1506 return;
1507 }
1508 if (ufunc->uf_dfunc_idx < 0)
1509 {
1510 semsg("Function %s is not compiled", eap->arg);
1511 return;
1512 }
1513 if (ufunc->uf_name_exp != NULL)
1514 msg((char *)ufunc->uf_name_exp);
1515 else
1516 msg((char *)ufunc->uf_name);
1517
1518 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
1519 instr = dfunc->df_instr;
1520 for (current = 0; current < dfunc->df_instr_count; ++current)
1521 {
1522 isn_T *iptr = &instr[current];
1523
1524 while (line_idx < iptr->isn_lnum && line_idx < ufunc->uf_lines.ga_len)
1525 {
1526 if (current > prev_current)
1527 {
1528 msg_puts("\n\n");
1529 prev_current = current;
1530 }
1531 msg(((char **)ufunc->uf_lines.ga_data)[line_idx++]);
1532 }
1533
1534 switch (iptr->isn_type)
1535 {
1536 case ISN_EXEC:
1537 smsg("%4d EXEC %s", current, iptr->isn_arg.string);
1538 break;
1539 case ISN_ECHO:
1540 {
1541 echo_T *echo = &iptr->isn_arg.echo;
1542
1543 smsg("%4d %s %d", current,
1544 echo->echo_with_white ? "ECHO" : "ECHON",
1545 echo->echo_count);
1546 }
1547 break;
1548 case ISN_LOAD:
1549 if (iptr->isn_arg.number < 0)
1550 smsg("%4d LOAD arg[%lld]", current,
1551 iptr->isn_arg.number + STACK_FRAME_SIZE);
1552 else
1553 smsg("%4d LOAD $%lld", current, iptr->isn_arg.number);
1554 break;
1555 case ISN_LOADV:
1556 smsg("%4d LOADV v:%s", current,
1557 get_vim_var_name(iptr->isn_arg.number));
1558 break;
1559 case ISN_LOADSCRIPT:
1560 {
1561 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001562 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001563 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1564 + iptr->isn_arg.script.script_idx;
1565
1566 smsg("%4d LOADSCRIPT %s from %s", current,
1567 sv->sv_name, si->sn_name);
1568 }
1569 break;
1570 case ISN_LOADS:
1571 {
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001572 scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001573
1574 smsg("%4d LOADS s:%s from %s", current,
1575 iptr->isn_arg.string, si->sn_name);
1576 }
1577 break;
1578 case ISN_LOADG:
1579 smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
1580 break;
1581 case ISN_LOADOPT:
1582 smsg("%4d LOADOPT %s", current, iptr->isn_arg.string);
1583 break;
1584 case ISN_LOADENV:
1585 smsg("%4d LOADENV %s", current, iptr->isn_arg.string);
1586 break;
1587 case ISN_LOADREG:
1588 smsg("%4d LOADREG @%c", current, iptr->isn_arg.number);
1589 break;
1590
1591 case ISN_STORE:
1592 smsg("%4d STORE $%lld", current, iptr->isn_arg.number);
1593 break;
1594 case ISN_STOREG:
1595 smsg("%4d STOREG g:%s", current, iptr->isn_arg.string);
1596 break;
1597 case ISN_STORESCRIPT:
1598 {
1599 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001600 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001601 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1602 + iptr->isn_arg.script.script_idx;
1603
1604 smsg("%4d STORESCRIPT %s in %s", current,
1605 sv->sv_name, si->sn_name);
1606 }
1607 break;
1608 case ISN_STOREOPT:
1609 smsg("%4d STOREOPT &%s", current,
1610 iptr->isn_arg.storeopt.so_name);
1611 break;
1612
1613 case ISN_STORENR:
1614 smsg("%4d STORE %lld in $%d", current,
1615 iptr->isn_arg.storenr.str_val,
1616 iptr->isn_arg.storenr.str_idx);
1617 break;
1618
1619 // constants
1620 case ISN_PUSHNR:
1621 smsg("%4d PUSHNR %lld", current, iptr->isn_arg.number);
1622 break;
1623 case ISN_PUSHBOOL:
1624 case ISN_PUSHSPEC:
1625 smsg("%4d PUSH %s", current,
1626 get_var_special_name(iptr->isn_arg.number));
1627 break;
1628 case ISN_PUSHF:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001629#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001630 smsg("%4d PUSHF %g", current, iptr->isn_arg.fnumber);
Bram Moolenaara5d59532020-01-26 21:42:03 +01001631#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001632 break;
1633 case ISN_PUSHS:
1634 smsg("%4d PUSHS \"%s\"", current, iptr->isn_arg.string);
1635 break;
1636 case ISN_PUSHBLOB:
1637 {
1638 char_u *r;
1639 char_u numbuf[NUMBUFLEN];
1640 char_u *tofree;
1641
1642 r = blob2string(iptr->isn_arg.blob, &tofree, numbuf);
1643 smsg("%4d PUSHBLOB \"%s\"", current, r);
1644 vim_free(tofree);
1645 }
1646 break;
1647 case ISN_PUSHEXC:
1648 smsg("%4d PUSH v:exception", current);
1649 break;
1650 case ISN_NEWLIST:
1651 smsg("%4d NEWLIST size %lld", current, iptr->isn_arg.number);
1652 break;
1653 case ISN_NEWDICT:
1654 smsg("%4d NEWDICT size %lld", current, iptr->isn_arg.number);
1655 break;
1656
1657 // function call
1658 case ISN_BCALL:
1659 {
1660 cbfunc_T *cbfunc = &iptr->isn_arg.bfunc;
1661
1662 smsg("%4d BCALL %s(argc %d)", current,
1663 internal_func_name(cbfunc->cbf_idx),
1664 cbfunc->cbf_argcount);
1665 }
1666 break;
1667 case ISN_DCALL:
1668 {
1669 cdfunc_T *cdfunc = &iptr->isn_arg.dfunc;
1670 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1671 + cdfunc->cdf_idx;
1672
1673 smsg("%4d DCALL %s(argc %d)", current,
1674 df->df_ufunc->uf_name_exp != NULL
1675 ? df->df_ufunc->uf_name_exp
1676 : df->df_ufunc->uf_name, cdfunc->cdf_argcount);
1677 }
1678 break;
1679 case ISN_UCALL:
1680 {
1681 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
1682
1683 smsg("%4d UCALL %s(argc %d)", current,
1684 cufunc->cuf_name, cufunc->cuf_argcount);
1685 }
1686 break;
1687 case ISN_PCALL:
1688 {
1689 cpfunc_T *cpfunc = &iptr->isn_arg.pfunc;
1690
1691 smsg("%4d PCALL%s (argc %d)", current,
1692 cpfunc->cpf_top ? " top" : "", cpfunc->cpf_argcount);
1693 }
1694 break;
1695 case ISN_RETURN:
1696 smsg("%4d RETURN", current);
1697 break;
1698 case ISN_FUNCREF:
1699 {
1700 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1701 + iptr->isn_arg.number;
1702
1703 smsg("%4d FUNCREF %s", current, df->df_ufunc->uf_name);
1704 }
1705 break;
1706
1707 case ISN_JUMP:
1708 {
1709 char *when = "?";
1710
1711 switch (iptr->isn_arg.jump.jump_when)
1712 {
1713 case JUMP_ALWAYS:
1714 when = "JUMP";
1715 break;
1716 case JUMP_IF_TRUE:
1717 when = "JUMP_IF_TRUE";
1718 break;
1719 case JUMP_AND_KEEP_IF_TRUE:
1720 when = "JUMP_AND_KEEP_IF_TRUE";
1721 break;
1722 case JUMP_IF_FALSE:
1723 when = "JUMP_IF_FALSE";
1724 break;
1725 case JUMP_AND_KEEP_IF_FALSE:
1726 when = "JUMP_AND_KEEP_IF_FALSE";
1727 break;
1728 }
1729 smsg("%4d %s -> %lld", current, when,
1730 iptr->isn_arg.jump.jump_where);
1731 }
1732 break;
1733
1734 case ISN_FOR:
1735 {
1736 forloop_T *forloop = &iptr->isn_arg.forloop;
1737
1738 smsg("%4d FOR $%d -> %d", current,
1739 forloop->for_idx, forloop->for_end);
1740 }
1741 break;
1742
1743 case ISN_TRY:
1744 {
1745 try_T *try = &iptr->isn_arg.try;
1746
1747 smsg("%4d TRY catch -> %d, finally -> %d", current,
1748 try->try_catch, try->try_finally);
1749 }
1750 break;
1751 case ISN_CATCH:
1752 // TODO
1753 smsg("%4d CATCH", current);
1754 break;
1755 case ISN_ENDTRY:
1756 smsg("%4d ENDTRY", current);
1757 break;
1758 case ISN_THROW:
1759 smsg("%4d THROW", current);
1760 break;
1761
1762 // expression operations on number
1763 case ISN_OPNR:
1764 case ISN_OPFLOAT:
1765 case ISN_OPANY:
1766 {
1767 char *what;
1768 char *ins;
1769
1770 switch (iptr->isn_arg.op.op_type)
1771 {
1772 case EXPR_MULT: what = "*"; break;
1773 case EXPR_DIV: what = "/"; break;
1774 case EXPR_REM: what = "%"; break;
1775 case EXPR_SUB: what = "-"; break;
1776 case EXPR_ADD: what = "+"; break;
1777 default: what = "???"; break;
1778 }
1779 switch (iptr->isn_type)
1780 {
1781 case ISN_OPNR: ins = "OPNR"; break;
1782 case ISN_OPFLOAT: ins = "OPFLOAT"; break;
1783 case ISN_OPANY: ins = "OPANY"; break;
1784 default: ins = "???"; break;
1785 }
1786 smsg("%4d %s %s", current, ins, what);
1787 }
1788 break;
1789
1790 case ISN_COMPAREBOOL:
1791 case ISN_COMPARESPECIAL:
1792 case ISN_COMPARENR:
1793 case ISN_COMPAREFLOAT:
1794 case ISN_COMPARESTRING:
1795 case ISN_COMPAREBLOB:
1796 case ISN_COMPARELIST:
1797 case ISN_COMPAREDICT:
1798 case ISN_COMPAREFUNC:
1799 case ISN_COMPAREPARTIAL:
1800 case ISN_COMPAREANY:
1801 {
1802 char *p;
1803 char buf[10];
1804 char *type;
1805
1806 switch (iptr->isn_arg.op.op_type)
1807 {
1808 case EXPR_EQUAL: p = "=="; break;
1809 case EXPR_NEQUAL: p = "!="; break;
1810 case EXPR_GREATER: p = ">"; break;
1811 case EXPR_GEQUAL: p = ">="; break;
1812 case EXPR_SMALLER: p = "<"; break;
1813 case EXPR_SEQUAL: p = "<="; break;
1814 case EXPR_MATCH: p = "=~"; break;
1815 case EXPR_IS: p = "is"; break;
1816 case EXPR_ISNOT: p = "isnot"; break;
1817 case EXPR_NOMATCH: p = "!~"; break;
1818 default: p = "???"; break;
1819 }
1820 STRCPY(buf, p);
1821 if (iptr->isn_arg.op.op_ic == TRUE)
1822 strcat(buf, "?");
1823 switch(iptr->isn_type)
1824 {
1825 case ISN_COMPAREBOOL: type = "COMPAREBOOL"; break;
1826 case ISN_COMPARESPECIAL:
1827 type = "COMPARESPECIAL"; break;
1828 case ISN_COMPARENR: type = "COMPARENR"; break;
1829 case ISN_COMPAREFLOAT: type = "COMPAREFLOAT"; break;
1830 case ISN_COMPARESTRING:
1831 type = "COMPARESTRING"; break;
1832 case ISN_COMPAREBLOB: type = "COMPAREBLOB"; break;
1833 case ISN_COMPARELIST: type = "COMPARELIST"; break;
1834 case ISN_COMPAREDICT: type = "COMPAREDICT"; break;
1835 case ISN_COMPAREFUNC: type = "COMPAREFUNC"; break;
1836 case ISN_COMPAREPARTIAL:
1837 type = "COMPAREPARTIAL"; break;
1838 case ISN_COMPAREANY: type = "COMPAREANY"; break;
1839 default: type = "???"; break;
1840 }
1841
1842 smsg("%4d %s %s", current, type, buf);
1843 }
1844 break;
1845
1846 case ISN_ADDLIST: smsg("%4d ADDLIST", current); break;
1847 case ISN_ADDBLOB: smsg("%4d ADDBLOB", current); break;
1848
1849 // expression operations
1850 case ISN_CONCAT: smsg("%4d CONCAT", current); break;
1851 case ISN_INDEX: smsg("%4d INDEX", current); break;
1852 case ISN_MEMBER: smsg("%4d MEMBER %s", current,
1853 iptr->isn_arg.string); break;
1854 case ISN_NEGATENR: smsg("%4d NEGATENR", current); break;
1855
1856 case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
1857 case ISN_CHECKTYPE: smsg("%4d CHECKTYPE %s stack[%d]", current,
1858 vartype_name(iptr->isn_arg.type.ct_type),
1859 iptr->isn_arg.type.ct_off);
1860 break;
1861 case ISN_2BOOL: if (iptr->isn_arg.number)
1862 smsg("%4d INVERT (!val)", current);
1863 else
1864 smsg("%4d 2BOOL (!!val)", current);
1865 break;
1866 case ISN_2STRING: smsg("%4d 2STRING stack[%d]", current,
1867 iptr->isn_arg.number);
1868 break;
1869
1870 case ISN_DROP: smsg("%4d DROP", current); break;
1871 }
1872 }
1873#endif
1874}
1875
1876/*
1877 * Return TRUE when "tv" is not falsey: non-zero, non-empty string, non-empty
1878 * list, etc. Mostly like what JavaScript does, except that empty list and
1879 * empty dictionary are FALSE.
1880 */
1881 int
1882tv2bool(typval_T *tv)
1883{
1884 switch (tv->v_type)
1885 {
1886 case VAR_NUMBER:
1887 return tv->vval.v_number != 0;
1888 case VAR_FLOAT:
1889#ifdef FEAT_FLOAT
1890 return tv->vval.v_float != 0.0;
1891#else
1892 break;
1893#endif
1894 case VAR_PARTIAL:
1895 return tv->vval.v_partial != NULL;
1896 case VAR_FUNC:
1897 case VAR_STRING:
1898 return tv->vval.v_string != NULL && *tv->vval.v_string != NUL;
1899 case VAR_LIST:
1900 return tv->vval.v_list != NULL && tv->vval.v_list->lv_len > 0;
1901 case VAR_DICT:
1902 return tv->vval.v_dict != NULL
1903 && tv->vval.v_dict->dv_hashtab.ht_used > 0;
1904 case VAR_BOOL:
1905 case VAR_SPECIAL:
1906 return tv->vval.v_number == VVAL_TRUE ? TRUE : FALSE;
1907 case VAR_JOB:
1908#ifdef FEAT_JOB_CHANNEL
1909 return tv->vval.v_job != NULL;
1910#else
1911 break;
1912#endif
1913 case VAR_CHANNEL:
1914#ifdef FEAT_JOB_CHANNEL
1915 return tv->vval.v_channel != NULL;
1916#else
1917 break;
1918#endif
1919 case VAR_BLOB:
1920 return tv->vval.v_blob != NULL && tv->vval.v_blob->bv_ga.ga_len > 0;
1921 case VAR_UNKNOWN:
1922 case VAR_VOID:
1923 break;
1924 }
1925 return FALSE;
1926}
1927
1928/*
1929 * If "tv" is a string give an error and return FAIL.
1930 */
1931 int
1932check_not_string(typval_T *tv)
1933{
1934 if (tv->v_type == VAR_STRING)
1935 {
1936 emsg(_("E1030: Using a String as a Number"));
1937 clear_tv(tv);
1938 return FAIL;
1939 }
1940 return OK;
1941}
1942
1943
1944#endif // FEAT_EVAL