case OP_REPEAT:
if (o->op_flags & OPf_STACKED)
break;
+ goto func_ops;
+ case OP_SUBSTR:
+ if (o->op_private == 4)
+ break;
/* FALL THROUGH */
case OP_GVSV:
case OP_WANTARRAY:
case OP_HEX:
case OP_OCT:
case OP_LENGTH:
- case OP_SUBSTR:
case OP_VEC:
case OP_INDEX:
case OP_RINDEX:
case OP_GGRNAM:
case OP_GGRGID:
case OP_GETLOGIN:
+ func_ops:
if (!(o->op_private & OPpLVAL_INTRO))
useless = op_desc[o->op_type];
break;
case OP_KEYS:
if (type != OP_SASSIGN)
goto nomod;
+ goto lvalue_func;
+ case OP_SUBSTR:
+ if (o->op_private == 4) /* don't allow 4 arg substr as lvalue */
+ goto nomod;
/* FALL THROUGH */
case OP_POS:
case OP_VEC:
- case OP_SUBSTR:
+ lvalue_func:
pad_free(o->op_targ);
o->op_targ = pad_alloc(o->op_type, SVs_PADMY);
assert(SvTYPE(PAD_SV(o->op_targ)) == SVt_NULL);
case OP_CONCAT:
case OP_SUBST:
case OP_TRANS:
+ case OP_READ:
+ case OP_SYSREAD:
+ case OP_RECV:
case OP_ANDASSIGN: /* may work later */
case OP_ORASSIGN: /* may work later */
return TRUE;
return o;
}
+void
+save_hints(void)
+{
+ SAVEI32(hints);
+ SAVESPTR(GvHV(hintgv));
+ GvHV(hintgv) = newHVhv(GvHV(hintgv));
+ SAVEFREESV(GvHV(hintgv));
+}
+
int
block_start(int full)
{
dTHR;
int retval = savestack_ix;
+
SAVEI32(comppad_name_floor);
if (full) {
if ((comppad_name_fill = AvFILLp(comppad_name)) > 0)
SAVEI32(padix_floor);
padix_floor = padix;
pad_reset_pending = FALSE;
- SAVEI32(hints);
+ SAVEHINTS();
hints &= ~HINT_BLOCK_SCOPE;
return retval;
}
pmop->op_flags = flags;
pmop->op_private = 0 | (flags >> 8);
+ if (hints & HINT_RE_TAINT)
+ pmop->op_pmpermflags |= PMf_RETAINT;
if (hints & HINT_LOCALE)
- pmop->op_pmpermflags = (pmop->op_pmflags |= PMf_LOCALE);
+ pmop->op_pmpermflags |= PMf_LOCALE;
+ pmop->op_pmflags = pmop->op_pmpermflags;
/* link into pm list */
if (type != OP_TRANS && curstash) {
{
PMOP *pm;
LOGOP *rcop;
+ I32 repl_has_vars = 0;
if (o->op_type == OP_TRANS)
return pmtrans(o, expr, repl);
p = SvPV(pat, plen);
pm->op_pmflags |= PMf_SKIPWHITE;
}
- pm->op_pmregexp = pregcomp(p, p + plen, pm);
+ pm->op_pmregexp = CALLREGCOMP(p, p + plen, pm);
if (strEQ("\\s+", pm->op_pmregexp->precomp))
pm->op_pmflags |= PMf_WHITE;
op_free(expr);
for (curop = LINKLIST(repl); curop!=repl; curop = LINKLIST(curop)) {
if (opargs[curop->op_type] & OA_DANGEROUS) {
#ifdef USE_THREADS
- if (curop->op_type == OP_THREADSV
- && strchr("&`'123456789+", curop->op_private)) {
- break;
+ if (curop->op_type == OP_THREADSV) {
+ repl_has_vars = 1;
+ if (strchr("&`'123456789+", curop->op_private))
+ break;
}
#else
if (curop->op_type == OP_GV) {
GV *gv = ((GVOP*)curop)->op_gv;
+ repl_has_vars = 1;
if (strchr("&`'123456789+", *GvENAME(gv)))
break;
}
curop->op_type == OP_PADAV ||
curop->op_type == OP_PADHV ||
curop->op_type == OP_PADANY) {
- /* is okay */
+ repl_has_vars = 1;
}
else
break;
lastop = curop;
}
}
- if (curop == repl) {
+ if (curop == repl
+ && !(repl_has_vars
+ && (!pm->op_pmregexp
+ || pm->op_pmregexp->reganch & ROPT_EVAL_SEEN))) {
pm->op_pmflags |= PMf_CONST; /* const for long enough */
pm->op_pmpermflags |= PMf_CONST; /* const for long enough */
prepend_elem(o->op_type, scalar(repl), o);
}
else {
+ if (curop == repl && !pm->op_pmregexp) { /* Has variables. */
+ pm->op_pmflags |= PMf_MAYBE_CONST;
+ pm->op_pmpermflags |= PMf_MAYBE_CONST;
+ }
Newz(1101, rcop, 1, LOGOP);
rcop->op_type = OP_SUBSTCONT;
rcop->op_ppaddr = ppaddr[OP_SUBSTCONT];
#endif
}
if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) {
- expr = scalar(ref(expr, OP_ITER));
+ expr = mod(force_list(scalar(ref(expr, OP_ITER))), OP_GREPSTART);
+ iterflags |= OPf_STACKED;
+ }
+ else if (expr->op_type == OP_NULL &&
+ (expr->op_flags & OPf_KIDS) &&
+ ((BINOP*)expr)->op_first->op_type == OP_FLOP)
+ {
+ /* Basically turn for($x..$y) into the same as for($x,$y), but we
+ * set the STACKED flag to indicate that these values are to be
+ * treated as min/max values by 'pp_iterinit'.
+ */
+ UNOP* flip = (UNOP*)((UNOP*)((BINOP*)expr)->op_first)->op_first;
+ CONDOP* range = (CONDOP*) flip->op_first;
+ OP* left = range->op_first;
+ OP* right = left->op_sibling;
+ LISTOP* listop;
+
+ range->op_flags &= ~OPf_KIDS;
+ range->op_first = Nullop;
+
+ listop = (LISTOP*)newLISTOP(OP_LIST, 0, left, right);
+ listop->op_first->op_next = range->op_true;
+ left->op_next = range->op_false;
+ right->op_next = (OP*)listop;
+ listop->op_next = listop->op_first;
+
+ op_free(expr);
+ expr = (OP*)(listop);
+ null(expr);
iterflags |= OPf_STACKED;
}
+ else {
+ expr = mod(force_list(expr), OP_GREPSTART);
+ }
+
+
loop = (LOOP*)list(convert(OP_ENTERITER, iterflags,
- append_elem(OP_LIST, mod(force_list(expr), OP_GREPSTART),
- scalar(sv))));
+ append_elem(OP_LIST, expr, scalar(sv))));
assert(!loop->op_next);
Renew(loop, 1, LOOP);
loop->op_targ = padoff;
GV *gv = gv_fetchpv(name ? name : "__ANON__",
GV_ADDMULTI | (block ? 0 : GV_NOINIT), SVt_PVCV);
char *ps = proto ? SvPVx(((SVOP*)proto)->op_sv, na) : Nullch;
- register CV *cv;
+ register CV *cv=0;
I32 ix;
if (o)
goto done;
}
/* ahem, death to those who redefine active sort subs */
- if (curstackinfo->si_type == SI_SORT && sortcop == CvSTART(cv))
+ if (curstackinfo->si_type == PERLSI_SORT && sortcop == CvSTART(cv))
croak("Can't redefine active sort subroutine %s", name);
if(const_sv = cv_const_sv(cv))
const_changed = sv_cmp(const_sv, op_const_sv(block, Nullcv));
case OP_PADAV:
if (o->op_next->op_type == OP_RV2AV
- && (o->op_next->op_flags && OPf_REF))
+ && (o->op_next->op_flags & OPf_REF))
{
null(o->op_next);
o->op_next = o->op_next->op_next;
case OP_PADHV:
if (o->op_next->op_type == OP_RV2HV
- && (o->op_next->op_flags && OPf_REF))
+ && (o->op_next->op_flags & OPf_REF))
{
null(o->op_next);
o->op_next = o->op_next->op_next;