0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.2812: Vim9: still crash when using substitute expression

Problem:    Vim9: still crash when using substitute expression.
Solution:   Put the instruction list in the stack frame. (closes #8154)
This commit is contained in:
Bram Moolenaar
2021-04-26 20:32:59 +02:00
parent b98cec28d9
commit 5930ddcd25
4 changed files with 15 additions and 11 deletions

View File

@@ -1208,15 +1208,18 @@ def Test_substitute_expr()
CheckDefFailure(['s/from/\="x"/9'], 'E488:') CheckDefFailure(['s/from/\="x"/9'], 'E488:')
# When calling a function the right instruction list needs to be restored. # When calling a function the right instruction list needs to be restored.
g:cond = true
var lines =<< trim END var lines =<< trim END
vim9script vim9script
def Foo() def Foo()
Bar([]) Bar([])
enddef enddef
def Bar(l: list<number>) def Bar(l: list<number>)
if g:cond
s/^/\=Rep()/ s/^/\=Rep()/
for n in l[:] for n in l[:]
endfor endfor
endif
enddef enddef
def Rep(): string def Rep(): string
return 'rep' return 'rep'
@@ -1227,6 +1230,7 @@ def Test_substitute_expr()
bwipe! bwipe!
END END
CheckScriptSuccess(lines) CheckScriptSuccess(lines)
unlet g:cond
enddef enddef
def Test_redir_to_var() def Test_redir_to_var()

View File

@@ -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 */
/**/
2812,
/**/ /**/
2811, 2811,
/**/ /**/

View File

@@ -427,15 +427,17 @@ struct dfunc_S {
// Number of entries used by stack frame for a function call. // Number of entries used by stack frame for a function call.
// - ec_dfunc_idx: function index // - ec_dfunc_idx: function index
// - ec_iidx: instruction index // - ec_iidx: instruction index
// - ec_instr: instruction list pointer
// - ec_outer: stack used for closures // - ec_outer: stack used for closures
// - funclocal: function-local data // - funclocal: function-local data
// - ec_frame_idx: previous frame index // - ec_frame_idx: previous frame index
#define STACK_FRAME_FUNC_OFF 0 #define STACK_FRAME_FUNC_OFF 0
#define STACK_FRAME_IIDX_OFF 1 #define STACK_FRAME_IIDX_OFF 1
#define STACK_FRAME_OUTER_OFF 2 #define STACK_FRAME_INSTR_OFF 2
#define STACK_FRAME_FUNCLOCAL_OFF 3 #define STACK_FRAME_OUTER_OFF 3
#define STACK_FRAME_IDX_OFF 4 #define STACK_FRAME_FUNCLOCAL_OFF 4
#define STACK_FRAME_SIZE 5 #define STACK_FRAME_IDX_OFF 5
#define STACK_FRAME_SIZE 6
#ifdef DEFINE_VIM9_GLOBALS #ifdef DEFINE_VIM9_GLOBALS

View File

@@ -279,6 +279,7 @@ call_dfunc(
// Store current execution state in stack frame for ISN_RETURN. // Store current execution state in stack frame for ISN_RETURN.
STACK_TV_BOT(STACK_FRAME_FUNC_OFF)->vval.v_number = ectx->ec_dfunc_idx; STACK_TV_BOT(STACK_FRAME_FUNC_OFF)->vval.v_number = ectx->ec_dfunc_idx;
STACK_TV_BOT(STACK_FRAME_IIDX_OFF)->vval.v_number = ectx->ec_iidx; STACK_TV_BOT(STACK_FRAME_IIDX_OFF)->vval.v_number = ectx->ec_iidx;
STACK_TV_BOT(STACK_FRAME_INSTR_OFF)->vval.v_string = (void *)ectx->ec_instr;
STACK_TV_BOT(STACK_FRAME_OUTER_OFF)->vval.v_string = (void *)ectx->ec_outer; STACK_TV_BOT(STACK_FRAME_OUTER_OFF)->vval.v_string = (void *)ectx->ec_outer;
STACK_TV_BOT(STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string = (void *)floc; STACK_TV_BOT(STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string = (void *)floc;
STACK_TV_BOT(STACK_FRAME_IDX_OFF)->vval.v_number = ectx->ec_frame_idx; STACK_TV_BOT(STACK_FRAME_IDX_OFF)->vval.v_number = ectx->ec_frame_idx;
@@ -592,6 +593,8 @@ func_return(ectx_T *ectx)
ectx->ec_dfunc_idx = prev_dfunc_idx; ectx->ec_dfunc_idx = prev_dfunc_idx;
ectx->ec_iidx = STACK_TV(ectx->ec_frame_idx ectx->ec_iidx = STACK_TV(ectx->ec_frame_idx
+ STACK_FRAME_IIDX_OFF)->vval.v_number; + STACK_FRAME_IIDX_OFF)->vval.v_number;
ectx->ec_instr = (void *)STACK_TV(ectx->ec_frame_idx
+ STACK_FRAME_INSTR_OFF)->vval.v_string;
ectx->ec_outer = (void *)STACK_TV(ectx->ec_frame_idx ectx->ec_outer = (void *)STACK_TV(ectx->ec_frame_idx
+ STACK_FRAME_OUTER_OFF)->vval.v_string; + STACK_FRAME_OUTER_OFF)->vval.v_string;
floc = (void *)STACK_TV(ectx->ec_frame_idx floc = (void *)STACK_TV(ectx->ec_frame_idx
@@ -599,13 +602,6 @@ func_return(ectx_T *ectx)
// restoring ec_frame_idx must be last // restoring ec_frame_idx must be last
ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx
+ STACK_FRAME_IDX_OFF)->vval.v_number; + STACK_FRAME_IDX_OFF)->vval.v_number;
ectx->ec_instr = INSTRUCTIONS(prev_dfunc);
// If the call was inside an ISN_SUBSTITUTE instruction need to use its
// list of instructions.
if (ectx->ec_instr[ectx->ec_iidx - 1].isn_type == ISN_SUBSTITUTE)
ectx->ec_instr = ectx->ec_instr[ectx->ec_iidx - 1]
.isn_arg.subs.subs_instr;
if (floc == NULL) if (floc == NULL)
ectx->ec_funclocal.floc_restore_cmdmod = FALSE; ectx->ec_funclocal.floc_restore_cmdmod = FALSE;