Mercurial > vim
diff src/userfunc.c @ 23249:43532077b5ff v8.2.2170
patch 8.2.2170: Vim9: a global function defined in a :def function fails
Commit: https://github.com/vim/vim/commit/f112f30a82f17114d8b08a0fb90928cd19440581
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Dec 20 17:47:52 2020 +0100
patch 8.2.2170: Vim9: a global function defined in a :def function fails
Problem: Vim9: a global function defined in a :def function fails if it
uses the context.
Solution: Create a partial to store the closure context. (see #7410)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 20 Dec 2020 18:00:06 +0100 |
parents | 033b2a97d59b |
children | 35583da6397e |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -1225,6 +1225,8 @@ func_clear_items(ufunc_T *fp) VIM_CLEAR(fp->uf_block_ids); VIM_CLEAR(fp->uf_va_name); clear_type_list(&fp->uf_type_list); + partial_unref(fp->uf_partial); + fp->uf_partial = NULL; #ifdef FEAT_LUA if (fp->uf_cb_free != NULL) @@ -1305,12 +1307,13 @@ func_clear_free(ufunc_T *fp, int force) /* * Copy already defined function "lambda" to a new function with name "global". * This is for when a compiled function defines a global function. + * Caller should take care of adding a partial for a closure. */ - void + ufunc_T * copy_func(char_u *lambda, char_u *global) { ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL); - ufunc_T *fp; + ufunc_T *fp = NULL; if (ufunc == NULL) semsg(_(e_lambda_function_not_found_str), lambda); @@ -1321,12 +1324,12 @@ copy_func(char_u *lambda, char_u *global if (fp != NULL) { semsg(_(e_funcexts), global); - return; + return NULL; } fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1); if (fp == NULL) - return; + return NULL; fp->uf_varargs = ufunc->uf_varargs; fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY; @@ -1362,15 +1365,17 @@ copy_func(char_u *lambda, char_u *global if (fp->uf_va_name == NULL) goto failed; } + fp->uf_ret_type = ufunc->uf_ret_type; fp->uf_refcount = 1; STRCPY(fp->uf_name, global); hash_add(&func_hashtab, UF2HIKEY(fp)); } - return; + return fp; failed: func_clear_free(fp, TRUE); + return NULL; } static int funcdepth = 0;