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