0
0
mirror of https://github.com/vim/vim.git synced 2025-08-31 20:53:42 -04:00

patch 8.2.4573: a nested function is compiled for debugging without context

Problem:    A nested function (closure) is compiled for debugging without
            context.
Solution:   Check if a nested function is marked for debugging before
            compiling it.  Give an error when trying to compile a closure
            without its context. (closes #9951)
This commit is contained in:
Bram Moolenaar 2022-03-15 15:57:04 +00:00
parent 1a572e9b3b
commit 96923b7a14
6 changed files with 24 additions and 1 deletions

View File

@ -3249,3 +3249,7 @@ EXTERN char e_cannot_create_vim9_script_variable_in_function_str[]
#endif
EXTERN char e_cannot_use_s_backslash_in_vim9_script[]
INIT(= N_("E1270: Cannot use :s\\/sub/ in Vim9 script"));
#ifdef FEAT_EVAL
EXTERN char e_compiling_closure_without_context_str[]
INIT(= N_("E1271: compiling closure without context: %s"));
#endif

View File

@ -1,5 +1,6 @@
/* vim9execute.c */
void to_string_error(vartype_T vartype);
void update_has_breakpoint(ufunc_T *ufunc);
void funcstack_check_refcount(funcstack_T *funcstack);
int set_ref_in_funcstacks(int copyID);
char_u *char_from_string(char_u *str, varnumber_T index);

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4573,
/**/
4572,
/**/

View File

@ -913,6 +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);
#ifdef FEAT_PROFILE
// If the outer function is profiled, also compile the nested function for
@ -2579,6 +2580,13 @@ compile_def_function(
new_def_function = TRUE;
}
if ((ufunc->uf_flags & FC_CLOSURE) && outer_cctx == NULL)
{
semsg(_(e_compiling_closure_without_context_str),
printable_func_name(ufunc));
return FAIL;
}
ufunc->uf_def_status = UF_COMPILING;
CLEAR_FIELD(cctx);

View File

@ -152,7 +152,7 @@ exe_newlist(int count, ectx_T *ectx)
* If debug_tick changed check if "ufunc" has a breakpoint and update
* "uf_has_breakpoint".
*/
static void
void
update_has_breakpoint(ufunc_T *ufunc)
{
if (ufunc->uf_debug_tick != debug_tick)

View File

@ -1007,6 +1007,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)
{
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
// "*arg" may point into it. Point into the original line to avoid a
// dangling pointer.