X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/f93695f990c755bfd70a59f0ac4caf55173fdb4a..2fdd76928f116a6e52e8f66669e8d76fcbe65ec6:/op.c diff --git a/op.c b/op.c index 5f25121..0de303c 100644 --- a/op.c +++ b/op.c @@ -297,9 +297,11 @@ Perl_Slab_Alloc(pTHX_ size_t sz) DEBUG_S_warn((aTHX_ "allocating op at %p, slab %p", (void*)o, (void*)slab)); gotit: - /* lastsib == 1, op_sibling == 0 implies a solitary unattached op */ - o->op_lastsib = 1; - assert(!o->op_sibling); +#ifdef PERL_OP_PARENT + /* moresib == 0, op_sibling == 0 implies a solitary unattached op */ + assert(!o->op_moresib); + assert(!o->op_sibparent); +#endif return (void *)o; } @@ -400,7 +402,7 @@ Perl_opslab_free(pTHX_ OPSLAB *slab) PERL_UNUSED_CONTEXT; DEBUG_S_warn((aTHX_ "freeing slab %p", (void*)slab)); assert(slab->opslab_refcnt == 1); - for (; slab; slab = slab2) { + do { slab2 = slab->opslab_next; #ifdef DEBUGGING slab->opslab_refcnt = ~(size_t)0; @@ -415,7 +417,8 @@ Perl_opslab_free(pTHX_ OPSLAB *slab) #else PerlMemShared_free(slab); #endif - } + slab = slab2; + } while (slab); } void @@ -507,7 +510,7 @@ Perl_op_refcnt_dec(pTHX_ OP *o) #define RETURN_UNLIMITED_NUMBER (PERL_INT_MAX / 2) -#define CHANGE_TYPE(o,type) \ +#define OpTYPE_set(o,type) \ STMT_START { \ o->op_type = (OPCODE)type; \ o->op_ppaddr = PL_ppaddr[type]; \ @@ -591,7 +594,7 @@ Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags) !(is_our || isALPHA(name[1]) || ((flags & SVf_UTF8) && isIDFIRST_utf8((U8 *)name+1)) || - (name[1] == '_' && (*name == '$' || len > 2)))) + (name[1] == '_' && len > 2))) { if (!(flags & SVf_UTF8 && UTF8_IS_START(name[1])) && isASCII(name[1]) @@ -604,13 +607,6 @@ Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags) PL_parser->in_my == KEY_state ? "state" : "my"), flags & SVf_UTF8); } } - else if (len == 2 && name[1] == '_' && !is_our) - /* diag_listed_as: Use of my $_ is experimental */ - Perl_ck_warner_d(aTHX_ packWARN(WARN_EXPERIMENTAL__LEXICAL_TOPIC), - "Use of %s $_ is experimental", - PL_parser->in_my == KEY_state - ? "state" - : "my"); /* allocate a spare slot and store the name in that slot */ @@ -716,10 +712,23 @@ Perl_op_free(pTHX_ OP *o) type = o->op_type; /* an op should only ever acquire op_private flags that we know about. - * If this fails, you may need to fix something in regen/op_private */ - if (o->op_ppaddr == PL_ppaddr[o->op_type]) { + * If this fails, you may need to fix something in regen/op_private. + * Don't bother testing if: + * * the op_ppaddr doesn't match the op; someone may have + * overridden the op and be doing strange things with it; + * * we've errored, as op flags are often left in an + * inconsistent state then. Note that an error when + * compiling the main program leaves PL_parser NULL, so + * we can't spot faults in the main code, only + * evaled/required code */ +#ifdef DEBUGGING + if ( o->op_ppaddr == PL_ppaddr[o->op_type] + && PL_parser + && !PL_parser->error_count) + { assert(!(o->op_private & ~PL_op_private_valid[type])); } +#endif if (o->op_private & OPpREFCOUNTED) { switch (type) { @@ -1180,11 +1189,12 @@ Perl_op_null(pTHX_ OP *o) return; op_clear(o); o->op_targ = o->op_type; - CHANGE_TYPE(o, OP_NULL); + OpTYPE_set(o, OP_NULL); } void Perl_op_refcnt_lock(pTHX) + PERL_TSA_ACQUIRE(PL_op_mutex) { #ifdef USE_ITHREADS dVAR; @@ -1195,6 +1205,7 @@ Perl_op_refcnt_lock(pTHX) void Perl_op_refcnt_unlock(pTHX) + PERL_TSA_RELEASE(PL_op_mutex) { #ifdef USE_ITHREADS dVAR; @@ -1208,32 +1219,33 @@ Perl_op_refcnt_unlock(pTHX) =for apidoc op_sibling_splice A general function for editing the structure of an existing chain of -op_sibling nodes. By analogy with the perl-level splice() function, allows +op_sibling nodes. By analogy with the perl-level C function, allows you to delete zero or more sequential nodes, replacing them with zero or more different nodes. Performs the necessary op_first/op_last housekeeping on the parent node and op_sibling manipulation on the children. The last deleted node will be marked as as the last node by -updating the op_sibling or op_lastsib field as appropriate. +updating the op_sibling/op_sibparent or op_moresib field as appropriate. Note that op_next is not manipulated, and nodes are not freed; that is the responsibility of the caller. It also won't create a new list op for an empty list etc; use higher-level functions like op_append_elem() for that. -parent is the parent node of the sibling chain. +C is the parent node of the sibling chain. It may passed as C if +the splicing doesn't affect the first or last op in the chain. -start is the node preceding the first node to be spliced. Node(s) +C is the node preceding the first node to be spliced. Node(s) following it will be deleted, and ops will be inserted after it. If it is -NULL, the first node onwards is deleted, and nodes are inserted at the +C, the first node onwards is deleted, and nodes are inserted at the beginning. -del_count is the number of nodes to delete. If zero, no nodes are deleted. +C is the number of nodes to delete. If zero, no nodes are deleted. If -1 or greater than or equal to the number of remaining kids, all remaining kids are deleted. -insert is the first of a chain of nodes to be inserted in place of the nodes. -If NULL, no nodes are inserted. +C is the first of a chain of nodes to be inserted in place of the nodes. +If C, no nodes are inserted. -The head of the chain of deleted ops is returned, or NULL if no ops were +The head of the chain of deleted ops is returned, or C if no ops were deleted. For example: @@ -1257,18 +1269,27 @@ For example: splice(P, B, 0, X-Y) | | NULL A-B-C-D A-B-X-Y-C-D + +For lower-level direct manipulation of C and C, +see C>, C>, C>. + =cut */ OP * Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert) { - OP *first = start ? OpSIBLING(start) : cLISTOPx(parent)->op_first; + OP *first; OP *rest; OP *last_del = NULL; OP *last_ins = NULL; - PERL_ARGS_ASSERT_OP_SIBLING_SPLICE; + if (start) + first = OpSIBLING(start); + else if (!parent) + goto no_parent; + else + first = cLISTOPx(parent)->op_first; assert(del_count >= -1); @@ -1277,8 +1298,7 @@ Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert) while (--del_count && OpHAS_SIBLING(last_del)) last_del = OpSIBLING(last_del); rest = OpSIBLING(last_del); - OpSIBLING_set(last_del, NULL); - last_del->op_lastsib = 1; + OpLASTSIB_set(last_del, NULL); } else rest = first; @@ -1287,17 +1307,17 @@ Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert) last_ins = insert; while (OpHAS_SIBLING(last_ins)) last_ins = OpSIBLING(last_ins); - OpSIBLING_set(last_ins, rest); - last_ins->op_lastsib = rest ? 0 : 1; + OpMAYBESIB_set(last_ins, rest, NULL); } else insert = rest; if (start) { - OpSIBLING_set(start, insert); - start->op_lastsib = insert ? 0 : 1; + OpMAYBESIB_set(start, insert, NULL); } else { + if (!parent) + goto no_parent; cLISTOPx(parent)->op_first = insert; if (insert) parent->op_flags |= OPf_KIDS; @@ -1307,12 +1327,25 @@ Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert) if (!rest) { /* update op_last etc */ - U32 type = parent->op_type; + U32 type; OP *lastop; - if (type == OP_NULL) - type = parent->op_targ; - type = PL_opargs[type] & OA_CLASS_MASK; + if (!parent) + goto no_parent; + + /* ought to use OP_CLASS(parent) here, but that can't handle + * ex-foo OP_NULL ops. Also note that XopENTRYCUSTOM() can't + * either */ + type = parent->op_type; + if (type == OP_CUSTOM) { + dTHX; + type = XopENTRYCUSTOM(parent, xop_class); + } + else { + if (type == OP_NULL) + type = parent->op_targ; + type = PL_opargs[type] & OA_CLASS_MASK; + } lastop = last_ins ? last_ins : start ? start : NULL; if ( type == OA_BINOP @@ -1322,22 +1355,23 @@ Perl_op_sibling_splice(OP *parent, OP *start, int del_count, OP* insert) ) cLISTOPx(parent)->op_last = lastop; - if (lastop) { - lastop->op_lastsib = 1; -#ifdef PERL_OP_PARENT - lastop->op_sibling = parent; -#endif - } + if (lastop) + OpLASTSIB_set(lastop, parent); } return last_del ? first : NULL; + + no_parent: + Perl_croak_nocontext("panic: op_sibling_splice(): NULL parent"); } + +#ifdef PERL_OP_PARENT + /* =for apidoc op_parent -returns the parent OP of o, if it has a parent. Returns NULL otherwise. -(Currently perl must be built with C<-DPERL_OP_PARENT> for this feature to -work. +Returns the parent OP of C, if it has a parent. Returns C otherwise. +This function is only available on perls built with C<-DPERL_OP_PARENT>. =cut */ @@ -1346,16 +1380,13 @@ OP * Perl_op_parent(OP *o) { PERL_ARGS_ASSERT_OP_PARENT; -#ifdef PERL_OP_PARENT while (OpHAS_SIBLING(o)) o = OpSIBLING(o); - return o->op_sibling; -#else - PERL_UNUSED_ARG(o); - return NULL; -#endif + return o->op_sibparent; } +#endif + /* replace the sibling following start with a new UNOP, which becomes * the parent of the original sibling; e.g. @@ -1401,18 +1432,14 @@ S_alloc_LOGOP(pTHX_ I32 type, OP *first, OP* other) LOGOP *logop; OP *kid = first; NewOp(1101, logop, 1, LOGOP); - CHANGE_TYPE(logop, type); + OpTYPE_set(logop, type); logop->op_first = first; logop->op_other = other; logop->op_flags = OPf_KIDS; while (kid && OpHAS_SIBLING(kid)) kid = OpSIBLING(kid); - if (kid) { - kid->op_lastsib = 1; -#ifdef PERL_OP_PARENT - kid->op_sibling = (OP*)logop; -#endif - } + if (kid) + OpLASTSIB_set(kid, (OP*)logop); return logop; } @@ -1423,7 +1450,7 @@ S_alloc_LOGOP(pTHX_ I32 type, OP *first, OP* other) =for apidoc Am|OP *|op_contextualize|OP *o|I32 context Applies a syntactic context to an op tree representing an expression. -I is the op tree, and I must be C, C, +C is the op tree, and C must be C, C, or C to specify the context to apply. The modified op tree is returned. @@ -1601,9 +1628,6 @@ S_scalar_slice_warning(pTHX_ const OP *o) case OP_LOCALTIME: case OP_GMTIME: case OP_ENTEREVAL: - case OP_REACH: - case OP_RKEYS: - case OP_RVALUES: return; } @@ -1970,19 +1994,19 @@ Perl_scalarvoid(pTHX_ OP *arg) break; case OP_POSTINC: - CHANGE_TYPE(o, OP_PREINC); /* pre-increment is faster */ + OpTYPE_set(o, OP_PREINC); /* pre-increment is faster */ break; case OP_POSTDEC: - CHANGE_TYPE(o, OP_PREDEC); /* pre-decrement is faster */ + OpTYPE_set(o, OP_PREDEC); /* pre-decrement is faster */ break; case OP_I_POSTINC: - CHANGE_TYPE(o, OP_I_PREINC); /* pre-increment is faster */ + OpTYPE_set(o, OP_I_PREINC); /* pre-increment is faster */ break; case OP_I_POSTDEC: - CHANGE_TYPE(o, OP_I_PREDEC); /* pre-decrement is faster */ + OpTYPE_set(o, OP_I_PREDEC); /* pre-decrement is faster */ break; case OP_SASSIGN: { @@ -2039,9 +2063,9 @@ Perl_scalarvoid(pTHX_ OP *arg) if (kid->op_type == OP_NOT && (kid->op_flags & OPf_KIDS)) { if (o->op_type == OP_AND) { - CHANGE_TYPE(o, OP_OR); + OpTYPE_set(o, OP_OR); } else { - CHANGE_TYPE(o, OP_AND); + OpTYPE_set(o, OP_AND); } op_null(kid); } @@ -2349,7 +2373,7 @@ S_check_hash_fields_and_hekify(pTHX_ UNOP *rop, SVOP *key_op) This function finalizes the optree. Should be called directly after the complete optree is built. It does some additional -checking which can't be done in the normal ck_xxx functions and makes +checking which can't be done in the normal Cxxx functions and makes the tree thread-safe. =cut @@ -2509,9 +2533,9 @@ S_finalize_op(pTHX_ OP* o) #ifdef DEBUGGING /* check that op_last points to the last sibling, and that - * the last op_sibling field points back to the parent, and - * that the only ops with KIDS are those which are entitled to - * them */ + * the last op_sibling/op_sibparent field points back to the + * parent, and that the only ops with KIDS are those which are + * entitled to them */ U32 type = o->op_type; U32 family; bool has_last; @@ -2550,17 +2574,11 @@ S_finalize_op(pTHX_ OP* o) if (!OpHAS_SIBLING(kid)) { if (has_last) assert(kid == cLISTOPo->op_last); - assert(kid->op_sibling == o); + assert(kid->op_sibparent == o); } # else - if (OpHAS_SIBLING(kid)) { - assert(!kid->op_lastsib); - } - else { - assert(kid->op_lastsib); - if (has_last) - assert(kid == cLISTOPo->op_last); - } + if (has_last && !OpHAS_SIBLING(kid)) + assert(kid == cLISTOPo->op_last); # endif } #endif @@ -2574,14 +2592,14 @@ S_finalize_op(pTHX_ OP* o) =for apidoc Amx|OP *|op_lvalue|OP *o|I32 type Propagate lvalue ("modifiable") context to an op and its children. -I represents the context type, roughly based on the type of op that -would do the modifying, although C is represented by OP_NULL, +C represents the context type, roughly based on the type of op that +would do the modifying, although C is represented by C, because it has no op type of its own (it is signalled by a flag on the lvalue op). This function detects things that can't be modified, such as C<$x+1>, and generates errors for them. For example, C<$x+1 = 2> would cause it to be -called with an op of type OP_ADD and a C argument of OP_SASSIGN. +called with an op of type C and a C argument of C. It also flags things that need to behave specially in an lvalue context, such as C<$$x = 5> which might have to vivify a reference in C<$x>. @@ -2643,7 +2661,7 @@ S_lvref(pTHX_ OP *o, I32 type) return; } slurpy: - CHANGE_TYPE(o, OP_LVAVREF); + OpTYPE_set(o, OP_LVAVREF); o->op_private &= OPpLVAL_INTRO|OPpPAD_STATE; o->op_flags |= OPf_MOD|OPf_REF; return; @@ -2653,7 +2671,7 @@ S_lvref(pTHX_ OP *o, I32 type) case OP_RV2CV: kid = cUNOPo->op_first; if (kid->op_type == OP_NULL) - kid = cUNOPx(kUNOP->op_first->op_sibling) + kid = cUNOPx(OpSIBLING(kUNOP->op_first)) ->op_first; o->op_private = OPpLVREF_CV; if (kid->op_type == OP_GV) @@ -2700,7 +2718,7 @@ S_lvref(pTHX_ OP *o, I32 type) break; case OP_ASLICE: case OP_HSLICE: - CHANGE_TYPE(o, OP_LVREFSLICE); + OpTYPE_set(o, OP_LVREFSLICE); o->op_private &= OPpLVAL_INTRO|OPpLVREF_ELEM; return; case OP_NULL: @@ -2732,7 +2750,7 @@ S_lvref(pTHX_ OP *o, I32 type) : OP_DESC(o), PL_op_desc[type])); } - CHANGE_TYPE(o, OP_LVREF); + OpTYPE_set(o, OP_LVREF); o->op_private &= OPpLVAL_INTRO|OPpLVREF_ELEM|OPpLVREF_TYPE|OPpPAD_STATE; if (type == OP_ENTERLOOP) @@ -2771,7 +2789,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) case OP_ENTERSUB: if ((type == OP_UNDEF || type == OP_REFGEN || type == OP_LOCK) && !(o->op_flags & OPf_STACKED)) { - CHANGE_TYPE(o, OP_RV2CV); /* entersub => rv2cv */ + OpTYPE_set(o, OP_RV2CV); /* entersub => rv2cv */ assert(cUNOPo->op_first->op_type == OP_NULL); op_null(((LISTOP*)cUNOPo->op_first)->op_first);/* disable pushmark */ break; @@ -2789,6 +2807,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) OP *kid = cUNOPo->op_first; CV *cv; GV *gv; + SV *namesv; if (kid->op_type != OP_PUSHMARK) { if (kid->op_type != OP_NULL || kid->op_targ != OP_LIST) @@ -2826,6 +2845,15 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) break; if (CvLVALUE(cv)) break; + if (flags & OP_LVALUE_NO_CROAK) + return NULL; + + namesv = cv_name(cv, NULL, 0); + yyerror_pv(Perl_form(aTHX_ "Can't modify non-lvalue " + "subroutine call of &%"SVf" in %s", + SVfARG(namesv), PL_op_desc[type]), + SvUTF8(namesv)); + return o; } } /* FALLTHROUGH */ @@ -2839,9 +2867,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) yyerror(Perl_form(aTHX_ "Can't modify %s in %s", (o->op_type == OP_NULL && (o->op_flags & OPf_SPECIAL) ? "do block" - : (o->op_type == OP_ENTERSUB - ? "non-lvalue subroutine call" - : OP_DESC(o))), + : OP_DESC(o)), type ? PL_op_desc[type] : "local")); return o; @@ -2985,7 +3011,6 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) break; case OP_KEYS: - case OP_RKEYS: if (type != OP_SASSIGN && type != OP_LEAVESUBLV) goto nomod; goto lvalue_func; @@ -3236,14 +3261,14 @@ Perl_doref(pTHX_ OP *o, I32 type, bool set_op_ref) PERL_ARGS_ASSERT_DOREF; - if (!o || (PL_parser && PL_parser->error_count)) + if (PL_parser && PL_parser->error_count) return o; switch (o->op_type) { case OP_ENTERSUB: if ((type == OP_EXISTS || type == OP_DEFINED) && !(o->op_flags & OPf_STACKED)) { - CHANGE_TYPE(o, OP_RV2CV); /* entersub => rv2cv */ + OpTYPE_set(o, OP_RV2CV); /* entersub => rv2cv */ assert(cUNOPo->op_first->op_type == OP_NULL); op_null(((LISTOP*)cUNOPo->op_first)->op_first); /* disable pushmark */ o->op_flags |= OPf_SPECIAL; @@ -3355,24 +3380,26 @@ S_dup_attrlist(pTHX_ OP *o) STATIC void S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs) { - SV * const stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no; - PERL_ARGS_ASSERT_APPLY_ATTRS; + { + SV * const stashsv = newSVhek(HvNAME_HEK(stash)); - /* fake up C */ + /* fake up C */ #define ATTRSMODULE "attributes" #define ATTRSMODULE_PM "attributes.pm" - Perl_load_module(aTHX_ PERL_LOADMOD_IMPORT_OPS, - newSVpvs(ATTRSMODULE), - NULL, - op_prepend_elem(OP_LIST, - newSVOP(OP_CONST, 0, stashsv), - op_prepend_elem(OP_LIST, - newSVOP(OP_CONST, 0, - newRV(target)), - dup_attrlist(attrs)))); + Perl_load_module( + aTHX_ PERL_LOADMOD_IMPORT_OPS, + newSVpvs(ATTRSMODULE), + NULL, + op_prepend_elem(OP_LIST, + newSVOP(OP_CONST, 0, stashsv), + op_prepend_elem(OP_LIST, + newSVOP(OP_CONST, 0, + newRV(target)), + dup_attrlist(attrs)))); + } } STATIC void @@ -3403,7 +3430,7 @@ S_apply_attrs_my(pTHX_ HV *stash, OP *target, OP *attrs, OP **imopsp) pack = newSVOP(OP_CONST, 0, newSVpvs(ATTRSMODULE)); /* Build up the real arg-list. */ - stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no; + stashsv = newSVhek(HvNAME_HEK(stash)); arg = newOP(OP_PADSV, 0); arg->op_targ = target->op_targ; @@ -3826,11 +3853,11 @@ Perl_op_scope(pTHX_ OP *o) if (o) { if (o->op_flags & OPf_PARENS || PERLDB_NOOPT || TAINTING_get) { o = op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), o); - CHANGE_TYPE(o, OP_LEAVE); + OpTYPE_set(o, OP_LEAVE); } else if (o->op_type == OP_LINESEQ) { OP *kid; - CHANGE_TYPE(o, OP_SCOPE); + OpTYPE_set(o, OP_SCOPE); kid = ((LISTOP*)o)->op_first; if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) { op_null(kid); @@ -3894,9 +3921,9 @@ Perl_block_start(pTHX_ int full) /* =for apidoc Am|OP *|block_end|I32 floor|OP *seq -Handles compile-time scope exit. I +Handles compile-time scope exit. C is the savestack index returned by -C, and I is the body of the block. Returns the block, +C, and C is the body of the block. Returns the block, possibly modified. =cut @@ -4129,7 +4156,8 @@ Perl_localize(pTHX_ OP *o, I32 lex) s++; while (1) { - if (*s && strchr("@$%*", *s) && *++s + if (*s && (strchr("@$%", *s) || (!lex && *s == '*')) + && *++s && (isWORDCHAR(*s) || UTF8_IS_CONTINUED(*s))) { s++; sigil = TRUE; @@ -4413,7 +4441,7 @@ S_gen_constant_list(pTHX_ OP *o) Perl_pp_anonlist(aTHX); PL_tmps_floor = oldtmps_floor; - CHANGE_TYPE(o, OP_RV2AV); + OpTYPE_set(o, OP_RV2AV); o->op_flags &= ~OPf_REF; /* treat \(1..2) like an ordinary list */ o->op_flags |= OPf_PARENS; /* and flatten \(1..2,3) */ o->op_opt = 0; /* needs to be revisited in rpeep() */ @@ -4444,10 +4472,10 @@ S_gen_constant_list(pTHX_ OP *o) =for apidoc Am|OP *|op_append_elem|I32 optype|OP *first|OP *last Append an item to the list of ops contained directly within a list-type -op, returning the lengthened list. I is the list-type op, -and I is the op to append to the list. I specifies the -intended opcode for the list. If I is not already a list of the -right type, it will be upgraded into one. If either I or I +op, returning the lengthened list. C is the list-type op, +and C is the op to append to the list. C specifies the +intended opcode for the list. If C is not already a list of the +right type, it will be upgraded into one. If either C or C is null, the other is returned unchanged. =cut @@ -4477,10 +4505,10 @@ Perl_op_append_elem(pTHX_ I32 type, OP *first, OP *last) =for apidoc Am|OP *|op_append_list|I32 optype|OP *first|OP *last Concatenate the lists of ops contained directly within two list-type ops, -returning the combined list. I and I are the list-type ops -to concatenate. I specifies the intended opcode for the list. -If either I or I is not already a list of the right type, -it will be upgraded into one. If either I or I is null, +returning the combined list. C and C are the list-type ops +to concatenate. C specifies the intended opcode for the list. +If either C or C is not already a list of the right type, +it will be upgraded into one. If either C or C is null, the other is returned unchanged. =cut @@ -4501,16 +4529,11 @@ Perl_op_append_list(pTHX_ I32 type, OP *first, OP *last) if (last->op_type != (unsigned)type) return op_append_elem(type, first, last); - ((LISTOP*)first)->op_last->op_lastsib = 0; - OpSIBLING_set(((LISTOP*)first)->op_last, ((LISTOP*)last)->op_first); + OpMORESIB_set(((LISTOP*)first)->op_last, ((LISTOP*)last)->op_first); ((LISTOP*)first)->op_last = ((LISTOP*)last)->op_last; - ((LISTOP*)first)->op_last->op_lastsib = 1; -#ifdef PERL_OP_PARENT - ((LISTOP*)first)->op_last->op_sibling = first; -#endif + OpLASTSIB_set(((LISTOP*)first)->op_last, first); first->op_flags |= (last->op_flags & OPf_KIDS); - S_op_destroy(aTHX_ last); return first; @@ -4520,10 +4543,10 @@ Perl_op_append_list(pTHX_ I32 type, OP *first, OP *last) =for apidoc Am|OP *|op_prepend_elem|I32 optype|OP *first|OP *last Prepend an item to the list of ops contained directly within a list-type -op, returning the lengthened list. I is the op to prepend to the -list, and I is the list-type op. I specifies the intended -opcode for the list. If I is not already a list of the right type, -it will be upgraded into one. If either I or I is null, +op, returning the lengthened list. C is the op to prepend to the +list, and C is the list-type op. C specifies the intended +opcode for the list. If C is not already a list of the right type, +it will be upgraded into one. If either C or C is null, the other is returned unchanged. =cut @@ -4557,8 +4580,8 @@ Perl_op_prepend_elem(pTHX_ I32 type, OP *first, OP *last) /* =for apidoc Am|OP *|op_convert_list|I32 type|I32 flags|OP *o -Converts I into a list op if it is not one already, and then converts it -into the specified I, calling its check function, allocating a target if +Converts C into a list op if it is not one already, and then converts it +into the specified C, calling its check function, allocating a target if it needs one, and folding constants. A list-type op is usually constructed one kid at a time via C, @@ -4591,7 +4614,7 @@ Perl_op_convert_list(pTHX_ I32 type, I32 flags, OP *o) } } - CHANGE_TYPE(o, type); + OpTYPE_set(o, type); o->op_flags |= flags; if (flags & OPf_FOLDED) o->op_folded = 1; @@ -4644,8 +4667,7 @@ S_force_list(pTHX_ OP *o, bool nullit) if (o) { /* manually detach any siblings then add them back later */ rest = OpSIBLING(o); - OpSIBLING_set(o, NULL); - o->op_lastsib = 1; + OpLASTSIB_set(o, NULL); } o = newLISTOP(OP_LIST, 0, o, NULL); if (rest) @@ -4659,16 +4681,16 @@ S_force_list(pTHX_ OP *o, bool nullit) /* =for apidoc Am|OP *|newLISTOP|I32 type|I32 flags|OP *first|OP *last -Constructs, checks, and returns an op of any list type. I is -the opcode. I gives the eight bits of C, except that -C will be set automatically if required. I and I +Constructs, checks, and returns an op of any list type. C is +the opcode. C gives the eight bits of C, except that +C will be set automatically if required. C and C supply up to two ops to be direct children of the list op; they are consumed by this function and become part of the constructed op tree. For most list operators, the check function expects all the kid ops to be present already, so calling C (e.g.) is not appropriate. What you want to do in that case is create an op of type -OP_LIST, append more children to it, and then call L. +C, append more children to it, and then call L. See L for more information. @@ -4686,7 +4708,7 @@ Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP *first, OP *last) NewOp(1101, listop, 1, LISTOP); - CHANGE_TYPE(listop, type); + OpTYPE_set(listop, type); if (first || last) flags |= OPf_KIDS; listop->op_flags = (U8)flags; @@ -4696,26 +4718,19 @@ Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP *first, OP *last) else if (!first && last) first = last; else if (first) - OpSIBLING_set(first, last); + OpMORESIB_set(first, last); listop->op_first = first; listop->op_last = last; if (type == OP_LIST) { OP* const pushop = newOP(OP_PUSHMARK, 0); - pushop->op_lastsib = 0; - OpSIBLING_set(pushop, first); + OpMORESIB_set(pushop, first); listop->op_first = pushop; listop->op_flags |= OPf_KIDS; if (!last) listop->op_last = pushop; } - if (first) - first->op_lastsib = 0; - if (listop->op_last) { - listop->op_last->op_lastsib = 1; -#ifdef PERL_OP_PARENT - listop->op_last->op_sibling = (OP*)listop; -#endif - } + if (listop->op_last) + OpLASTSIB_set(listop->op_last, (OP*)listop); return CHECKOP(type, listop); } @@ -4724,7 +4739,7 @@ Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP *first, OP *last) =for apidoc Am|OP *|newOP|I32 type|I32 flags Constructs, checks, and returns an op of any base type (any type that -has no extra fields). I is the opcode. I gives the +has no extra fields). C is the opcode. C gives the eight bits of C, and, shifted up eight bits, the eight bits of C. @@ -4748,7 +4763,7 @@ Perl_newOP(pTHX_ I32 type, I32 flags) || (PL_opargs[type] & OA_CLASS_MASK) == OA_LOOPEXOP); NewOp(1101, o, 1, OP); - CHANGE_TYPE(o, type); + OpTYPE_set(o, type); o->op_flags = (U8)flags; o->op_next = o; @@ -4763,11 +4778,11 @@ Perl_newOP(pTHX_ I32 type, I32 flags) /* =for apidoc Am|OP *|newUNOP|I32 type|I32 flags|OP *first -Constructs, checks, and returns an op of any unary type. I is -the opcode. I gives the eight bits of C, except that +Constructs, checks, and returns an op of any unary type. C is +the opcode. C gives the eight bits of C, except that C will be set automatically if required, and, shifted up eight bits, the eight bits of C, except that the bit with value 1 -is automatically set. I supplies an optional op to be the direct +is automatically set. C supplies an optional op to be the direct child of the unary op; it is consumed by this function and become part of the constructed op tree. @@ -4800,15 +4815,13 @@ Perl_newUNOP(pTHX_ I32 type, I32 flags, OP *first) first = force_list(first, 1); NewOp(1101, unop, 1, UNOP); - CHANGE_TYPE(unop, type); + OpTYPE_set(unop, type); unop->op_first = first; unop->op_flags = (U8)(flags | OPf_KIDS); unop->op_private = (U8)(1 | (flags >> 8)); -#ifdef PERL_OP_PARENT if (!OpHAS_SIBLING(first)) /* true unless weird syntax error */ - first->op_sibling = (OP*)unop; -#endif + OpLASTSIB_set(first, (OP*)unop); unop = (UNOP*) CHECKOP(type, unop); if (unop->op_next) @@ -4820,8 +4833,8 @@ Perl_newUNOP(pTHX_ I32 type, I32 flags, OP *first) /* =for apidoc newUNOP_AUX -Similar to C, but creates an UNOP_AUX struct instead, with op_aux -initialised to aux +Similar to C, but creates an C struct instead, with C +initialised to C =cut */ @@ -4843,10 +4856,8 @@ Perl_newUNOP_AUX(pTHX_ I32 type, I32 flags, OP *first, UNOP_AUX_item *aux) unop->op_private = (U8)((first ? 1 : 0) | (flags >> 8)); unop->op_aux = aux; -#ifdef PERL_OP_PARENT if (first && !OpHAS_SIBLING(first)) /* true unless weird syntax error */ - first->op_sibling = (OP*)unop; -#endif + OpLASTSIB_set(first, (OP*)unop); unop = (UNOP_AUX*) CHECKOP(type, unop); @@ -4857,13 +4868,13 @@ Perl_newUNOP_AUX(pTHX_ I32 type, I32 flags, OP *first, UNOP_AUX_item *aux) =for apidoc Am|OP *|newMETHOP|I32 type|I32 flags|OP *first Constructs, checks, and returns an op of method type with a method name -evaluated at runtime. I is the opcode. I gives the eight +evaluated at runtime. C is the opcode. C gives the eight bits of C, except that C will be set automatically, and, shifted up eight bits, the eight bits of C, except that -the bit with value 1 is automatically set. I supplies an +the bit with value 1 is automatically set. C supplies an op which evaluates method name; it is consumed by this function and become part of the constructed op tree. -Supported optypes: OP_METHOD. +Supported optypes: C. =cut */ @@ -4883,10 +4894,8 @@ S_newMETHOP_internal(pTHX_ I32 type, I32 flags, OP* dynamic_meth, SV* const_meth methop->op_u.op_first = dynamic_meth; methop->op_private = (U8)(1 | (flags >> 8)); -#ifdef PERL_OP_PARENT if (!OpHAS_SIBLING(dynamic_meth)) - dynamic_meth->op_sibling = (OP*)methop; -#endif + OpLASTSIB_set(dynamic_meth, (OP*)methop); } else { assert(const_meth); @@ -4902,7 +4911,7 @@ S_newMETHOP_internal(pTHX_ I32 type, I32 flags, OP* dynamic_meth, SV* const_meth methop->op_rclass_sv = NULL; #endif - CHANGE_TYPE(methop, type); + OpTYPE_set(methop, type); return CHECKOP(type, methop); } @@ -4916,11 +4925,11 @@ Perl_newMETHOP (pTHX_ I32 type, I32 flags, OP* dynamic_meth) { =for apidoc Am|OP *|newMETHOP_named|I32 type|I32 flags|SV *const_meth Constructs, checks, and returns an op of method type with a constant -method name. I is the opcode. I gives the eight bits of +method name. C is the opcode. C gives the eight bits of C, and, shifted up eight bits, the eight bits of -C. I supplies a constant method name; +C. C supplies a constant method name; it must be a shared COW string. -Supported optypes: OP_METHOD_NAMED. +Supported optypes: C. =cut */ @@ -4934,11 +4943,11 @@ Perl_newMETHOP_named (pTHX_ I32 type, I32 flags, SV* const_meth) { /* =for apidoc Am|OP *|newBINOP|I32 type|I32 flags|OP *first|OP *last -Constructs, checks, and returns an op of any binary type. I -is the opcode. I gives the eight bits of C, except +Constructs, checks, and returns an op of any binary type. C +is the opcode. C gives the eight bits of C, except that C will be set automatically, and, shifted up eight bits, the eight bits of C, except that the bit with value 1 or -2 is automatically set as required. I and I supply up to +2 is automatically set as required. C and C supply up to two ops to be the direct children of the binary op; they are consumed by this function and become part of the constructed op tree. @@ -4959,7 +4968,7 @@ Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first, OP *last) if (!first) first = newOP(OP_NULL, 0); - CHANGE_TYPE(binop, type); + OpTYPE_set(binop, type); binop->op_first = first; binop->op_flags = (U8)(flags | OPf_KIDS); if (!last) { @@ -4968,20 +4977,15 @@ Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first, OP *last) } else { binop->op_private = (U8)(2 | (flags >> 8)); - OpSIBLING_set(first, last); - first->op_lastsib = 0; + OpMORESIB_set(first, last); } -#ifdef PERL_OP_PARENT if (!OpHAS_SIBLING(last)) /* true unless weird syntax error */ - last->op_sibling = (OP*)binop; -#endif + OpLASTSIB_set(last, (OP*)binop); binop->op_last = OpSIBLING(binop->op_first); -#ifdef PERL_OP_PARENT if (binop->op_last) - binop->op_last->op_sibling = (OP*)binop; -#endif + OpLASTSIB_set(binop->op_last, (OP*)binop); binop = (BINOP*)CHECKOP(type, binop); if (binop->op_next || binop->op_type != (OPCODE)type) @@ -5174,7 +5178,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl) } } - /* now see which range will peter our first, if either. */ + /* now see which range will peter out first, if either. */ tdiff = tlast - tfirst; rdiff = rlast - rfirst; tcount += tdiff + 1; @@ -5206,7 +5210,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl) max = rfirst + diff; if (!grows) grows = (tfirst < rfirst && - UNISKIP(tfirst) < UNISKIP(rfirst + diff)); + UVCHR_SKIP(tfirst) < UVCHR_SKIP(rfirst + diff)); rfirst += diff + 1; } tfirst += diff + 1; @@ -5345,7 +5349,7 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl) =for apidoc Am|OP *|newPMOP|I32 type|I32 flags Constructs, checks, and returns an op of any pattern matching type. -I is the opcode. I gives the eight bits of C +C is the opcode. C gives the eight bits of C and, shifted up eight bits, the eight bits of C. =cut @@ -5361,7 +5365,7 @@ Perl_newPMOP(pTHX_ I32 type, I32 flags) || type == OP_CUSTOM); NewOp(1101, pmop, 1, PMOP); - CHANGE_TYPE(pmop, type); + OpTYPE_set(pmop, type); pmop->op_flags = (U8)flags; pmop->op_private = (U8)(0 | (flags >> 8)); if (PL_opargs[type] & OA_RETSCALAR) @@ -5786,8 +5790,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor) =for apidoc Am|OP *|newSVOP|I32 type|I32 flags|SV *sv Constructs, checks, and returns an op of any type that involves an -embedded SV. I is the opcode. I gives the eight bits -of C. I gives the SV to embed in the op; this function +embedded SV. C is the opcode. C gives the eight bits +of C. C gives the SV to embed in the op; this function takes ownership of one reference to it. =cut @@ -5807,7 +5811,7 @@ Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv) || type == OP_CUSTOM); NewOp(1101, svop, 1, SVOP); - CHANGE_TYPE(svop, type); + OpTYPE_set(svop, type); svop->op_sv = sv; svop->op_next = (OP*)svop; svop->op_flags = (U8)flags; @@ -5822,9 +5826,7 @@ Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv) /* =for apidoc Am|OP *|newDEFSVOP| -Constructs and returns an op to access C<$_>, either as a lexical -variable (if declared as C) in the current scope, or the -global C<$_>. +Constructs and returns an op to access C<$_>. =cut */ @@ -5832,15 +5834,7 @@ global C<$_>. OP * Perl_newDEFSVOP(pTHX) { - const PADOFFSET offset = pad_findmy_pvs("$_", 0); - if (offset == NOT_IN_PAD || PAD_COMPNAME_FLAGS_isOUR(offset)) { return newSVREF(newGVOP(OP_GV, 0, PL_defgv)); - } - else { - OP * const o = newOP(OP_PADSV, 0); - o->op_targ = offset; - return o; - } } #ifdef USE_ITHREADS @@ -5849,9 +5843,9 @@ Perl_newDEFSVOP(pTHX) =for apidoc Am|OP *|newPADOP|I32 type|I32 flags|SV *sv Constructs, checks, and returns an op of any type that involves a -reference to a pad element. I is the opcode. I gives the +reference to a pad element. C is the opcode. C gives the eight bits of C. A pad slot is automatically allocated, and -is populated with I; this function takes ownership of one reference +is populated with C; this function takes ownership of one reference to it. This function only exists if Perl has been compiled to use ithreads. @@ -5873,7 +5867,7 @@ Perl_newPADOP(pTHX_ I32 type, I32 flags, SV *sv) || type == OP_CUSTOM); NewOp(1101, padop, 1, PADOP); - CHANGE_TYPE(padop, type); + OpTYPE_set(padop, type); padop->op_padix = pad_alloc(type, isGV(sv) ? SVf_READONLY : SVs_PADTMP); SvREFCNT_dec(PAD_SVl(padop->op_padix)); @@ -5894,8 +5888,8 @@ Perl_newPADOP(pTHX_ I32 type, I32 flags, SV *sv) =for apidoc Am|OP *|newGVOP|I32 type|I32 flags|GV *gv Constructs, checks, and returns an op of any type that involves an -embedded reference to a GV. I is the opcode. I gives the -eight bits of C. I identifies the GV that the op should +embedded reference to a GV. C is the opcode. C gives the +eight bits of C. C identifies the GV that the op should reference; calling this function does not transfer ownership of any reference to it. @@ -5918,8 +5912,8 @@ Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv) =for apidoc Am|OP *|newPVOP|I32 type|I32 flags|char *pv Constructs, checks, and returns an op of any type that involves an -embedded C-level pointer (PV). I is the opcode. I gives -the eight bits of C. I supplies the C-level pointer, which +embedded C-level pointer (PV). C is the opcode. C gives +the eight bits of C. C supplies the C-level pointer, which must have been allocated using C; the memory will be freed when the op is destroyed. @@ -5940,7 +5934,7 @@ Perl_newPVOP(pTHX_ I32 type, I32 flags, char *pv) || (PL_opargs[type] & OA_CLASS_MASK) == OA_LOOPEXOP); NewOp(1101, pvop, 1, PVOP); - CHANGE_TYPE(pvop, type); + OpTYPE_set(pvop, type); pvop->op_pv = pv; pvop->op_next = (OP*)pvop; pvop->op_flags = (U8)flags; @@ -6118,15 +6112,15 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg) Loads the module whose name is pointed to by the string part of name. Note that the actual module name, not its filename, should be given. Eg, "Foo::Bar" instead of "Foo/Bar.pm". flags can be any of -PERL_LOADMOD_DENY, PERL_LOADMOD_NOIMPORT, or PERL_LOADMOD_IMPORT_OPS +C, C, or C (or 0 for no flags). ver, if specified and not NULL, provides version semantics similar to C. The optional trailing SV* -arguments can be used to specify arguments to the module's import() +arguments can be used to specify arguments to the module's C method, similar to C. They must be -terminated with a final NULL pointer. Note that this list can only -be omitted when the PERL_LOADMOD_NOIMPORT flag has been used. -Otherwise at least a single NULL pointer to designate the default +terminated with a final C pointer. Note that this list can only +be omitted when the C flag has been used. +Otherwise at least a single C pointer to designate the default import list is required. The reference count for each specified C parameter is decremented. @@ -6234,11 +6228,11 @@ Perl_dofile(pTHX_ OP *term, I32 force_builtin) =for apidoc Am|OP *|newSLICEOP|I32 flags|OP *subscript|OP *listval -Constructs, checks, and returns an C (list slice) op. I +Constructs, checks, and returns an C (list slice) op. C gives the eight bits of C, except that C will be set automatically, and, shifted up eight bits, the eight bits of C, except that the bit with value 1 or 2 is automatically -set as required. I and I supply the parameters of +set as required. C and C supply the parameters of the slice; they are consumed by this function and become part of the constructed op tree. @@ -6316,149 +6310,23 @@ S_assignment_type(pTHX_ const OP *o) return ret; } -/* - Helper function for newASSIGNOP to detect commonality between the - lhs and the rhs. (It is actually called very indirectly. newASSIGNOP - flags the op and the peephole optimizer calls this helper function - if the flag is set.) Marks all variables with PL_generation. If it - returns TRUE the assignment must be able to handle common variables. - - PL_generation sorcery: - An assignment like ($a,$b) = ($c,$d) is easier than - ($a,$b) = ($c,$a), since there is no need for temporary vars. - To detect whether there are common vars, the global var - PL_generation is incremented for each assign op we compile. - Then, while compiling the assign op, we run through all the - variables on both sides of the assignment, setting a spare slot - in each of them to PL_generation. If any of them already have - that value, we know we've got commonality. Also, if the - generation number is already set to PERL_INT_MAX, then - the variable is involved in aliasing, so we also have - potential commonality in that case. We could use a - single bit marker, but then we'd have to make 2 passes, first - to clear the flag, then to test and set it. And that - wouldn't help with aliasing, either. To find somewhere - to store these values, evil chicanery is done with SvUVX(). -*/ -PERL_STATIC_INLINE bool -S_aassign_common_vars(pTHX_ OP* o) -{ - OP *curop; - for (curop = cUNOPo->op_first; curop; curop = OpSIBLING(curop)) { - if (PL_opargs[curop->op_type] & OA_DANGEROUS) { - if (curop->op_type == OP_GV || curop->op_type == OP_GVSV - || curop->op_type == OP_AELEMFAST) { - GV *gv = cGVOPx_gv(curop); - if (gv == PL_defgv - || (int)GvASSIGN_GENERATION(gv) == PL_generation) - return TRUE; - GvASSIGN_GENERATION_set(gv, PL_generation); - } - else if (curop->op_type == OP_PADSV || - curop->op_type == OP_PADAV || - curop->op_type == OP_PADHV || - curop->op_type == OP_AELEMFAST_LEX || - curop->op_type == OP_PADANY) - { - padcheck: - if (PAD_COMPNAME_GEN(curop->op_targ) - == (STRLEN)PL_generation - || PAD_COMPNAME_GEN(curop->op_targ) == PERL_INT_MAX) - return TRUE; - PAD_COMPNAME_GEN_set(curop->op_targ, PL_generation); - - } - else if (curop->op_type == OP_RV2CV) - return TRUE; - else if (curop->op_type == OP_RV2SV || - curop->op_type == OP_RV2AV || - curop->op_type == OP_RV2HV || - curop->op_type == OP_RV2GV) { - if (cUNOPx(curop)->op_first->op_type != OP_GV) /* funny deref? */ - return TRUE; - } - else if (curop->op_type == OP_PUSHRE) { - GV *const gv = -#ifdef USE_ITHREADS - ((PMOP*)curop)->op_pmreplrootu.op_pmtargetoff - ? MUTABLE_GV(PAD_SVl(((PMOP*)curop)->op_pmreplrootu.op_pmtargetoff)) - : NULL; -#else - ((PMOP*)curop)->op_pmreplrootu.op_pmtargetgv; -#endif - if (gv) { - if (gv == PL_defgv - || (int)GvASSIGN_GENERATION(gv) == PL_generation) - return TRUE; - GvASSIGN_GENERATION_set(gv, PL_generation); - } - else if (curop->op_targ) - goto padcheck; - } - else if (curop->op_type == OP_PADRANGE) - /* Ignore padrange; checking its siblings is sufficient. */ - continue; - else - return TRUE; - } - else if (PL_opargs[curop->op_type] & OA_TARGLEX - && curop->op_private & OPpTARGET_MY) - goto padcheck; - - if (curop->op_flags & OPf_KIDS) { - if (aassign_common_vars(curop)) - return TRUE; - } - } - return FALSE; -} - -/* This variant only handles lexical aliases. It is called when - newASSIGNOP decides that we don’t have any common vars, as lexical ali- - ases trump that decision. */ -PERL_STATIC_INLINE bool -S_aassign_common_vars_aliases_only(pTHX_ OP *o) -{ - OP *curop; - for (curop = cUNOPo->op_first; curop; curop = OpSIBLING(curop)) { - if ((curop->op_type == OP_PADSV || - curop->op_type == OP_PADAV || - curop->op_type == OP_PADHV || - curop->op_type == OP_AELEMFAST_LEX || - curop->op_type == OP_PADANY || - ( PL_opargs[curop->op_type] & OA_TARGLEX - && curop->op_private & OPpTARGET_MY )) - && PAD_COMPNAME_GEN(curop->op_targ) == PERL_INT_MAX) - return TRUE; - - if (curop->op_type == OP_PUSHRE && curop->op_targ - && PAD_COMPNAME_GEN(curop->op_targ) == PERL_INT_MAX) - return TRUE; - - if (curop->op_flags & OPf_KIDS) { - if (S_aassign_common_vars_aliases_only(aTHX_ curop)) - return TRUE; - } - } - return FALSE; -} /* =for apidoc Am|OP *|newASSIGNOP|I32 flags|OP *left|I32 optype|OP *right -Constructs, checks, and returns an assignment op. I and I +Constructs, checks, and returns an assignment op. C and C supply the parameters of the assignment; they are consumed by this function and become part of the constructed op tree. -If I is C, C, or C, then -a suitable conditional optree is constructed. If I is the opcode +If C is C, C, or C, then +a suitable conditional optree is constructed. If C is the opcode of a binary operator, such as C, then an op is constructed that performs the binary operation and assigns the result to the left argument. -Either way, if I is non-zero then I has no effect. +Either way, if C is non-zero then C has no effect. -If I is zero, then a plain scalar or list assignment is +If C is zero, then a plain scalar or list assignment is constructed. Which type of assignment it is is automatically determined. -I gives the eight bits of C, except that C +C gives the eight bits of C, except that C will be set automatically, and, shifted up eight bits, the eight bits of C, except that the bit with value 1 or 2 is automatically set as required. @@ -6488,7 +6356,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) static const char no_list_state[] = "Initialization of state variables" " in list context currently forbidden"; OP *curop; - bool maybe_common_vars = TRUE; if (left->op_type == OP_ASLICE || left->op_type == OP_HSLICE) left->op_private &= ~ OPpSLICEWARNING; @@ -6502,47 +6369,24 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) if (OP_TYPE_IS_OR_WAS(left, OP_LIST)) { OP* lop = ((LISTOP*)left)->op_first; - maybe_common_vars = FALSE; while (lop) { - if (lop->op_type == OP_PADSV || - lop->op_type == OP_PADAV || - lop->op_type == OP_PADHV || - lop->op_type == OP_PADANY) { - if (!(lop->op_private & OPpLVAL_INTRO)) - maybe_common_vars = TRUE; - - if (lop->op_private & OPpPAD_STATE) { - if (left->op_private & OPpLVAL_INTRO) { - /* Each variable in state($a, $b, $c) = ... */ - } - else { - /* Each state variable in - (state $a, my $b, our $c, $d, undef) = ... */ - } - yyerror(no_list_state); - } else { - /* Each my variable in - (state $a, my $b, our $c, $d, undef) = ... */ - } - } else if (lop->op_type == OP_UNDEF || - OP_TYPE_IS_OR_WAS(lop, OP_PUSHMARK)) { - /* undef may be interesting in - (state $a, undef, state $c) */ - } else { - /* Other ops in the list. */ - maybe_common_vars = TRUE; - } + if ((lop->op_type == OP_PADSV || + lop->op_type == OP_PADAV || + lop->op_type == OP_PADHV || + lop->op_type == OP_PADANY) + && (lop->op_private & OPpPAD_STATE) + ) + yyerror(no_list_state); lop = OpSIBLING(lop); } } - else if ((left->op_private & OPpLVAL_INTRO) + else if ( (left->op_private & OPpLVAL_INTRO) + && (left->op_private & OPpPAD_STATE) && ( left->op_type == OP_PADSV || left->op_type == OP_PADAV || left->op_type == OP_PADHV - || left->op_type == OP_PADANY)) - { - if (left->op_type == OP_PADSV) maybe_common_vars = FALSE; - if (left->op_private & OPpPAD_STATE) { + || left->op_type == OP_PADANY) + ) { /* All single variable list context state assignments, hence state ($a) = ... (state $a) = ... @@ -6554,13 +6398,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) (state %a) = ... */ yyerror(no_list_state); - } - } - - if (maybe_common_vars) { - /* The peephole optimizer will do the full check and pos- - sibly turn this off. */ - o->op_private |= OPpASSIGN_COMMON; } if (right && right->op_type == OP_SPLIT @@ -6673,13 +6510,13 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) Constructs a state op (COP). The state op is normally a C op, but will be a C op if debugging is enabled for currently-compiled code. The state op is populated from C (or C). -If I