The SVs in the names AV have their PV being the name of the variable.
NV+1..IV inclusive is a range of cop_seq numbers for which the name is
valid. For typed lexicals name SV is SVt_PVMG and SvSTASH points at the
-type. For C<our> lexicals, the type is SVt_PVGV, and GvSTASH points at the
-stash of the associated global (so that duplicate C<our> declarations in the
-same package can be detected). SvCUR is sometimes hijacked to
-store the generation number during compilation.
+type. For C<our> lexicals, the type is also SVt_PVGV, with the MAGIC slot
+pointing at the stash of the associated global (so that duplicate C<our>
+declarations in the same package can be detected). SvCUR is sometimes
+hijacked to store the generation number during compilation.
If SvFAKE is set on the name SV, then that slot in the frame AV is
a REFCNT'ed reference to a lexical from "outside". In this case,
#define PAD_MAX 999999999
-
+#ifdef PERL_MAD
+void pad_peg(const char* s) {
+ static int pegcnt;
+ pegcnt++;
+}
+#endif
/*
=for apidoc pad_new
I32 ix;
const PADLIST * const padlist = CvPADLIST(cv);
+ pad_peg("pad_undef");
if (!padlist)
return;
if (SvIS_FREED(padlist)) /* may be during global destruction */
SvREFCNT_dec(innercv);
inner_rc--;
}
- if (inner_rc /* in use, not just a prototype */
- && CvOUTSIDE(innercv) == cv)
- {
+
+ /* in use, not just a prototype */
+ if (inner_rc && (CvOUTSIDE(innercv) == cv)) {
assert(CvWEAKOUTSIDE(innercv));
/* don't relink to grandfather if he's being freed */
if (outercv && SvREFCNT(outercv)) {
CvWEAKOUTSIDE_off(innercv);
CvOUTSIDE(innercv) = outercv;
CvOUTSIDE_SEQ(innercv) = seq;
- (void)SvREFCNT_inc(outercv);
+ SvREFCNT_inc_void_NN(outercv);
}
else {
CvOUTSIDE(innercv) = NULL;
}
-
}
-
}
}
}
ix = AvFILLp(padlist);
while (ix >= 0) {
- SV* const sv = AvARRAY(padlist)[ix--];
- if (!sv)
- continue;
- if (sv == (SV*)PL_comppad_name)
- PL_comppad_name = NULL;
- else if (sv == (SV*)PL_comppad) {
- PL_comppad = Null(PAD*);
- PL_curpad = Null(SV**);
+ const SV* const sv = AvARRAY(padlist)[ix--];
+ if (sv) {
+ if (sv == (SV*)PL_comppad_name)
+ PL_comppad_name = NULL;
+ else if (sv == (SV*)PL_comppad) {
+ PL_comppad = NULL;
+ PL_curpad = NULL;
+ }
}
SvREFCNT_dec(sv);
}
SvREFCNT_dec((SV*)CvPADLIST(cv));
- CvPADLIST(cv) = Null(PADLIST*);
+ CvPADLIST(cv) = NULL;
}
If C<typestash> is valid, the name is for a typed lexical; set the
name's stash to that value.
If C<ourstash> is valid, it's an our lexical, set the name's
-GvSTASH to that value
+OURSTASH to that value
If fake, it means we're cloning an existing entry
ASSERT_CURPAD_ACTIVE("pad_add_name");
- sv_upgrade(namesv, ourstash ? SVt_PVGV : typestash ? SVt_PVMG : SVt_PVNV);
+ sv_upgrade(namesv, (ourstash || typestash) ? SVt_PVMG : SVt_PVNV);
sv_setpv(namesv, name);
if (typestash) {
- SvFLAGS(namesv) |= SVpad_TYPED;
- SvSTASH_set(namesv, (HV*)SvREFCNT_inc((SV*) typestash));
+ SvPAD_TYPED_on(namesv);
+ SvSTASH_set(namesv, (HV*)SvREFCNT_inc_simple_NN((SV*)typestash));
}
if (ourstash) {
- SvFLAGS(namesv) |= SVpad_OUR;
- GvSTASH(namesv) = ourstash;
- Perl_sv_add_backref(aTHX_ (SV*)ourstash, namesv);
+ SvPAD_OUR_on(namesv);
+ OURSTASH_set(namesv, ourstash);
+ SvREFCNT_inc_void_NN(ourstash);
}
av_store(PL_comppad_name, offset, namesv);
dVAR;
PADOFFSET ix;
SV* const name = newSV(0);
+ pad_peg("add_anon");
sv_upgrade(name, SVt_PVNV);
sv_setpvn(name, "&", 1);
SvIV_set(name, -1);
&& (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
&& strEQ(name, SvPVX_const(sv)))
{
- if (is_our && (SvFLAGS(sv) & SVpad_OUR))
+ if (is_our && (SvPAD_OUR(sv)))
break; /* "our" masking "our" */
Perl_warner(aTHX_ packWARN(WARN_MISC),
"\"%s\" variable %s masks earlier declaration in same %s",
&& sv != &PL_sv_undef
&& !SvFAKE(sv)
&& (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
- && ((SvFLAGS(sv) & SVpad_OUR) && GvSTASH(sv) == ourstash)
+ && OURSTASH(sv) == ourstash
&& strEQ(name, SvPVX_const(sv)))
{
Perl_warner(aTHX_ packWARN(WARN_MISC),
const AV *nameav;
SV **name_svp;
+ pad_peg("pad_findmy");
offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
- Null(SV**), &out_sv, &out_flags);
+ NULL, &out_sv, &out_flags);
if (offset != NOT_IN_PAD)
return offset;
const SV * const namesv = name_svp[offset];
if (namesv && namesv != &PL_sv_undef
&& !SvFAKE(namesv)
- && (SvFLAGS(namesv) & SVpad_OUR)
+ && (SvPAD_OUR(namesv))
&& strEQ(SvPVX_const(namesv), name)
&& U_32(SvNVX(namesv)) == PAD_MAX /* min */
)
SV *out_sv;
int out_flags;
return pad_findlex("$_", find_runcv(NULL), PL_curcop->cop_seq, 1,
- Null(SV**), &out_sv, &out_flags);
+ NULL, &out_sv, &out_flags);
}
/*
if (out_capture) {
/* our ? */
- if ((SvFLAGS(*out_name_sv) & SVpad_OUR)) {
+ if (SvPAD_OUR(*out_name_sv)) {
*out_capture = NULL;
return offset;
}
/* out_capture non-null means caller wants us to capture lex; in
* addition we capture ourselves unless it's an ANON/format */
new_capturep = out_capture ? out_capture :
- CvLATE(cv) ? Null(SV**) : &new_capture;
+ CvLATE(cv) ? NULL : &new_capture;
offset = pad_findlex(name, CvOUTSIDE(cv), CvOUTSIDE_SEQ(cv), 1,
new_capturep, out_name_sv, out_flags);
new_offset = pad_add_name(
SvPVX_const(*out_name_sv),
- (SvFLAGS(*out_name_sv) & SVpad_TYPED)
+ SvPAD_TYPED(*out_name_sv)
? SvSTASH(*out_name_sv) : NULL,
- (SvFLAGS(*out_name_sv) & SVpad_OUR)
- ? GvSTASH(*out_name_sv) : NULL,
+ OURSTASH(*out_name_sv),
1 /* fake */
);
SvIV_set(new_namesv, *out_flags);
SvNV_set(new_namesv, (NV)0);
- if (SvFLAGS(new_namesv) & SVpad_OUR) {
- /* do nothing */
+ if (SvPAD_OUR(new_namesv)) {
+ /*EMPTY*/; /* do nothing */
}
else if (CvLATE(cv)) {
/* delayed creation - just note the offset within parent pad */
PL_comppad_name = ocomppad_name;
PL_comppad = ocomppad;
- PL_curpad = ocomppad ? AvARRAY(ocomppad) : Null(SV **);
+ PL_curpad = ocomppad ? AvARRAY(ocomppad) : NULL;
}
return new_offset;
}
CvCLONED_on(cv);
#ifdef USE_ITHREADS
- CvFILE(cv) = CvXSUB(proto) ? CvFILE(proto)
- : savepv(CvFILE(proto));
+ CvFILE(cv) = CvISXSUB(proto) ? CvFILE(proto)
+ : savepv(CvFILE(proto));
#else
CvFILE(cv) = CvFILE(proto);
#endif
CvROOT(cv) = OpREFCNT_inc(CvROOT(proto));
OP_REFCNT_UNLOCK;
CvSTART(cv) = CvSTART(proto);
- CvOUTSIDE(cv) = (CV*)SvREFCNT_inc(outside);
+ CvOUTSIDE(cv) = (CV*)SvREFCNT_inc_simple(outside);
CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(proto);
if (SvPOK(proto))
}
else {
assert(!SvPADSTALE(sv));
- sv = SvREFCNT_inc(sv);
+ SvREFCNT_inc_simple_void(sv);
}
}
if (!sv) {
Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
{
dVAR;
- if (depth <= AvFILLp(padlist))
- return;
-
- {
+ if (depth > AvFILLp(padlist)) {
SV** const svp = AvARRAY(padlist);
AV* const newpad = newAV();
SV** const oldpad = AvARRAY(svp[depth-1]);
{
dVAR;
SV* const * const av = av_fetch(PL_comppad_name, po, FALSE);
- if ( SvFLAGS(*av) & SVpad_TYPED ) {
+ if ( SvPAD_TYPED(*av) ) {
return SvSTASH(*av);
}
return NULL;