diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-05-24 23:00:18 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-05-24 23:00:18 +0200 |
commit | 822ba24743af9ee1b5e7f656a7a61a38f3638bca (patch) | |
tree | 7fb853a5f43c2d2682b4c9fd55a0e257e95d2446 /src/vim9compile.c | |
parent | f7271e831614d15d173c7f562cc26f48c2554ce9 (diff) | |
download | vim-git-822ba24743af9ee1b5e7f656a7a61a38f3638bca.tar.gz |
patch 8.2.0818: Vim9: using a discovery phase doesn't work wellv8.2.0818
Problem: Vim9: using a discovery phase doesn't work well.
Solution: Remove the discovery phase, instead compile a function only when
it is used. Add :defcompile to compile def functions earlier.
Diffstat (limited to 'src/vim9compile.c')
-rw-r--r-- | src/vim9compile.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/vim9compile.c b/src/vim9compile.c index 416198a0c..d41dd5396 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1418,7 +1418,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) return FAIL; } - if (ufunc->uf_dfunc_idx >= 0) + if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED) { int i; @@ -1442,12 +1442,16 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) return FAIL; } } + if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED) + if (compile_def_function(ufunc, TRUE, cctx) == FAIL) + return FAIL; } if ((isn = generate_instr(cctx, - ufunc->uf_dfunc_idx >= 0 ? ISN_DCALL : ISN_UCALL)) == NULL) + ufunc->uf_dfunc_idx != UF_NOT_COMPILED ? ISN_DCALL + : ISN_UCALL)) == NULL) return FAIL; - if (ufunc->uf_dfunc_idx >= 0) + if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED) { isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx; isn->isn_arg.dfunc.cdf_argcount = argcount; @@ -4454,9 +4458,12 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx) eap->cookie = cctx; eap->skip = cctx->ctx_skip == TRUE; eap->forceit = FALSE; - ufunc = def_function(eap, name, cctx, TRUE); + ufunc = def_function(eap, name); - if (ufunc == NULL || ufunc->uf_dfunc_idx < 0) + if (ufunc == NULL) + return NULL; + if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED + && compile_def_function(ufunc, TRUE, cctx) == FAIL) return NULL; // Define a local variable for the function reference. @@ -6302,7 +6309,7 @@ theend: * Add a function to the list of :def functions. * This "sets ufunc->uf_dfunc_idx" but the function isn't compiled yet. */ - int + static int add_def_function(ufunc_T *ufunc) { dfunc_T *dfunc; @@ -6328,8 +6335,9 @@ add_def_function(ufunc_T *ufunc) * "outer_cctx" is set for a nested function. * This can be used recursively through compile_lambda(), which may reallocate * "def_functions". + * Returns OK or FAIL. */ - void + int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx) { char_u *line = NULL; @@ -6352,7 +6360,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx) delete_def_function_contents(dfunc); } else if (add_def_function(ufunc) == FAIL) - return; + return FAIL; CLEAR_FIELD(cctx); cctx.ctx_ufunc = ufunc; @@ -6816,7 +6824,7 @@ erret: delete_instr(((isn_T *)instr->ga_data) + idx); ga_clear(instr); - ufunc->uf_dfunc_idx = -1; + ufunc->uf_dfunc_idx = UF_NOT_COMPILED; if (!dfunc->df_deleted) --def_functions.ga_len; @@ -6836,6 +6844,7 @@ erret: free_imported(&cctx); free_locals(&cctx); ga_clear(&cctx.ctx_type_stack); + return ret; } /* |