diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-03-17 15:03:04 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-03-17 15:03:04 +0100 |
commit | c970e4225b68ff8650ff23df09e04246c147fca3 (patch) | |
tree | 9c46d37f0a911323058fd11964a69e72aa98d80a /src/userfunc.c | |
parent | 6ccfd99b923cc3452a6e6450dfdd7e31ea602dfd (diff) |
patch 8.2.2614: Vim9: function is deleted while executingv8.2.2614
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)
Diffstat (limited to 'src/userfunc.c')
-rw-r--r-- | src/userfunc.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/userfunc.c b/src/userfunc.c index e89b8858d3..4793ee5552 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1359,9 +1359,12 @@ func_remove(ufunc_T *fp) // function, so we can find the index when defining the function again. // Do remove it when it's a copy. if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0) + { fp->uf_flags |= FC_DEAD; - else - hash_remove(&func_hashtab, hi); + return FALSE; + } + hash_remove(&func_hashtab, hi); + fp->uf_flags |= FC_DELETED; return TRUE; } return FALSE; @@ -2134,11 +2137,23 @@ delete_script_functions(int sid) int changed = func_hashtab.ht_changed; fp->uf_flags |= FC_DEAD; - func_clear(fp, TRUE); - // When clearing a function another function can be cleared - // as a side effect. When that happens start over. - if (changed != func_hashtab.ht_changed) - break; + + if (fp->uf_calls > 0) + { + // Function is executing, don't free it but do remove + // it from the hashtable. + if (func_remove(fp)) + fp->uf_refcount--; + } + else + { + func_clear(fp, TRUE); + // When clearing a function another function can be + // cleared as a side effect. When that happens start + // over. + if (changed != func_hashtab.ht_changed) + break; + } } --todo; } @@ -4251,7 +4266,6 @@ ex_delfunction(exarg_T *eap) // do remove it from the hashtable. if (func_remove(fp)) fp->uf_refcount--; - fp->uf_flags |= FC_DELETED; } else func_clear_free(fp, FALSE); |