Mercurial > vim
diff src/vim9compile.c @ 26323:3841da4eac23 v8.2.3692
patch 8.2.3692: Vim9: cannot use :func inside a :def function
Commit: https://github.com/vim/vim/commit/38453528c3372293d70c8e85471a6188749ff331
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Nov 28 22:00:12 2021 +0000
patch 8.2.3692: Vim9: cannot use :func inside a :def function
Problem: Vim9: cannot use :func inside a :def function.
Solution: Make it work.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 28 Nov 2021 23:15:03 +0100 |
parents | 36361f080ffd |
children | 4044306e3836 |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1675,7 +1675,10 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T * RETURN_OK_IF_SKIP(cctx); if ((isn = generate_instr(cctx, ISN_FUNCREF)) == NULL) return FAIL; - isn->isn_arg.funcref.fr_func = ufunc->uf_dfunc_idx; + if (ufunc->uf_def_status == UF_NOT_COMPILED) + isn->isn_arg.funcref.fr_func_name = vim_strsave(ufunc->uf_name); + else + isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; cctx->ctx_has_closure = 1; // If the referenced function is a closure, it may use items further up in @@ -5835,6 +5838,7 @@ compile_nested_function(exarg_T *eap, cc fill_exarg_from_cctx(eap, cctx); eap->forceit = FALSE; + // We use the special <Lamba>99 name, but it's not really a lambda. lambda_name = vim_strsave(get_lambda_name()); if (lambda_name == NULL) return NULL; @@ -9976,16 +9980,11 @@ compile_def_function( switch (ea.cmdidx) { case CMD_def: + case CMD_function: ea.arg = p; line = compile_nested_function(&ea, &cctx); break; - case CMD_function: - // TODO: should we allow this, e.g. to declare a global - // function? - emsg(_(e_cannot_use_function_inside_def)); - goto erret; - case CMD_return: line = compile_return(p, check_return_type, local_cmdmod.cmod_flags & CMOD_LEGACY, &cctx); @@ -10442,12 +10441,23 @@ delete_instr(isn_T *isn) case ISN_FUNCREF: { - dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) - + isn->isn_arg.funcref.fr_func; - ufunc_T *ufunc = dfunc->df_ufunc; - - if (ufunc != NULL && func_name_refcount(ufunc->uf_name)) - func_ptr_unref(ufunc); + if (isn->isn_arg.funcref.fr_func_name == NULL) + { + dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + + isn->isn_arg.funcref.fr_dfunc_idx; + ufunc_T *ufunc = dfunc->df_ufunc; + + if (ufunc != NULL && func_name_refcount(ufunc->uf_name)) + func_ptr_unref(ufunc); + } + else + { + char_u *name = isn->isn_arg.funcref.fr_func_name; + + if (name != NULL) + func_unref(name); + vim_free(isn->isn_arg.funcref.fr_func_name); + } } break;