Patch 8.1.0190
Problem: Perl refcounts are wrong.
Solution: Improve refcounting. Add a test. (Damien)
Files: src/if_perl.xs, src/testdir/test_perl.vim
*** ../vim-8.1.0189/src/if_perl.xs 2018-07-08 17:18:58.416462371 +0200
--- src/if_perl.xs 2018-07-16 17:34:41.750473682 +0200
***************
*** 845,850 ****
--- 845,858 ----
return sv_bless(rv, gv_stashpv("VIBUF", TRUE));
}
+ #if 0
+ SV *__sv_save[1024];
+ int __sv_save_ix;
+ # define D_Save_Sv(sv) do { if (__sv_save_ix < 1024)
__sv_save[__sv_save_ix++] = (sv); } while (0)
+ #else
+ # define D_Save_Sv(sv) NOOP
+ #endif
+
/*
* perl_win_free
* Remove all references to the window to be destroyed
***************
*** 852,868 ****
void
perl_win_free(win_T *wp)
{
! if (wp->w_perl_private)
! sv_setiv((SV *)wp->w_perl_private, 0);
! return;
}
void
perl_buf_free(buf_T *bp)
{
! if (bp->b_perl_private)
! sv_setiv((SV *)bp->b_perl_private, 0);
! return;
}
#ifndef PROTO
--- 860,886 ----
void
perl_win_free(win_T *wp)
{
! if (wp->w_perl_private && perl_interp != NULL)
! {
! SV *sv = (SV*)wp->w_perl_private;
! D_Save_Sv(sv);
! sv_setiv(sv, 0);
! SvREFCNT_dec(sv);
! }
! wp->w_perl_private = NULL;
}
void
perl_buf_free(buf_T *bp)
{
! if (bp->b_perl_private && perl_interp != NULL)
! {
! SV *sv = (SV *)bp->b_perl_private;
! D_Save_Sv(sv);
! sv_setiv(sv, 0);
! SvREFCNT_dec(sv);
! }
! bp->b_perl_private = NULL;
}
#ifndef PROTO
***************
*** 885,896 ****
# endif
{
SV *rv;
if (iv == 0)
rv = newWINrv(newSV(0), curwin);
else
rv = newBUFrv(newSV(0), curbuf);
! sv_setsv(sv, rv);
! SvREFCNT_dec(SvRV(rv));
return 0;
}
#endif /* !PROTO */
--- 903,921 ----
# endif
{
SV *rv;
+
if (iv == 0)
rv = newWINrv(newSV(0), curwin);
else
rv = newBUFrv(newSV(0), curbuf);
!
! if (SvRV(sv) == SvRV(rv))
! SvREFCNT_dec(SvRV(rv));
! else /* XXX: Not sure if the `else` condition are right
! * Test_SvREFCNT() pass in all case.
! */
! sv_setsv(sv, rv);
!
return 0;
}
#endif /* !PROTO */
***************
*** 1539,1545 ****
else
{
FOR_ALL_BUFFERS(vimbuf)
! XPUSHs(newBUFrv(newSV(0), vimbuf));
}
}
else
--- 1564,1570 ----
else
{
FOR_ALL_BUFFERS(vimbuf)
! XPUSHs(sv_2mortal(newBUFrv(newSV(0), vimbuf)));
}
}
else
***************
*** 1564,1570 ****
{
vimbuf = buflist_findnr(b);
if (vimbuf)
! XPUSHs(newBUFrv(newSV(0), vimbuf));
}
}
}
--- 1589,1595 ----
{
vimbuf = buflist_findnr(b);
if (vimbuf)
! XPUSHs(sv_2mortal(newBUFrv(newSV(0), vimbuf)));
}
}
}
***************
*** 1584,1590 ****
else
{
FOR_ALL_WINDOWS(vimwin)
! XPUSHs(newWINrv(newSV(0), vimwin));
}
}
else
--- 1609,1615 ----
else
{
FOR_ALL_WINDOWS(vimwin)
! XPUSHs(sv_2mortal(newWINrv(newSV(0), vimwin)));
}
}
else
***************
*** 1594,1600 ****
w = (int) SvIV(ST(i));
vimwin = win_find_nr(w);
if (vimwin)
! XPUSHs(newWINrv(newSV(0), vimwin));
}
}
--- 1619,1625 ----
w = (int) SvIV(ST(i));
vimwin = win_find_nr(w);
if (vimwin)
! XPUSHs(sv_2mortal(newWINrv(newSV(0), vimwin)));
}
}
*** ../vim-8.1.0189/src/testdir/test_perl.vim 2017-03-18 19:45:55.000000000
+0100
--- src/testdir/test_perl.vim 2018-07-16 17:34:41.754473657 +0200
***************
*** 219,238 ****
call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n"))
endfunc
! func Test_SvREFCNT()
new t
perl <<--perl
my ($b, $w);
! $b = $curbuf for 0 .. 10;
! $w = $curwin for 0 .. 10;
VIM::DoCommand('bw! t');
if (exists &Internals::SvREFCNT) {
my $cb = Internals::SvREFCNT($$b);
my $cw = Internals::SvREFCNT($$w);
! VIM::Eval("assert_equal(2, $cb)");
! VIM::Eval("assert_equal(2, $cw)");
}
VIM::Eval("assert_false($$b)");
VIM::Eval("assert_false($$w)");
--perl
endfunc
--- 219,260 ----
call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n"))
endfunc
! " Run first to get a clean namespace
! func Test_000_SvREFCNT()
! for i in range(10)
! exec 'new X'.i
! endfor
new t
perl <<--perl
+ #line 5 "Test_000_SvREFCNT()"
my ($b, $w);
!
! $b = $curbuf for 0 .. 100;
! $w = $curwin for 0 .. 100;
! () = VIM::Buffers for 0 .. 100;
! () = VIM::Windows for 0 .. 100;
!
VIM::DoCommand('bw! t');
if (exists &Internals::SvREFCNT) {
my $cb = Internals::SvREFCNT($$b);
my $cw = Internals::SvREFCNT($$w);
! VIM::Eval("assert_equal(2, $cb, 'T1')");
! VIM::Eval("assert_equal(2, $cw, 'T2')");
! foreach ( VIM::Buffers, VIM::Windows ) {
! my $c = Internals::SvREFCNT($_);
! VIM::Eval("assert_equal(2, $c, 'T3')");
! $c = Internals::SvREFCNT($$_);
! # Why only one ref?
! # Look wrong but work. Maybe not portable...
! VIM::Eval("assert_equal(1, $c, 'T4')");
! }
! $cb = Internals::SvREFCNT($$curbuf);
! $cw = Internals::SvREFCNT($$curwin);
! VIM::Eval("assert_equal(3, $cb, 'T5')");
! VIM::Eval("assert_equal(3, $cw, 'T6')");
}
VIM::Eval("assert_false($$b)");
VIM::Eval("assert_false($$w)");
--perl
+ %bw!
endfunc
*** ../vim-8.1.0189/src/version.c 2018-07-15 20:26:37.418459878 +0200
--- src/version.c 2018-07-16 17:37:41.017344049 +0200
***************
*** 791,792 ****
--- 791,794 ----
{ /* Add new patch number below this line */
+ /**/
+ 190,
/**/
--
hundred-and-one symptoms of being an internet addict:
255. You work for a newspaper and your editor asks you to write an
article about Internet addiction...in the "first person."
/// Bram Moolenaar -- [email protected] -- 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 ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.