comparison src/vim9execute.c @ 30427:4198995b9210 v9.0.0549

patch 9.0.0549: duplicated code in calling a :def function Commit: https://github.com/vim/vim/commit/5800c798385b4a7eded9ea63cfd4f57d1499a673 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Sep 22 17:34:01 2022 +0100 patch 9.0.0549: duplicated code in calling a :def function Problem: Duplicated code in calling a :def function. Solution: Simplify the code.
author Bram Moolenaar <Bram@vim.org>
date Thu, 22 Sep 2022 18:45:03 +0200
parents 221cca379bd5
children 30025bbc1705
comparison
equal deleted inserted replaced
30426:d083c8d6f256 30427:4198995b9210
378 378
379 /* 379 /*
380 * Call compiled function "cdf_idx" from compiled code. 380 * Call compiled function "cdf_idx" from compiled code.
381 * This adds a stack frame and sets the instruction pointer to the start of the 381 * This adds a stack frame and sets the instruction pointer to the start of the
382 * called function. 382 * called function.
383 * If "pt" is not null use "pt->pt_outer" for ec_outer_ref->or_outer. 383 * If "pt_arg" is not NULL use "pt_arg->pt_outer" for ec_outer_ref->or_outer.
384 * 384 *
385 * Stack has: 385 * Stack has:
386 * - current arguments (already there) 386 * - current arguments (already there)
387 * - omitted optional argument (default values) added here 387 * - omitted optional argument (default values) added here
388 * - stack frame: 388 * - stack frame:
392 * - reserved space for local variables 392 * - reserved space for local variables
393 */ 393 */
394 static int 394 static int
395 call_dfunc( 395 call_dfunc(
396 int cdf_idx, 396 int cdf_idx,
397 partial_T *pt, 397 partial_T *pt_arg,
398 int argcount_arg, 398 int argcount_arg,
399 ectx_T *ectx) 399 ectx_T *ectx)
400 { 400 {
401 int argcount = argcount_arg; 401 int argcount = argcount_arg;
402 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx; 402 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
541 (void *)ectx->ec_outer_ref; 541 (void *)ectx->ec_outer_ref;
542 STACK_TV_BOT(STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string = (void *)floc; 542 STACK_TV_BOT(STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string = (void *)floc;
543 STACK_TV_BOT(STACK_FRAME_IDX_OFF)->vval.v_number = ectx->ec_frame_idx; 543 STACK_TV_BOT(STACK_FRAME_IDX_OFF)->vval.v_number = ectx->ec_frame_idx;
544 ectx->ec_frame_idx = ectx->ec_stack.ga_len; 544 ectx->ec_frame_idx = ectx->ec_stack.ga_len;
545 545
546 // Initialize local variables 546 // Initialize all local variables to number zero. Also initialize the
547 for (idx = 0; idx < dfunc->df_varcount; ++idx) 547 // variable that counts how many closures were created. This is used in
548 // handle_closure_in_use().
549 int initcount = dfunc->df_varcount + (dfunc->df_has_closure ? 1 : 0);
550 for (idx = 0; idx < initcount; ++idx)
548 { 551 {
549 typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + idx); 552 typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + idx);
550 553
551 tv->v_type = VAR_NUMBER; 554 tv->v_type = VAR_NUMBER;
552 tv->vval.v_number = 0; 555 tv->vval.v_number = 0;
553 } 556 }
554 if (dfunc->df_has_closure)
555 {
556 typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + dfunc->df_varcount);
557
558 // Initialize the variable that counts how many closures were created.
559 // This is used in handle_closure_in_use().
560 tv->v_type = VAR_NUMBER;
561 tv->vval.v_number = 0;
562 }
563 ectx->ec_stack.ga_len += STACK_FRAME_SIZE + varcount; 557 ectx->ec_stack.ga_len += STACK_FRAME_SIZE + varcount;
564 558
565 if (pt != NULL || ufunc->uf_partial != NULL 559 partial_T *pt = pt_arg != NULL ? pt_arg : ufunc->uf_partial;
566 || (ufunc->uf_flags & FC_CLOSURE)) 560 if (pt != NULL || (ufunc->uf_flags & FC_CLOSURE))
567 { 561 {
568 outer_ref_T *ref = ALLOC_CLEAR_ONE(outer_ref_T); 562 outer_ref_T *ref = ALLOC_CLEAR_ONE(outer_ref_T);
569 563
570 if (ref == NULL) 564 if (ref == NULL)
571 return FAIL; 565 return FAIL;
572 if (pt != NULL) 566 if (pt != NULL)
573 { 567 {
574 ref->or_outer = get_pt_outer(pt); 568 ref->or_outer = get_pt_outer(pt);
575 ++pt->pt_refcount; 569 ++pt->pt_refcount;
576 ref->or_partial = pt; 570 ref->or_partial = pt;
577 }
578 else if (ufunc->uf_partial != NULL)
579 {
580 ref->or_outer = get_pt_outer(ufunc->uf_partial);
581 ++ufunc->uf_partial->pt_refcount;
582 ref->or_partial = ufunc->uf_partial;
583 } 571 }
584 else 572 else
585 { 573 {
586 ref->or_outer = ALLOC_CLEAR_ONE(outer_T); 574 ref->or_outer = ALLOC_CLEAR_ONE(outer_T);
587 if (unlikely(ref->or_outer == NULL)) 575 if (unlikely(ref->or_outer == NULL))
5830 did_emsg_def = 0; 5818 did_emsg_def = 0;
5831 5819
5832 ectx.ec_where.wt_index = 0; 5820 ectx.ec_where.wt_index = 0;
5833 ectx.ec_where.wt_variable = FALSE; 5821 ectx.ec_where.wt_variable = FALSE;
5834 5822
5835 // Execute the instructions until done. 5823 /*
5824 * Execute the instructions until done.
5825 */
5836 ret = exec_instructions(&ectx); 5826 ret = exec_instructions(&ectx);
5837 if (ret == OK) 5827 if (ret == OK)
5838 { 5828 {
5839 // function finished, get result from the stack. 5829 // function finished, get result from the stack.
5840 if (ufunc->uf_ret_type == &t_void) 5830 if (ufunc->uf_ret_type == &t_void)