diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2003-08-24 16:52:00 +0100 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2003-08-26 19:13:39 +0000 |
commit | 5dd42e15760f2e77ab3979bfe1b6aafaa9ff1227 (patch) | |
tree | 0afca94ca8522b7c1ac1afeea67258cd0ce57290 | |
parent | d7f1a795527ad4875d71a2e977851f754d4b7b3f (diff) | |
download | perl-5dd42e15760f2e77ab3979bfe1b6aafaa9ff1227.tar.gz |
improved 19064 (local $_[0] problems)
Message-ID: <20030824145159.GA12210@fdgroup.com>
p4raw-id: //depot/perl@20909
-rw-r--r-- | pp_ctl.c | 8 | ||||
-rw-r--r-- | pp_hot.c | 20 | ||||
-rw-r--r-- | scope.c | 13 | ||||
-rwxr-xr-x | t/op/args.t | 6 |
4 files changed, 31 insertions, 16 deletions
@@ -1883,6 +1883,7 @@ PP(pp_return) switch (CxTYPE(cx)) { case CXt_SUB: popsub2 = TRUE; + cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */ break; case CXt_EVAL: if (!(PL_in_eval & EVAL_KEEPERR)) @@ -1942,15 +1943,16 @@ PP(pp_return) } PL_stack_sp = newsp; + LEAVE; /* Stack values are safe: */ if (popsub2) { + cxstack_ix--; POPSUB(cx,sv); /* release CV and @_ ... */ } else sv = Nullsv; PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); if (clear_errsv) sv_setpv(ERRSV,""); @@ -1985,6 +1987,7 @@ PP(pp_last) dounwind(cxix); POPBLOCK(cx,newpm); + cxstack_ix++; /* temporarily protect top context */ mark = newsp; switch (CxTYPE(cx)) { case CXt_LOOP: @@ -2026,6 +2029,8 @@ PP(pp_last) SP = newsp; PUTBACK; + LEAVE; + cxstack_ix--; /* Stack values are safe: */ switch (pop2) { case CXt_LOOP: @@ -2038,7 +2043,6 @@ PP(pp_last) } PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return nextop; } @@ -2291,6 +2291,7 @@ PP(pp_leavesub) SV *sv; POPBLOCK(cx,newpm); + cxstack_ix++; /* temporarily protect top context */ TAINT_NOT; if (gimme == G_SCALAR) { @@ -2328,10 +2329,11 @@ PP(pp_leavesub) } PUTBACK; + LEAVE; + cxstack_ix--; POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return pop_return(); } @@ -2349,6 +2351,7 @@ PP(pp_leavesublv) SV *sv; POPBLOCK(cx,newpm); + cxstack_ix++; /* temporarily protect top context */ TAINT_NOT; @@ -2384,9 +2387,10 @@ PP(pp_leavesublv) * the refcounts so the caller gets a live guy. Cannot set * TEMP, so sv_2mortal is out of question. */ if (!CvLVALUE(cx->blk_sub.cv)) { + LEAVE; + cxstack_ix--; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "Can't modify non-lvalue subroutine call"); } @@ -2395,9 +2399,10 @@ PP(pp_leavesublv) EXTEND_MORTAL(1); if (MARK == SP) { if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { + LEAVE; + cxstack_ix--; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "Can't return %s from lvalue subroutine", SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef" @@ -2410,9 +2415,10 @@ PP(pp_leavesublv) } } else { /* Should not happen? */ + LEAVE; + cxstack_ix--; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "%s returned from lvalue subroutine in scalar context", (MARK > SP ? "Empty array" : "Array")); @@ -2426,9 +2432,10 @@ PP(pp_leavesublv) && SvFLAGS(*mark) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { /* Might be flattened array after $#array = */ PUTBACK; + LEAVE; + cxstack_ix--; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "Can't return a %s from lvalue subroutine", SvREADONLY(TOPs) ? "readonly value" : "temporary"); @@ -2480,10 +2487,11 @@ PP(pp_leavesublv) } PUTBACK; + LEAVE; + cxstack_ix--; POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return pop_return(); } @@ -624,6 +624,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 @@ -706,7 +709,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; @@ -739,6 +742,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, @@ -774,6 +778,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; @@ -983,13 +989,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; } } @@ -1007,8 +1014,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; } } diff --git a/t/op/args.t b/t/op/args.t index bac8fd0301..90a7d25771 100755 --- a/t/op/args.t +++ b/t/op/args.t @@ -1,6 +1,6 @@ #!./perl -print "1..9\n"; +print "1..11\n"; # test various operations on @_ @@ -74,9 +74,6 @@ for (1..5) { try() } ++$ord; print "ok $ord\n"; -# These tests disabled because the change #19064 was retracted. -# http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2003-08/msg01485.html -if (0) { # bug #21542 local $_[0] causes reify problems and coredumps sub local1 { local $_[0] } @@ -89,4 +86,3 @@ sub local2 { local $_[0]; last L } L: { local2 } $ord++; print "ok $ord\n"; -} |