forked from aniani/vim
patch 8.2.0488: Vim9: compiling can break when using a lambda inside :def
Problem: Vim9: Compiling can break when using a lambda inside :def. Solution: Do not keep a pointer to the dfunc_T for longer time.
This commit is contained in:
parent
bd5da371aa
commit
05afceeddc
@ -738,6 +738,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
488,
|
||||
/**/
|
||||
487,
|
||||
/**/
|
||||
|
@ -257,7 +257,7 @@ struct dfunc_S {
|
||||
// Functions defined with :def are stored in this growarray.
|
||||
// They are never removed, so that they can be found by index.
|
||||
// Deleted functions have the df_deleted flag set.
|
||||
garray_T def_functions = {0, 0, sizeof(dfunc_T), 200, NULL};
|
||||
garray_T def_functions = {0, 0, sizeof(dfunc_T), 50, NULL};
|
||||
#else
|
||||
extern garray_T def_functions;
|
||||
#endif
|
||||
|
@ -5029,11 +5029,12 @@ compile_execute(char_u *arg, cctx_T *cctx)
|
||||
* Adds the function to "def_functions".
|
||||
* When "set_return_type" is set then set ufunc->uf_ret_type to the type of the
|
||||
* return statement (used for lambda).
|
||||
* This can be used recursively through compile_lambda(), which may reallocate
|
||||
* "def_functions".
|
||||
*/
|
||||
void
|
||||
compile_def_function(ufunc_T *ufunc, int set_return_type)
|
||||
{
|
||||
dfunc_T *dfunc;
|
||||
char_u *line = NULL;
|
||||
char_u *p;
|
||||
exarg_T ea;
|
||||
@ -5046,6 +5047,9 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
|
||||
sctx_T save_current_sctx = current_sctx;
|
||||
int emsg_before = called_emsg;
|
||||
|
||||
{
|
||||
dfunc_T *dfunc; // may be invalidated by compile_lambda()
|
||||
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
{
|
||||
// Redefining a function that was compiled before.
|
||||
@ -5066,6 +5070,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
|
||||
dfunc->df_ufunc = ufunc;
|
||||
++def_functions.ga_len;
|
||||
}
|
||||
}
|
||||
|
||||
vim_memset(&cctx, 0, sizeof(cctx));
|
||||
cctx.ctx_ufunc = ufunc;
|
||||
@ -5414,10 +5419,14 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
|
||||
generate_instr(&cctx, ISN_RETURN);
|
||||
}
|
||||
|
||||
{
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
dfunc->df_deleted = FALSE;
|
||||
dfunc->df_instr = instr->ga_data;
|
||||
dfunc->df_instr_count = instr->ga_len;
|
||||
dfunc->df_varcount = cctx.ctx_max_local;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
|
||||
@ -5425,6 +5434,8 @@ erret:
|
||||
if (ret == FAIL)
|
||||
{
|
||||
int idx;
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
|
||||
for (idx = 0; idx < instr->ga_len; ++idx)
|
||||
delete_instr(((isn_T *)instr->ga_data) + idx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user