Patch 8.2.1849
Problem: Vim9: garbage collection frees block-local variables.
Solution: Mark all script variables as used.
Files: src/evalvars.c, src/testdir/test_vim9_script.vim
*** ../vim-8.2.1848/src/evalvars.c 2020-10-14 19:39:16.041002546 +0200
--- src/evalvars.c 2020-10-15 20:39:04.723050433 +0200
***************
*** 303,314 ****
int
garbage_collect_scriptvars(int copyID)
{
! int i;
! int abort = FALSE;
for (i = 1; i <= script_items.ga_len; ++i)
abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
return abort;
}
--- 303,326 ----
int
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;
}
*** ../vim-8.2.1848/src/testdir/test_vim9_script.vim 2020-10-15 12:46:38.737199511 +0200
--- src/testdir/test_vim9_script.vim 2020-10-15 20:38:22.687218401 +0200
***************
*** 253,283 ****
def Test_block_local_vars()
var lines =<< trim END
vim9script
if true
! var text = 'hello'
! def SayHello(): string
return text
enddef
def SetText(v: string)
! text = v
enddef
endif
if true
! var text = 'again'
! def SayAgain(): string
return text
enddef
endif
defcompile
! assert_equal('hello', SayHello())
! assert_equal('again', SayAgain())
SetText('foobar')
! assert_equal('foobar', SayHello())
END
! CheckScriptSuccess(lines)
enddef
func g:NoSuchFunc()
--- 253,299 ----
def Test_block_local_vars()
var lines =<< trim END
vim9script
+ v:testing = 1
if true
! var text = ['hello']
! def SayHello(): list<string>
return text
enddef
def SetText(v: string)
! text = [v]
enddef
endif
if true
! 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())
SetText('foobar')
! assert_equal(['foobar'], SayHello())
!
! call writefile(['ok'], 'Xdidit')
! qall!
END
!
! # 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()
*** ../vim-8.2.1848/src/version.c 2020-10-15 19:10:53.203606791 +0200
--- src/version.c 2020-10-15 19:52:27.720521913 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 1849,
/**/
--
How many light bulbs does it take to change a person?
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///