diff options
author | David Mitchell <davem@iabyn.com> | 2011-10-26 13:21:10 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2011-12-19 15:06:02 +0000 |
commit | 483e10fc61e1c2307020e1c5e9c77e788f3be13e (patch) | |
tree | 9f608b07194abb99ff0466dd055c4dc22b597d3a | |
parent | af06e8de86f6a962a6914d3d91ba91778032c4bd (diff) | |
download | perl-483e10fc61e1c2307020e1c5e9c77e788f3be13e.tar.gz |
pp_regcomp: split overloading and concat tasks
Make two passes through the list of args: first to apply
magic/overloading, and secondly to concatenate them. This will
shortly allow us to pass a processed, but unconcatenated list to
re_op_compile().
Also, simplify the code by treating the 1-arg case as an arg list
of length 1. This also allows us to use the tryAMAGICregexp macro
in only one place, and thus to unroll and eliminate it.
-rw-r--r-- | pp_ctl.c | 74 |
1 files changed, 39 insertions, 35 deletions
@@ -81,49 +81,56 @@ PP(pp_regcomp) dVAR; dSP; register PMOP *pm = (PMOP*)cLOGOP->op_other; + SV **args, **svp; + int nargs; SV *tmpstr; REGEXP *re = NULL; + if (PL_op->op_flags & OPf_STACKED) { + dMARK; + nargs = SP - MARK; + args = ++MARK; + } + else { + nargs = 1; + args = SP; + } + /* prevent recompiling under /o and ithreads. */ #if defined(USE_ITHREADS) if (pm->op_pmflags & PMf_KEEP && PM_GETRE(pm)) { - if (PL_op->op_flags & OPf_STACKED) { - dMARK; - SP = MARK; - } - else - (void)POPs; + SP = args-1; RETURN; } #endif -#define tryAMAGICregexp(rx) \ - STMT_START { \ - SvGETMAGIC(rx); \ - if (SvROK(rx) && SvAMAGIC(rx)) { \ - SV *sv = AMG_CALLunary(rx, regexp_amg); \ - if (sv) { \ - if (SvROK(sv)) \ - sv = SvRV(sv); \ - if (SvTYPE(sv) != SVt_REGEXP) \ - Perl_croak(aTHX_ "Overloaded qr did not return a REGEXP"); \ - rx = sv; \ - } \ - } \ - } STMT_END - + /* apply magic and RE overloading to each arg */ + + for (svp = args; svp <= SP; svp++) { + SV *rx = *svp; + SvGETMAGIC(rx); + if (SvROK(rx) && SvAMAGIC(rx)) { + SV *sv = AMG_CALLunary(rx, regexp_amg); + if (sv) { + if (SvROK(sv)) + sv = SvRV(sv); + if (SvTYPE(sv) != SVt_REGEXP) + Perl_croak(aTHX_ "Overloaded qr did not return a REGEXP"); + *svp = sv; + } + } + } - if (PL_op->op_flags & OPf_STACKED) { - /* multiple args; concatenate them */ - dMARK; dORIGMARK; + /* concat multiple args */ + + if (nargs > 1) { tmpstr = PAD_SV(ARGTARG); sv_setpvs(tmpstr, ""); - while (++MARK <= SP) { - SV *msv = *MARK; + svp = args-1; + while (++svp <= SP) { + SV *msv = *svp; SV *sv; - tryAMAGICregexp(msv); - if ((SvAMAGIC(tmpstr) || SvAMAGIC(msv)) && (sv = amagic_call(tmpstr, msv, concat_amg, AMGf_assign))) { @@ -133,14 +140,10 @@ PP(pp_regcomp) sv_catsv_nomg(tmpstr, msv); } SvSETMAGIC(tmpstr); - SP = ORIGMARK; - } - else { - tmpstr = POPs; - tryAMAGICregexp(tmpstr); } + else + tmpstr = *args; -#undef tryAMAGICregexp if (SvROK(tmpstr)) { SV * const sv = SvRV(tmpstr); @@ -161,7 +164,7 @@ PP(pp_regcomp) SV *lhs; const bool was_tainted = PL_tainted; if (pm->op_flags & OPf_STACKED) - lhs = TOPs; + lhs = args[-1]; else if (pm->op_private & OPpTARGET_MY) lhs = PAD_SV(pm->op_targ); else lhs = DEFSV; @@ -247,6 +250,7 @@ PP(pp_regcomp) cLOGOP->op_first->op_next = PL_op->op_next; } #endif + SP = args-1; RETURN; } |