summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/proto/userfunc.pro1
-rw-r--r--src/userfunc.c2
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c5
4 files changed, 7 insertions, 3 deletions
diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro
index b5ea9b666..85144482e 100644
--- a/src/proto/userfunc.pro
+++ b/src/proto/userfunc.pro
@@ -12,6 +12,7 @@ ufunc_T *find_func_even_dead(char_u *name, int is_global, cctx_T *cctx);
ufunc_T *find_func(char_u *name, int is_global, cctx_T *cctx);
int func_is_global(ufunc_T *ufunc);
int func_name_refcount(char_u *name);
+void func_clear_free(ufunc_T *fp, int force);
int copy_func(char_u *lambda, char_u *global, ectx_T *ectx);
int funcdepth_increment(void);
void funcdepth_decrement(void);
diff --git a/src/userfunc.c b/src/userfunc.c
index 7fc764e4d..4f86c0791 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -2281,7 +2281,7 @@ func_free(ufunc_T *fp, int force)
* Free all things that a function contains and free the function itself.
* When "force" is TRUE we are exiting.
*/
- static void
+ void
func_clear_free(ufunc_T *fp, int force)
{
func_clear(fp, force);
diff --git a/src/version.c b/src/version.c
index 6d6356967..aff25cfdd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3753,
+/**/
3752,
/**/
3751,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index adfb9207c..f805dc0f1 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -4988,8 +4988,9 @@ call_def_function(
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 (--ufunc->uf_calls <= 0 && ufunc->uf_refcount <= 0)
+ // Function was unreferenced while being used, free it now.
+ func_clear_free(ufunc, FALSE);
if (*msg_list != NULL && saved_msg_list != NULL)
{