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