register CV *compcv = PL_compcv;
SV *const_sv;
PADNAME *name;
+ PADOFFSET pax = o->op_targ;
+ CV *outcv = CvOUTSIDE(PL_compcv);
PERL_ARGS_ASSERT_NEWMYSUB;
- /* PL_comppad is the pad owned by the new sub. We need to look in
- CvOUTSIDE and find the pad belonging to the enclosing sub, where we
- store the new one. */
- name = PadlistNAMESARRAY(CvPADLIST(CvOUTSIDE(PL_compcv)))[o->op_targ];
+ /* Find the pad slot for storing the new sub.
+ We cannot use PL_comppad, as it is the pad owned by the new sub. We
+ need to look in CvOUTSIDE and find the pad belonging to the enclos-
+ ing sub. And then we need to dig deeper if this is a lexical from
+ outside, as in:
+ my sub foo; sub { sub foo { } }
+ */
+ redo:
+ name = PadlistNAMESARRAY(CvPADLIST(outcv))[pax];
+ if (PadnameOUTER(name) && PARENT_PAD_INDEX(name)) {
+ pax = PARENT_PAD_INDEX(name);
+ outcv = CvOUTSIDE(outcv);
+ assert(outcv);
+ goto redo;
+ }
svspot =
- &PadARRAY(PadlistARRAY(CvPADLIST(CvOUTSIDE(PL_compcv)))[1])
- [o->op_targ];
+ &PadARRAY(PadlistARRAY(CvPADLIST(outcv))[1])[pax];
spot = (CV **)svspot;
if (proto) {
PL_compcv = NULL;
goto done;
}
- SvREFCNT_dec(CvOUTSIDE(compcv));
- CvWEAKOUTSIDE_on(compcv);
+ if (outcv == CvOUTSIDE(compcv)) {
+ assert(!CvWEAKOUTSIDE(compcv));
+ SvREFCNT_dec(CvOUTSIDE(compcv));
+ CvWEAKOUTSIDE_on(compcv);
+ }
+ /* XXX else do we have a circular reference? */
if (cv) { /* must reuse cv in case stub is referenced elsewhere */
/* transfer PL_compcv to cv */
if (block
cv_flags_t existing_builtin_attrs = CvFLAGS(cv) & CVf_BUILTIN_ATTRS;
PADLIST *const temp_padl = CvPADLIST(cv);
CV *const temp_cv = CvOUTSIDE(cv);
- const cv_flags_t slabbed = CvSLABBED(cv);
+ const cv_flags_t other_flags =
+ CvFLAGS(cv) & (CVf_SLABBED|CVf_WEAKOUTSIDE);
OP * const cvstart = CvSTART(cv);
assert(CvWEAKOUTSIDE(cv));
CvPADLIST(compcv) = temp_padl;
CvSTART(cv) = CvSTART(compcv);
CvSTART(compcv) = cvstart;
- if (slabbed) CvSLABBED_on(compcv);
- else CvSLABBED_off(compcv);
+ CvFLAGS(compcv) &= ~(CVf_SLABBED|CVf_WEAKOUTSIDE);
+ CvFLAGS(compcv) |= other_flags;
if (CvFILE(cv) && CvDYNFILE(cv)) {
Safefree(CvFILE(cv));
*bar::like = *like;
}
no warnings 'deprecated';
-plan 104;
+plan 106;
# -------------------- our -------------------- #
}
is eval{sb3}, 47,
'sub foo{} applying to "state sub foo;" even inside state sub foo{}';
+ # Same test again, but inside an anonymous sub
+ sub {
+ state sub sb4;
+ {
+ state sub sb4 {
+ sub sb4 { 47 }
+ }
+ }
+ is sb4, 47,
+ 'sub foo{} applying to "state sub foo;" even inside state sub foo{}';
+ }->();
}
sub sc { 43 }
{
}
is eval{mb3}, 47,
'sub foo{} applying to "my sub foo;" even inside my sub foo{}';
+ # Same test again, but inside an anonymous sub
+ sub {
+ my sub mb4;
+ {
+ my sub mb4 {
+ sub mb4 { 47 }
+ }
+ }
+ is mb4, 47,
+ 'sub foo{} applying to "my sub foo;" even inside my sub foo{}';
+ }->();
}
sub mc { 43 }
{