@@ -5171,13 +5171,7 @@ exec_instructions(ectx_T *ectx)
51715171done :
51725172 ret = OK ;
51735173theend :
5174- {
5175- dfunc_T * dfunc = ((dfunc_T * )def_functions .ga_data )
5176- + ectx -> ec_dfunc_idx ;
5177-
5178- if (dfunc -> df_defer_var_idx > 0 )
5179- invoke_defer_funcs (ectx );
5180- }
5174+ may_invoke_defer_funcs (ectx );
51815175
51825176 dict_stack_clear (dict_stack_len_at_start );
51835177 ectx -> ec_trylevel_at_start = save_trylevel_at_start ;
@@ -5258,6 +5252,7 @@ call_def_function(
52585252 int argc_arg , // nr of arguments
52595253 typval_T * argv , // arguments
52605254 partial_T * partial , // optional partial for context
5255+ funccall_T * funccal ,
52615256 typval_T * rettv ) // return value
52625257{
52635258 ectx_T ectx ; // execution context
@@ -5494,6 +5489,10 @@ call_def_function(
54945489 ectx .ec_instr = INSTRUCTIONS (dfunc );
54955490 }
54965491
5492+ // Store the execution context in funccal, used by invoke_all_defer().
5493+ if (funccal != NULL )
5494+ funccal -> fc_ectx = & ectx ;
5495+
54975496 // Following errors are in the function, not the caller.
54985497 // Commands behave like vim9script.
54995498 estack_push_ufunc (ufunc , 1 );
@@ -5537,8 +5536,7 @@ call_def_function(
55375536 }
55385537
55395538 // When failed need to unwind the call stack.
5540- while (ectx .ec_frame_idx != ectx .ec_initial_frame_idx )
5541- func_return (& ectx );
5539+ unwind_def_callstack (& ectx );
55425540
55435541 // Deal with any remaining closures, they may be in use somewhere.
55445542 if (ectx .ec_funcrefs .ga_len > 0 )
@@ -5603,6 +5601,30 @@ call_def_function(
56035601 return ret ;
56045602}
56055603
5604+ /*
5605+ * Called when a def function has finished (possibly failed).
5606+ * Invoke all the function returns to clean up and invoke deferred functions,
5607+ * except the toplevel one.
5608+ */
5609+ void
5610+ unwind_def_callstack (ectx_T * ectx )
5611+ {
5612+ while (ectx -> ec_frame_idx != ectx -> ec_initial_frame_idx )
5613+ func_return (ectx );
5614+ }
5615+
5616+ /*
5617+ * Invoke any deffered functions for the top function in "ectx".
5618+ */
5619+ void
5620+ may_invoke_defer_funcs (ectx_T * ectx )
5621+ {
5622+ dfunc_T * dfunc = ((dfunc_T * )def_functions .ga_data ) + ectx -> ec_dfunc_idx ;
5623+
5624+ if (dfunc -> df_defer_var_idx > 0 )
5625+ invoke_defer_funcs (ectx );
5626+ }
5627+
56065628/*
56075629 * List instructions "instr" up to "instr_count" or until ISN_FINISH.
56085630 * "ufunc" has the source lines, NULL for the instructions of ISN_SUBSTITUTE.
0 commit comments