Note that formats are treated as anon subs, and are cloned each time
write is called (if necessary).
+The flag SVf_PADSTALE is cleared on lexicals each time the my() is executed,
+and set on scope exit. This allows the 'Variable $x is not available' warning
+to be generated in evals, such as
+
+ { my $x = 1; sub f { eval '$x'} } f();
+
=cut
*/
&& CvOUTSIDE(innercv) == cv)
{
assert(CvWEAKOUTSIDE(innercv));
- CvWEAKOUTSIDE_off(innercv);
- CvOUTSIDE(innercv) = outercv;
- CvOUTSIDE_SEQ(innercv) = seq;
- SvREFCNT_inc(outercv);
+ /* don't relink to grandfather if he's being freed */
+ if (outercv && SvREFCNT(outercv)) {
+ CvWEAKOUTSIDE_off(innercv);
+ CvOUTSIDE(innercv) = outercv;
+ CvOUTSIDE_SEQ(innercv) = seq;
+ SvREFCNT_inc(outercv);
+ }
+ else {
+ CvOUTSIDE(innercv) = Nullcv;
+ }
+
}
+
}
}
}
{
SV *out_sv;
int out_flags;
+ I32 offset;
+ AV *nameav;
+ SV **name_svp;
- return pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
+ offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
Null(SV**), &out_sv, &out_flags);
+ if (offset != NOT_IN_PAD)
+ return offset;
+
+ /* look for an our that's being introduced; this allows
+ * our $foo = 0 unless defined $foo;
+ * to not give a warning. (Yes, this is a hack) */
+
+ nameav = (AV*)AvARRAY(CvPADLIST(PL_compcv))[0];
+ name_svp = AvARRAY(nameav);
+ for (offset = AvFILLp(nameav); offset > 0; offset--) {
+ SV *namesv = name_svp[offset];
+ if (namesv && namesv != &PL_sv_undef
+ && !SvFAKE(namesv)
+ && (SvFLAGS(namesv) & SVpad_OUR)
+ && strEQ(SvPVX(namesv), name)
+ && U_32(SvNVX(namesv)) == PAD_MAX /* min */
+ )
+ return offset;
+ }
+ return NOT_IN_PAD;
}
{
if (SvFAKE(namesv))
fake_offset = offset; /* in case we don't find a real one */
- else if ( seq > (U32)I_32(SvNVX(namesv)) /* min */
- && seq <= (U32)SvIVX(namesv)) /* max */
+ else if ( seq > U_32(SvNVX(namesv)) /* min */
+ && seq <= (U32)SvIVX(namesv)) /* max */
break;
}
}
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad findlex cv=0x%"UVxf" matched: offset=%ld (%ld,%ld)\n",
- PTR2UV(cv), (long)offset, (long)I_32(SvNVX(*out_name_sv)),
+ PTR2UV(cv), (long)offset, (long)U_32(SvNVX(*out_name_sv)),
(long)SvIVX(*out_name_sv)));
}
else { /* fake match */
*out_name_sv = name_svp[offset]; /* return the namesv */
*out_flags = SvIVX(*out_name_sv);
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
- "Pad findlex cv=0x%"UVxf" matched: offset=%ld flags=0x%x index=%lu\n",
+ "Pad findlex cv=0x%"UVxf" matched: offset=%ld flags=0x%lx index=%lu\n",
PTR2UV(cv), (long)offset, (unsigned long)*out_flags,
(unsigned long)SvNVX(*out_name_sv)
));
CvDEPTH(cv) ? CvDEPTH(cv) : 1])[offset];
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad findlex cv=0x%"UVxf" found lex=0x%"UVxf"\n",
- PTR2UV(cv), *out_capture));
+ PTR2UV(cv), PTR2UV(*out_capture)));
if (SvPADSTALE(*out_capture)) {
if (ckWARN(WARN_CLOSURE))
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad intromy: %ld \"%s\", (%ld,%ld)\n",
(long)i, SvPVX(sv),
- (long)I_32(SvNVX(sv)), (long)SvIVX(sv))
+ (long)U_32(SvNVX(sv)), (long)SvIVX(sv))
);
}
}
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad leavemy: %ld \"%s\", (%ld,%ld)\n",
(long)off, SvPVX(sv),
- (long)I_32(SvNVX(sv)), (long)SvIVX(sv))
+ (long)U_32(SvNVX(sv)), (long)SvIVX(sv))
);
}
}
(int) ix,
PTR2UV(ppad[ix]),
(unsigned long) (ppad[ix] ? SvREFCNT(ppad[ix]) : 0),
- (long)I_32(SvNVX(namesv)),
+ (long)U_32(SvNVX(namesv)),
(long)SvIVX(namesv),
SvPVX(namesv)
);