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