comparison src/vim9execute.c @ 23735:7caffd835aa1 v8.2.2409

patch 8.2.2409: Vim9: profiling only works for one function Commit: https://github.com/vim/vim/commit/e5ea346a07a7750c02a89996b67716b43c767d06 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jan 25 21:01:48 2021 +0100 patch 8.2.2409: Vim9: profiling only works for one function Problem: Vim9: profiling only works for one function. Solution: Select the right instructions when calling and returning. (closes #7743)
author Bram Moolenaar <Bram@vim.org>
date Mon, 25 Jan 2021 21:15:06 +0100
parents f98692ae09a0
children d12ef361d9de
comparison
equal deleted inserted replaced
23734:f4946b73ba39 23735:7caffd835aa1
179 emsg_funcname(e_func_deleted, 179 emsg_funcname(e_func_deleted,
180 dfunc->df_name == NULL ? (char_u *)"unknown" : dfunc->df_name); 180 dfunc->df_name == NULL ? (char_u *)"unknown" : dfunc->df_name);
181 return FAIL; 181 return FAIL;
182 } 182 }
183 183
184 #ifdef FEAT_PROFILE
185 // Profiling might be enabled/disabled along the way. This should not
186 // fail, since the function was compiled before and toggling profiling
187 // doesn't change any errors.
188 if (func_needs_compiling(ufunc, PROFILING(ufunc))
189 && compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
190 == FAIL)
191 return FAIL;
192 #endif
193
184 if (ufunc->uf_va_name != NULL) 194 if (ufunc->uf_va_name != NULL)
185 { 195 {
186 // Need to make a list out of the vararg arguments. 196 // Need to make a list out of the vararg arguments.
187 // Stack at time of call with 2 varargs: 197 // Stack at time of call with 2 varargs:
188 // normal_arg 198 // normal_arg
291 else 301 else
292 ectx->ec_outer = NULL; 302 ectx->ec_outer = NULL;
293 303
294 // Set execution state to the start of the called function. 304 // Set execution state to the start of the called function.
295 ectx->ec_dfunc_idx = cdf_idx; 305 ectx->ec_dfunc_idx = cdf_idx;
296 ectx->ec_instr = dfunc->df_instr; 306 ectx->ec_instr = INSTRUCTIONS(dfunc);
297 entry = estack_push_ufunc(ufunc, 1); 307 entry = estack_push_ufunc(ufunc, 1);
298 if (entry != NULL) 308 if (entry != NULL)
299 { 309 {
300 // Set the script context to the script where the function was defined. 310 // Set the script context to the script where the function was defined.
301 // TODO: save more than the SID? 311 // TODO: save more than the SID?
540 + STACK_FRAME_OUTER_OFF)->vval.v_string; 550 + STACK_FRAME_OUTER_OFF)->vval.v_string;
541 // restoring ec_frame_idx must be last 551 // restoring ec_frame_idx must be last
542 ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx 552 ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx
543 + STACK_FRAME_IDX_OFF)->vval.v_number; 553 + STACK_FRAME_IDX_OFF)->vval.v_number;
544 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; 554 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
545 ectx->ec_instr = dfunc->df_instr; 555 ectx->ec_instr = INSTRUCTIONS(dfunc);
546 556
547 if (ret_idx > 0) 557 if (ret_idx > 0)
548 { 558 {
549 // Reset the stack to the position before the call, with a spot for the 559 // Reset the stack to the position before the call, with a spot for the
550 // return value, moved there from above the frame. 560 // return value, moved there from above the frame.
1100 ++ectx->ec_funcrefs.ga_len; 1110 ++ectx->ec_funcrefs.ga_len;
1101 } 1111 }
1102 ++ufunc->uf_refcount; 1112 ++ufunc->uf_refcount;
1103 return OK; 1113 return OK;
1104 } 1114 }
1115
1105 1116
1106 /* 1117 /*
1107 * Call a "def" function from old Vim script. 1118 * Call a "def" function from old Vim script.
1108 * Return OK or FAIL. 1119 * Return OK or FAIL.
1109 */ 1120 */
1133 int restore_cmdmod_stacklen = 0; 1144 int restore_cmdmod_stacklen = 0;
1134 int save_emsg_silent_def = emsg_silent_def; 1145 int save_emsg_silent_def = emsg_silent_def;
1135 int save_did_emsg_def = did_emsg_def; 1146 int save_did_emsg_def = did_emsg_def;
1136 int trylevel_at_start = trylevel; 1147 int trylevel_at_start = trylevel;
1137 int orig_funcdepth; 1148 int orig_funcdepth;
1138 #ifdef FEAT_PROFILE
1139 int profiling = do_profiling == PROF_YES && ufunc->uf_profiling;
1140 #else
1141 # define profiling FALSE
1142 #endif
1143 1149
1144 // Get pointer to item in the stack. 1150 // Get pointer to item in the stack.
1145 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) 1151 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
1146 1152
1147 // Get pointer to item at the bottom of the stack, -1 is the bottom. 1153 // Get pointer to item at the bottom of the stack, -1 is the bottom.
1150 1156
1151 // Get pointer to a local variable on the stack. Negative for arguments. 1157 // Get pointer to a local variable on the stack. Negative for arguments.
1152 #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx) 1158 #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
1153 1159
1154 if (ufunc->uf_def_status == UF_NOT_COMPILED 1160 if (ufunc->uf_def_status == UF_NOT_COMPILED
1155 || (func_needs_compiling(ufunc, profiling) 1161 || (func_needs_compiling(ufunc, PROFILING(ufunc))
1156 && compile_def_function(ufunc, FALSE, profiling, NULL) 1162 && compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
1157 == FAIL)) 1163 == FAIL))
1158 { 1164 {
1159 if (did_emsg_cumul + did_emsg == did_emsg_before) 1165 if (did_emsg_cumul + did_emsg == did_emsg_before)
1160 semsg(_(e_function_is_not_compiled_str), 1166 semsg(_(e_function_is_not_compiled_str),
1161 printable_func_name(ufunc)); 1167 printable_func_name(ufunc));
1164 1170
1165 { 1171 {
1166 // Check the function was really compiled. 1172 // Check the function was really compiled.
1167 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) 1173 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
1168 + ufunc->uf_dfunc_idx; 1174 + ufunc->uf_dfunc_idx;
1169 if (( 1175 if (INSTRUCTIONS(dfunc) == NULL)
1170 #ifdef FEAT_PROFILE
1171 profiling ? dfunc->df_instr_prof :
1172 #endif
1173 dfunc->df_instr) == NULL)
1174 { 1176 {
1175 iemsg("using call_def_function() on not compiled function"); 1177 iemsg("using call_def_function() on not compiled function");
1176 return FAIL; 1178 return FAIL;
1177 } 1179 }
1178 } 1180 }
1307 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; 1309 STACK_TV_VAR(idx)->v_type = VAR_NUMBER;
1308 STACK_TV_VAR(idx)->vval.v_number = 0; 1310 STACK_TV_VAR(idx)->vval.v_number = 0;
1309 ++ectx.ec_stack.ga_len; 1311 ++ectx.ec_stack.ga_len;
1310 } 1312 }
1311 1313
1312 #ifdef FEAT_PROFILE 1314 ectx.ec_instr = INSTRUCTIONS(dfunc);
1313 ectx.ec_instr = profiling ? dfunc->df_instr_prof : dfunc->df_instr;
1314 #else
1315 ectx.ec_instr = dfunc->df_instr;
1316 #endif
1317 } 1315 }
1318 1316
1319 // Following errors are in the function, not the caller. 1317 // Following errors are in the function, not the caller.
1320 // Commands behave like vim9script. 1318 // Commands behave like vim9script.
1321 estack_push_ufunc(ufunc, 1); 1319 estack_push_ufunc(ufunc, 1);