diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-09-18 21:25:32 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-09-18 21:25:32 +0200 |
commit | 7cbfaa51de7b225effdc79a008c71a5551883c38 (patch) | |
tree | f42d0121c3170d694383a5fac15186a46edfe40b | |
parent | e8df0104985af58ee501a6fbac8ac9f886e84e5a (diff) |
patch 8.2.1706: Vim9: crash after running into the "Multiple closures" errorv8.2.1706
Problem: Vim9: crash after running into the "Multiple closures" error.
Solution: When a function fails still update any closures. (closes #6973)
-rw-r--r-- | src/testdir/test_vim9_func.vim | 14 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9execute.c | 14 |
3 files changed, 23 insertions, 7 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index f3aae7c6ca..8c2349c343 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1294,6 +1294,20 @@ def Test_call_closure_not_compiled() GetResult(g:Ref)->assert_equal('sometext') enddef +def Test_double_closure_fails() + let lines =<< trim END + vim9script + def Func() + let var = 0 + for i in range(2) + timer_start(0, {-> var}) + endfor + enddef + Func() + END + CheckScriptFailure(lines, 'Multiple closures not supported yet') +enddef + def Test_sort_return_type() let res: list<number> res = [1, 2, 3]->sort() diff --git a/src/version.c b/src/version.c index e47f0d19a4..93f770144a 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 */ /**/ + 1706, +/**/ 1705, /**/ 1704, diff --git a/src/vim9execute.c b/src/vim9execute.c index 4332c03ed9..5fe587892f 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2676,15 +2676,11 @@ call_def_function( continue; func_return: - // Restore previous function. If the frame pointer is zero then there - // is none and we are done. + // Restore previous function. If the frame pointer is where we started + // then there is none and we are done. if (ectx.ec_frame_idx == initial_frame_idx) - { - if (handle_closure_in_use(&ectx, FALSE) == FAIL) - // only fails when out of memory - goto failed; goto done; - } + if (func_return(&ectx) == FAIL) // only fails when out of memory goto failed; @@ -2703,6 +2699,10 @@ done: ret = OK; failed: + // Also deal with closures when failed, they may already be in use + // somewhere. + handle_closure_in_use(&ectx, FALSE); + // When failed need to unwind the call stack. while (ectx.ec_frame_idx != initial_frame_idx) func_return(&ectx); |