Skip to content

Commit

Permalink
patch 8.2.4573: a nested function is compiled for debugging without c…
Browse files Browse the repository at this point in the history
…ontext

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)
  • Loading branch information
brammool committed Mar 15, 2022
1 parent 1a572e9 commit 96923b7
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/errors.h
Expand Up @@ -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
1 change: 1 addition & 0 deletions src/proto/vim9execute.pro
@@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -750,6 +750,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4573,
/**/
4572,
/**/
Expand Down
8 changes: 8 additions & 0 deletions src/vim9compile.c
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/vim9execute.c
Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions src/vim9expr.c
Expand Up @@ -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.
Expand Down

0 comments on commit 96923b7

Please sign in to comment.