Mercurial > vim
diff src/vim9compile.c @ 28173:b0c885507de4 v8.2.4612
patch 8.2.4612: Vim9: cannot use a recursive call in a nested function
Commit: https://github.com/vim/vim/commit/a915fa010330ee7212e06d3511acd363d04d2d28
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Mar 23 11:29:15 2022 +0000
patch 8.2.4612: Vim9: cannot use a recursive call in a nested function
Problem: Vim9: cannot use a recursive call in a nested function. (Sergey
Vlasov)
Solution: Define the funcref before compiling the function. (closes #9989)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 23 Mar 2022 12:30:04 +0100 |
parents | 088d8dc22045 |
children | 662d2d5db9a6 |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -818,6 +818,7 @@ compile_nested_function(exarg_T *eap, cc ufunc_T *ufunc; int r = FAIL; compiletype_T compile_type; + isn_T *funcref_isn = NULL; if (eap->forceit) { @@ -913,6 +914,27 @@ compile_nested_function(exarg_T *eap, cc } } + // Define the funcref before compiling, so that it is found by any + // recursive call. + if (is_global) + { + r = generate_NEWFUNC(cctx, lambda_name, func_name); + func_name = NULL; + lambda_name = NULL; + } + else + { + // Define a local variable for the function reference. + lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start, + TRUE, ufunc->uf_func_type); + + if (lvar == NULL) + goto theend; + if (generate_FUNCREF(cctx, ufunc, &funcref_isn) == FAIL) + goto theend; + r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); + } + compile_type = get_compile_type(ufunc); #ifdef FEAT_PROFILE // If the outer function is profiled, also compile the nested function for @@ -934,24 +956,9 @@ compile_nested_function(exarg_T *eap, cc compile_def_function(ufunc, FALSE, CT_NONE, cctx); #endif - if (is_global) - { - r = generate_NEWFUNC(cctx, lambda_name, func_name); - func_name = NULL; - lambda_name = NULL; - } - else - { - // Define a local variable for the function reference. - lvar_T *lvar = reserve_local(cctx, func_name, name_end - name_start, - TRUE, ufunc->uf_func_type); - - if (lvar == NULL) - goto theend; - if (generate_FUNCREF(cctx, ufunc) == FAIL) - goto theend; - r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); - } + // If a FUNCREF instruction was generated, set the index after compiling. + if (funcref_isn != NULL && ufunc->uf_def_status == UF_COMPILED) + funcref_isn->isn_arg.funcref.fr_dfunc_idx = ufunc->uf_dfunc_idx; theend: vim_free(lambda_name);