X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_hot.c;h=40386293691856011ee9cb93f64136233e93fd06;hb=f8babb2524be4b18ced06634d930c03291c1f313;hp=d1873b2a32f2f658a562584952b006e2bb9e7419;hpb=cfc4a7da389202132834a0ef4ed2d46dd167c176;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_hot.c b/pp_hot.c index d1873b2..4038629 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -138,7 +138,7 @@ PP(pp_sassign) assert(SvROK(cv)); } - /* Can do the optimisation if right (LVAUE) is not a typeglob, + /* Can do the optimisation if right (LVALUE) is not a typeglob, left (RVALUE) is a reference to something, and we're in void context. */ if (!got_coderef && gv_type != SVt_PVGV && GIMME_V == G_VOID) { @@ -150,7 +150,7 @@ PP(pp_sassign) SV *const value = SvRV(cv); SvUPGRADE((SV *)gv, SVt_RV); - SvROK_on(gv); + SvPCS_IMPORTED_on(gv); SvRV_set(gv, value); SvREFCNT_inc_simple_void(value); SETs(right); @@ -180,6 +180,10 @@ PP(pp_sassign) LEAVE; } + if (strEQ(GvNAME(right),"isa")) { + GvCVGEN(right) = 0; + ++PL_sub_generation; + } } SvSetMagicSV(right, left); SETs(right); @@ -1300,6 +1304,7 @@ PP(pp_match) const I32 oldsave = PL_savestack_ix; I32 update_minmatch = 1; I32 had_zerolen = 0; + U32 gpos = 0; if (PL_op->op_flags & OPf_STACKED) TARG = POPs; @@ -1346,18 +1351,23 @@ PP(pp_match) if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) { MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global); if (mg && mg->mg_len >= 0) { - if (!(rx->reganch & ROPT_GPOS_SEEN)) + if (!(rx->extflags & RXf_GPOS_SEEN)) rx->endp[0] = rx->startp[0] = mg->mg_len; - else if (rx->reganch & ROPT_ANCH_GPOS) { + else if (rx->extflags & RXf_ANCH_GPOS) { r_flags |= REXEC_IGNOREPOS; rx->endp[0] = rx->startp[0] = mg->mg_len; - } - minmatch = (mg->mg_flags & MGf_MINMATCH); + } else if (rx->extflags & RXf_GPOS_FLOAT) + gpos = mg->mg_len; + else + rx->endp[0] = rx->startp[0] = mg->mg_len; + minmatch = (mg->mg_flags & MGf_MINMATCH) ? rx->gofs + 1 : 0; update_minmatch = 0; } } } - if ((!global && rx->nparens) + /* 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) || SvTEMP(TARG) || PL_sawampersand || (pm->op_pmflags & PMf_EVAL)) r_flags |= REXEC_COPY_STR; if (SvSCREAM(TARG)) @@ -1365,29 +1375,29 @@ PP(pp_match) play_it_again: if (global && rx->startp[0] != -1) { - t = s = rx->endp[0] + truebase; - if ((s + rx->minlen) > strend) + t = s = rx->endp[0] + truebase - rx->gofs; + if ((s + rx->minlen) > strend || s < truebase) goto nope; if (update_minmatch++) minmatch = had_zerolen; } - if (rx->reganch & RE_USE_INTUIT && - DO_UTF8(TARG) == ((rx->reganch & ROPT_UTF8) != 0)) { + if (rx->extflags & RXf_USE_INTUIT && + DO_UTF8(TARG) == ((rx->extflags & RXf_UTF8) != 0)) { /* FIXME - can PL_bostr be made const char *? */ PL_bostr = (char *)truebase; s = CALLREG_INTUIT_START(rx, TARG, (char *)s, (char *)strend, r_flags, NULL); if (!s) goto nope; - if ( (rx->reganch & ROPT_CHECK_ALL) + if ( (rx->extflags & RXf_CHECK_ALL) && !PL_sawampersand - && ((rx->reganch & ROPT_NOSCAN) - || !((rx->reganch & RE_INTUIT_TAIL) + && ((rx->extflags & RXf_NOSCAN) + || !((rx->extflags & RXf_INTUIT_TAIL) && (r_flags & REXEC_SCREAM))) && !SvROK(TARG)) /* Cannot trust since INTUIT cannot guess ^ */ goto yup; } - if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NULL, r_flags)) + if (CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, INT2PTR(void*, gpos), r_flags)) { PL_curpm = pm; if (dynpm->op_pmflags & PMf_ONCE) @@ -1437,14 +1447,14 @@ play_it_again: } if (rx->startp[0] != -1) { mg->mg_len = rx->endp[0]; - if (rx->startp[0] == rx->endp[0]) + if (rx->startp[0] + rx->gofs == (UV)rx->endp[0]) mg->mg_flags |= MGf_MINMATCH; else mg->mg_flags &= ~MGf_MINMATCH; } } had_zerolen = (rx->startp[0] != -1 - && rx->startp[0] == rx->endp[0]); + && rx->startp[0] + rx->gofs == (UV)rx->endp[0]); PUTBACK; /* EVAL blocks may use stack */ r_flags |= REXEC_IGNOREPOS | REXEC_NOT_FIRST; goto play_it_again; @@ -1471,7 +1481,7 @@ play_it_again: } if (rx->startp[0] != -1) { mg->mg_len = rx->endp[0]; - if (rx->startp[0] == rx->endp[0]) + if (rx->startp[0] + rx->gofs == (UV)rx->endp[0]) mg->mg_flags |= MGf_MINMATCH; else mg->mg_flags &= ~MGf_MINMATCH; @@ -1497,11 +1507,11 @@ yup: /* Confirmed by INTUIT */ rx->subbeg = (char *) truebase; rx->startp[0] = s - truebase; if (RX_MATCH_UTF8(rx)) { - char * const t = (char*)utf8_hop((U8*)s, rx->minlen); + char * const t = (char*)utf8_hop((U8*)s, rx->minlenret); rx->endp[0] = t - truebase; } else { - rx->endp[0] = s - truebase + rx->minlen; + rx->endp[0] = s - truebase + rx->minlenret; } rx->sublen = strend - truebase; goto gotcha; @@ -1531,11 +1541,11 @@ yup: /* Confirmed by INTUIT */ rx->sublen = strend - t; RX_MATCH_COPIED_on(rx); off = rx->startp[0] = s - t; - rx->endp[0] = off + rx->minlen; + rx->endp[0] = off + rx->minlenret; } else { /* startp/endp are used by @- @+. */ rx->startp[0] = s - truebase; - rx->endp[0] = s - truebase + rx->minlen; + rx->endp[0] = s - truebase + rx->minlenret; } rx->nparens = rx->lastparen = rx->lastcloseparen = 0; /* used by @-, @+, and $^N */ LEAVE_SCOPE(oldsave); @@ -1640,8 +1650,14 @@ Perl_do_readline(pTHX) have_fp: if (gimme == G_SCALAR) { sv = TARG; - if (SvROK(sv)) - sv_unref(sv); + if (type == OP_RCATLINE && SvGMAGICAL(sv)) + mg_get(sv); + if (SvROK(sv)) { + if (type == OP_RCATLINE) + SvPV_force_nolen(sv); + else + sv_unref(sv); + } else if (isGV_with_GP(sv)) { SvPV_force_nolen(sv); } @@ -2104,7 +2120,8 @@ PP(pp_subst) !is_cow && #endif (SvREADONLY(TARG) - || ( (SvTYPE(TARG) == SVt_PVGV || SvTYPE(TARG) > SVt_PVLV) + || ( ((SvTYPE(TARG) == SVt_PVGV && isGV_with_GP(TARG)) + || SvTYPE(TARG) > SVt_PVLV) && !(SvTYPE(TARG) == SVt_PVGV && SvFAKE(TARG))))) DIE(aTHX_ PL_no_modify); PUTBACK; @@ -2141,17 +2158,17 @@ PP(pp_subst) r_flags |= REXEC_SCREAM; orig = m = s; - if (rx->reganch & RE_USE_INTUIT) { + if (rx->extflags & RXf_USE_INTUIT) { PL_bostr = orig; s = CALLREG_INTUIT_START(rx, TARG, s, strend, r_flags, NULL); if (!s) goto nope; /* How to do it in subst? */ -/* if ( (rx->reganch & ROPT_CHECK_ALL) +/* if ( (rx->extflags & RXf_CHECK_ALL) && !PL_sawampersand - && ((rx->reganch & ROPT_NOSCAN) - || !((rx->reganch & RE_INTUIT_TAIL) + && ((rx->extflags & RXf_NOSCAN) + || !((rx->extflags & RXf_INTUIT_TAIL) && (r_flags & REXEC_SCREAM)))) goto yup; */ @@ -2188,8 +2205,8 @@ PP(pp_subst) #ifdef PERL_OLD_COPY_ON_WRITE && !is_cow #endif - && (I32)clen <= rx->minlen && (once || !(r_flags & REXEC_COPY_STR)) - && !(rx->reganch & ROPT_LOOKBEHIND_SEEN) + && (I32)clen <= rx->minlenret && (once || !(r_flags & REXEC_COPY_STR)) + && !(rx->extflags & RXf_LOOKBEHIND_SEEN) && (!doutf8 || SvUTF8(TARG))) { if (!CALLREGEXEC(rx, s, strend, orig, 0, TARG, NULL, r_flags | REXEC_CHECKED)) @@ -2666,45 +2683,6 @@ PP(pp_leavesublv) return cx->blk_sub.retop; } - -STATIC CV * -S_get_db_sub(pTHX_ SV **svp, CV *cv) -{ - dVAR; - SV * const dbsv = GvSVn(PL_DBsub); - - save_item(dbsv); - if (!PERLDB_SUB_NN) { - GV * const gv = CvGV(cv); - - if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) - || strEQ(GvNAME(gv), "END") - || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */ - !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) ))) { - /* Use GV from the stack as a fallback. */ - /* GV is potentially non-unique, or contain different CV. */ - SV * const tmp = newRV((SV*)cv); - sv_setsv(dbsv, tmp); - SvREFCNT_dec(tmp); - } - else { - gv_efullname3(dbsv, gv, NULL); - } - } - else { - const int type = SvTYPE(dbsv); - if (type < SVt_PVIV && type != SVt_IV) - sv_upgrade(dbsv, SVt_PVIV); - (void)SvIOK_on(dbsv); - SvIV_set(dbsv, PTR2IV(cv)); /* Do it the quickest way */ - } - - if (CvISXSUB(cv)) - PL_curcopdb = PL_curcop; - cv = GvCV(PL_DBsub); - return cv; -} - PP(pp_entersub) { dVAR; dSP; dPOPss; @@ -2812,7 +2790,11 @@ try_autoload: if (CvASSERTION(cv) && PL_DBassertion) sv_setiv(PL_DBassertion, 1); - cv = get_db_sub(&sv, cv); + Perl_get_db_sub(aTHX_ &sv, cv); + if (CvISXSUB(cv)) + PL_curcopdb = PL_curcop; + cv = GvCV(PL_DBsub); + if (!cv || (!CvXSUB(cv) && !CvSTART(cv))) DIE(aTHX_ "No DB::sub routine defined"); } @@ -2856,13 +2838,13 @@ try_autoload: SV **ary = AvALLOC(av); if (AvARRAY(av) != ary) { AvMAX(av) += AvARRAY(av) - AvALLOC(av); - SvPV_set(av, (char*)ary); + AvARRAY(av) = ary; } if (items > AvMAX(av) + 1) { AvMAX(av) = items - 1; Renew(ary,items,SV*); AvALLOC(av) = ary; - SvPV_set(av, (char*)ary); + AvARRAY(av) = ary; } } Copy(MARK,AvARRAY(av),items,SV*);