diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-04-25 14:48:49 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-04-25 14:48:49 +0200 |
commit | d386e923c751f389b2ac038ff2cb7b40035f8cc6 (patch) | |
tree | e30c10509be00a9d1570172cc16316e2725740fc | |
parent | dc4c2309f2af347068edd60548269018f476dab9 (diff) | |
download | vim-git-d386e923c751f389b2ac038ff2cb7b40035f8cc6.tar.gz |
patch 8.2.2810: Vim9: crash when calling a function in a substitute expressionv8.2.2810
Problem: Vim9: crash when calling a function in a substitute expression.
Solution: Set the instructions back to the substitute expression
instrunctions. (closes #8148)
-rw-r--r-- | src/testdir/test_vim9_cmd.vim | 23 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 6 |
3 files changed, 30 insertions, 1 deletions
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index ab2ad6788..401cc0f4c 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -1194,10 +1194,31 @@ def Test_substitute_expr() endfor assert_equal('yes no abc', getline(1)) + bwipe! + CheckDefFailure(['s/from/\="x")/'], 'E488:') CheckDefFailure(['s/from/\="x"/9'], 'E488:') - bwipe! + # When calling a function the right instruction list needs to be restored. + var lines =<< trim END + vim9script + def Foo() + Bar([]) + enddef + def Bar(l: list<number>) + s/^/\=Rep()/ + for n in l[:] + endfor + enddef + def Rep(): string + return 'rep' + enddef + new + Foo() + assert_equal('rep', getline(1)) + bwipe! + END + CheckScriptSuccess(lines) enddef def Test_redir_to_var() diff --git a/src/version.c b/src/version.c index d235e94eb..53735b27f 100644 --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2810, +/**/ 2809, /**/ 2808, diff --git a/src/vim9execute.c b/src/vim9execute.c index c90fb65b6..7f6ce5f33 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -601,6 +601,12 @@ func_return(ectx_T *ectx) + 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) ectx->ec_funclocal.floc_restore_cmdmod = FALSE; else |