X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_hot.c;h=6fb53d49a4c303f56b0e43e120d41c02b6594312;hb=fca1d8b34fac5a740ae67bc3b873bc01cd76a8a9;hp=034495d87211e6cb04b963503bdee5fdc2c83227;hpb=b7c442934df5578585948a9249cd388c152963f7;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_hot.c b/pp_hot.c index 034495d..6fb53d4 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -168,23 +168,44 @@ PP(pp_sassign) if (!got_coderef) { /* We've been returned a constant rather than a full subroutine, but they expect a subroutine reference to apply. */ - ENTER; - SvREFCNT_inc_void(SvRV(cv)); - /* newCONSTSUB takes a reference count on the passed in SV - from us. We set the name to NULL, otherwise we get into - all sorts of fun as the reference to our new sub is - donated to the GV that we're about to assign to. - */ - SvRV_set(left, (SV *)newCONSTSUB(GvSTASH(right), NULL, + if (SvROK(cv)) { + ENTER; + SvREFCNT_inc_void(SvRV(cv)); + /* newCONSTSUB takes a reference count on the passed in SV + from us. We set the name to NULL, otherwise we get into + all sorts of fun as the reference to our new sub is + donated to the GV that we're about to assign to. + */ + SvRV_set(left, (SV *)newCONSTSUB(GvSTASH(right), NULL, SvRV(cv))); - SvREFCNT_dec(cv); - LEAVE; - } + SvREFCNT_dec(cv); + LEAVE; + } else { + /* What can happen for the corner case *{"BONK"} = \&{"BONK"}; + is that + First: ops for \&{"BONK"}; return us the constant in the + symbol table + Second: ops for *{"BONK"} cause that symbol table entry + (and our reference to it) to be upgraded from RV + to typeblob) + Thirdly: We get here. cv is actually PVGV now, and its + GvCV() is actually the subroutine we're looking for + + So change the reference so that it points to the subroutine + of that typeglob, as that's what they were after all along. + */ + GV *const upgraded = (GV *) cv; + CV *const source = GvCV(upgraded); - if (strEQ(GvNAME(right),"isa")) { - GvCVGEN(right) = 0; - ++PL_sub_generation; /* I don't get this at all --blblack */ + assert(source); + assert(CvFLAGS(source) & CVf_CONST); + + SvREFCNT_inc_void(source); + SvREFCNT_dec(upgraded); + SvRV_set(left, (SV *)source); + } } + } SvSetMagicSV(right, left); SETs(right); @@ -1010,6 +1031,8 @@ PP(pp_aassign) } TAINT_NOT; } + if (PL_delaymagic & DM_ARRAY) + SvSETMAGIC((SV*)ary); break; case SVt_PVHV: { /* normal hash */ SV *tmpstr; @@ -1156,6 +1179,7 @@ PP(pp_aassign) while (relem <= SP) *relem++ = (lelem <= lastlelem) ? *lelem++ : &PL_sv_undef; } + RETURN; } @@ -1164,7 +1188,7 @@ PP(pp_qr) dVAR; dSP; register PMOP * const pm = cPMOP; REGEXP * rx = PM_GETRE(pm); - SV * const pkg = CALLREG_QRPKG(rx); + SV * const pkg = CALLREG_PACKAGE(rx); SV * const rv = sv_newmortal(); SV * const sv = newSVrv(rv, SvPV_nolen(pkg)); if (rx->extflags & RXf_TAINTED) @@ -1262,9 +1286,12 @@ PP(pp_match) } } } - /* remove comment to get faster /g but possibly unsafe $1 vars after a - match. Test for the unsafe vars will fail as well*/ - if (( /* !global && */ rx->nparens) + /* XXX: comment out !global get safe $1 vars after a + match, BUT be aware that this leads to dramatic slowdowns on + /g matches against large strings. So far a solution to this problem + appears to be quite tricky. + Test for the unsafe vars are TODO for now. */ + if (( !global && rx->nparens) || SvTEMP(TARG) || PL_sawampersand || (rx->extflags & (RXf_EVAL_SEEN|RXf_PMf_KEEPCOPY))) r_flags |= REXEC_COPY_STR; @@ -2706,9 +2733,6 @@ try_autoload: gimme = GIMME_V; if ((PL_op->op_private & OPpENTERSUB_DB) && GvCV(PL_DBsub) && !CvNODEBUG(cv)) { - if (CvASSERTION(cv) && PL_DBassertion) - sv_setiv(PL_DBassertion, 1); - Perl_get_db_sub(aTHX_ &sv, cv); if (CvISXSUB(cv)) PL_curcopdb = PL_curcop; @@ -3015,7 +3039,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp) packsv = sv; else { SV* const ref = newSViv(PTR2IV(stash)); - hv_store(PL_stashcache, packname, packlen, ref, 0); + (void)hv_store(PL_stashcache, packname, packlen, ref, 0); } goto fetch; } @@ -3046,7 +3070,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp) gv = (GV*)HeVAL(he); if (isGV(gv) && GvCV(gv) && (!GvCVGEN(gv) || GvCVGEN(gv) - == (PL_sub_generation + HvMROMETA(stash)->sub_generation))) + == (PL_sub_generation + HvMROMETA(stash)->cache_gen))) return (SV*)GvCV(gv); } }