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.

Raspunde prin e-mail lui