X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=scope.c;h=f738b5b68c9db337447e8a10b91f77a90c1db6cb;hb=4aad327484f5f36a4e39bd7979447d47a5417a57;hp=a5cc4f49fa9afb6d6bb1276b4d18ce75e90361d3;hpb=4c79ee7a1e7564ef83d0ac25d6677fdebb3ec7aa;p=p5sagit%2Fp5-mst-13.2.git diff --git a/scope.c b/scope.c index a5cc4f4..f738b5b 100644 --- a/scope.c +++ b/scope.c @@ -1,6 +1,7 @@ /* scope.c * - * Copyright (c) 1991-2003, Larry Wall + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + * 2000, 2001, 2002, 2003, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -154,6 +155,13 @@ Perl_savestack_grow(pTHX) Renew(PL_savestack, PL_savestack_max, ANY); } +void +Perl_savestack_grow_cnt(pTHX_ I32 need) +{ + PL_savestack_max = PL_savestack_ix + need; + Renew(PL_savestack, PL_savestack_max, ANY); +} + #undef GROW void @@ -276,7 +284,7 @@ Perl_save_shared_pvref(pTHX_ char **str) void Perl_save_gp(pTHX_ GV *gv, I32 empty) { - SSCHECK(6); + SSGROW(6); SSPUSHIV((IV)SvLEN(gv)); SvLEN(gv) = 0; /* forget that anything was allocated here */ SSPUSHIV((IV)SvCUR(gv)); @@ -604,6 +612,9 @@ Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr) SSPUSHINT(idx); SSPUSHPTR(SvREFCNT_inc(*sptr)); SSPUSHINT(SAVEt_AELEM); + /* if it gets reified later, the restore will have the wrong refcnt */ + if (!AvREAL(av) && AvREIFY(av)) + SvREFCNT_inc(*sptr); save_scalar_at(sptr); sv = *sptr; /* If we're localizing a tied array element, this new sv @@ -686,7 +697,7 @@ Perl_leave_scope(pTHX_ I32 base) value = (SV*)SSPOPPTR; gv = (GV*)SSPOPPTR; ptr = &GvSV(gv); - SvREFCNT_dec(gv); + av = (AV*)gv; /* what to refcnt_dec */ goto restore_sv; case SAVEt_GENERIC_PVREF: /* generic pv */ str = (char*)SSPOPPTR; @@ -719,6 +730,7 @@ Perl_leave_scope(pTHX_ I32 base) case SAVEt_SVREF: /* scalar reference */ value = (SV*)SSPOPPTR; ptr = SSPOPPTR; + av = Nullav; /* what to refcnt_dec */ restore_sv: sv = *(SV**)ptr; DEBUG_S(PerlIO_printf(Perl_debug_log, @@ -754,6 +766,8 @@ Perl_leave_scope(pTHX_ I32 base) SvSETMAGIC(value); PL_localizing = 0; SvREFCNT_dec(value); + if (av) /* actually an av, hv or gv */ + SvREFCNT_dec(av); break; case SAVEt_AV: /* array reference */ av = (AV*)SSPOPPTR; @@ -963,13 +977,14 @@ Perl_leave_scope(pTHX_ I32 base) value = (SV*)SSPOPPTR; i = SSPOPINT; av = (AV*)SSPOPPTR; + if (!AvREAL(av) && AvREIFY(av)) /* undo reify guard */ + SvREFCNT_dec(value); ptr = av_fetch(av,i,1); if (ptr) { sv = *(SV**)ptr; if (sv && sv != &PL_sv_undef) { if (SvTIED_mg((SV*)av, PERL_MAGIC_tied)) (void)SvREFCNT_inc(sv); - SvREFCNT_dec(av); goto restore_sv; } } @@ -987,8 +1002,8 @@ Perl_leave_scope(pTHX_ I32 base) ptr = &HeVAL((HE*)ptr); if (SvTIED_mg((SV*)hv, PERL_MAGIC_tied)) (void)SvREFCNT_inc(*(SV**)ptr); - SvREFCNT_dec(hv); SvREFCNT_dec(sv); + av = (AV*)hv; /* what to refcnt_dec */ goto restore_sv; } }