diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-04-17 08:56:23 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-04-17 09:08:08 +0800 |
commit | 6bfba3660c5fbb22104cd87bd66a1381007fca22 (patch) | |
tree | 354d2833c46402470c3c09fdd9e6a6f4bcd57e1c /src | |
parent | 78535664bd29e6f2bd4b64c20cb29ef40f9bccd4 (diff) | |
download | rneovim-6bfba3660c5fbb22104cd87bd66a1381007fca22.tar.gz rneovim-6bfba3660c5fbb22104cd87bd66a1381007fca22.tar.bz2 rneovim-6bfba3660c5fbb22104cd87bd66a1381007fca22.zip |
vim-patch:9.0.0406: deferred functions not invoked when partial func exits
Problem: Deferred functions not invoked when partial func exits.
Solution: Create a funccall_T when calling a :def function.
https://github.com/vim/vim/commit/9667b2c888351b04751bdb43cba0d4ffc8c13ab1
The remove_funccal() function is currently unused, but it will be used
in patch 9.0.0618.
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval/userfunc.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 6016ad0646..32f9f9182c 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -881,6 +881,27 @@ static void func_clear_free(ufunc_T *fp, bool force) func_free(fp); } +/// Allocate a funccall_T, link it in current_funccal and fill in "fp" and "rettv". +/// Must be followed by one call to remove_funccal() or cleanup_function_call(). +funccall_T *create_funccal(ufunc_T *fp, typval_T *rettv) +{ + funccall_T *fc = xcalloc(1, sizeof(funccall_T)); + fc->fc_caller = current_funccal; + current_funccal = fc; + fc->fc_func = fp; + func_ptr_ref(fp); + fc->fc_rettv = rettv; + return fc; +} + +/// Restore current_funccal. +void remove_funccal(void) +{ + funccall_T *fc = current_funccal; + current_funccal = fc->fc_caller; + free_funccal(fc); +} + /// Call a user function /// /// @param fp Function to call. @@ -895,7 +916,6 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett FUNC_ATTR_NONNULL_ARG(1, 3, 4) { bool using_sandbox = false; - funccall_T *fc; int save_did_emsg; static int depth = 0; dictitem_T *v; @@ -930,19 +950,13 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett // check for CTRL-C hit line_breakcheck(); // prepare the funccall_T structure - fc = xcalloc(1, sizeof(funccall_T)); - fc->fc_caller = current_funccal; - current_funccal = fc; - fc->fc_func = fp; - fc->fc_rettv = rettv; + funccall_T *fc = create_funccal(fp, rettv); fc->fc_level = ex_nesting_level; // Check if this function has a breakpoint. fc->fc_breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0); fc->fc_dbg_tick = debug_tick; - // Set up fields for closure. ga_init(&fc->fc_ufuncs, sizeof(ufunc_T *), 1); - func_ptr_ref(fp); if (strncmp(fp->uf_name, "<lambda>", 8) == 0) { islambda = true; |