else {
/* runtime pattern: build chain of regcomp etc ops */
bool reglist;
+ PADOFFSET cv_targ = 0;
reglist = isreg && expr->op_type == OP_LIST;
if (reglist)
*/
SvREFCNT_inc_simple_void(PL_compcv);
- expr = list(force_list(newUNOP(OP_ENTERSUB, 0,
- scalar(newANONATTRSUB(floor, NULL, NULL, expr)))));
+ /* these lines are just an unrolled newANONATTRSUB */
+ expr = newSVOP(OP_ANONCODE, 0,
+ MUTABLE_SV(newATTRSUB(floor, 0, NULL, NULL, expr)));
+ cv_targ = expr->op_targ;
+ expr = newUNOP(OP_REFGEN, 0, expr);
+
+ expr = list(force_list(newUNOP(OP_ENTERSUB, 0, scalar(expr))));
}
NewOp(1101, rcop, 1, LOGOP);
| (reglist ? OPf_STACKED : 0);
rcop->op_private = 0;
rcop->op_other = o;
+ rcop->op_targ = cv_targ;
/* /$x/ may cause an eval, since $x might be qr/(?{..})/ */
if (PL_hints & HINT_RE_EVAL) PL_cv_has_eval = 1;
PL_reginterp_cnt = (I32_MAX>>1); /* Mark as safe. */
new_re = re_op_compile(args, nargs, pm->op_code_list, eng, re,
- &is_bare_re, (pm->op_pmflags & RXf_PMf_COMPILETIME));
+ &is_bare_re,
+ (pm->op_pmflags & (RXf_PMf_COMPILETIME|PMf_HAS_CV)));
+ if (pm->op_pmflags & PMf_HAS_CV)
+ ((struct regexp *)SvANY(new_re))->qr_anoncv = PAD_SV(PL_op->op_targ);
if (is_bare_re) {
REGEXP *tmp;
}
if (pat_count > 1) {
- /* concat multiple args */
+ /* concat multiple args and find any code block indexes */
+
+ OP *o = NULL;
+ int n = 0;
+
+ if (pRExC_state->num_code_blocks) {
+ o = cLISTOPx(expr)->op_first;
+ assert(o->op_type == OP_PUSHMARK);
+ o = o->op_sibling;
+ }
- pRExC_state->num_code_blocks = 0; /* XXX tmp */
pat = newSVpvn("", 0);
SAVEFREESV(pat);
for (svp = patternp; svp < patternp + pat_count; svp++) {
SV *sv, *msv = *svp;
+ bool code = 0;
+ if (o) {
+ if (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL)) {
+ n++;
+ assert(n <= pRExC_state->num_code_blocks);
+ pRExC_state->code_blocks[n-1].start = SvCUR(pat);
+ pRExC_state->code_blocks[n-1].block = o;
+ code = 1;
+ o = o->op_sibling; /* skip CONST */
+ assert(o);
+ }
+ o = o->op_sibling;;
+ }
+
if ((SvAMAGIC(pat) || SvAMAGIC(msv)) &&
(sv = amagic_call(pat, msv, concat_amg, AMGf_assign)))
+ {
sv_setsv(pat, sv);
- else
+ /* overloading involved: all bets are off over literal
+ * code. Pretend we haven't seen it */
+ pRExC_state->num_code_blocks -= n;
+ n = 0;
+
+ }
+ else {
sv_catsv_nomg(pat, msv);
+ if (code)
+ pRExC_state->code_blocks[n-1].end = SvCUR(pat);
+ }
}
SvSETMAGIC(pat);
}
# literal qr code only created once, embedded with text
$cr2 //= qr/B(??{$x})$/;
- tok(0, "ABa" =~ /^A$cr2/, "[$x] literal qr once embedded text");
+ ok("ABa" =~ /^A$cr2/, "[$x] literal qr once embedded text");
# literal qr code only created once, embedded with text + lit code
$cr3 //= qr/C(??{$x})$/;
- tok($bc, "A$x-BCa" =~ /^A(??{$x})-B$cr3/,
+ ok("A$x-BCa" =~ /^A(??{$x})-B$cr3/,
"[$x] literal qr once embedded text + lit code");
# literal qr code only created once, embedded with text + run code
my $rr5 = qr/^A(??{"$x$y"})-$r5/;
push @rr5, $rr5;
- tok("$x$y" ne "ad", "A$x$y-C$x" =~ $rr5,
+ tok($bc, "A$x$y-C$x" =~ $rr5,
"[$x-$y] literal qr + r5");
my $rr6 = qr/^A(??{"$x$y"})-$r6/;
push @rr6, $rr6;
- tok("$x$y" ne "ad", "A$x$y-$x-C$x" =~ $rr6,
+ tok($bc, "A$x$y-$x-C$x" =~ $rr6,
"[$x-$y] literal qr + r6");
}
my $y = 'Y';
my $yy = (qw(d e f))[$i];
my $rr5 = $rr5[$i];
- tok("$x$yy" ne "ad", "A$x$yy-C$x" =~ $rr5,
+ tok($bc, "A$x$yy-C$x" =~ $rr5,
"[$x-$yy] literal qr + r5, outside");
tok(1, "A$x$yy-C$x-D$x" =~ /$rr5-D(??{$x})/,
"[$x-$yy] literal qr + r5 + lit, outside");
my $rr6 = $rr6[$i];
push @rr6, $rr6;
- tok("$x$yy" ne "ad", "A$x$yy-$x-C$x" =~ $rr6,
+ tok($bc, "A$x$yy-$x-C$x" =~ $rr6,
"[$x-$yy] literal qr + r6, outside");
tok(1, "A$x$yy-$x-C$x-D$x" =~ /$rr6-D(??{$x})/,
"[$x-$yy] literal qr + r6 +lit, outside");