X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_hot.c;h=fc2b9c5925f97c73746c37ecb1983b5b40de7fff;hb=6a93df2e699ee31021f3373dcafbb41d67f7f951;hp=eb166f943bb56b5605739fb837f2f7f50bcb33ae;hpb=4c79ee7a1e7564ef83d0ac25d6677fdebb3ec7aa;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_hot.c b/pp_hot.c index eb166f9..fc2b9c5 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1,6 +1,7 @@ /* pp_hot.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. @@ -807,7 +808,7 @@ PP(pp_rv2hv) RETURN; } else if (LVRET) { - if (GIMME == G_SCALAR) + if (GIMME != G_SCALAR) Perl_croak(aTHX_ "Can't return hash to lvalue scalar context"); SETs((SV*)hv); RETURN; @@ -1494,8 +1495,10 @@ Perl_do_readline(pTHX) } if (gimme == G_SCALAR) { /* undef TARG, and push that undefined value */ - SV_CHECK_THINKFIRST_COW_DROP(TARG); - (void)SvOK_off(TARG); + if (type != OP_RCATLINE) { + SV_CHECK_THINKFIRST_COW_DROP(TARG); + (void)SvOK_off(TARG); + } PUSHTARG; } RETURN; @@ -1507,7 +1510,7 @@ Perl_do_readline(pTHX) sv_unref(sv); (void)SvUPGRADE(sv, SVt_PV); tmplen = SvLEN(sv); /* remember if already alloced */ - if (!tmplen) + if (!tmplen && !SvREADONLY(sv)) Sv_Grow(sv, 80); /* try short-buffering it */ offset = 0; if (type == OP_RCATLINE && SvOK(sv)) { @@ -1556,8 +1559,10 @@ Perl_do_readline(pTHX) } } if (gimme == G_SCALAR) { - SV_CHECK_THINKFIRST_COW_DROP(TARG); - (void)SvOK_off(TARG); + if (type != OP_RCATLINE) { + SV_CHECK_THINKFIRST_COW_DROP(TARG); + (void)SvOK_off(TARG); + } SPAGAIN; PUSHTARG; } @@ -1854,6 +1859,12 @@ PP(pp_iter) else { sv = AvARRAY(av)[++cx->blk_loop.iterix]; } + if (sv && SvREFCNT(sv) == 0) { + *itersvp = Nullsv; + Perl_croak(aTHX_ + "Use of freed value in iteration (perhaps you modified the iterated array within the loop?)"); + } + if (sv) SvTEMP_off(sv); else @@ -2150,6 +2161,7 @@ PP(pp_subst) if (!c) { register PERL_CONTEXT *cx; SPAGAIN; + ReREFCNT_inc(rx); PUSHSUBST(cx); RETURNOP(cPMOP->op_pmreplroot); } @@ -2316,10 +2328,10 @@ PP(pp_leavesub) } PUTBACK; + LEAVE; POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return pop_return(); } @@ -2372,9 +2384,9 @@ 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; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "Can't modify non-lvalue subroutine call"); } @@ -2383,9 +2395,9 @@ PP(pp_leavesublv) EXTEND_MORTAL(1); if (MARK == SP) { if (SvFLAGS(TOPs) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { + LEAVE; 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" @@ -2398,9 +2410,9 @@ PP(pp_leavesublv) } } else { /* Should not happen? */ + LEAVE; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "%s returned from lvalue subroutine in scalar context", (MARK > SP ? "Empty array" : "Array")); @@ -2414,9 +2426,9 @@ PP(pp_leavesublv) && SvFLAGS(*mark) & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)) { /* Might be flattened array after $#array = */ PUTBACK; + LEAVE; POPSUB(cx,sv); PL_curpm = newpm; - LEAVE; LEAVESUB(sv); DIE(aTHX_ "Can't return a %s from lvalue subroutine", SvREADONLY(TOPs) ? "readonly value" : "temporary"); @@ -2468,10 +2480,10 @@ PP(pp_leavesublv) } PUTBACK; + LEAVE; POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */ PL_curpm = newpm; /* ... and pop $1 et al */ - LEAVE; LEAVESUB(sv); return pop_return(); } @@ -2922,8 +2934,18 @@ S_method_common(pTHX_ SV* meth, U32* hashp) /* this isn't a reference */ packname = Nullch; + + if(SvOK(sv) && (packname = SvPV(sv, packlen))) { + HE* he; + he = hv_fetch_ent(PL_stashcache, sv, 0, 0); + if (he) { + stash = INT2PTR(HV*,SvIV(HeVAL(he))); + goto fetch; + } + } + if (!SvOK(sv) || - !(packname = SvPV(sv, packlen)) || + !(packname) || !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) || !(ob=(SV*)GvIO(iogv))) { @@ -2942,6 +2964,10 @@ S_method_common(pTHX_ SV* meth, U32* hashp) stash = gv_stashpvn(packname, packlen, FALSE); if (!stash) packsv = sv; + else { + SV* ref = newSViv(PTR2IV(stash)); + hv_store(PL_stashcache, packname, packlen, ref, 0); + } goto fetch; } /* it _is_ a filehandle name -- replace with a reference */ @@ -2998,7 +3024,11 @@ S_method_common(pTHX_ SV* meth, U32* hashp) /* the method name is unqualified or starts with SUPER:: */ packname = sep ? CopSTASHPV(PL_curcop) : stash ? HvNAME(stash) : packname; - packlen = strlen(packname); + if (!packname) + Perl_croak(aTHX_ + "Can't use anonymous symbol table for method lookup"); + else + packlen = strlen(packname); } else { /* the method name is qualified */