if (type != OP_SPLIT)
/* At this point o is a LISTOP, but OP_SPLIT is a PMOP; let
* ck_split() create a real PMOP and leave the op's type as listop
- * for for now. Otherwise op_free() etc will crash.
+ * for now. Otherwise op_free() etc will crash.
*/
OpTYPE_set(o, type);
* constant), or convert expr into a runtime regcomp op sequence (if it's
* not)
*
- * Flags currently has 2 bits or meaning:
+ * Flags currently has 2 bits of meaning:
* 1: isreg indicates that the pattern is part of a regex construct, eg
* $x =~ /pattern/ or split /pattern/, as opposed to $x =~ $pattern or
* split "pattern", which aren't. In the former case, expr will be a list
{
/* @pkg or @lex or local @pkg' or 'my @lex' */
OP *tmpop;
- PMOP * const pm = (PMOP*)right;
if (gvop) {
#ifdef USE_ITHREADS
- pm->op_pmreplrootu.op_pmtargetoff
+ ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff
= cPADOPx(gvop)->op_padix;
cPADOPx(gvop)->op_padix = 0; /* steal it */
#else
- pm->op_pmreplrootu.op_pmtargetgv
+ ((PMOP*)right)->op_pmreplrootu.op_pmtargetgv
= MUTABLE_GV(cSVOPx(gvop)->op_sv);
cSVOPx(gvop)->op_sv = NULL; /* steal it */
#endif
left->op_private & OPpOUR_INTRO;
}
else {
- pm->op_pmreplrootu.op_pmtargetoff = left->op_targ;
+ ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff = left->op_targ;
left->op_targ = 0; /* steal it */
right->op_private |= OPpSPLIT_LEX;
}
kid = cLISTOPo->op_first;
if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
- /* remove match expression, and replace with new optree with
+ /* remove match expression, and replace with new optree with
* a match op at its head */
op_sibling_splice(o, NULL, 1, NULL);
/* pmruntime will handle split " " behavior with flag==2 */
* into its place, then convert the match op into a split op. i.e.
*
* SPLIT MATCH SPLIT(ex-MATCH)
- * | | |
- * MATCH - A - B - C => R - A - B - C => R - A - B - C
- * | | |
- * R X - Y X - Y
+ * | | |
+ * MATCH - A - B - C => R - A - B - C => R - A - B - C
+ * | | |
+ * R X - Y X - Y
* |
* X - Y
*
case OP_PADAV:
case OP_PADHV:
(*scalars_p) += 2;
+ /* if !top, could be e.g. @a[0,1] */
if (top && (o->op_flags & OPf_REF))
return (o->op_private & OPpLVAL_INTRO)
? AAS_MY_AGG : AAS_LEX_AGG;
if (cUNOPx(o)->op_first->op_type != OP_GV)
return AAS_DANGEROUS; /* @{expr}, %{expr} */
/* @pkg, %pkg */
+ /* if !top, could be e.g. @a[0,1] */
if (top && (o->op_flags & OPf_REF))
return AAS_PKG_AGG;
return AAS_DANGEROUS;
return AAS_PKG_SCALAR; /* $pkg */
case OP_SPLIT:
- if (1) { /* XXX this condition is wrong - fix later
- if (cLISTOPo->op_first->op_type == OP_PUSHRE) {
- */
- /* "@foo = split... " optimises away the aassign and stores its
- * destination array in the OP_PUSHRE that precedes it.
- * A flattened array is always dangerous.
+ if (o->op_private & OPpSPLIT_ASSIGN) {
+ /* the assign in @a = split() has been optimised away
+ * and the @a attached directly to the split op
+ * Treat the array as appearing on the RHS, i.e.
+ * ... = (@a = split)
+ * is treated like
+ * ... = @a;
*/
+
+ if (o->op_flags & OPf_STACKED)
+ /* @{expr} = split() - the array expression is tacked
+ * on as an extra child to split - process kid */
+ return S_aassign_scan(aTHX_ cLISTOPo->op_last, rhs,
+ top, scalars_p);
+
+ /* ... else array is directly attached to split op */
(*scalars_p) += 2;
- return AAS_DANGEROUS;
+ if (PL_op->op_private & OPpSPLIT_LEX)
+ return (o->op_private & OPpLVAL_INTRO)
+ ? AAS_MY_AGG : AAS_LEX_AGG;
+ else
+ return AAS_PKG_AGG;
}
- break;
+ (*scalars_p)++;
+ /* other args of split can't be returned */
+ return AAS_SAFE_SCALAR;
case OP_UNDEF:
/* undef counts as a scalar on the RHS: