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