#define too_many_arguments S_too_many_arguments
#define op_clear S_op_clear
#define null S_null
+#define pad_addlex S_pad_addlex
#define pad_findlex S_pad_findlex
#define newDEFSVOP S_newDEFSVOP
#define new_logop S_new_logop
#define too_many_arguments(a,b) S_too_many_arguments(aTHX_ a,b)
#define op_clear(a) S_op_clear(aTHX_ a)
#define null(a) S_null(aTHX_ a)
+#define pad_addlex(a) S_pad_addlex(aTHX_ a)
#define pad_findlex(a,b,c,d,e,f,g) S_pad_findlex(aTHX_ a,b,c,d,e,f,g)
#define newDEFSVOP() S_newDEFSVOP(aTHX)
#define new_logop(a,b,c,d) S_new_logop(aTHX_ a,b,c,d)
#define op_clear S_op_clear
#define S_null CPerlObj::S_null
#define null S_null
+#define S_pad_addlex CPerlObj::S_pad_addlex
+#define pad_addlex S_pad_addlex
#define S_pad_findlex CPerlObj::S_pad_findlex
#define pad_findlex S_pad_findlex
#define S_newDEFSVOP CPerlObj::S_newDEFSVOP
return off;
}
+STATIC PADOFFSET
+S_pad_addlex(pTHX_ SV *proto_namesv)
+{
+ SV *namesv = NEWSV(1103,0);
+ PADOFFSET newoff = pad_alloc(OP_PADSV, SVs_PADMY);
+ sv_upgrade(namesv, SVt_PVNV);
+ sv_setpv(namesv, SvPVX(proto_namesv));
+ av_store(PL_comppad_name, newoff, namesv);
+ SvNVX(namesv) = (NV)PL_curcop->cop_seq;
+ SvIVX(namesv) = PAD_MAX; /* A ref, intro immediately */
+ SvFAKE_on(namesv); /* A ref, not a real var */
+ if (SvFLAGS(proto_namesv) & SVpad_OUR) { /* An "our" variable */
+ SvFLAGS(namesv) |= SVpad_OUR;
+ (void)SvUPGRADE(namesv, SVt_PVGV);
+ GvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)GvSTASH(proto_namesv));
+ }
+ if (SvOBJECT(proto_namesv)) { /* A typed var */
+ SvOBJECT_on(namesv);
+ (void)SvUPGRADE(namesv, SVt_PVMG);
+ SvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)SvSTASH(proto_namesv));
+ PL_sv_objcount++;
+ }
+ return newoff;
+}
+
#define FINDLEX_NOSEARCH 1 /* don't search outer contexts */
STATIC PADOFFSET
}
depth = 1;
}
- oldpad = (AV*)*av_fetch(curlist, depth, FALSE);
+ oldpad = (AV*)AvARRAY(curlist)[depth];
oldsv = *av_fetch(oldpad, off, TRUE);
if (!newoff) { /* Not a mere clone operation. */
- SV *namesv = NEWSV(1103,0);
- newoff = pad_alloc(OP_PADSV, SVs_PADMY);
- sv_upgrade(namesv, SVt_PVNV);
- sv_setpv(namesv, name);
- av_store(PL_comppad_name, newoff, namesv);
- SvNVX(namesv) = (NV)PL_curcop->cop_seq;
- SvIVX(namesv) = PAD_MAX; /* A ref, intro immediately */
- SvFAKE_on(namesv); /* A ref, not a real var */
- if (SvFLAGS(sv) & SVpad_OUR) { /* An "our" variable */
- SvFLAGS(namesv) |= SVpad_OUR;
- (void)SvUPGRADE(namesv, SVt_PVGV);
- GvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)GvSTASH(sv));
- }
- if (SvOBJECT(sv)) { /* A typed var */
- SvOBJECT_on(namesv);
- (void)SvUPGRADE(namesv, SVt_PVMG);
- SvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)SvSTASH(sv));
- PL_sv_objcount++;
- }
+ newoff = pad_addlex(sv);
if (CvANON(PL_compcv) || SvTYPE(PL_compcv) == SVt_PVFM) {
/* "It's closures all the way down." */
CvCLONE_on(PL_compcv);
bcv && bcv != cv && !CvCLONE(bcv);
bcv = CvOUTSIDE(bcv))
{
- if (CvANON(bcv))
+ if (CvANON(bcv)) {
+ /* install the missing pad entry in intervening
+ * nested subs and mark them cloneable.
+ * XXX fix pad_foo() to not use globals */
+ AV *ocomppad_name = PL_comppad_name;
+ AV *ocomppad = PL_comppad;
+ SV **ocurpad = PL_curpad;
+ AV *padlist = CvPADLIST(bcv);
+ PL_comppad_name = (AV*)AvARRAY(padlist)[0];
+ PL_comppad = (AV*)AvARRAY(padlist)[1];
+ PL_curpad = AvARRAY(PL_comppad);
+ pad_addlex(sv);
+ PL_comppad_name = ocomppad_name;
+ PL_comppad = ocomppad;
+ PL_curpad = ocurpad;
CvCLONE_on(bcv);
+ }
else {
if (ckWARN(WARN_CLOSURE)
&& !CvUNIQUE(bcv) && !CvUNIQUE(cv))
STATIC OP* S_too_many_arguments(pTHX_ OP *o, char* name);
STATIC void S_op_clear(pTHX_ OP* o);
STATIC void S_null(pTHX_ OP* o);
+STATIC PADOFFSET S_pad_addlex(pTHX_ SV* name);
STATIC PADOFFSET S_pad_findlex(pTHX_ char* name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix, I32 saweval, U32 flags);
STATIC OP* S_newDEFSVOP(pTHX);
STATIC OP* S_new_logop(pTHX_ I32 type, I32 flags, OP **firstp, OP **otherp);