mirror of
https://github.com/vim/vim.git
synced 2025-09-06 21:53:38 -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:
parent
1a572e9b3b
commit
96923b7a14
@ -3249,3 +3249,7 @@ EXTERN char e_cannot_create_vim9_script_variable_in_function_str[]
|
|||||||
#endif
|
#endif
|
||||||
EXTERN char e_cannot_use_s_backslash_in_vim9_script[]
|
EXTERN char e_cannot_use_s_backslash_in_vim9_script[]
|
||||||
INIT(= N_("E1270: Cannot use :s\\/sub/ 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,5 +1,6 @@
|
|||||||
/* vim9execute.c */
|
/* vim9execute.c */
|
||||||
void to_string_error(vartype_T vartype);
|
void to_string_error(vartype_T vartype);
|
||||||
|
void update_has_breakpoint(ufunc_T *ufunc);
|
||||||
void funcstack_check_refcount(funcstack_T *funcstack);
|
void funcstack_check_refcount(funcstack_T *funcstack);
|
||||||
int set_ref_in_funcstacks(int copyID);
|
int set_ref_in_funcstacks(int copyID);
|
||||||
char_u *char_from_string(char_u *str, varnumber_T index);
|
char_u *char_from_string(char_u *str, varnumber_T index);
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
4573,
|
||||||
/**/
|
/**/
|
||||||
4572,
|
4572,
|
||||||
/**/
|
/**/
|
||||||
|
@ -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);
|
compile_type = COMPILE_TYPE(ufunc);
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
// If the outer function is profiled, also compile the nested function for
|
// If the outer function is profiled, also compile the nested function for
|
||||||
@ -2579,6 +2580,13 @@ compile_def_function(
|
|||||||
new_def_function = TRUE;
|
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;
|
ufunc->uf_def_status = UF_COMPILING;
|
||||||
|
|
||||||
CLEAR_FIELD(cctx);
|
CLEAR_FIELD(cctx);
|
||||||
|
@ -152,7 +152,7 @@ exe_newlist(int count, ectx_T *ectx)
|
|||||||
* If debug_tick changed check if "ufunc" has a breakpoint and update
|
* If debug_tick changed check if "ufunc" has a breakpoint and update
|
||||||
* "uf_has_breakpoint".
|
* "uf_has_breakpoint".
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
update_has_breakpoint(ufunc_T *ufunc)
|
update_has_breakpoint(ufunc_T *ufunc)
|
||||||
{
|
{
|
||||||
if (ufunc->uf_debug_tick != debug_tick)
|
if (ufunc->uf_debug_tick != debug_tick)
|
||||||
|
@ -1007,6 +1007,14 @@ compile_lambda(char_u **arg, cctx_T *cctx)
|
|||||||
)
|
)
|
||||||
compile_def_function(ufunc, FALSE, CT_NONE, 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
|
// 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
|
// "*arg" may point into it. Point into the original line to avoid a
|
||||||
// dangling pointer.
|
// dangling pointer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user