comparison src/vim9execute.c @ 24146:03fc95628eb0 v8.2.2614

patch 8.2.2614: Vim9: function is deleted while executing Commit: https://github.com/vim/vim/commit/c970e4225b68ff8650ff23df09e04246c147fca3 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Mar 17 15:03:04 2021 +0100 patch 8.2.2614: Vim9: function is deleted while executing Problem: Vim9: function is deleted while executing. Solution: increment the call count, when more than zero do not delete the function but mark it as dead. (closes #7977)
author Bram Moolenaar <Bram@vim.org>
date Wed, 17 Mar 2021 15:15:03 +0100
parents fcbb1d4df15b
children 40e27d96e395
comparison
equal deleted inserted replaced
24145:4d64b2bee122 24146:03fc95628eb0
321 ectx->ec_outer = outer; 321 ectx->ec_outer = outer;
322 } 322 }
323 else 323 else
324 ectx->ec_outer = NULL; 324 ectx->ec_outer = NULL;
325 325
326 ++ufunc->uf_calls;
327
326 // Set execution state to the start of the called function. 328 // Set execution state to the start of the called function.
327 ectx->ec_dfunc_idx = cdf_idx; 329 ectx->ec_dfunc_idx = cdf_idx;
328 ectx->ec_instr = INSTRUCTIONS(dfunc); 330 ectx->ec_instr = INSTRUCTIONS(dfunc);
329 entry = estack_push_ufunc(ufunc, 1); 331 entry = estack_push_ufunc(ufunc, 1);
330 if (entry != NULL) 332 if (entry != NULL)
554 + profile_info_ga.ga_len - 1, dfunc->df_ufunc, caller); 556 + profile_info_ga.ga_len - 1, dfunc->df_ufunc, caller);
555 --profile_info_ga.ga_len; 557 --profile_info_ga.ga_len;
556 } 558 }
557 } 559 }
558 #endif 560 #endif
561 // TODO: when is it safe to delete the function when it is no longer used?
562 --dfunc->df_ufunc->uf_calls;
563
559 // execution context goes one level up 564 // execution context goes one level up
560 entry = estack_pop(); 565 entry = estack_pop();
561 if (entry != NULL) 566 if (entry != NULL)
562 current_sctx.sc_sid = entry->es_save_sid; 567 current_sctx.sc_sid = entry->es_save_sid;
563 568
1332 { 1337 {
1333 STACK_TV_BOT(0)->v_type = VAR_UNKNOWN; 1338 STACK_TV_BOT(0)->v_type = VAR_UNKNOWN;
1334 ++ectx.ec_stack.ga_len; 1339 ++ectx.ec_stack.ga_len;
1335 } 1340 }
1336 if (ufunc->uf_va_name != NULL) 1341 if (ufunc->uf_va_name != NULL)
1337 ++ectx.ec_stack.ga_len; 1342 ++ectx.ec_stack.ga_len;
1338 1343
1339 // Frame pointer points to just after arguments. 1344 // Frame pointer points to just after arguments.
1340 ectx.ec_frame_idx = ectx.ec_stack.ga_len; 1345 ectx.ec_frame_idx = ectx.ec_stack.ga_len;
1341 initial_frame_idx = ectx.ec_frame_idx; 1346 initial_frame_idx = ectx.ec_frame_idx;
1342 1347
1404 saved_msg_list = msg_list; 1409 saved_msg_list = msg_list;
1405 msg_list = &private_msg_list; 1410 msg_list = &private_msg_list;
1406 1411
1407 // Do turn errors into exceptions. 1412 // Do turn errors into exceptions.
1408 suppress_errthrow = FALSE; 1413 suppress_errthrow = FALSE;
1414
1415 // Do not delete the function while executing it.
1416 ++ufunc->uf_calls;
1409 1417
1410 // When ":silent!" was used before calling then we still abort the 1418 // When ":silent!" was used before calling then we still abort the
1411 // function. If ":silent!" is used in the function then we don't. 1419 // function. If ":silent!" is used in the function then we don't.
1412 emsg_silent_def = emsg_silent; 1420 emsg_silent_def = emsg_silent;
1413 did_emsg_def = 0; 1421 did_emsg_def = 0;
3836 } 3844 }
3837 3845
3838 estack_pop(); 3846 estack_pop();
3839 current_sctx = save_current_sctx; 3847 current_sctx = save_current_sctx;
3840 3848
3849 // TODO: when is it safe to delete the function if it is no longer used?
3850 --ufunc->uf_calls;
3851
3841 if (*msg_list != NULL && saved_msg_list != NULL) 3852 if (*msg_list != NULL && saved_msg_list != NULL)
3842 { 3853 {
3843 msglist_T **plist = saved_msg_list; 3854 msglist_T **plist = saved_msg_list;
3844 3855
3845 // Append entries from the current msg_list (uncaught exceptions) to 3856 // Append entries from the current msg_list (uncaught exceptions) to