X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/77d27ef6e34ee43b493f2338726532d40c13a985..03b6c93d31676fe9936f9a438ca3f9c1ba46fba9:/pp_hot.c diff --git a/pp_hot.c b/pp_hot.c index 8871593..899f35f 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -322,7 +322,7 @@ PP(pp_concat) * I suspect that the mg_get is no longer needed, but while padav * differs, it can't share this function */ -void +STATIC void S_pushav(pTHX_ AV* const av) { dSP; @@ -783,7 +783,7 @@ PP(pp_print) Move(MARK, MARK + 1, (SP - MARK) + 1, SV*); ++SP; } - return Perl_tied_method(aTHX_ "PRINT", mark - 1, MUTABLE_SV(io), + return Perl_tied_method(aTHX_ SV_CONST(PRINT), mark - 1, MUTABLE_SV(io), mg, (G_SCALAR | TIED_METHOD_ARGUMENTS_ON_STACK | (PL_op->op_type == OP_SAY @@ -1173,10 +1173,10 @@ PP(pp_aassign) } if (PL_delaymagic & ~DM_DELAY) { /* Will be used to set PL_tainting below */ - UV tmp_uid = PerlProc_getuid(); - UV tmp_euid = PerlProc_geteuid(); - UV tmp_gid = PerlProc_getgid(); - UV tmp_egid = PerlProc_getegid(); + Uid_t tmp_uid = PerlProc_getuid(); + Uid_t tmp_euid = PerlProc_geteuid(); + Gid_t tmp_gid = PerlProc_getgid(); + Gid_t tmp_egid = PerlProc_getegid(); if (PL_delaymagic & DM_UID) { #ifdef HAS_SETRESUID @@ -1243,6 +1243,12 @@ PP(pp_aassign) tmp_egid = PerlProc_getegid(); } TAINTING_set( TAINTING_get | (tmp_uid && (tmp_euid != tmp_uid || tmp_egid != tmp_gid)) ); +#ifdef NO_TAINT_SUPPORT + PERL_UNUSED_VAR(tmp_uid); + PERL_UNUSED_VAR(tmp_euid); + PERL_UNUSED_VAR(tmp_gid); + PERL_UNUSED_VAR(tmp_egid); +#endif } PL_delaymagic = 0; @@ -1352,8 +1358,6 @@ PP(pp_match) (TAINT_get && (pm->op_pmflags & PMf_RETAINT))); TAINT_NOT; - RX_MATCH_UTF8_set(rx, DO_UTF8(TARG)); - /* We need to know this in case we fail out early - pos() must be reset */ global = dynpm->op_pmflags & PMf_GLOBAL; @@ -1386,10 +1390,9 @@ PP(pp_match) /* XXXX What part of this is needed with true \G-support? */ if (global) { + MAGIC * const mg = mg_find_mglob(TARG); RX_OFFS(rx)[0].start = -1; - if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) { - MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global); - if (mg && mg->mg_len >= 0) { + if (mg && mg->mg_len >= 0) { if (!(RX_EXTFLAGS(rx) & RXf_GPOS_SEEN)) RX_OFFS(rx)[0].end = RX_OFFS(rx)[0].start = mg->mg_len; else if (RX_EXTFLAGS(rx) & RXf_ANCH_GPOS) { @@ -1401,7 +1404,6 @@ PP(pp_match) RX_OFFS(rx)[0].end = RX_OFFS(rx)[0].start = mg->mg_len; minmatch = (mg->mg_flags & MGf_MINMATCH) ? RX_GOFS(rx) + 1 : 0; update_minmatch = 0; - } } } #ifdef PERL_SAWAMPERSAND @@ -1432,24 +1434,41 @@ PP(pp_match) } if (RX_EXTFLAGS(rx) & RXf_USE_INTUIT && DO_UTF8(TARG) == (RX_UTF8(rx) != 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); + s = CALLREG_INTUIT_START(rx, TARG, truebase, + (char *)s, (char *)strend, r_flags, NULL); if (!s) goto nope; -#ifdef PERL_SAWAMPERSAND if ( (RX_EXTFLAGS(rx) & RXf_CHECK_ALL) - && !PL_sawampersand - && !(RX_EXTFLAGS(rx) & RXf_PMf_KEEPCOPY) && !SvROK(TARG)) /* Cannot trust since INTUIT cannot guess ^ */ - goto yup; -#endif + { + /* we can match based purely on the result of INTUIT. + * Fix up all the things that won't get set because we skip + * calling regexec() */ + assert(!RX_NPARENS(rx)); + /* match via INTUIT shouldn't have any captures. + * Let @-, @+, $^N know */ + RX_LASTPAREN(rx) = RX_LASTCLOSEPAREN(rx) = 0; + RX_MATCH_UTF8_set(rx, cBOOL(DO_UTF8(rx))); + if ( !(r_flags & REXEC_NOT_FIRST) ) + Perl_reg_set_capture_string(aTHX_ rx, + (char*)truebase, (char *)strend, + TARG, r_flags, cBOOL(DO_UTF8(TARG))); + + /* skipping regexec means that indices for $&, $-[0] etc not set */ + RX_OFFS(rx)[0].start = s - truebase; + RX_OFFS(rx)[0].end = + RX_MATCH_UTF8(rx) + ? (char*)utf8_hop((U8*)s, RX_MINLENRET(rx)) - truebase + : s - truebase + RX_MINLENRET(rx); + goto gotcha; + } } if (!CALLREGEXEC(rx, (char*)s, (char *)strend, (char*)truebase, minmatch, TARG, NUM2PTR(void*, gpos), r_flags)) - goto ret_no; + goto nope; + gotcha: PL_curpm = pm; if (dynpm->op_pmflags & PMf_ONCE) { #ifdef USE_ITHREADS @@ -1459,11 +1478,34 @@ PP(pp_match) #endif } - gotcha: if (rxtainted) RX_MATCH_TAINTED_on(rx); TAINT_IF(RX_MATCH_TAINTED(rx)); - if (gimme == G_ARRAY) { + + /* update pos */ + + if (global && (gimme != G_ARRAY || (dynpm->op_pmflags & PMf_CONTINUE))) { + MAGIC *mg = mg_find_mglob(TARG); + if (!mg) { + mg = sv_magicext_mglob(TARG); + } + if (RX_OFFS(rx)[0].start != -1) { + mg->mg_len = RX_OFFS(rx)[0].end; + if (RX_OFFS(rx)[0].start + RX_GOFS(rx) == (UV)RX_OFFS(rx)[0].end) + mg->mg_flags |= MGf_MINMATCH; + else + mg->mg_flags &= ~MGf_MINMATCH; + } + } + + if ((!RX_NPARENS(rx) && !global) || gimme != G_ARRAY) { + LEAVE_SCOPE(oldsave); + RETPUSHYES; + } + + /* push captures on stack */ + + { const I32 nparens = RX_NPARENS(rx); I32 i = (global && !nparens) ? 1 : 0; @@ -1487,26 +1529,6 @@ PP(pp_match) } } if (global) { - if (dynpm->op_pmflags & PMf_CONTINUE) { - MAGIC* mg = NULL; - if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) - mg = mg_find(TARG, PERL_MAGIC_regex_global); - if (!mg) { -#ifdef PERL_OLD_COPY_ON_WRITE - if (SvIsCOW(TARG)) - sv_force_normal_flags(TARG, 0); -#endif - mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global, - &PL_vtbl_mglob, NULL, 0); - } - if (RX_OFFS(rx)[0].start != -1) { - mg->mg_len = RX_OFFS(rx)[0].end; - if (RX_OFFS(rx)[0].start + RX_GOFS(rx) == (UV)RX_OFFS(rx)[0].end) - mg->mg_flags |= MGf_MINMATCH; - else - mg->mg_flags &= ~MGf_MINMATCH; - } - } had_zerolen = (RX_OFFS(rx)[0].start != -1 && (RX_OFFS(rx)[0].start + RX_GOFS(rx) == (UV)RX_OFFS(rx)[0].end)); @@ -1514,125 +1536,16 @@ PP(pp_match) r_flags |= REXEC_IGNOREPOS | REXEC_NOT_FIRST; goto play_it_again; } - else if (!nparens) - XPUSHs(&PL_sv_yes); LEAVE_SCOPE(oldsave); RETURN; } - else { - if (global) { - MAGIC* mg; - if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) - mg = mg_find(TARG, PERL_MAGIC_regex_global); - else - mg = NULL; - if (!mg) { -#ifdef PERL_OLD_COPY_ON_WRITE - if (SvIsCOW(TARG)) - sv_force_normal_flags(TARG, 0); -#endif - mg = sv_magicext(TARG, NULL, PERL_MAGIC_regex_global, - &PL_vtbl_mglob, NULL, 0); - } - if (RX_OFFS(rx)[0].start != -1) { - mg->mg_len = RX_OFFS(rx)[0].end; - if (RX_OFFS(rx)[0].start + RX_GOFS(rx) == (UV)RX_OFFS(rx)[0].end) - mg->mg_flags |= MGf_MINMATCH; - else - mg->mg_flags &= ~MGf_MINMATCH; - } - } - LEAVE_SCOPE(oldsave); - RETPUSHYES; - } - -#ifdef PERL_SAWAMPERSAND -yup: /* Confirmed by INTUIT */ -#endif - if (rxtainted) - RX_MATCH_TAINTED_on(rx); - TAINT_IF(RX_MATCH_TAINTED(rx)); - PL_curpm = pm; - if (dynpm->op_pmflags & PMf_ONCE) { -#ifdef USE_ITHREADS - SvREADONLY_on(PL_regex_pad[dynpm->op_pmoffset]); -#else - dynpm->op_pmflags |= PMf_USED; -#endif - } - if (RX_MATCH_COPIED(rx)) - Safefree(RX_SUBBEG(rx)); - RX_MATCH_COPIED_off(rx); - RX_SUBBEG(rx) = NULL; - if (global) { - /* FIXME - should rx->subbeg be const char *? */ - RX_SUBBEG(rx) = (char *) truebase; - RX_SUBOFFSET(rx) = 0; - RX_SUBCOFFSET(rx) = 0; - RX_OFFS(rx)[0].start = s - truebase; - if (RX_MATCH_UTF8(rx)) { - char * const t = (char*)utf8_hop((U8*)s, RX_MINLENRET(rx)); - RX_OFFS(rx)[0].end = t - truebase; - } - else { - RX_OFFS(rx)[0].end = s - truebase + RX_MINLENRET(rx); - } - RX_SUBLEN(rx) = strend - truebase; - goto gotcha; - } -#ifdef PERL_SAWAMPERSAND - if (PL_sawampersand || RX_EXTFLAGS(rx) & RXf_PMf_KEEPCOPY) -#endif - { - I32 off; -#ifdef PERL_ANY_COW - if (SvCANCOW(TARG)) { - if (DEBUG_C_TEST) { - PerlIO_printf(Perl_debug_log, - "Copy on write: pp_match $& capture, type %d, truebase=%p, t=%p, difference %d\n", - (int) SvTYPE(TARG), (void*)truebase, (void*)t, - (int)(t-truebase)); - } - RX_SAVED_COPY(rx) = sv_setsv_cow(RX_SAVED_COPY(rx), TARG); - RX_SUBBEG(rx) - = (char *) SvPVX_const(RX_SAVED_COPY(rx)) + (t - truebase); - assert (SvPOKp(RX_SAVED_COPY(rx))); - } else -#endif - { - - RX_SUBBEG(rx) = savepvn(t, strend - t); -#ifdef PERL_ANY_COW - RX_SAVED_COPY(rx) = NULL; -#endif - } - RX_SUBLEN(rx) = strend - t; - RX_SUBOFFSET(rx) = 0; - RX_SUBCOFFSET(rx) = 0; - RX_MATCH_COPIED_on(rx); - off = RX_OFFS(rx)[0].start = s - t; - RX_OFFS(rx)[0].end = off + RX_MINLENRET(rx); - } -#ifdef PERL_SAWAMPERSAND - else { /* startp/endp are used by @- @+. */ - RX_OFFS(rx)[0].start = s - truebase; - RX_OFFS(rx)[0].end = s - truebase + RX_MINLENRET(rx); - } -#endif - /* match via INTUIT shouldn't have any captures. Let @-, @+, $^N know */ - assert(!RX_NPARENS(rx)); - RX_LASTPAREN(rx) = RX_LASTCLOSEPAREN(rx) = 0; - LEAVE_SCOPE(oldsave); - RETPUSHYES; + /* NOTREACHED */ nope: -ret_no: if (global && !(dynpm->op_pmflags & PMf_CONTINUE)) { - if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) { - MAGIC* const mg = mg_find(TARG, PERL_MAGIC_regex_global); + MAGIC* const mg = mg_find_mglob(TARG); if (mg) mg->mg_len = -1; - } } LEAVE_SCOPE(oldsave); if (gimme == G_ARRAY) @@ -1655,7 +1568,7 @@ Perl_do_readline(pTHX) if (io) { const MAGIC *const mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar); if (mg) { - Perl_tied_method(aTHX_ "READLINE", SP, MUTABLE_SV(io), mg, gimme, 0); + Perl_tied_method(aTHX_ SV_CONST(READLINE), SP, MUTABLE_SV(io), mg, gimme, 0); if (gimme == G_SCALAR) { SPAGAIN; SvSetSV_nosteal(TARG, TOPs); @@ -2039,8 +1952,12 @@ PP(pp_iter) *itersvp = NULL; Perl_croak(aTHX_ "Use of freed value in iteration"); } - SvTEMP_off(sv); - SvREFCNT_inc_simple_void_NN(sv); + if (SvPADTMP(sv) && !IS_PADGV(sv)) + sv = newSVsv(sv); + else { + SvTEMP_off(sv); + SvREFCNT_inc_simple_void_NN(sv); + } } else sv = &PL_sv_undef; @@ -2219,14 +2136,12 @@ PP(pp_subst) TAINT_NOT; } - RX_MATCH_UTF8_set(rx, DO_UTF8(TARG)); - force_it: if (!pm || !s) DIE(aTHX_ "panic: pp_subst, pm=%p, s=%p", pm, s); strend = s + len; - slen = RX_MATCH_UTF8(rx) ? utf8_length((U8*)s, (U8*)strend) : len; + slen = DO_UTF8(TARG) ? utf8_length((U8*)s, (U8*)strend) : len; maxiters = 2 * slen + 10; /* We can match twice at each position, once with zero-length, second time with non-zero. */ @@ -2250,8 +2165,7 @@ PP(pp_subst) orig = m = s; if (RX_EXTFLAGS(rx) & RXf_USE_INTUIT) { - PL_bostr = orig; - s = CALLREG_INTUIT_START(rx, TARG, s, strend, r_flags, NULL); + s = CALLREG_INTUIT_START(rx, TARG, orig, s, strend, r_flags, NULL); if (!s) goto ret_no; @@ -2308,7 +2222,7 @@ PP(pp_subst) #endif && (I32)clen <= RX_MINLENRET(rx) && (once || !(r_flags & REXEC_COPY_STR)) - && !(RX_EXTFLAGS(rx) & (RXf_LOOKBEHIND_SEEN|RXf_MODIFIES_VARS)) + && !(RX_EXTFLAGS(rx) & RXf_NO_INPLACE_SUBST) && (!doutf8 || SvUTF8(TARG)) && !(rpm->op_pmflags & PMf_NONDESTRUCT)) { @@ -2573,6 +2487,10 @@ PP(pp_grepwhile) SAVEVPTR(PL_curpm); src = PL_stack_base[*PL_markstack_ptr]; + if (SvPADTMP(src) && !IS_PADGV(src)) { + src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src); + PL_tmps_floor++; + } SvTEMP_off(src); if (PL_op->op_private & OPpGREP_LEX) PAD_SVl(PL_op->op_targ) = src; @@ -2718,7 +2636,6 @@ PP(pp_entersub) } ENTER; - SAVETMPS; retry: if (CvCLONE(cv) && ! CvCLONED(cv)) @@ -2818,12 +2735,18 @@ try_autoload: Copy(MARK,AvARRAY(av),items,SV*); AvFILLp(av) = items - 1; + MARK = AvARRAY(av); while (items--) { if (*MARK) + { + if (SvPADTMP(*MARK) && !IS_PADGV(*MARK)) + *MARK = sv_mortalcopy(*MARK); SvTEMP_off(*MARK); + } MARK++; } } + SAVETMPS; if ((cx->blk_u16 & OPpENTERSUB_LVAL_MASK) == OPpLVAL_INTRO && !CvLVALUE(cv)) DIE(aTHX_ "Can't modify non-lvalue subroutine call"); @@ -2839,8 +2762,15 @@ try_autoload: else { I32 markix = TOPMARK; + SAVETMPS; PUTBACK; + if (((PL_op->op_private + & PUSHSUB_GET_LVALUE_MASK(Perl_is_lvalue_sub) + ) & OPpENTERSUB_LVAL_MASK) == OPpLVAL_INTRO && + !CvLVALUE(cv)) + DIE(aTHX_ "Can't modify non-lvalue subroutine call"); + if (!hasargs) { /* Need to copy @_ to stack. Alternative may be to * switch stack to @_, and copy return values @@ -2889,8 +2819,15 @@ Perl_sub_crush_depth(pTHX_ CV *cv) if (CvANON(cv)) Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on anonymous subroutine"); else { - SV* const tmpstr = sv_newmortal(); - gv_efullname3(tmpstr, CvGV(cv), NULL); + HEK *const hek = CvNAME_HEK(cv); + SV *tmpstr; + if (hek) { + tmpstr = sv_2mortal(newSVhek(hek)); + } + else { + tmpstr = sv_newmortal(); + gv_efullname3(tmpstr, CvGV(cv), NULL); + } Perl_warner(aTHX_ packWARN(WARN_RECURSION), "Deep recursion on subroutine \"%"SVf"\"", SVfARG(tmpstr)); } @@ -3062,6 +2999,19 @@ S_method_common(pTHX_ SV* meth, U32* hashp) if (SvROK(sv)) ob = MUTABLE_SV(SvRV(sv)); else if (!SvOK(sv)) goto undefined; + else if (isGV_with_GP(sv)) { + if (!GvIO(sv)) + Perl_croak(aTHX_ "Can't call method \"%"SVf"\" " + "without a package or object reference", + SVfARG(meth)); + ob = sv; + if (SvTYPE(ob) == SVt_PVLV && LvTYPE(ob) == 'y') { + assert(!LvTARGLEN(ob)); + ob = LvTARG(ob); + assert(ob); + } + *(PL_stack_base + TOPMARK + 1) = sv_2mortal(newRV(ob)); + } else { /* this isn't a reference */ GV* iogv; @@ -3110,10 +3060,9 @@ S_method_common(pTHX_ SV* meth, U32* hashp) *(PL_stack_base + TOPMARK + 1) = sv_2mortal(newRV(MUTABLE_SV(iogv))); } - /* if we got here, ob should be a reference or a glob */ + /* if we got here, ob should be an object or a glob */ if (!ob || !(SvOBJECT(ob) - || (SvTYPE(ob) == SVt_PVGV - && isGV_with_GP(ob) + || (isGV_with_GP(ob) && (ob = MUTABLE_SV(GvIO((const GV *)ob))) && SvOBJECT(ob)))) {