blob: e4aa7fe8d0dd1c77491abb2ca4756ab34cdc6cca [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
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100491 // load s: variable in Vim9 script
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100492 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 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100510 hashtab_T *ht = &SCRIPT_VARS(
511 iptr->isn_arg.loadstore.ls_sid);
512 char_u *name = iptr->isn_arg.loadstore.ls_name;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100513 dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE);
514 if (di == NULL)
515 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100516 semsg(_(e_undefvar), name);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100517 goto failed;
518 }
519 else
520 {
521 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
522 goto failed;
523 copy_tv(&di->di_tv, STACK_TV_BOT(0));
524 ++ectx.ec_stack.ga_len;
525 }
526 }
527 break;
528
529 // load g: variable
530 case ISN_LOADG:
531 {
532 dictitem_T *di;
533
534 di = find_var_in_ht(get_globvar_ht(), 0,
535 iptr->isn_arg.string, TRUE);
536 if (di == NULL)
537 {
538 semsg(_("E121: Undefined variable: g:%s"),
539 iptr->isn_arg.string);
540 goto failed;
541 }
542 else
543 {
544 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
545 goto failed;
546 copy_tv(&di->di_tv, STACK_TV_BOT(0));
547 ++ectx.ec_stack.ga_len;
548 }
549 }
550 break;
551
552 // load &option
553 case ISN_LOADOPT:
554 {
555 typval_T optval;
556 char_u *name = iptr->isn_arg.string;
557
558 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
559 goto failed;
Bram Moolenaar58ceca52020-01-28 22:46:22 +0100560 if (get_option_tv(&name, &optval, TRUE) == FAIL)
561 goto failed;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100562 *STACK_TV_BOT(0) = optval;
563 ++ectx.ec_stack.ga_len;
564 }
565 break;
566
567 // load $ENV
568 case ISN_LOADENV:
569 {
570 typval_T optval;
571 char_u *name = iptr->isn_arg.string;
572
573 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
574 goto failed;
Bram Moolenaar07da94b2020-01-28 22:39:19 +0100575 if (get_env_tv(&name, &optval, TRUE) == FAIL)
576 {
577 semsg(_("E1060: Invalid environment variable name: %s"),
578 iptr->isn_arg.string);
579 goto failed;
580 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100581 *STACK_TV_BOT(0) = optval;
582 ++ectx.ec_stack.ga_len;
583 }
584 break;
585
586 // load @register
587 case ISN_LOADREG:
588 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
589 goto failed;
590 tv = STACK_TV_BOT(0);
591 tv->v_type = VAR_STRING;
592 tv->vval.v_string = get_reg_contents(
593 iptr->isn_arg.number, GREG_EXPR_SRC);
594 ++ectx.ec_stack.ga_len;
595 break;
596
597 // store local variable
598 case ISN_STORE:
599 --ectx.ec_stack.ga_len;
600 tv = STACK_TV_VAR(iptr->isn_arg.number);
601 clear_tv(tv);
602 *tv = *STACK_TV_BOT(0);
603 break;
604
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100605 // store s: variable in old script
606 case ISN_STORES:
607 {
608 hashtab_T *ht = &SCRIPT_VARS(
609 iptr->isn_arg.loadstore.ls_sid);
610 char_u *name = iptr->isn_arg.loadstore.ls_name;
611 dictitem_T *di = find_var_in_ht(ht, 0, name, TRUE);
612
613 if (di == NULL)
614 {
615 semsg(_(e_undefvar), name);
616 goto failed;
617 }
618 --ectx.ec_stack.ga_len;
619 clear_tv(&di->di_tv);
620 di->di_tv = *STACK_TV_BOT(0);
621 }
622 break;
623
624 // store script-local variable in Vim9 script
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100625 case ISN_STORESCRIPT:
626 {
Bram Moolenaar21b9e972020-01-26 19:26:46 +0100627 scriptitem_T *si = SCRIPT_ITEM(
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100628 iptr->isn_arg.script.script_sid);
629 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
630 + iptr->isn_arg.script.script_idx;
631
632 --ectx.ec_stack.ga_len;
633 clear_tv(sv->sv_tv);
634 *sv->sv_tv = *STACK_TV_BOT(0);
635 }
636 break;
637
638 // store option
639 case ISN_STOREOPT:
640 {
641 long n = 0;
642 char_u *s = NULL;
643 char *msg;
644
645 --ectx.ec_stack.ga_len;
646 tv = STACK_TV_BOT(0);
647 if (tv->v_type == VAR_STRING)
Bram Moolenaar97a2af32020-01-28 22:52:48 +0100648 {
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100649 s = tv->vval.v_string;
Bram Moolenaar97a2af32020-01-28 22:52:48 +0100650 if (s == NULL)
651 s = (char_u *)"";
652 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100653 else if (tv->v_type == VAR_NUMBER)
654 n = tv->vval.v_number;
655 else
656 {
657 emsg(_("E1051: Expected string or number"));
658 goto failed;
659 }
660 msg = set_option_value(iptr->isn_arg.storeopt.so_name,
661 n, s, iptr->isn_arg.storeopt.so_flags);
662 if (msg != NULL)
663 {
664 emsg(_(msg));
665 goto failed;
666 }
667 clear_tv(tv);
668 }
669 break;
670
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100671 // store $ENV
672 case ISN_STOREENV:
673 --ectx.ec_stack.ga_len;
674 vim_setenv_ext(iptr->isn_arg.string,
675 tv_get_string(STACK_TV_BOT(0)));
676 break;
677
678 // store @r
679 case ISN_STOREREG:
680 {
681 int reg = iptr->isn_arg.number;
682
683 --ectx.ec_stack.ga_len;
684 write_reg_contents(reg == '@' ? '"' : reg,
685 tv_get_string(STACK_TV_BOT(0)), -1, FALSE);
686 }
687 break;
688
689 // store v: variable
690 case ISN_STOREV:
691 --ectx.ec_stack.ga_len;
692 if (set_vim_var_tv(iptr->isn_arg.number, STACK_TV_BOT(0))
693 == FAIL)
694 goto failed;
695 break;
696
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100697 // store g: variable
698 case ISN_STOREG:
699 {
700 dictitem_T *di;
701
702 --ectx.ec_stack.ga_len;
703 di = find_var_in_ht(get_globvar_ht(), 0,
704 iptr->isn_arg.string, TRUE);
705 if (di == NULL)
706 {
707 funccal_entry_T entry;
708
709 save_funccal(&entry);
710 set_var_const(iptr->isn_arg.string, NULL,
711 STACK_TV_BOT(0), FALSE, 0);
712 restore_funccal();
713 }
714 else
715 {
716 clear_tv(&di->di_tv);
717 di->di_tv = *STACK_TV_BOT(0);
718 }
719 }
720 break;
721
722 // store number in local variable
723 case ISN_STORENR:
724 tv = STACK_TV_VAR(iptr->isn_arg.storenr.str_idx);
725 clear_tv(tv);
726 tv->v_type = VAR_NUMBER;
727 tv->vval.v_number = iptr->isn_arg.storenr.str_val;
728 break;
729
730 // push constant
731 case ISN_PUSHNR:
732 case ISN_PUSHBOOL:
733 case ISN_PUSHSPEC:
734 case ISN_PUSHF:
735 case ISN_PUSHS:
736 case ISN_PUSHBLOB:
737 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
738 goto failed;
739 tv = STACK_TV_BOT(0);
740 ++ectx.ec_stack.ga_len;
741 switch (iptr->isn_type)
742 {
743 case ISN_PUSHNR:
744 tv->v_type = VAR_NUMBER;
745 tv->vval.v_number = iptr->isn_arg.number;
746 break;
747 case ISN_PUSHBOOL:
748 tv->v_type = VAR_BOOL;
749 tv->vval.v_number = iptr->isn_arg.number;
750 break;
751 case ISN_PUSHSPEC:
752 tv->v_type = VAR_SPECIAL;
753 tv->vval.v_number = iptr->isn_arg.number;
754 break;
755#ifdef FEAT_FLOAT
756 case ISN_PUSHF:
757 tv->v_type = VAR_FLOAT;
758 tv->vval.v_float = iptr->isn_arg.fnumber;
759 break;
760#endif
761 case ISN_PUSHBLOB:
762 blob_copy(iptr->isn_arg.blob, tv);
763 break;
764 default:
765 tv->v_type = VAR_STRING;
766 tv->vval.v_string = vim_strsave(iptr->isn_arg.string);
767 }
768 break;
769
770 // create a list from items on the stack; uses a single allocation
771 // for the list header and the items
772 case ISN_NEWLIST:
773 {
774 int count = iptr->isn_arg.number;
775 list_T *list = list_alloc_with_items(count);
776
777 if (list == NULL)
778 goto failed;
779 for (idx = 0; idx < count; ++idx)
780 list_set_item(list, idx, STACK_TV_BOT(idx - count));
781
782 if (count > 0)
783 ectx.ec_stack.ga_len -= count - 1;
784 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
785 goto failed;
786 else
787 ++ectx.ec_stack.ga_len;
788 tv = STACK_TV_BOT(-1);
789 tv->v_type = VAR_LIST;
790 tv->vval.v_list = list;
791 ++list->lv_refcount;
792 }
793 break;
794
795 // create a dict from items on the stack
796 case ISN_NEWDICT:
797 {
798 int count = iptr->isn_arg.number;
799 dict_T *dict = dict_alloc();
800 dictitem_T *item;
801
802 if (dict == NULL)
803 goto failed;
804 for (idx = 0; idx < count; ++idx)
805 {
806 // check key type is VAR_STRING
807 tv = STACK_TV_BOT(2 * (idx - count));
808 item = dictitem_alloc(tv->vval.v_string);
809 clear_tv(tv);
810 if (item == NULL)
811 goto failed;
812 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
813 item->di_tv.v_lock = 0;
814 if (dict_add(dict, item) == FAIL)
815 goto failed;
816 }
817
818 if (count > 0)
819 ectx.ec_stack.ga_len -= 2 * count - 1;
820 else if (ga_grow(&ectx.ec_stack, 1) == FAIL)
821 goto failed;
822 else
823 ++ectx.ec_stack.ga_len;
824 tv = STACK_TV_BOT(-1);
825 tv->v_type = VAR_DICT;
826 tv->vval.v_dict = dict;
827 ++dict->dv_refcount;
828 }
829 break;
830
831 // call a :def function
832 case ISN_DCALL:
833 if (call_dfunc(iptr->isn_arg.dfunc.cdf_idx,
834 iptr->isn_arg.dfunc.cdf_argcount,
835 &ectx) == FAIL)
836 goto failed;
837 break;
838
839 // call a builtin function
840 case ISN_BCALL:
841 SOURCING_LNUM = iptr->isn_lnum;
842 if (call_bfunc(iptr->isn_arg.bfunc.cbf_idx,
843 iptr->isn_arg.bfunc.cbf_argcount,
844 &ectx) == FAIL)
845 goto failed;
846 break;
847
848 // call a funcref or partial
849 case ISN_PCALL:
850 {
851 cpfunc_T *pfunc = &iptr->isn_arg.pfunc;
852 int r;
853 typval_T partial;
854
855 SOURCING_LNUM = iptr->isn_lnum;
856 if (pfunc->cpf_top)
857 {
858 // funcref is above the arguments
859 tv = STACK_TV_BOT(-pfunc->cpf_argcount - 1);
860 }
861 else
862 {
863 // Get the funcref from the stack.
864 --ectx.ec_stack.ga_len;
865 partial = *STACK_TV_BOT(0);
866 tv = &partial;
867 }
868 r = call_partial(tv, pfunc->cpf_argcount, &ectx);
869 if (tv == &partial)
870 clear_tv(&partial);
871 if (r == FAIL)
872 goto failed;
873
874 if (pfunc->cpf_top)
875 {
876 // Get the funcref from the stack, overwrite with the
877 // return value.
878 clear_tv(tv);
879 --ectx.ec_stack.ga_len;
880 *STACK_TV_BOT(-1) = *STACK_TV_BOT(0);
881 }
882 }
883 break;
884
885 // call a user defined function or funcref/partial
886 case ISN_UCALL:
887 {
888 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
889
890 SOURCING_LNUM = iptr->isn_lnum;
891 if (call_eval_func(cufunc->cuf_name,
892 cufunc->cuf_argcount, &ectx) == FAIL)
893 goto failed;
894 }
895 break;
896
897 // return from a :def function call
898 case ISN_RETURN:
899 {
Bram Moolenaar8cbd6df2020-01-28 22:59:45 +0100900 garray_T *trystack = &ectx.ec_trystack;
901
902 if (trystack->ga_len > 0)
903 trycmd = ((trycmd_T *)trystack->ga_data)
904 + trystack->ga_len - 1;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100905 if (trycmd != NULL && trycmd->tcd_frame == ectx.ec_frame
906 && trycmd->tcd_finally_idx != 0)
907 {
908 // jump to ":finally"
909 ectx.ec_iidx = trycmd->tcd_finally_idx;
910 trycmd->tcd_return = TRUE;
911 }
912 else
913 {
914 // Restore previous function. If the frame pointer
915 // is zero then there is none and we are done.
916 if (ectx.ec_frame == initial_frame_ptr)
917 goto done;
918
919 func_return(&ectx);
920 }
921 }
922 break;
923
924 // push a function reference to a compiled function
925 case ISN_FUNCREF:
926 {
927 partial_T *pt = NULL;
928
929 pt = ALLOC_CLEAR_ONE(partial_T);
930 if (pt == NULL)
931 goto failed;
932 dfunc = ((dfunc_T *)def_functions.ga_data)
933 + iptr->isn_arg.number;
934 pt->pt_func = dfunc->df_ufunc;
935 pt->pt_refcount = 1;
936 ++dfunc->df_ufunc->uf_refcount;
937
938 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
939 goto failed;
940 tv = STACK_TV_BOT(0);
941 ++ectx.ec_stack.ga_len;
942 tv->vval.v_partial = pt;
943 tv->v_type = VAR_PARTIAL;
944 }
945 break;
946
947 // jump if a condition is met
948 case ISN_JUMP:
949 {
950 jumpwhen_T when = iptr->isn_arg.jump.jump_when;
951 int jump = TRUE;
952
953 if (when != JUMP_ALWAYS)
954 {
955 tv = STACK_TV_BOT(-1);
956 jump = tv2bool(tv);
957 if (when == JUMP_IF_FALSE
958 || when == JUMP_AND_KEEP_IF_FALSE)
959 jump = !jump;
960 if (when == JUMP_IF_FALSE || when == JUMP_IF_TRUE
961 || !jump)
962 {
963 // drop the value from the stack
964 clear_tv(tv);
965 --ectx.ec_stack.ga_len;
966 }
967 }
968 if (jump)
969 ectx.ec_iidx = iptr->isn_arg.jump.jump_where;
970 }
971 break;
972
973 // top of a for loop
974 case ISN_FOR:
975 {
976 list_T *list = STACK_TV_BOT(-1)->vval.v_list;
977 typval_T *idxtv =
978 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx);
979
980 // push the next item from the list
981 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
982 goto failed;
983 if (++idxtv->vval.v_number >= list->lv_len)
984 // past the end of the list, jump to "endfor"
985 ectx.ec_iidx = iptr->isn_arg.forloop.for_end;
986 else if (list->lv_first == &range_list_item)
987 {
988 // non-materialized range() list
989 tv = STACK_TV_BOT(0);
990 tv->v_type = VAR_NUMBER;
991 tv->vval.v_number = list_find_nr(
992 list, idxtv->vval.v_number, NULL);
993 ++ectx.ec_stack.ga_len;
994 }
995 else
996 {
997 listitem_T *li = list_find(list, idxtv->vval.v_number);
998
999 if (li == NULL)
1000 goto failed;
1001 copy_tv(&li->li_tv, STACK_TV_BOT(0));
1002 ++ectx.ec_stack.ga_len;
1003 }
1004 }
1005 break;
1006
1007 // start of ":try" block
1008 case ISN_TRY:
1009 {
1010 if (ga_grow(&ectx.ec_trystack, 1) == FAIL)
1011 goto failed;
1012 trycmd = ((trycmd_T *)ectx.ec_trystack.ga_data)
1013 + ectx.ec_trystack.ga_len;
1014 ++ectx.ec_trystack.ga_len;
1015 ++trylevel;
1016 trycmd->tcd_frame = ectx.ec_frame;
1017 trycmd->tcd_catch_idx = iptr->isn_arg.try.try_catch;
1018 trycmd->tcd_finally_idx = iptr->isn_arg.try.try_finally;
1019 }
1020 break;
1021
1022 case ISN_PUSHEXC:
1023 if (current_exception == NULL)
1024 {
1025 iemsg("Evaluating catch while current_exception is NULL");
1026 goto failed;
1027 }
1028 if (ga_grow(&ectx.ec_stack, 1) == FAIL)
1029 goto failed;
1030 tv = STACK_TV_BOT(0);
1031 ++ectx.ec_stack.ga_len;
1032 tv->v_type = VAR_STRING;
1033 tv->vval.v_string = vim_strsave(
1034 (char_u *)current_exception->value);
1035 break;
1036
1037 case ISN_CATCH:
1038 {
1039 garray_T *trystack = &ectx.ec_trystack;
1040
1041 if (trystack->ga_len > 0)
1042 {
1043 trycmd = ((trycmd_T *)trystack->ga_data)
1044 + trystack->ga_len - 1;
1045 trycmd->tcd_caught = TRUE;
1046 }
1047 did_emsg = got_int = did_throw = FALSE;
1048 catch_exception(current_exception);
1049 }
1050 break;
1051
1052 // end of ":try" block
1053 case ISN_ENDTRY:
1054 {
1055 garray_T *trystack = &ectx.ec_trystack;
1056
1057 if (trystack->ga_len > 0)
1058 {
1059 --trystack->ga_len;
1060 --trylevel;
1061 trycmd = ((trycmd_T *)trystack->ga_data)
1062 + trystack->ga_len;
1063 if (trycmd->tcd_caught)
1064 {
1065 // discard the exception
1066 if (caught_stack == current_exception)
1067 caught_stack = caught_stack->caught;
1068 discard_current_exception();
1069 }
1070
1071 if (trycmd->tcd_return)
1072 {
1073 // Restore previous function. If the frame pointer
1074 // is zero then there is none and we are done.
1075 if (ectx.ec_frame == initial_frame_ptr)
1076 goto done;
1077
1078 func_return(&ectx);
1079 }
1080 }
1081 }
1082 break;
1083
1084 case ISN_THROW:
1085 --ectx.ec_stack.ga_len;
1086 tv = STACK_TV_BOT(0);
1087 if (throw_exception(tv->vval.v_string, ET_USER, NULL) == FAIL)
1088 {
1089 vim_free(tv->vval.v_string);
1090 goto failed;
1091 }
1092 did_throw = TRUE;
1093 break;
1094
1095 // compare with special values
1096 case ISN_COMPAREBOOL:
1097 case ISN_COMPARESPECIAL:
1098 {
1099 typval_T *tv1 = STACK_TV_BOT(-2);
1100 typval_T *tv2 = STACK_TV_BOT(-1);
1101 varnumber_T arg1 = tv1->vval.v_number;
1102 varnumber_T arg2 = tv2->vval.v_number;
1103 int res;
1104
1105 switch (iptr->isn_arg.op.op_type)
1106 {
1107 case EXPR_EQUAL: res = arg1 == arg2; break;
1108 case EXPR_NEQUAL: res = arg1 != arg2; break;
1109 default: res = 0; break;
1110 }
1111
1112 --ectx.ec_stack.ga_len;
1113 tv1->v_type = VAR_BOOL;
1114 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1115 }
1116 break;
1117
1118 // Operation with two number arguments
1119 case ISN_OPNR:
1120 case ISN_COMPARENR:
1121 {
1122 typval_T *tv1 = STACK_TV_BOT(-2);
1123 typval_T *tv2 = STACK_TV_BOT(-1);
1124 varnumber_T arg1 = tv1->vval.v_number;
1125 varnumber_T arg2 = tv2->vval.v_number;
1126 varnumber_T res;
1127
1128 switch (iptr->isn_arg.op.op_type)
1129 {
1130 case EXPR_MULT: res = arg1 * arg2; break;
1131 case EXPR_DIV: res = arg1 / arg2; break;
1132 case EXPR_REM: res = arg1 % arg2; break;
1133 case EXPR_SUB: res = arg1 - arg2; break;
1134 case EXPR_ADD: res = arg1 + arg2; break;
1135
1136 case EXPR_EQUAL: res = arg1 == arg2; break;
1137 case EXPR_NEQUAL: res = arg1 != arg2; break;
1138 case EXPR_GREATER: res = arg1 > arg2; break;
1139 case EXPR_GEQUAL: res = arg1 >= arg2; break;
1140 case EXPR_SMALLER: res = arg1 < arg2; break;
1141 case EXPR_SEQUAL: res = arg1 <= arg2; break;
1142 default: res = 0; break;
1143 }
1144
1145 --ectx.ec_stack.ga_len;
1146 if (iptr->isn_type == ISN_COMPARENR)
1147 {
1148 tv1->v_type = VAR_BOOL;
1149 tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
1150 }
1151 else
1152 tv1->vval.v_number = res;
1153 }
1154 break;
1155
1156 // Computation with two float arguments
1157 case ISN_OPFLOAT:
1158 case ISN_COMPAREFLOAT:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001159#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001160 {
1161 typval_T *tv1 = STACK_TV_BOT(-2);
1162 typval_T *tv2 = STACK_TV_BOT(-1);
1163 float_T arg1 = tv1->vval.v_float;
1164 float_T arg2 = tv2->vval.v_float;
1165 float_T res = 0;
1166 int cmp = FALSE;
1167
1168 switch (iptr->isn_arg.op.op_type)
1169 {
1170 case EXPR_MULT: res = arg1 * arg2; break;
1171 case EXPR_DIV: res = arg1 / arg2; break;
1172 case EXPR_SUB: res = arg1 - arg2; break;
1173 case EXPR_ADD: res = arg1 + arg2; break;
1174
1175 case EXPR_EQUAL: cmp = arg1 == arg2; break;
1176 case EXPR_NEQUAL: cmp = arg1 != arg2; break;
1177 case EXPR_GREATER: cmp = arg1 > arg2; break;
1178 case EXPR_GEQUAL: cmp = arg1 >= arg2; break;
1179 case EXPR_SMALLER: cmp = arg1 < arg2; break;
1180 case EXPR_SEQUAL: cmp = arg1 <= arg2; break;
1181 default: cmp = 0; break;
1182 }
1183 --ectx.ec_stack.ga_len;
1184 if (iptr->isn_type == ISN_COMPAREFLOAT)
1185 {
1186 tv1->v_type = VAR_BOOL;
1187 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1188 }
1189 else
1190 tv1->vval.v_float = res;
1191 }
Bram Moolenaara5d59532020-01-26 21:42:03 +01001192#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001193 break;
1194
1195 case ISN_COMPARELIST:
1196 {
1197 typval_T *tv1 = STACK_TV_BOT(-2);
1198 typval_T *tv2 = STACK_TV_BOT(-1);
1199 list_T *arg1 = tv1->vval.v_list;
1200 list_T *arg2 = tv2->vval.v_list;
1201 int cmp = FALSE;
1202 int ic = iptr->isn_arg.op.op_ic;
1203
1204 switch (iptr->isn_arg.op.op_type)
1205 {
1206 case EXPR_EQUAL: cmp =
1207 list_equal(arg1, arg2, ic, FALSE); break;
1208 case EXPR_NEQUAL: cmp =
1209 !list_equal(arg1, arg2, ic, FALSE); break;
1210 case EXPR_IS: cmp = arg1 == arg2; break;
1211 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1212 default: cmp = 0; break;
1213 }
1214 --ectx.ec_stack.ga_len;
1215 clear_tv(tv1);
1216 clear_tv(tv2);
1217 tv1->v_type = VAR_BOOL;
1218 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1219 }
1220 break;
1221
1222 case ISN_COMPAREBLOB:
1223 {
1224 typval_T *tv1 = STACK_TV_BOT(-2);
1225 typval_T *tv2 = STACK_TV_BOT(-1);
1226 blob_T *arg1 = tv1->vval.v_blob;
1227 blob_T *arg2 = tv2->vval.v_blob;
1228 int cmp = FALSE;
1229
1230 switch (iptr->isn_arg.op.op_type)
1231 {
1232 case EXPR_EQUAL: cmp = blob_equal(arg1, arg2); break;
1233 case EXPR_NEQUAL: cmp = !blob_equal(arg1, arg2); break;
1234 case EXPR_IS: cmp = arg1 == arg2; break;
1235 case EXPR_ISNOT: cmp = arg1 != arg2; break;
1236 default: cmp = 0; break;
1237 }
1238 --ectx.ec_stack.ga_len;
1239 clear_tv(tv1);
1240 clear_tv(tv2);
1241 tv1->v_type = VAR_BOOL;
1242 tv1->vval.v_number = cmp ? VVAL_TRUE : VVAL_FALSE;
1243 }
1244 break;
1245
1246 // TODO: handle separately
1247 case ISN_COMPARESTRING:
1248 case ISN_COMPAREDICT:
1249 case ISN_COMPAREFUNC:
1250 case ISN_COMPAREPARTIAL:
1251 case ISN_COMPAREANY:
1252 {
1253 typval_T *tv1 = STACK_TV_BOT(-2);
1254 typval_T *tv2 = STACK_TV_BOT(-1);
1255 exptype_T exptype = iptr->isn_arg.op.op_type;
1256 int ic = iptr->isn_arg.op.op_ic;
1257
1258 typval_compare(tv1, tv2, exptype, ic);
1259 clear_tv(tv2);
1260 tv1->v_type = VAR_BOOL;
1261 tv1->vval.v_number = tv1->vval.v_number
1262 ? VVAL_TRUE : VVAL_FALSE;
1263 --ectx.ec_stack.ga_len;
1264 }
1265 break;
1266
1267 case ISN_ADDLIST:
1268 case ISN_ADDBLOB:
1269 {
1270 typval_T *tv1 = STACK_TV_BOT(-2);
1271 typval_T *tv2 = STACK_TV_BOT(-1);
1272
1273 if (iptr->isn_type == ISN_ADDLIST)
1274 eval_addlist(tv1, tv2);
1275 else
1276 eval_addblob(tv1, tv2);
1277 clear_tv(tv2);
1278 --ectx.ec_stack.ga_len;
1279 }
1280 break;
1281
1282 // Computation with two arguments of unknown type
1283 case ISN_OPANY:
1284 {
1285 typval_T *tv1 = STACK_TV_BOT(-2);
1286 typval_T *tv2 = STACK_TV_BOT(-1);
1287 varnumber_T n1, n2;
1288#ifdef FEAT_FLOAT
1289 float_T f1 = 0, f2 = 0;
1290#endif
1291 int error = FALSE;
1292
1293 if (iptr->isn_arg.op.op_type == EXPR_ADD)
1294 {
1295 if (tv1->v_type == VAR_LIST && tv2->v_type == VAR_LIST)
1296 {
1297 eval_addlist(tv1, tv2);
1298 clear_tv(tv2);
1299 --ectx.ec_stack.ga_len;
1300 break;
1301 }
1302 else if (tv1->v_type == VAR_BLOB
1303 && tv2->v_type == VAR_BLOB)
1304 {
1305 eval_addblob(tv1, tv2);
1306 clear_tv(tv2);
1307 --ectx.ec_stack.ga_len;
1308 break;
1309 }
1310 }
1311#ifdef FEAT_FLOAT
1312 if (tv1->v_type == VAR_FLOAT)
1313 {
1314 f1 = tv1->vval.v_float;
1315 n1 = 0;
1316 }
1317 else
1318#endif
1319 {
1320 n1 = tv_get_number_chk(tv1, &error);
1321 if (error)
1322 goto failed;
1323#ifdef FEAT_FLOAT
1324 if (tv2->v_type == VAR_FLOAT)
1325 f1 = n1;
1326#endif
1327 }
1328#ifdef FEAT_FLOAT
1329 if (tv2->v_type == VAR_FLOAT)
1330 {
1331 f2 = tv2->vval.v_float;
1332 n2 = 0;
1333 }
1334 else
1335#endif
1336 {
1337 n2 = tv_get_number_chk(tv2, &error);
1338 if (error)
1339 goto failed;
1340#ifdef FEAT_FLOAT
1341 if (tv1->v_type == VAR_FLOAT)
1342 f2 = n2;
1343#endif
1344 }
1345#ifdef FEAT_FLOAT
1346 // if there is a float on either side the result is a float
1347 if (tv1->v_type == VAR_FLOAT || tv2->v_type == VAR_FLOAT)
1348 {
1349 switch (iptr->isn_arg.op.op_type)
1350 {
1351 case EXPR_MULT: f1 = f1 * f2; break;
1352 case EXPR_DIV: f1 = f1 / f2; break;
1353 case EXPR_SUB: f1 = f1 - f2; break;
1354 case EXPR_ADD: f1 = f1 + f2; break;
1355 default: emsg(_(e_modulus)); goto failed;
1356 }
1357 clear_tv(tv1);
1358 clear_tv(tv2);
1359 tv1->v_type = VAR_FLOAT;
1360 tv1->vval.v_float = f1;
1361 --ectx.ec_stack.ga_len;
1362 }
1363 else
1364#endif
1365 {
1366 switch (iptr->isn_arg.op.op_type)
1367 {
1368 case EXPR_MULT: n1 = n1 * n2; break;
1369 case EXPR_DIV: n1 = num_divide(n1, n2); break;
1370 case EXPR_SUB: n1 = n1 - n2; break;
1371 case EXPR_ADD: n1 = n1 + n2; break;
1372 default: n1 = num_modulus(n1, n2); break;
1373 }
1374 clear_tv(tv1);
1375 clear_tv(tv2);
1376 tv1->v_type = VAR_NUMBER;
1377 tv1->vval.v_number = n1;
1378 --ectx.ec_stack.ga_len;
1379 }
1380 }
1381 break;
1382
1383 case ISN_CONCAT:
1384 {
1385 char_u *str1 = STACK_TV_BOT(-2)->vval.v_string;
1386 char_u *str2 = STACK_TV_BOT(-1)->vval.v_string;
1387 char_u *res;
1388
1389 res = concat_str(str1, str2);
1390 clear_tv(STACK_TV_BOT(-2));
1391 clear_tv(STACK_TV_BOT(-1));
1392 --ectx.ec_stack.ga_len;
1393 STACK_TV_BOT(-1)->vval.v_string = res;
1394 }
1395 break;
1396
1397 case ISN_INDEX:
1398 {
1399 list_T *list;
1400 varnumber_T n;
1401 listitem_T *li;
1402
1403 // list index: list is at stack-2, index at stack-1
1404 tv = STACK_TV_BOT(-2);
1405 if (tv->v_type != VAR_LIST)
1406 {
1407 emsg(_(e_listreq));
1408 goto failed;
1409 }
1410 list = tv->vval.v_list;
1411
1412 tv = STACK_TV_BOT(-1);
1413 if (tv->v_type != VAR_NUMBER)
1414 {
1415 emsg(_(e_number_exp));
1416 goto failed;
1417 }
1418 n = tv->vval.v_number;
1419 clear_tv(tv);
1420 if ((li = list_find(list, n)) == NULL)
1421 {
1422 semsg(_(e_listidx), n);
1423 goto failed;
1424 }
1425 --ectx.ec_stack.ga_len;
1426 clear_tv(STACK_TV_BOT(-1));
1427 copy_tv(&li->li_tv, STACK_TV_BOT(-1));
1428 }
1429 break;
1430
1431 // dict member with string key
1432 case ISN_MEMBER:
1433 {
1434 dict_T *dict;
1435 dictitem_T *di;
1436
1437 tv = STACK_TV_BOT(-1);
1438 if (tv->v_type != VAR_DICT || tv->vval.v_dict == NULL)
1439 {
1440 emsg(_(e_dictreq));
1441 goto failed;
1442 }
1443 dict = tv->vval.v_dict;
1444
1445 if ((di = dict_find(dict, iptr->isn_arg.string, -1))
1446 == NULL)
1447 {
1448 semsg(_(e_dictkey), iptr->isn_arg.string);
1449 goto failed;
1450 }
1451 clear_tv(tv);
1452 copy_tv(&di->di_tv, tv);
1453 }
1454 break;
1455
1456 case ISN_NEGATENR:
1457 tv = STACK_TV_BOT(-1);
1458 tv->vval.v_number = -tv->vval.v_number;
1459 break;
1460
1461 case ISN_CHECKNR:
1462 {
1463 int error = FALSE;
1464
1465 tv = STACK_TV_BOT(-1);
1466 if (check_not_string(tv) == FAIL)
1467 {
1468 --ectx.ec_stack.ga_len;
1469 goto failed;
1470 }
1471 (void)tv_get_number_chk(tv, &error);
1472 if (error)
1473 goto failed;
1474 }
1475 break;
1476
1477 case ISN_CHECKTYPE:
1478 {
1479 checktype_T *ct = &iptr->isn_arg.type;
1480
1481 tv = STACK_TV_BOT(ct->ct_off);
1482 if (tv->v_type != ct->ct_type)
1483 {
1484 semsg(_("E1029: Expected %s but got %s"),
1485 vartype_name(ct->ct_type),
1486 vartype_name(tv->v_type));
1487 goto failed;
1488 }
1489 }
1490 break;
1491
1492 case ISN_2BOOL:
1493 {
1494 int n;
1495
1496 tv = STACK_TV_BOT(-1);
1497 n = tv2bool(tv);
1498 if (iptr->isn_arg.number) // invert
1499 n = !n;
1500 clear_tv(tv);
1501 tv->v_type = VAR_BOOL;
1502 tv->vval.v_number = n ? VVAL_TRUE : VVAL_FALSE;
1503 }
1504 break;
1505
1506 case ISN_2STRING:
1507 {
1508 char_u *str;
1509
1510 tv = STACK_TV_BOT(iptr->isn_arg.number);
1511 if (tv->v_type != VAR_STRING)
1512 {
1513 str = typval_tostring(tv);
1514 clear_tv(tv);
1515 tv->v_type = VAR_STRING;
1516 tv->vval.v_string = str;
1517 }
1518 }
1519 break;
1520
1521 case ISN_DROP:
1522 --ectx.ec_stack.ga_len;
1523 clear_tv(STACK_TV_BOT(0));
1524 break;
1525 }
1526 }
1527
1528done:
1529 // function finished, get result from the stack.
1530 tv = STACK_TV_BOT(-1);
1531 *rettv = *tv;
1532 tv->v_type = VAR_UNKNOWN;
1533 ret = OK;
1534
1535failed:
1536 for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
1537 clear_tv(STACK_TV(idx));
1538 vim_free(ectx.ec_stack.ga_data);
1539 return ret;
1540}
1541
1542#define DISASSEMBLE 1
1543
1544/*
1545 * ":dissassemble".
1546 */
1547 void
1548ex_disassemble(exarg_T *eap)
1549{
1550#ifdef DISASSEMBLE
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001551 char_u *fname;
1552 ufunc_T *ufunc;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001553 dfunc_T *dfunc;
1554 isn_T *instr;
1555 int current;
1556 int line_idx = 0;
1557 int prev_current = 0;
1558
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001559 fname = trans_function_name(&eap->arg, FALSE,
1560 TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD | TFN_NO_DEREF, NULL, NULL);
1561 ufunc = find_func(fname, NULL);
1562 vim_free(fname);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001563 if (ufunc == NULL)
1564 {
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001565 semsg("E1061: Cannot find function %s", eap->arg);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001566 return;
1567 }
1568 if (ufunc->uf_dfunc_idx < 0)
1569 {
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +01001570 semsg("E1062: Function %s is not compiled", eap->arg);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001571 return;
1572 }
1573 if (ufunc->uf_name_exp != NULL)
1574 msg((char *)ufunc->uf_name_exp);
1575 else
1576 msg((char *)ufunc->uf_name);
1577
1578 dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
1579 instr = dfunc->df_instr;
1580 for (current = 0; current < dfunc->df_instr_count; ++current)
1581 {
1582 isn_T *iptr = &instr[current];
1583
1584 while (line_idx < iptr->isn_lnum && line_idx < ufunc->uf_lines.ga_len)
1585 {
1586 if (current > prev_current)
1587 {
1588 msg_puts("\n\n");
1589 prev_current = current;
1590 }
1591 msg(((char **)ufunc->uf_lines.ga_data)[line_idx++]);
1592 }
1593
1594 switch (iptr->isn_type)
1595 {
1596 case ISN_EXEC:
1597 smsg("%4d EXEC %s", current, iptr->isn_arg.string);
1598 break;
1599 case ISN_ECHO:
1600 {
1601 echo_T *echo = &iptr->isn_arg.echo;
1602
1603 smsg("%4d %s %d", current,
1604 echo->echo_with_white ? "ECHO" : "ECHON",
1605 echo->echo_count);
1606 }
1607 break;
1608 case ISN_LOAD:
1609 if (iptr->isn_arg.number < 0)
1610 smsg("%4d LOAD arg[%lld]", current,
1611 iptr->isn_arg.number + STACK_FRAME_SIZE);
1612 else
1613 smsg("%4d LOAD $%lld", current, iptr->isn_arg.number);
1614 break;
1615 case ISN_LOADV:
1616 smsg("%4d LOADV v:%s", current,
1617 get_vim_var_name(iptr->isn_arg.number));
1618 break;
1619 case ISN_LOADSCRIPT:
1620 {
1621 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001622 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001623 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1624 + iptr->isn_arg.script.script_idx;
1625
1626 smsg("%4d LOADSCRIPT %s from %s", current,
1627 sv->sv_name, si->sn_name);
1628 }
1629 break;
1630 case ISN_LOADS:
1631 {
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001632 scriptitem_T *si = SCRIPT_ITEM(
1633 iptr->isn_arg.loadstore.ls_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001634
1635 smsg("%4d LOADS s:%s from %s", current,
1636 iptr->isn_arg.string, si->sn_name);
1637 }
1638 break;
1639 case ISN_LOADG:
1640 smsg("%4d LOADG g:%s", current, iptr->isn_arg.string);
1641 break;
1642 case ISN_LOADOPT:
1643 smsg("%4d LOADOPT %s", current, iptr->isn_arg.string);
1644 break;
1645 case ISN_LOADENV:
1646 smsg("%4d LOADENV %s", current, iptr->isn_arg.string);
1647 break;
1648 case ISN_LOADREG:
1649 smsg("%4d LOADREG @%c", current, iptr->isn_arg.number);
1650 break;
1651
1652 case ISN_STORE:
1653 smsg("%4d STORE $%lld", current, iptr->isn_arg.number);
1654 break;
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001655 case ISN_STOREV:
1656 smsg("%4d STOREV v:%s", current,
1657 get_vim_var_name(iptr->isn_arg.number));
1658 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001659 case ISN_STOREG:
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001660 smsg("%4d STOREG %s", current, iptr->isn_arg.string);
1661 break;
1662 case ISN_STORES:
1663 {
1664 scriptitem_T *si = SCRIPT_ITEM(
1665 iptr->isn_arg.loadstore.ls_sid);
1666
1667 smsg("%4d STORES s:%s in %s", current,
1668 iptr->isn_arg.string, si->sn_name);
1669 }
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001670 break;
1671 case ISN_STORESCRIPT:
1672 {
1673 scriptitem_T *si =
Bram Moolenaar21b9e972020-01-26 19:26:46 +01001674 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001675 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
1676 + iptr->isn_arg.script.script_idx;
1677
1678 smsg("%4d STORESCRIPT %s in %s", current,
1679 sv->sv_name, si->sn_name);
1680 }
1681 break;
1682 case ISN_STOREOPT:
1683 smsg("%4d STOREOPT &%s", current,
1684 iptr->isn_arg.storeopt.so_name);
1685 break;
Bram Moolenaarb283a8a2020-02-02 22:24:04 +01001686 case ISN_STOREENV:
1687 smsg("%4d STOREENV $%s", current, iptr->isn_arg.string);
1688 break;
1689 case ISN_STOREREG:
1690 smsg("%4d STOREREG @%c", current, iptr->isn_arg.number);
1691 break;
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001692 case ISN_STORENR:
1693 smsg("%4d STORE %lld in $%d", current,
1694 iptr->isn_arg.storenr.str_val,
1695 iptr->isn_arg.storenr.str_idx);
1696 break;
1697
1698 // constants
1699 case ISN_PUSHNR:
1700 smsg("%4d PUSHNR %lld", current, iptr->isn_arg.number);
1701 break;
1702 case ISN_PUSHBOOL:
1703 case ISN_PUSHSPEC:
1704 smsg("%4d PUSH %s", current,
1705 get_var_special_name(iptr->isn_arg.number));
1706 break;
1707 case ISN_PUSHF:
Bram Moolenaara5d59532020-01-26 21:42:03 +01001708#ifdef FEAT_FLOAT
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001709 smsg("%4d PUSHF %g", current, iptr->isn_arg.fnumber);
Bram Moolenaara5d59532020-01-26 21:42:03 +01001710#endif
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001711 break;
1712 case ISN_PUSHS:
1713 smsg("%4d PUSHS \"%s\"", current, iptr->isn_arg.string);
1714 break;
1715 case ISN_PUSHBLOB:
1716 {
1717 char_u *r;
1718 char_u numbuf[NUMBUFLEN];
1719 char_u *tofree;
1720
1721 r = blob2string(iptr->isn_arg.blob, &tofree, numbuf);
1722 smsg("%4d PUSHBLOB \"%s\"", current, r);
1723 vim_free(tofree);
1724 }
1725 break;
1726 case ISN_PUSHEXC:
1727 smsg("%4d PUSH v:exception", current);
1728 break;
1729 case ISN_NEWLIST:
1730 smsg("%4d NEWLIST size %lld", current, iptr->isn_arg.number);
1731 break;
1732 case ISN_NEWDICT:
1733 smsg("%4d NEWDICT size %lld", current, iptr->isn_arg.number);
1734 break;
1735
1736 // function call
1737 case ISN_BCALL:
1738 {
1739 cbfunc_T *cbfunc = &iptr->isn_arg.bfunc;
1740
1741 smsg("%4d BCALL %s(argc %d)", current,
1742 internal_func_name(cbfunc->cbf_idx),
1743 cbfunc->cbf_argcount);
1744 }
1745 break;
1746 case ISN_DCALL:
1747 {
1748 cdfunc_T *cdfunc = &iptr->isn_arg.dfunc;
1749 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1750 + cdfunc->cdf_idx;
1751
1752 smsg("%4d DCALL %s(argc %d)", current,
1753 df->df_ufunc->uf_name_exp != NULL
1754 ? df->df_ufunc->uf_name_exp
1755 : df->df_ufunc->uf_name, cdfunc->cdf_argcount);
1756 }
1757 break;
1758 case ISN_UCALL:
1759 {
1760 cufunc_T *cufunc = &iptr->isn_arg.ufunc;
1761
1762 smsg("%4d UCALL %s(argc %d)", current,
1763 cufunc->cuf_name, cufunc->cuf_argcount);
1764 }
1765 break;
1766 case ISN_PCALL:
1767 {
1768 cpfunc_T *cpfunc = &iptr->isn_arg.pfunc;
1769
1770 smsg("%4d PCALL%s (argc %d)", current,
1771 cpfunc->cpf_top ? " top" : "", cpfunc->cpf_argcount);
1772 }
1773 break;
1774 case ISN_RETURN:
1775 smsg("%4d RETURN", current);
1776 break;
1777 case ISN_FUNCREF:
1778 {
1779 dfunc_T *df = ((dfunc_T *)def_functions.ga_data)
1780 + iptr->isn_arg.number;
1781
1782 smsg("%4d FUNCREF %s", current, df->df_ufunc->uf_name);
1783 }
1784 break;
1785
1786 case ISN_JUMP:
1787 {
1788 char *when = "?";
1789
1790 switch (iptr->isn_arg.jump.jump_when)
1791 {
1792 case JUMP_ALWAYS:
1793 when = "JUMP";
1794 break;
1795 case JUMP_IF_TRUE:
1796 when = "JUMP_IF_TRUE";
1797 break;
1798 case JUMP_AND_KEEP_IF_TRUE:
1799 when = "JUMP_AND_KEEP_IF_TRUE";
1800 break;
1801 case JUMP_IF_FALSE:
1802 when = "JUMP_IF_FALSE";
1803 break;
1804 case JUMP_AND_KEEP_IF_FALSE:
1805 when = "JUMP_AND_KEEP_IF_FALSE";
1806 break;
1807 }
1808 smsg("%4d %s -> %lld", current, when,
1809 iptr->isn_arg.jump.jump_where);
1810 }
1811 break;
1812
1813 case ISN_FOR:
1814 {
1815 forloop_T *forloop = &iptr->isn_arg.forloop;
1816
1817 smsg("%4d FOR $%d -> %d", current,
1818 forloop->for_idx, forloop->for_end);
1819 }
1820 break;
1821
1822 case ISN_TRY:
1823 {
1824 try_T *try = &iptr->isn_arg.try;
1825
1826 smsg("%4d TRY catch -> %d, finally -> %d", current,
1827 try->try_catch, try->try_finally);
1828 }
1829 break;
1830 case ISN_CATCH:
1831 // TODO
1832 smsg("%4d CATCH", current);
1833 break;
1834 case ISN_ENDTRY:
1835 smsg("%4d ENDTRY", current);
1836 break;
1837 case ISN_THROW:
1838 smsg("%4d THROW", current);
1839 break;
1840
1841 // expression operations on number
1842 case ISN_OPNR:
1843 case ISN_OPFLOAT:
1844 case ISN_OPANY:
1845 {
1846 char *what;
1847 char *ins;
1848
1849 switch (iptr->isn_arg.op.op_type)
1850 {
1851 case EXPR_MULT: what = "*"; break;
1852 case EXPR_DIV: what = "/"; break;
1853 case EXPR_REM: what = "%"; break;
1854 case EXPR_SUB: what = "-"; break;
1855 case EXPR_ADD: what = "+"; break;
1856 default: what = "???"; break;
1857 }
1858 switch (iptr->isn_type)
1859 {
1860 case ISN_OPNR: ins = "OPNR"; break;
1861 case ISN_OPFLOAT: ins = "OPFLOAT"; break;
1862 case ISN_OPANY: ins = "OPANY"; break;
1863 default: ins = "???"; break;
1864 }
1865 smsg("%4d %s %s", current, ins, what);
1866 }
1867 break;
1868
1869 case ISN_COMPAREBOOL:
1870 case ISN_COMPARESPECIAL:
1871 case ISN_COMPARENR:
1872 case ISN_COMPAREFLOAT:
1873 case ISN_COMPARESTRING:
1874 case ISN_COMPAREBLOB:
1875 case ISN_COMPARELIST:
1876 case ISN_COMPAREDICT:
1877 case ISN_COMPAREFUNC:
1878 case ISN_COMPAREPARTIAL:
1879 case ISN_COMPAREANY:
1880 {
1881 char *p;
1882 char buf[10];
1883 char *type;
1884
1885 switch (iptr->isn_arg.op.op_type)
1886 {
1887 case EXPR_EQUAL: p = "=="; break;
1888 case EXPR_NEQUAL: p = "!="; break;
1889 case EXPR_GREATER: p = ">"; break;
1890 case EXPR_GEQUAL: p = ">="; break;
1891 case EXPR_SMALLER: p = "<"; break;
1892 case EXPR_SEQUAL: p = "<="; break;
1893 case EXPR_MATCH: p = "=~"; break;
1894 case EXPR_IS: p = "is"; break;
1895 case EXPR_ISNOT: p = "isnot"; break;
1896 case EXPR_NOMATCH: p = "!~"; break;
1897 default: p = "???"; break;
1898 }
1899 STRCPY(buf, p);
1900 if (iptr->isn_arg.op.op_ic == TRUE)
1901 strcat(buf, "?");
1902 switch(iptr->isn_type)
1903 {
1904 case ISN_COMPAREBOOL: type = "COMPAREBOOL"; break;
1905 case ISN_COMPARESPECIAL:
1906 type = "COMPARESPECIAL"; break;
1907 case ISN_COMPARENR: type = "COMPARENR"; break;
1908 case ISN_COMPAREFLOAT: type = "COMPAREFLOAT"; break;
1909 case ISN_COMPARESTRING:
1910 type = "COMPARESTRING"; break;
1911 case ISN_COMPAREBLOB: type = "COMPAREBLOB"; break;
1912 case ISN_COMPARELIST: type = "COMPARELIST"; break;
1913 case ISN_COMPAREDICT: type = "COMPAREDICT"; break;
1914 case ISN_COMPAREFUNC: type = "COMPAREFUNC"; break;
1915 case ISN_COMPAREPARTIAL:
1916 type = "COMPAREPARTIAL"; break;
1917 case ISN_COMPAREANY: type = "COMPAREANY"; break;
1918 default: type = "???"; break;
1919 }
1920
1921 smsg("%4d %s %s", current, type, buf);
1922 }
1923 break;
1924
1925 case ISN_ADDLIST: smsg("%4d ADDLIST", current); break;
1926 case ISN_ADDBLOB: smsg("%4d ADDBLOB", current); break;
1927
1928 // expression operations
1929 case ISN_CONCAT: smsg("%4d CONCAT", current); break;
1930 case ISN_INDEX: smsg("%4d INDEX", current); break;
1931 case ISN_MEMBER: smsg("%4d MEMBER %s", current,
1932 iptr->isn_arg.string); break;
1933 case ISN_NEGATENR: smsg("%4d NEGATENR", current); break;
1934
1935 case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
1936 case ISN_CHECKTYPE: smsg("%4d CHECKTYPE %s stack[%d]", current,
1937 vartype_name(iptr->isn_arg.type.ct_type),
1938 iptr->isn_arg.type.ct_off);
1939 break;
1940 case ISN_2BOOL: if (iptr->isn_arg.number)
1941 smsg("%4d INVERT (!val)", current);
1942 else
1943 smsg("%4d 2BOOL (!!val)", current);
1944 break;
1945 case ISN_2STRING: smsg("%4d 2STRING stack[%d]", current,
1946 iptr->isn_arg.number);
1947 break;
1948
1949 case ISN_DROP: smsg("%4d DROP", current); break;
1950 }
1951 }
1952#endif
1953}
1954
1955/*
1956 * Return TRUE when "tv" is not falsey: non-zero, non-empty string, non-empty
1957 * list, etc. Mostly like what JavaScript does, except that empty list and
1958 * empty dictionary are FALSE.
1959 */
1960 int
1961tv2bool(typval_T *tv)
1962{
1963 switch (tv->v_type)
1964 {
1965 case VAR_NUMBER:
1966 return tv->vval.v_number != 0;
1967 case VAR_FLOAT:
1968#ifdef FEAT_FLOAT
1969 return tv->vval.v_float != 0.0;
1970#else
1971 break;
1972#endif
1973 case VAR_PARTIAL:
1974 return tv->vval.v_partial != NULL;
1975 case VAR_FUNC:
1976 case VAR_STRING:
1977 return tv->vval.v_string != NULL && *tv->vval.v_string != NUL;
1978 case VAR_LIST:
1979 return tv->vval.v_list != NULL && tv->vval.v_list->lv_len > 0;
1980 case VAR_DICT:
1981 return tv->vval.v_dict != NULL
1982 && tv->vval.v_dict->dv_hashtab.ht_used > 0;
1983 case VAR_BOOL:
1984 case VAR_SPECIAL:
1985 return tv->vval.v_number == VVAL_TRUE ? TRUE : FALSE;
1986 case VAR_JOB:
1987#ifdef FEAT_JOB_CHANNEL
1988 return tv->vval.v_job != NULL;
1989#else
1990 break;
1991#endif
1992 case VAR_CHANNEL:
1993#ifdef FEAT_JOB_CHANNEL
1994 return tv->vval.v_channel != NULL;
1995#else
1996 break;
1997#endif
1998 case VAR_BLOB:
1999 return tv->vval.v_blob != NULL && tv->vval.v_blob->bv_ga.ga_len > 0;
2000 case VAR_UNKNOWN:
2001 case VAR_VOID:
2002 break;
2003 }
2004 return FALSE;
2005}
2006
2007/*
2008 * If "tv" is a string give an error and return FAIL.
2009 */
2010 int
2011check_not_string(typval_T *tv)
2012{
2013 if (tv->v_type == VAR_STRING)
2014 {
2015 emsg(_("E1030: Using a String as a Number"));
2016 clear_tv(tv);
2017 return FAIL;
2018 }
2019 return OK;
2020}
2021
2022
2023#endif // FEAT_EVAL