# HG changeset patch # User Bram Moolenaar # Date 1647372603 -3600 # Node ID 3bc0a639dfb0cd7673aa6d2261759713f0eaee0d # Parent 0b5711bd05a90b37124cd5548ba5b9573532511c patch 8.2.4575: Vim9: test for profiling still fails Commit: https://github.com/vim/vim/commit/139575de6653e7fd5807cb036dfb3684b815c519 Author: Bram Moolenaar Date: Tue Mar 15 19:29:30 2022 +0000 patch 8.2.4575: Vim9: test for profiling still fails 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. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -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; diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -23,6 +23,7 @@ int compile_lhs(char_u *var_start, lhs_T 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); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4575, +/**/ 4574, /**/ 4573, diff --git a/src/vim.h b/src/vim.h --- 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 diff --git a/src/vim9.h b/src/vim9.h --- a/src/vim9.h +++ b/src/vim9.h @@ -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) \ diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -913,8 +913,7 @@ compile_nested_function(exarg_T *eap, cc } } - 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, cct 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. diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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), diff --git a/src/vim9expr.c b/src/vim9expr.c --- a/src/vim9expr.c +++ b/src/vim9expr.c @@ -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 *cct ) 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 diff --git a/src/vim9instr.c b/src/vim9instr.c --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -1207,8 +1207,10 @@ generate_FUNCREF(cctx_T *cctx, ufunc_T * 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 *ufu && 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 *ufu 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)