To: vim_dev@googlegroups.com Subject: Patch 8.2.4575 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4575 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. Files: src/vim.h, src/vim9compile.c, src/proto/vim9compile.pro, src/eval.c, src/vim9execute.c, src/vim9expr.c, src/vim9instr.c, src/vim9.h *** ../vim-8.2.4574/src/vim.h 2022-03-14 19:24:41.867926390 +0000 --- src/vim.h 2022-03-15 18:18:03.789486166 +0000 *************** *** 1839,1858 **** 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 --- 1839,1844 ---- *** ../vim-8.2.4574/src/vim9compile.c 2022-03-15 15:57:00.422428459 +0000 --- src/vim9compile.c 2022-03-15 19:25:13.328140346 +0000 *************** *** 913,920 **** } } ! update_has_breakpoint(ufunc); ! compile_type = COMPILE_TYPE(ufunc); #ifdef FEAT_PROFILE // If the outer function is profiled, also compile the nested function for // profiling. --- 913,919 ---- } } ! compile_type = get_compile_type(ufunc); #ifdef FEAT_PROFILE // If the outer function is profiled, also compile the nested function for // profiling. *************** *** 2475,2480 **** --- 2474,2503 ---- 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. *** ../vim-8.2.4574/src/proto/vim9compile.pro 2022-02-13 21:51:02.388484128 +0000 --- src/proto/vim9compile.pro 2022-03-15 18:35:41.131618176 +0000 *************** *** 23,28 **** --- 23,29 ---- 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); *** ../vim-8.2.4574/src/eval.c 2022-03-13 13:12:23.767131845 +0000 --- src/eval.c 2022-03-15 18:35:46.019608561 +0000 *************** *** 3794,3801 **** // 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) { clear_tv(rettv); ret = FAIL; --- 3794,3801 ---- // 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, ! get_compile_type(ufunc), NULL) == FAIL) { clear_tv(rettv); ret = FAIL; *** ../vim-8.2.4574/src/vim9execute.c 2022-03-15 15:57:00.426428445 +0000 --- src/vim9execute.c 2022-03-15 18:54:30.580371785 +0000 *************** *** 284,289 **** --- 284,290 ---- estack_T *entry; funclocal_T *floc = NULL; int res = OK; + compiletype_T compile_type; if (dfunc->df_deleted) { *************** *** 309,322 **** } #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))) { ! res = compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL); // compile_def_function() may cause def_functions.ga_data to change dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx; --- 310,321 ---- } #endif // When debugging and using "cont" switches to the not-debugged // instructions, may need to still compile them. ! compile_type = get_compile_type(ufunc); ! if (func_needs_compiling(ufunc, compile_type)) { ! 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,932 **** int error; int idx; int did_emsg_before = did_emsg; ! compiletype_T compile_type = COMPILE_TYPE(ufunc); if (func_needs_compiling(ufunc, compile_type) && compile_def_function(ufunc, FALSE, compile_type, NULL) --- 925,931 ---- int error; int idx; int did_emsg_before = did_emsg; ! compiletype_T compile_type = get_compile_type(ufunc); if (func_needs_compiling(ufunc, compile_type) && compile_def_function(ufunc, FALSE, compile_type, NULL) *************** *** 4993,5006 **** #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)) { if (did_emsg_cumul + did_emsg == did_emsg_before) semsg(_(e_function_is_not_compiled_str), --- 4992,5002 ---- #undef STACK_TV_VAR #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx) if (ufunc->uf_def_status == UF_NOT_COMPILED || ufunc->uf_def_status == UF_COMPILE_ERROR ! || (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), *** ../vim-8.2.4574/src/vim9expr.c 2022-03-15 15:57:00.426428445 +0000 --- src/vim9expr.c 2022-03-15 18:35:21.827656073 +0000 *************** *** 355,369 **** generate_funcref(cctx_T *cctx, char_u *name, int has_g_prefix) { ufunc_T *ufunc = find_func(name, FALSE); // 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) return FAIL; return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type); } --- 355,370 ---- 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. ! 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,1018 **** ) 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) { ! update_has_breakpoint(ufunc); ! if (COMPILE_TYPE(ufunc) == CT_DEBUG) ! compile_def_function(ufunc, FALSE, CT_DEBUG, cctx); } // The last entry in evalarg.eval_tofree_ga is a copy of the last line and --- 1008,1021 ---- ) compile_def_function(ufunc, FALSE, CT_NONE, cctx); ! // if the outer function is not compiled for debugging or profiling, this ! // one might be ! if (cctx->ctx_compile_type == CT_NONE) { ! 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 *** ../vim-8.2.4574/src/vim9instr.c 2022-03-10 19:23:24.329580643 +0000 --- src/vim9instr.c 2022-03-15 19:24:12.404455131 +0000 *************** *** 1207,1214 **** 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) cctx->ctx_ufunc->uf_flags |= FC_CLOSURE; type = ufunc->uf_func_type == NULL ? &t_func_any : ufunc->uf_func_type; --- 1207,1216 ---- 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. 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,1492 **** --- 1489,1495 ---- && ufunc->uf_def_status != UF_COMPILE_ERROR) { int i; + compiletype_T compile_type; for (i = 0; i < argcount; ++i) { *************** *** 1519,1527 **** return FAIL; } } ! if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc)) && compile_def_function(ufunc, ufunc->uf_ret_type == NULL, ! COMPILE_TYPE(ufunc), NULL) == FAIL) return FAIL; } if (ufunc->uf_def_status == UF_COMPILE_ERROR) --- 1522,1531 ---- return FAIL; } } ! compile_type = get_compile_type(ufunc); ! if (func_needs_compiling(ufunc, compile_type) && compile_def_function(ufunc, ufunc->uf_ret_type == NULL, ! compile_type, NULL) == FAIL) return FAIL; } if (ufunc->uf_def_status == UF_COMPILE_ERROR) *** ../vim-8.2.4574/src/vim9.h 2022-03-10 21:53:40.829910566 +0000 --- src/vim9.h 2022-03-15 18:32:35.667979281 +0000 *************** *** 518,524 **** // 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() #ifdef FEAT_PROFILE # define INSTRUCTIONS(dfunc) \ (debug_break_level > 0 || may_break_in_function(dfunc->df_ufunc) \ --- 518,524 ---- // 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 get_compile_type() #ifdef FEAT_PROFILE # define INSTRUCTIONS(dfunc) \ (debug_break_level > 0 || may_break_in_function(dfunc->df_ufunc) \ *** ../vim-8.2.4574/src/version.c 2022-03-15 16:16:44.275058631 +0000 --- src/version.c 2022-03-15 19:26:47.031680828 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4575, /**/ -- ARTHUR: This new learning amazes me, Sir Bedevere. Explain again how sheep's bladders may be employed to prevent earthquakes. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///