# HG changeset patch # User Bram Moolenaar # Date 1638803703 -3600 # Node ID 568f93dcdc62196fb9607895156ce86a0bc777cf # Parent aee00d57234dd58e54440c2aa10b55ee41aa0c92 patch 8.2.3753: Vim9: function unreferenced while called is never deleted Commit: https://github.com/vim/vim/commit/2336c376d5796446d44622b0dfa8fd3fd1a5d22b Author: Bram Moolenaar Date: Mon Dec 6 15:06:54 2021 +0000 patch 8.2.3753: Vim9: function unreferenced while called is never deleted Problem: Vim9: function unreferenced while called is never deleted. Solution: Delete a function when no longer referenced. diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro --- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -12,6 +12,7 @@ ufunc_T *find_func_even_dead(char_u *nam 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 --- 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 --- 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 --- 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) {