comparison src/if_perl.xs @ 14350:142c0083b3b8 v8.1.0190

patch 8.1.0190: Perl refcounts are wrong commit https://github.com/vim/vim/commit/18c4f1badbc96d39de5b348f268ac8d55c2b0b67 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Jul 16 17:45:38 2018 +0200 patch 8.1.0190: Perl refcounts are wrong Problem: Perl refcounts are wrong. Solution: Improve refcounting. Add a test. (Damien)
author Christian Brabandt <cb@256bit.org>
date Mon, 16 Jul 2018 18:00:07 +0200
parents f761a55a8aed
children 378eefcbbb12
comparison
equal deleted inserted replaced
14349:6e065a3bad97 14350:142c0083b3b8
843 SvRV(rv) = ptr->b_perl_private; 843 SvRV(rv) = ptr->b_perl_private;
844 SvROK_on(rv); 844 SvROK_on(rv);
845 return sv_bless(rv, gv_stashpv("VIBUF", TRUE)); 845 return sv_bless(rv, gv_stashpv("VIBUF", TRUE));
846 } 846 }
847 847
848 #if 0
849 SV *__sv_save[1024];
850 int __sv_save_ix;
851 # define D_Save_Sv(sv) do { if (__sv_save_ix < 1024) __sv_save[__sv_save_ix++] = (sv); } while (0)
852 #else
853 # define D_Save_Sv(sv) NOOP
854 #endif
855
848 /* 856 /*
849 * perl_win_free 857 * perl_win_free
850 * Remove all references to the window to be destroyed 858 * Remove all references to the window to be destroyed
851 */ 859 */
852 void 860 void
853 perl_win_free(win_T *wp) 861 perl_win_free(win_T *wp)
854 { 862 {
855 if (wp->w_perl_private) 863 if (wp->w_perl_private && perl_interp != NULL)
856 sv_setiv((SV *)wp->w_perl_private, 0); 864 {
857 return; 865 SV *sv = (SV*)wp->w_perl_private;
866 D_Save_Sv(sv);
867 sv_setiv(sv, 0);
868 SvREFCNT_dec(sv);
869 }
870 wp->w_perl_private = NULL;
858 } 871 }
859 872
860 void 873 void
861 perl_buf_free(buf_T *bp) 874 perl_buf_free(buf_T *bp)
862 { 875 {
863 if (bp->b_perl_private) 876 if (bp->b_perl_private && perl_interp != NULL)
864 sv_setiv((SV *)bp->b_perl_private, 0); 877 {
865 return; 878 SV *sv = (SV *)bp->b_perl_private;
879 D_Save_Sv(sv);
880 sv_setiv(sv, 0);
881 SvREFCNT_dec(sv);
882 }
883 bp->b_perl_private = NULL;
866 } 884 }
867 885
868 #ifndef PROTO 886 #ifndef PROTO
869 # if (PERL_REVISION == 5) && (PERL_VERSION >= 8) 887 # if (PERL_REVISION == 5) && (PERL_VERSION >= 8)
870 I32 cur_val(pTHX_ IV iv, SV *sv); 888 I32 cur_val(pTHX_ IV iv, SV *sv);
883 # else 901 # else
884 I32 cur_val(IV iv, SV *sv) 902 I32 cur_val(IV iv, SV *sv)
885 # endif 903 # endif
886 { 904 {
887 SV *rv; 905 SV *rv;
906
888 if (iv == 0) 907 if (iv == 0)
889 rv = newWINrv(newSV(0), curwin); 908 rv = newWINrv(newSV(0), curwin);
890 else 909 else
891 rv = newBUFrv(newSV(0), curbuf); 910 rv = newBUFrv(newSV(0), curbuf);
892 sv_setsv(sv, rv); 911
893 SvREFCNT_dec(SvRV(rv)); 912 if (SvRV(sv) == SvRV(rv))
913 SvREFCNT_dec(SvRV(rv));
914 else /* XXX: Not sure if the `else` condition are right
915 * Test_SvREFCNT() pass in all case.
916 */
917 sv_setsv(sv, rv);
918
894 return 0; 919 return 0;
895 } 920 }
896 #endif /* !PROTO */ 921 #endif /* !PROTO */
897 922
898 struct ufuncs cw_funcs = { cur_val, 0, 0 }; 923 struct ufuncs cw_funcs = { cur_val, 0, 0 };
1537 XPUSHs(sv_2mortal(newSViv(i))); 1562 XPUSHs(sv_2mortal(newSViv(i)));
1538 } 1563 }
1539 else 1564 else
1540 { 1565 {
1541 FOR_ALL_BUFFERS(vimbuf) 1566 FOR_ALL_BUFFERS(vimbuf)
1542 XPUSHs(newBUFrv(newSV(0), vimbuf)); 1567 XPUSHs(sv_2mortal(newBUFrv(newSV(0), vimbuf)));
1543 } 1568 }
1544 } 1569 }
1545 else 1570 else
1546 { 1571 {
1547 for (i = 0; i < items; i++) 1572 for (i = 0; i < items; i++)
1562 1587
1563 if (b >= 0) 1588 if (b >= 0)
1564 { 1589 {
1565 vimbuf = buflist_findnr(b); 1590 vimbuf = buflist_findnr(b);
1566 if (vimbuf) 1591 if (vimbuf)
1567 XPUSHs(newBUFrv(newSV(0), vimbuf)); 1592 XPUSHs(sv_2mortal(newBUFrv(newSV(0), vimbuf)));
1568 } 1593 }
1569 } 1594 }
1570 } 1595 }
1571 1596
1572 void 1597 void
1582 if (GIMME == G_SCALAR) 1607 if (GIMME == G_SCALAR)
1583 XPUSHs(sv_2mortal(newSViv(win_count()))); 1608 XPUSHs(sv_2mortal(newSViv(win_count())));
1584 else 1609 else
1585 { 1610 {
1586 FOR_ALL_WINDOWS(vimwin) 1611 FOR_ALL_WINDOWS(vimwin)
1587 XPUSHs(newWINrv(newSV(0), vimwin)); 1612 XPUSHs(sv_2mortal(newWINrv(newSV(0), vimwin)));
1588 } 1613 }
1589 } 1614 }
1590 else 1615 else
1591 { 1616 {
1592 for (i = 0; i < items; i++) 1617 for (i = 0; i < items; i++)
1593 { 1618 {
1594 w = (int) SvIV(ST(i)); 1619 w = (int) SvIV(ST(i));
1595 vimwin = win_find_nr(w); 1620 vimwin = win_find_nr(w);
1596 if (vimwin) 1621 if (vimwin)
1597 XPUSHs(newWINrv(newSV(0), vimwin)); 1622 XPUSHs(sv_2mortal(newWINrv(newSV(0), vimwin)));
1598 } 1623 }
1599 } 1624 }
1600 1625
1601 MODULE = VIM PACKAGE = VIWIN 1626 MODULE = VIM PACKAGE = VIWIN
1602 1627