Skip to content

Commit 7cbfaa5

Browse files
committed
patch 8.2.1706: Vim9: crash after running into the "Multiple closures" error
Problem: Vim9: crash after running into the "Multiple closures" error. Solution: When a function fails still update any closures. (closes #6973)
1 parent e8df010 commit 7cbfaa5

3 files changed

Lines changed: 23 additions & 7 deletions

File tree

src/testdir/test_vim9_func.vim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,20 @@ def Test_call_closure_not_compiled()
12941294
GetResult(g:Ref)->assert_equal('sometext')
12951295
enddef
12961296

1297+
def Test_double_closure_fails()
1298+
let lines =<< trim END
1299+
vim9script
1300+
def Func()
1301+
let var = 0
1302+
for i in range(2)
1303+
timer_start(0, {-> var})
1304+
endfor
1305+
enddef
1306+
Func()
1307+
END
1308+
CheckScriptFailure(lines, 'Multiple closures not supported yet')
1309+
enddef
1310+
12971311
def Test_sort_return_type()
12981312
let res: list<number>
12991313
res = [1, 2, 3]->sort()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
1706,
753755
/**/
754756
1705,
755757
/**/

src/vim9execute.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2676,15 +2676,11 @@ call_def_function(
26762676
continue;
26772677

26782678
func_return:
2679-
// Restore previous function. If the frame pointer is zero then there
2680-
// is none and we are done.
2679+
// Restore previous function. If the frame pointer is where we started
2680+
// then there is none and we are done.
26812681
if (ectx.ec_frame_idx == initial_frame_idx)
2682-
{
2683-
if (handle_closure_in_use(&ectx, FALSE) == FAIL)
2684-
// only fails when out of memory
2685-
goto failed;
26862682
goto done;
2687-
}
2683+
26882684
if (func_return(&ectx) == FAIL)
26892685
// only fails when out of memory
26902686
goto failed;
@@ -2703,6 +2699,10 @@ call_def_function(
27032699
ret = OK;
27042700

27052701
failed:
2702+
// Also deal with closures when failed, they may already be in use
2703+
// somewhere.
2704+
handle_closure_in_use(&ectx, FALSE);
2705+
27062706
// When failed need to unwind the call stack.
27072707
while (ectx.ec_frame_idx != initial_frame_idx)
27082708
func_return(&ectx);

0 commit comments

Comments
 (0)