: OPf_KIDS);
rcop->op_private = 1;
rcop->op_other = o;
+ /* /$x/ may cause an eval, since $x might be qr/(?{..})/ */
+ PL_cv_has_eval = 1;
/* establish postfix order */
if (pm->op_pmflags & PMf_KEEP || !(PL_hints & HINT_RE_EVAL)) {
if (!next)
next = unstack;
cont = append_elem(OP_LINESEQ, cont, unstack);
- if ((line_t)whileline != NOLINE) {
- PL_copline = (line_t)whileline;
- cont = append_elem(OP_LINESEQ, cont,
- newSTATEOP(0, Nullch, Nullop));
- }
}
listop = append_list(OP_LINESEQ, (LISTOP*)block, (LISTOP*)cont);
OP *wop;
PADOFFSET padoff = 0;
I32 iterflags = 0;
+ I32 iterpflags = 0;
if (sv) {
if (sv->op_type == OP_RV2SV) { /* symbol table variable */
+ iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */
sv->op_type = OP_RV2GV;
sv->op_ppaddr = PL_ppaddr[OP_RV2GV];
}
else if (sv->op_type == OP_PADSV) { /* private variable */
+ iterpflags = sv->op_private & OPpLVAL_INTRO; /* for my $x () */
padoff = sv->op_targ;
sv->op_targ = 0;
op_free(sv);
loop = (LOOP*)list(convert(OP_ENTERITER, iterflags,
append_elem(OP_LIST, expr, scalar(sv))));
assert(!loop->op_next);
+ /* for my $x () sets OPpLVAL_INTRO;
+ * for our $x () sets OPpOUR_INTRO; both only used by Deparse.pm */
+ loop->op_private = iterpflags;
#ifdef PL_OP_SLAB_ALLOC
{
LOOP *tmp;
return (SV*)CvXSUBANY(cv).any_ptr;
}
+/* op_const_sv: examine an optree to determine whether it's in-lineable.
+ * Can be called in 3 ways:
+ *
+ * !cv
+ * look for a single OP_CONST with attached value: return the value
+ *
+ * cv && CvCLONE(cv) && !CvCONST(cv)
+ *
+ * examine the clone prototype, and if contains only a single
+ * OP_CONST referencing a pad const, or a single PADSV referencing
+ * an outer lexical, return a non-zero value to indicate the CV is
+ * a candidate for "constizing" at clone time
+ *
+ * cv && CvCONST(cv)
+ *
+ * We have just cloned an anon prototype that was marked as a const
+ * candidiate. Try to grab the current value, and in the case of
+ * PADSV, ignore it if it has multiple references. Return the value.
+ */
+
SV *
Perl_op_const_sv(pTHX_ OP *o, CV *cv)
{
return Nullsv;
if (type == OP_CONST && cSVOPo->op_sv)
sv = cSVOPo->op_sv;
- else if ((type == OP_PADSV || type == OP_CONST) && cv) {
+ else if (cv && type == OP_CONST) {
sv = PAD_BASE_SV(CvPADLIST(cv), o->op_targ);
if (!sv)
return Nullsv;
- if (CvCONST(cv)) {
- /* We get here only from cv_clone2() while creating a closure.
- Copy the const value here instead of in cv_clone2 so that
- SvREADONLY_on doesn't lead to problems when leaving
- scope.
- */
+ }
+ else if (cv && type == OP_PADSV) {
+ if (CvCONST(cv)) { /* newly cloned anon */
+ sv = PAD_BASE_SV(CvPADLIST(cv), o->op_targ);
+ /* the candidate should have 1 ref from this pad and 1 ref
+ * from the parent */
+ if (!sv || SvREFCNT(sv) != 2)
+ return Nullsv;
sv = newSVsv(sv);
+ SvREADONLY_on(sv);
+ return sv;
+ }
+ else {
+ if (PAD_COMPNAME_FLAGS(o->op_targ) & SVf_FAKE)
+ sv = &PL_sv_undef; /* an arbitrary non-null value */
}
- if (!SvREADONLY(sv) && SvREFCNT(sv) > 1)
- return Nullsv;
}
- else
+ else {
return Nullsv;
+ }
}
- if (sv)
- SvREADONLY_on(sv);
return sv;
}
pad_fixup_inner_anons(CvPADLIST(cv), PL_compcv, cv);
/* ... before we throw it away */
SvREFCNT_dec(PL_compcv);
+ PL_compcv = cv;
if (PERLDB_INTER)/* Advice debugger on the new sub. */
++PL_sub_generation;
}
enter->op_other = o;
return o;
}
- else
+ else {
scalar((OP*)kid);
+ PL_cv_has_eval = 1;
+ }
}
else {
op_free(o);