0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.1849: Vim9: garbage collection frees block-local variables

Problem:    Vim9: garbage collection frees block-local variables.
Solution:   Mark all script variables as used.
This commit is contained in:
Bram Moolenaar
2020-10-15 20:42:20 +02:00
parent 74f8eece5e
commit ed234f24f3
3 changed files with 41 additions and 11 deletions

View File

@@ -304,11 +304,23 @@ garbage_collect_vimvars(int copyID)
garbage_collect_scriptvars(int copyID)
{
int i;
int idx;
int abort = FALSE;
scriptitem_T *si;
for (i = 1; i <= script_items.ga_len; ++i)
{
abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
si = SCRIPT_ITEM(i);
for (idx = 0; idx < si->sn_var_vals.ga_len; ++idx)
{
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
abort = abort || set_ref_in_item(sv->sv_tv, copyID, NULL, NULL);
}
}
return abort;
}

View File

@@ -253,31 +253,47 @@ enddef
def Test_block_local_vars()
var lines =<< trim END
vim9script
v:testing = 1
if true
var text = 'hello'
def SayHello(): string
var text = ['hello']
def SayHello(): list<string>
return text
enddef
def SetText(v: string)
text = v
text = [v]
enddef
endif
if true
var text = 'again'
def SayAgain(): string
var text = ['again']
def SayAgain(): list<string>
return text
enddef
endif
# test that the "text" variables are not cleaned up
test_garbagecollect_now()
defcompile
assert_equal('hello', SayHello())
assert_equal('again', SayAgain())
assert_equal(['hello'], SayHello())
assert_equal(['again'], SayAgain())
SetText('foobar')
assert_equal('foobar', SayHello())
assert_equal(['foobar'], SayHello())
call writefile(['ok'], 'Xdidit')
qall!
END
CheckScriptSuccess(lines)
# need to execute this with a separate Vim instance to avoid the current
# context gets garbage collected.
writefile(lines, 'Xscript')
RunVim([], [], '-S Xscript')
assert_equal(['ok'], readfile('Xdidit'))
delete('Xscript')
delete('Xdidit')
enddef
func g:NoSuchFunc()

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1849,
/**/
1848,
/**/