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) garbage_collect_scriptvars(int copyID)
{ {
int i; int i;
int idx;
int abort = FALSE; int abort = FALSE;
scriptitem_T *si;
for (i = 1; i <= script_items.ga_len; ++i) for (i = 1; i <= script_items.ga_len; ++i)
{
abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL); 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; return abort;
} }

View File

@@ -253,31 +253,47 @@ enddef
def Test_block_local_vars() def Test_block_local_vars()
var lines =<< trim END var lines =<< trim END
vim9script vim9script
v:testing = 1
if true if true
var text = 'hello' var text = ['hello']
def SayHello(): string def SayHello(): list<string>
return text return text
enddef enddef
def SetText(v: string) def SetText(v: string)
text = v text = [v]
enddef enddef
endif endif
if true if true
var text = 'again' var text = ['again']
def SayAgain(): string def SayAgain(): list<string>
return text return text
enddef enddef
endif endif
# test that the "text" variables are not cleaned up
test_garbagecollect_now()
defcompile defcompile
assert_equal('hello', SayHello()) assert_equal(['hello'], SayHello())
assert_equal('again', SayAgain()) assert_equal(['again'], SayAgain())
SetText('foobar') SetText('foobar')
assert_equal('foobar', SayHello()) assert_equal(['foobar'], SayHello())
call writefile(['ok'], 'Xdidit')
qall!
END 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 enddef
func g:NoSuchFunc() func g:NoSuchFunc()

View File

@@ -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 */
/**/
1849,
/**/ /**/
1848, 1848,
/**/ /**/