Mercurial > vim
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) |