]> granicus.if.org Git - vim/commitdiff
patch 8.2.4575: Vim9: test for profiling still fails v8.2.4575
authorBram Moolenaar <Bram@vim.org>
Tue, 15 Mar 2022 19:29:30 +0000 (19:29 +0000)
committerBram Moolenaar <Bram@vim.org>
Tue, 15 Mar 2022 19:29:30 +0000 (19:29 +0000)
Problem:    Vim9: test for profiling still fails.
Solution:   Update flags for profiling and breakpoints when obtaining the
            compile type.  Do not set the FC_CLOSURE flag for a toplevel
            function.

src/eval.c
src/proto/vim9compile.pro
src/version.c
src/vim.h
src/vim9.h
src/vim9compile.c
src/vim9execute.c
src/vim9expr.c
src/vim9instr.c

index 3ecbf6546fd66ea3a9a9491df3b6a9ea223191ed..b55ae1a20c3a8c11143dd9440d3b5adf18413540 100644 (file)
@@ -3794,8 +3794,8 @@ eval7(
                        // This is recognized in compile_return().
                        if (ufunc->uf_ret_type->tt_type == VAR_VOID)
                            ufunc->uf_ret_type = &t_unknown;
-                       if (compile_def_function(ufunc,
-                                    FALSE, COMPILE_TYPE(ufunc), NULL) == FAIL)
+                       if (compile_def_function(ufunc, FALSE,
+                                       get_compile_type(ufunc), NULL) == FAIL)
                        {
                            clear_tv(rettv);
                            ret = FAIL;
index 0e71b93fa0997fd0cfcf56e7cbbcd0db2b43852c..94ef8277e8314e96388a1b84e6aad04ad6092b0d 100644 (file)
@@ -23,6 +23,7 @@ int compile_lhs(char_u *var_start, lhs_T *lhs, int cmdidx, int heredoc, int ople
 int compile_assign_lhs(char_u *var_start, lhs_T *lhs, int cmdidx, int is_decl, int heredoc, int oplen, cctx_T *cctx);
 int compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx);
 int compile_assign_unlet(char_u *var_start, lhs_T *lhs, int is_assign, type_T *rhs_type, cctx_T *cctx);
+compiletype_T get_compile_type(ufunc_T *ufunc);
 int compile_def_function(ufunc_T *ufunc, int check_return_type, compiletype_T compile_type, cctx_T *outer_cctx);
 void set_function_type(ufunc_T *ufunc);
 void unlink_def_function(ufunc_T *ufunc);
index 4dfbdd59d3cea02c40b37a5a29d27e27814c5343..a68a6628fa0cc040abfcf7dbdb0b52e5f38fb705 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4575,
 /**/
     4574,
 /**/
index 4f80a09264077187aa2e4cb1504444bffa3d8560..5f43ac7a6402ce0a9750fa51eaa70410b9a2eacf 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -1839,20 +1839,6 @@ typedef enum {
     CT_DEBUG       // use df_instr_debug, overrules CT_PROFILE
 } compiletype_T;
 
-// Keep in sync with INSTRUCTIONS().
-#ifdef FEAT_PROFILE
-# define COMPILE_TYPE(ufunc) (debug_break_level > 0 \
-       || may_break_in_function(ufunc) \
-               ? CT_DEBUG \
-               : do_profiling == PROF_YES && (ufunc)->uf_profiling \
-                       ? CT_PROFILE : CT_NONE)
-#else
-# define COMPILE_TYPE(ufunc) debug_break_level > 0 \
-       || may_break_in_function(ufunc) \
-               ? CT_DEBUG \
-               : CT_NONE
-#endif
-
 /*
  * When compiling with 32 bit Perl time_t is 32 bits in the Perl code but 64
  * bits elsewhere.  That causes memory corruption.  Define time_T and use it
index 03602e674c75a5cbfb79ede18d98204b467d999b..5fd852630f67963adc63f7a3ecbf93de80fccb89 100644 (file)
@@ -518,7 +518,7 @@ extern garray_T def_functions;
 // Used for "lnum" when a range is to be taken from the stack and "!" is used.
 #define LNUM_VARIABLE_RANGE_ABOVE -888
 
-// Keep in sync with COMPILE_TYPE()
+// Keep in sync with get_compile_type()
 #ifdef FEAT_PROFILE
 # define INSTRUCTIONS(dfunc) \
        (debug_break_level > 0 || may_break_in_function(dfunc->df_ufunc) \
index d8119c566576f9bc9498bb01c2913b44ba479592..fa5f067f5df227e5f4dd9825d74704102585347c 100644 (file)
@@ -913,8 +913,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx, garray_T *lines_to_free)
        }
     }
 
-    update_has_breakpoint(ufunc);
-    compile_type = COMPILE_TYPE(ufunc);
+    compile_type = get_compile_type(ufunc);
 #ifdef FEAT_PROFILE
     // If the outer function is profiled, also compile the nested function for
     // profiling.
@@ -2475,6 +2474,30 @@ check_args_shadowing(ufunc_T *ufunc, cctx_T *cctx)
     return r;
 }
 
+/*
+ * Get the compilation type that should be used for "ufunc".
+ * Keep in sync with INSTRUCTIONS().
+ */
+    compiletype_T
+get_compile_type(ufunc_T *ufunc)
+{
+    // Update uf_has_breakpoint if needed.
+    update_has_breakpoint(ufunc);
+
+    if (debug_break_level > 0 || may_break_in_function(ufunc))
+       return CT_DEBUG;
+#ifdef FEAT_PROFILE
+    if (do_profiling == PROF_YES)
+    {
+       if (!ufunc->uf_profiling && has_profiling(FALSE, ufunc->uf_name, NULL))
+           func_do_profile(ufunc);
+       if (ufunc->uf_profiling)
+           return CT_PROFILE;
+    }
+#endif
+    return CT_NONE;
+}
+
 
 /*
  * Add a function to the list of :def functions.
index 681847a793e4a859a0bcf71da9422bb5c808248d..4d24eb96eb72cab8569271bf52ecac10f23cee3f 100644 (file)
@@ -284,6 +284,7 @@ call_dfunc(
     estack_T   *entry;
     funclocal_T        *floc = NULL;
     int                res = OK;
+    compiletype_T compile_type;
 
     if (dfunc->df_deleted)
     {
@@ -309,14 +310,12 @@ call_dfunc(
     }
 #endif
 
-    // Update uf_has_breakpoint if needed.
-    update_has_breakpoint(ufunc);
-
     // When debugging and using "cont" switches to the not-debugged
     // instructions, may need to still compile them.
-    if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc)))
+    compile_type = get_compile_type(ufunc);
+    if (func_needs_compiling(ufunc, compile_type))
     {
-       res = compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL);
+       res = compile_def_function(ufunc, FALSE, compile_type, NULL);
 
        // compile_def_function() may cause def_functions.ga_data to change
        dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
@@ -926,7 +925,7 @@ call_ufunc(
     int                error;
     int                idx;
     int                did_emsg_before = did_emsg;
-    compiletype_T compile_type = COMPILE_TYPE(ufunc);
+    compiletype_T compile_type = get_compile_type(ufunc);
 
     if (func_needs_compiling(ufunc, compile_type)
                && compile_def_function(ufunc, FALSE, compile_type, NULL)
@@ -4993,14 +4992,11 @@ call_def_function(
 #undef STACK_TV_VAR
 #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
 
-    // Update uf_has_breakpoint if needed.
-    update_has_breakpoint(ufunc);
-
     if (ufunc->uf_def_status == UF_NOT_COMPILED
            || ufunc->uf_def_status == UF_COMPILE_ERROR
-           || (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
-               && compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
-                                                                     == FAIL))
+           || (func_needs_compiling(ufunc, get_compile_type(ufunc))
+               && compile_def_function(ufunc, FALSE,
+                                      get_compile_type(ufunc), NULL) == FAIL))
     {
        if (did_emsg_cumul + did_emsg == did_emsg_before)
            semsg(_(e_function_is_not_compiled_str),
index e2e4f8e6af19e70d1f9902f993969b31f6e675ee..8276a779b805016644bffba37f9dec48ca8c8bf2 100644 (file)
@@ -355,15 +355,16 @@ compile_load_scriptvar(
 generate_funcref(cctx_T *cctx, char_u *name, int has_g_prefix)
 {
     ufunc_T *ufunc = find_func(name, FALSE);
+    compiletype_T compile_type;
 
     // Reject a global non-autoload function found without the "g:" prefix.
     if (ufunc == NULL || (!has_g_prefix && func_requires_g_prefix(ufunc)))
        return FAIL;
 
     // Need to compile any default values to get the argument types.
-    if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
-           && compile_def_function(ufunc, TRUE, COMPILE_TYPE(ufunc), NULL)
-                                                                      == FAIL)
+    compile_type = get_compile_type(ufunc);
+    if (func_needs_compiling(ufunc, compile_type)
+             && compile_def_function(ufunc, TRUE, compile_type, cctx) == FAIL)
        return FAIL;
     return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
 }
@@ -1007,12 +1008,14 @@ compile_lambda(char_u **arg, cctx_T *cctx)
        )
        compile_def_function(ufunc, FALSE, CT_NONE, cctx);
 
-    // if the outer function is not compiled for debugging, this one might be
-    if (cctx->ctx_compile_type != CT_DEBUG)
+    // if the outer function is not compiled for debugging or profiling, this
+    // one might be
+    if (cctx->ctx_compile_type == CT_NONE)
     {
-       update_has_breakpoint(ufunc);
-       if (COMPILE_TYPE(ufunc) == CT_DEBUG)
-           compile_def_function(ufunc, FALSE, CT_DEBUG, cctx);
+       compiletype_T compile_type = get_compile_type(ufunc);
+
+       if (compile_type != CT_NONE)
+           compile_def_function(ufunc, FALSE, compile_type, cctx);
     }
 
     // The last entry in evalarg.eval_tofree_ga is a copy of the last line and
index 9b176dfb5d6dad4b90b2ee55ea4a2e79c407058a..de144dcc10d1f2d55f3304410e4fe43f2bed2f50 100644 (file)
@@ -1207,8 +1207,10 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T *ufunc)
     cctx->ctx_has_closure = 1;
 
     // If the referenced function is a closure, it may use items further up in
-    // the nested context, including this one.
-    if (ufunc->uf_flags & FC_CLOSURE)
+    // the nested context, including this one.  But not a function defined at
+    // the script level.
+    if ((ufunc->uf_flags & FC_CLOSURE)
+                              && func_name_refcount(cctx->ctx_ufunc->uf_name))
        cctx->ctx_ufunc->uf_flags |= FC_CLOSURE;
 
     type = ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type;
@@ -1487,6 +1489,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
            && ufunc->uf_def_status != UF_COMPILE_ERROR)
     {
        int             i;
+       compiletype_T   compile_type;
 
        for (i = 0; i < argcount; ++i)
        {
@@ -1519,9 +1522,10 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
                return FAIL;
            }
        }
-       if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
+       compile_type = get_compile_type(ufunc);
+       if (func_needs_compiling(ufunc, compile_type)
                && compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
-                                           COMPILE_TYPE(ufunc), NULL) == FAIL)
+                                                  compile_type, NULL) == FAIL)
            return FAIL;
     }
     if (ufunc->uf_def_status == UF_COMPILE_ERROR)