Mercurial > vim
diff src/vim9compile.c @ 20943:1693ca876049 v8.2.1023
patch 8.2.1023: Vim9: redefining a function uses a new index every time
Commit: https://github.com/vim/vim/commit/0cb5bcf5836de83f7d64fb01d3ce708caacaf66c
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 20 18:19:09 2020 +0200
patch 8.2.1023: Vim9: redefining a function uses a new index every time
Problem: Vim9: redefining a function uses a new index every time.
Solution: When redefining a function clear the contents and re-use the
index.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 20 Jun 2020 18:30:04 +0200 |
parents | e2fd5f05342f |
children | 0653b9b72091 |
line wrap: on
line diff
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1493,7 +1493,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu return FAIL; } - if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED) + if (ufunc->uf_def_status != UF_NOT_COMPILED) { int i; @@ -1517,16 +1517,16 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu return FAIL; } } - if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED) + if (ufunc->uf_def_status == UF_TO_BE_COMPILED) if (compile_def_function(ufunc, TRUE, NULL) == FAIL) return FAIL; } if ((isn = generate_instr(cctx, - ufunc->uf_dfunc_idx != UF_NOT_COMPILED ? ISN_DCALL + ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL : ISN_UCALL)) == NULL) return FAIL; - if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED) + if (ufunc->uf_def_status != UF_NOT_COMPILED) { isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx; isn->isn_arg.dfunc.cdf_argcount = argcount; @@ -3042,7 +3042,7 @@ compile_lambda(char_u **arg, cctx_T *cct // Compile it into instructions. compile_def_function(ufunc, TRUE, cctx); - if (ufunc->uf_dfunc_idx >= 0) + if (ufunc->uf_def_status == UF_COMPILED) return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx); return FAIL; } @@ -4539,7 +4539,7 @@ compile_nested_function(exarg_T *eap, cc if (ufunc == NULL) return NULL; - if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED + if (ufunc->uf_def_status == UF_TO_BE_COMPILED && compile_def_function(ufunc, TRUE, cctx) == FAIL) return NULL; @@ -6517,13 +6517,22 @@ theend: /* * Add a function to the list of :def functions. - * This "sets ufunc->uf_dfunc_idx" but the function isn't compiled yet. + * This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet. */ static int add_def_function(ufunc_T *ufunc) { dfunc_T *dfunc; + if (def_functions.ga_len == 0) + { + // The first position is not used, so that a zero uf_dfunc_idx means it + // wasn't set. + if (ga_grow(&def_functions, 1) == FAIL) + return FAIL; + ++def_functions.ga_len; + } + // Add the function to "def_functions". if (ga_grow(&def_functions, 1) == FAIL) return FAIL; @@ -6563,7 +6572,7 @@ compile_def_function(ufunc_T *ufunc, int // When using a function that was compiled before: Free old instructions. // Otherwise add a new entry in "def_functions". - if (ufunc->uf_dfunc_idx >= 0) + if (ufunc->uf_dfunc_idx > 0) { dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; @@ -7014,6 +7023,7 @@ compile_def_function(ufunc_T *ufunc, int dfunc->df_closure_count = cctx.ctx_closure_count; if (cctx.ctx_outer_used) ufunc->uf_flags |= FC_CLOSURE; + ufunc->uf_def_status = UF_COMPILED; } ret = OK; @@ -7033,7 +7043,7 @@ erret: if (!dfunc->df_deleted && ufunc->uf_dfunc_idx == def_functions.ga_len - 1) --def_functions.ga_len; - ufunc->uf_dfunc_idx = UF_NOT_COMPILED; + ufunc->uf_def_status = UF_NOT_COMPILED; while (cctx.ctx_scope != NULL) drop_scope(&cctx); @@ -7261,17 +7271,19 @@ delete_def_function_contents(dfunc_T *df } /* - * When a user function is deleted, delete any associated def function. + * When a user function is deleted, clear the contents of any associated def + * function. The position in def_functions can be re-used. */ void -delete_def_function(ufunc_T *ufunc) -{ - if (ufunc->uf_dfunc_idx >= 0) +clear_def_function(ufunc_T *ufunc) +{ + if (ufunc->uf_dfunc_idx > 0) { dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; delete_def_function_contents(dfunc); + ufunc->uf_def_status = UF_NOT_COMPILED; } }