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:
@@ -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()
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
10
src/vim9.h
10
src/vim9.h
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user