diff src/vim9execute.c @ 24146:03fc95628eb0 v8.2.2614

patch 8.2.2614: Vim9: function is deleted while executing Commit: https://github.com/vim/vim/commit/c970e4225b68ff8650ff23df09e04246c147fca3 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Mar 17 15:03:04 2021 +0100 patch 8.2.2614: Vim9: function is deleted while executing Problem: Vim9: function is deleted while executing. Solution: increment the call count, when more than zero do not delete the function but mark it as dead. (closes #7977)
author Bram Moolenaar <Bram@vim.org>
date Wed, 17 Mar 2021 15:15:03 +0100
parents fcbb1d4df15b
children 40e27d96e395
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -323,6 +323,8 @@ call_dfunc(int cdf_idx, partial_T *pt, i
     else
 	ectx->ec_outer = NULL;
 
+    ++ufunc->uf_calls;
+
     // Set execution state to the start of the called function.
     ectx->ec_dfunc_idx = cdf_idx;
     ectx->ec_instr = INSTRUCTIONS(dfunc);
@@ -556,6 +558,9 @@ func_return(ectx_T *ectx)
 	}
     }
 #endif
+    // TODO: when is it safe to delete the function when it is no longer used?
+    --dfunc->df_ufunc->uf_calls;
+
     // execution context goes one level up
     entry = estack_pop();
     if (entry != NULL)
@@ -1334,7 +1339,7 @@ call_def_function(
 	    ++ectx.ec_stack.ga_len;
 	}
     if (ufunc->uf_va_name != NULL)
-	    ++ectx.ec_stack.ga_len;
+	++ectx.ec_stack.ga_len;
 
     // Frame pointer points to just after arguments.
     ectx.ec_frame_idx = ectx.ec_stack.ga_len;
@@ -1407,6 +1412,9 @@ call_def_function(
     // Do turn errors into exceptions.
     suppress_errthrow = FALSE;
 
+    // Do not delete the function while executing it.
+    ++ufunc->uf_calls;
+
     // When ":silent!" was used before calling then we still abort the
     // function.  If ":silent!" is used in the function then we don't.
     emsg_silent_def = emsg_silent;
@@ -3838,6 +3846,9 @@ failed:
     estack_pop();
     current_sctx = save_current_sctx;
 
+    // TODO: when is it safe to delete the function if it is no longer used?
+    --ufunc->uf_calls;
+
     if (*msg_list != NULL && saved_msg_list != NULL)
     {
 	msglist_T **plist = saved_msg_list;