Mercurial > vim
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 |