mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.1778: Vim9: returning from a partial call clears outer context
Problem: Vim9: returning from a partial call clears outer context, causing a crash. Solution: Put the outer context in the stack frame. (closes #7044)
This commit is contained in:
parent
55759b5228
commit
5366e1aecf
@ -1384,6 +1384,21 @@ def Test_nested_closure_fails()
|
|||||||
CheckScriptFailure(lines, 'E1012:')
|
CheckScriptFailure(lines, 'E1012:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_nested_lambda()
|
||||||
|
var lines =<< trim END
|
||||||
|
vim9script
|
||||||
|
def Func()
|
||||||
|
var x = 4
|
||||||
|
var Lambda1 = {-> 7}
|
||||||
|
var Lambda2 = {-> [Lambda1(), x]}
|
||||||
|
var res = Lambda2()
|
||||||
|
assert_equal([7, 4], res)
|
||||||
|
enddef
|
||||||
|
Func()
|
||||||
|
END
|
||||||
|
CheckScriptSuccess(lines)
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_sort_return_type()
|
def Test_sort_return_type()
|
||||||
var res: list<number>
|
var res: list<number>
|
||||||
res = [1, 2, 3]->sort()
|
res = [1, 2, 3]->sort()
|
||||||
|
@ -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 */
|
||||||
|
/**/
|
||||||
|
1778,
|
||||||
/**/
|
/**/
|
||||||
1777,
|
1777,
|
||||||
/**/
|
/**/
|
||||||
|
10
src/vim9.h
10
src/vim9.h
@ -326,10 +326,12 @@ 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.
|
||||||
// - function index
|
// - ec_dfunc_idx: function index
|
||||||
// - instruction index
|
// - ec_iidx: instruction index
|
||||||
// - previous frame index
|
// - ec_outer_stack: stack used for closures TODO: can we avoid this?
|
||||||
#define STACK_FRAME_SIZE 3
|
// - ec_outer_frame: stack frame for closures
|
||||||
|
// - ec_frame_idx: previous frame index
|
||||||
|
#define STACK_FRAME_SIZE 5
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEFINE_VIM9_GLOBALS
|
#ifdef DEFINE_VIM9_GLOBALS
|
||||||
|
@ -239,7 +239,9 @@ call_dfunc(int cdf_idx, int argcount_arg, ectx_T *ectx)
|
|||||||
// Store current execution state in stack frame for ISN_RETURN.
|
// Store current execution state in stack frame for ISN_RETURN.
|
||||||
STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
|
STACK_TV_BOT(0)->vval.v_number = ectx->ec_dfunc_idx;
|
||||||
STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
|
STACK_TV_BOT(1)->vval.v_number = ectx->ec_iidx;
|
||||||
STACK_TV_BOT(2)->vval.v_number = ectx->ec_frame_idx;
|
STACK_TV_BOT(2)->vval.v_string = (void *)ectx->ec_outer_stack;
|
||||||
|
STACK_TV_BOT(3)->vval.v_number = ectx->ec_outer_frame;
|
||||||
|
STACK_TV_BOT(4)->vval.v_number = ectx->ec_frame_idx;
|
||||||
ectx->ec_frame_idx = ectx->ec_stack.ga_len;
|
ectx->ec_frame_idx = ectx->ec_stack.ga_len;
|
||||||
|
|
||||||
// Initialize local variables
|
// Initialize local variables
|
||||||
@ -455,7 +457,11 @@ func_return(ectx_T *ectx)
|
|||||||
// Restore the previous frame.
|
// Restore the previous frame.
|
||||||
ectx->ec_dfunc_idx = STACK_TV(ectx->ec_frame_idx)->vval.v_number;
|
ectx->ec_dfunc_idx = STACK_TV(ectx->ec_frame_idx)->vval.v_number;
|
||||||
ectx->ec_iidx = STACK_TV(ectx->ec_frame_idx + 1)->vval.v_number;
|
ectx->ec_iidx = STACK_TV(ectx->ec_frame_idx + 1)->vval.v_number;
|
||||||
ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx + 2)->vval.v_number;
|
ectx->ec_outer_stack =
|
||||||
|
(void *)STACK_TV(ectx->ec_frame_idx + 2)->vval.v_string;
|
||||||
|
ectx->ec_outer_frame = STACK_TV(ectx->ec_frame_idx + 3)->vval.v_number;
|
||||||
|
// restoring ec_frame_idx must be last
|
||||||
|
ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx + 4)->vval.v_number;
|
||||||
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
|
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
|
||||||
ectx->ec_instr = dfunc->df_instr;
|
ectx->ec_instr = dfunc->df_instr;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user