backward in the execution order. (The bottom-up parser builds that
part of the execution order it knows about, but if you follow the "next"
links around, you'll find it's actually a closed loop through the
-top level node.
+top level node.)
Whenever the bottom-up parser gets to a node that supplies context to
its components, it invokes that portion of the top-down pass that applies
/* faked up qw list? */
if (slot == '(' &&
tm->mad_type == MAD_SV &&
- SvPVX((const SV *)tm->mad_val)[0] == 'q')
+ SvPVX((SV *)tm->mad_val)[0] == 'q')
slot = 'x';
if (o) {
}
MADPROP *
-Perl_newMADPROP(pTHX_ char key, char type, const void* val, I32 vlen)
+Perl_newMADPROP(pTHX_ char key, char type, void* val, I32 vlen)
{
MADPROP *mp;
Newxz(mp, 1, MADPROP);
(or 0 for no flags). ver, if specified, provides version semantics
similar to C<use Foo::Bar VERSION>. The optional trailing SV*
arguments can be used to specify arguments to the module's import()
-method, similar to C<use Foo::Bar VERSION LIST>.
+method, similar to C<use Foo::Bar VERSION LIST>. 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
+import list is required.
=cut */
return newop;
}
op_free(first);
+ if (other->op_type == OP_LEAVE)
+ other = newUNOP(OP_NULL, OPf_SPECIAL, other);
return other;
}
else {
op_free(first);
op_free(dead);
}
+ if (live->op_type == OP_LEAVE)
+ live = newUNOP(OP_NULL, OPf_SPECIAL, live);
return live;
}
NewOp(1101, logop, 1, LOGOP);
Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
{
dVAR;
- const char *aname;
GV *gv;
const char *ps;
STRLEN ps_len;
|| PL_madskills)
? GV_ADDMULTI : GV_ADDMULTI | GV_NOINIT;
const char * const name = o ? SvPV_nolen_const(cSVOPo->op_sv) : NULL;
+ bool has_name;
if (proto) {
assert(proto->op_type == OP_CONST);
else
ps = NULL;
- if (!name && PERLDB_NAMEANON && CopLINE(PL_curcop)) {
+ if (name) {
+ gv = gv_fetchsv(cSVOPo->op_sv, gv_fetch_flags, SVt_PVCV);
+ has_name = TRUE;
+ } else if (PERLDB_NAMEANON && CopLINE(PL_curcop)) {
SV * const sv = sv_newmortal();
Perl_sv_setpvf(aTHX_ sv, "%s[%s:%"IVdf"]",
PL_curstash ? "__ANON__" : "__ANON__::__ANON__",
CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
- aname = SvPVX_const(sv);
+ gv = gv_fetchsv(sv, gv_fetch_flags, SVt_PVCV);
+ has_name = TRUE;
+ } else if (PL_curstash) {
+ gv = gv_fetchpvs("__ANON__", gv_fetch_flags, SVt_PVCV);
+ has_name = FALSE;
+ } else {
+ gv = gv_fetchpvs("__ANON__::__ANON__", gv_fetch_flags, SVt_PVCV);
+ has_name = FALSE;
}
- else
- aname = NULL;
-
- gv = name ? gv_fetchsv(cSVOPo->op_sv, gv_fetch_flags, SVt_PVCV)
- : gv_fetchpv(aname ? aname
- : (PL_curstash ? "__ANON__" : "__ANON__::__ANON__"),
- gv_fetch_flags, SVt_PVCV);
if (!PL_madskills) {
if (o)
PL_compcv = NULL;
goto done;
}
- if (attrs) {
- HV *stash;
- SV *rcv;
-
- /* Need to do a C<use attributes $stash_of_cv,\&cv,@attrs>
- * before we clobber PL_compcv.
- */
- if (cv && (!block
+ if (cv) { /* must reuse cv if autoloaded */
+ /* transfer PL_compcv to cv */
+ if (block
#ifdef PERL_MAD
- || block->op_type == OP_NULL
+ && block->op_type != OP_NULL
#endif
- )) {
- rcv = MUTABLE_SV(cv);
- /* Might have had built-in attributes applied -- propagate them. */
- CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS);
- if (CvGV(cv) && GvSTASH(CvGV(cv)))
- stash = GvSTASH(CvGV(cv));
- else if (CvSTASH(cv))
- stash = CvSTASH(cv);
- else
- stash = PL_curstash;
+ ) {
+ cv_undef(cv);
+ CvFLAGS(cv) = CvFLAGS(PL_compcv);
+ if (!CvWEAKOUTSIDE(cv))
+ SvREFCNT_dec(CvOUTSIDE(cv));
+ CvOUTSIDE(cv) = CvOUTSIDE(PL_compcv);
+ CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(PL_compcv);
+ CvOUTSIDE(PL_compcv) = 0;
+ CvPADLIST(cv) = CvPADLIST(PL_compcv);
+ CvPADLIST(PL_compcv) = 0;
+ /* inner references to PL_compcv must be fixed up ... */
+ pad_fixup_inner_anons(CvPADLIST(cv), PL_compcv, cv);
+ if (PERLDB_INTER)/* Advice debugger on the new sub. */
+ ++PL_sub_generation;
}
else {
- /* possibly about to re-define existing subr -- ignore old cv */
- rcv = MUTABLE_SV(PL_compcv);
- if (name && GvSTASH(gv))
- stash = GvSTASH(gv);
- else
- stash = PL_curstash;
- }
- apply_attrs(stash, rcv, attrs, FALSE);
- }
- if (cv) { /* must reuse cv if autoloaded */
- if (
-#ifdef PERL_MAD
- (
-#endif
- !block
-#ifdef PERL_MAD
- || block->op_type == OP_NULL) && !PL_madskills
-#endif
- ) {
- /* got here with just attrs -- work done, so bug out */
- SAVEFREESV(PL_compcv);
- goto done;
+ /* Might have had built-in attributes applied -- propagate them. */
+ CvFLAGS(cv) |= (CvFLAGS(PL_compcv) & CVf_BUILTIN_ATTRS);
}
- /* transfer PL_compcv to cv */
- cv_undef(cv);
- CvFLAGS(cv) = CvFLAGS(PL_compcv);
- if (!CvWEAKOUTSIDE(cv))
- SvREFCNT_dec(CvOUTSIDE(cv));
- CvOUTSIDE(cv) = CvOUTSIDE(PL_compcv);
- CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(PL_compcv);
- CvOUTSIDE(PL_compcv) = 0;
- CvPADLIST(cv) = CvPADLIST(PL_compcv);
- CvPADLIST(PL_compcv) = 0;
- /* inner references to PL_compcv must be fixed up ... */
- 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;
}
else {
cv = PL_compcv;
mro_method_changed_in(GvSTASH(gv)); /* sub Foo::bar { (shift)+1 } */
}
}
- CvGV(cv) = gv;
- CvFILE_set_from_cop(cv, PL_curcop);
- CvSTASH(cv) = PL_curstash;
+ if (!CvGV(cv)) {
+ CvGV(cv) = gv;
+ CvFILE_set_from_cop(cv, PL_curcop);
+ CvSTASH(cv) = PL_curstash;
+ }
+ if (attrs) {
+ /* Need to do a C<use attributes $stash_of_cv,\&cv,@attrs>. */
+ HV *stash = name && GvSTASH(CvGV(cv)) ? GvSTASH(CvGV(cv)) : PL_curstash;
+ apply_attrs(stash, MUTABLE_SV(cv), attrs, FALSE);
+ }
if (ps)
sv_setpvn(MUTABLE_SV(cv), ps, ps_len);
CvCONST_on(cv);
}
- if (name || aname) {
+ if (has_name) {
if (PERLDB_SUBLINE && PL_curstash != PL_debstash) {
SV * const sv = newSV(0);
SV * const tmpstr = sv_newmortal();
Perl_croak(aTHX_ "%s argument is not a HASH or ARRAY element or slice",
OP_DESC(o));
}
+ if (kid->op_private & OPpLVAL_INTRO)
+ o->op_private |= OPpLVAL_INTRO;
op_null(kid);
}
return o;
PERL_ARGS_ASSERT_CK_SHIFT;
if (!(o->op_flags & OPf_KIDS)) {
- OP *argop;
- /* FIXME - this can be refactored to reduce code in #ifdefs */
-#ifdef PERL_MAD
- OP * const oldo = o;
-#else
- op_free(o);
-#endif
- argop = newUNOP(OP_RV2AV, 0,
+ OP *argop = newUNOP(OP_RV2AV, 0,
scalar(newGVOP(OP_GV, 0, CvUNIQUE(PL_compcv) ? PL_argvgv : PL_defgv)));
#ifdef PERL_MAD
+ OP * const oldo = o;
o = newUNOP(type, 0, scalar(argop));
op_getmad(oldo,o,'O');
return o;
#else
+ op_free(o);
return newUNOP(type, 0, scalar(argop));
#endif
}