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