diff src/vim9compile.c @ 20528:489cb75c76b6 v8.2.0818

patch 8.2.0818: Vim9: using a discovery phase doesn't work well Commit: https://github.com/vim/vim/commit/822ba24743af9ee1b5e7f656a7a61a38f3638bca Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 24 23:00:18 2020 +0200 patch 8.2.0818: Vim9: using a discovery phase doesn't work well 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.
author Bram Moolenaar <Bram@vim.org>
date Sun, 24 May 2020 23:15:04 +0200
parents d54dfb5f12db
children cb4831fa7e25
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1418,7 +1418,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu
 	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 *ufu
 		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, cc
     eap->cookie = cctx;
     eap->skip = cctx->ctx_skip == TRUE;
     eap->forceit = FALSE;
-    ufunc = def_function(eap, name, cctx, TRUE);
-
-    if (ufunc == NULL || ufunc->uf_dfunc_idx < 0)
+    ufunc = def_function(eap, name);
+
+    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
 	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;
 }
 
 /*