This is a live mirror of the Perl 5 development currently hosted at
https://github.com/perl/perl5
https://perl5.git.perl.org
/
perl5.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Add MUTABLE_CV(), and eliminate (CV *) casts in *.c.
[perl5.git]
/
pad.c
diff --git
a/pad.c
b/pad.c
index
cae1c02
..
caf3df5
100644
(file)
--- a/
pad.c
+++ b/
pad.c
@@
-1,6
+1,7
@@
/* pad.c
*
/* pad.c
*
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ * by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
@@
-75,7
+76,7
@@
The SVs in the names AV have their PV being the name of the variable.
xlow+1..xhigh inclusive in the NV union 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 also SVt_PVMG, with the
xlow+1..xhigh inclusive in the NV union 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 also SVt_PVMG, with the
-OURSTASH slot pointing at the stash of the associated global (so that
+
Sv
OURSTASH slot pointing at the stash of the associated global (so that
duplicate C<our> declarations in the same package can be detected). SvUVX is
sometimes hijacked to store the generation number during compilation.
duplicate C<our> declarations in the same package can be detected). SvUVX is
sometimes hijacked to store the generation number during compilation.
@@
-102,6
+103,8
@@
to be generated in evals, such as
{ my $x = 1; sub f { eval '$x'} } f();
{ my $x = 1; sub f { eval '$x'} } f();
+For state vars, SVf_PADSTALE is overloaded to mean 'not yet initialised'
+
=cut
*/
=cut
*/
@@
-121,11
+124,14
@@
to be generated in evals, such as
#define PARENT_FAKELEX_FLAGS_set(sv,val) \
STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = (val); } STMT_END
#define PARENT_FAKELEX_FLAGS_set(sv,val) \
STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = (val); } STMT_END
-#define PAD_MAX I
V
_MAX
+#define PAD_MAX I
32
_MAX
#ifdef PERL_MAD
void pad_peg(const char* s) {
static int pegcnt;
#ifdef PERL_MAD
void pad_peg(const char* s) {
static int pegcnt;
+
+ PERL_ARGS_ASSERT_PAD_PEG;
+
pegcnt++;
}
#endif
pegcnt++;
}
#endif
@@
-168,7
+174,7
@@
Perl_pad_new(pTHX_ int flags)
SAVEI32(PL_comppad_name_fill);
SAVEI32(PL_min_intro_pending);
SAVEI32(PL_max_intro_pending);
SAVEI32(PL_comppad_name_fill);
SAVEI32(PL_min_intro_pending);
SAVEI32(PL_max_intro_pending);
- SAVE
I32
(PL_cv_has_eval);
+ SAVE
BOOL
(PL_cv_has_eval);
if (flags & padnew_SAVESUB) {
SAVEI32(PL_pad_reset_pending);
}
if (flags & padnew_SAVESUB) {
SAVEI32(PL_pad_reset_pending);
}
@@
-248,6
+254,8
@@
Perl_pad_undef(pTHX_ CV* cv)
I32 ix;
const PADLIST * const padlist = CvPADLIST(cv);
I32 ix;
const PADLIST * const padlist = CvPADLIST(cv);
+ PERL_ARGS_ASSERT_PAD_UNDEF;
+
pad_peg("pad_undef");
if (!padlist)
return;
pad_peg("pad_undef");
if (!padlist)
return;
@@
-255,8
+263,8
@@
Perl_pad_undef(pTHX_ CV* cv)
return;
DEBUG_X(PerlIO_printf(Perl_debug_log,
return;
DEBUG_X(PerlIO_printf(Perl_debug_log,
- "Pad undef: cv=0x%"UVxf" padlist=0x%"UVxf"\n",
- PTR2UV(cv), PTR2UV(padlist))
+ "Pad undef: cv=0x%"UVxf" padlist=0x%"UVxf"
comppad=0x%"UVxf"
\n",
+ PTR2UV(cv), PTR2UV(padlist)
, PTR2UV(PL_comppad)
)
);
/* detach any '&' anon children in the pad; if afterwards they
);
/* detach any '&' anon children in the pad; if afterwards they
@@
-277,7
+285,7
@@
Perl_pad_undef(pTHX_ CV* cv)
if (namesv && namesv != &PL_sv_undef
&& *SvPVX_const(namesv) == '&')
{
if (namesv && namesv != &PL_sv_undef
&& *SvPVX_const(namesv) == '&')
{
- CV * const innercv =
(CV*)curpad[ix]
;
+ CV * const innercv =
MUTABLE_CV(curpad[ix])
;
U32 inner_rc = SvREFCNT(innercv);
assert(inner_rc);
namepad[ix] = NULL;
U32 inner_rc = SvREFCNT(innercv);
assert(inner_rc);
namepad[ix] = NULL;
@@
-309,7
+317,7
@@
Perl_pad_undef(pTHX_ CV* cv)
ix = AvFILLp(padlist);
while (ix >= 0) {
ix = AvFILLp(padlist);
while (ix >= 0) {
-
const
SV* const sv = AvARRAY(padlist)[ix--];
+ SV* const sv = AvARRAY(padlist)[ix--];
if (sv) {
if (sv == (SV*)PL_comppad_name)
PL_comppad_name = NULL;
if (sv) {
if (sv == (SV*)PL_comppad_name)
PL_comppad_name = NULL;
@@
-335,7
+343,7
@@
offset.
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
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
-OURSTASH to that value
+
Sv
OURSTASH to that value
If fake, it means we're cloning an existing entry
If fake, it means we're cloning an existing entry
@@
-347,22
+355,23
@@
Perl_pad_add_name(pTHX_ const char *name, HV* typestash, HV* ourstash, bool fake
{
dVAR;
const PADOFFSET offset = pad_alloc(OP_PADSV, SVs_PADMY);
{
dVAR;
const PADOFFSET offset = pad_alloc(OP_PADSV, SVs_PADMY);
- SV* const namesv = newSV(0);
+ SV* const namesv
+ = newSV_type((ourstash || typestash) ? SVt_PVMG : SVt_PVNV);
-
ASSERT_CURPAD_ACTIVE("pad_add_name")
;
+
PERL_ARGS_ASSERT_PAD_ADD_NAME
;
+ ASSERT_CURPAD_ACTIVE("pad_add_name");
- sv_upgrade(namesv, (ourstash || typestash) ? SVt_PVMG : SVt_PVNV);
sv_setpv(namesv, name);
if (typestash) {
assert(SvTYPE(namesv) == SVt_PVMG);
SvPAD_TYPED_on(namesv);
sv_setpv(namesv, name);
if (typestash) {
assert(SvTYPE(namesv) == SVt_PVMG);
SvPAD_TYPED_on(namesv);
- SvSTASH_set(namesv,
(HV*)SvREFCNT_inc_simple_NN((SV*)typestash
));
+ SvSTASH_set(namesv,
MUTABLE_HV(SvREFCNT_inc_simple_NN((SV*)typestash)
));
}
if (ourstash) {
SvPAD_OUR_on(namesv);
}
if (ourstash) {
SvPAD_OUR_on(namesv);
- OURSTASH_set(namesv, ourstash);
+
Sv
OURSTASH_set(namesv, ourstash);
SvREFCNT_inc_simple_void_NN(ourstash);
}
else if (state) {
SvREFCNT_inc_simple_void_NN(ourstash);
}
else if (state) {
@@
-485,9
+494,11
@@
Perl_pad_add_anon(pTHX_ SV* sv, OPCODE op_type)
{
dVAR;
PADOFFSET ix;
{
dVAR;
PADOFFSET ix;
- SV* const name = newSV(0);
+ SV* const name = newSV_type(SVt_PVNV);
+
+ PERL_ARGS_ASSERT_PAD_ADD_ANON;
+
pad_peg("add_anon");
pad_peg("add_anon");
- sv_upgrade(name, SVt_PVNV);
sv_setpvn(name, "&", 1);
/* Are these two actually ever read? */
COP_SEQ_RANGE_HIGH_set(name, ~0);
sv_setpvn(name, "&", 1);
/* Are these two actually ever read? */
COP_SEQ_RANGE_HIGH_set(name, ~0);
@@
-500,10
+511,10
@@
Perl_pad_add_anon(pTHX_ SV* sv, OPCODE op_type)
/* to avoid ref loops, we never have parent + child referencing each
* other simultaneously */
/* to avoid ref loops, we never have parent + child referencing each
* other simultaneously */
- if (CvOUTSIDE((
CV
*)sv)) {
- assert(!CvWEAKOUTSIDE((
CV
*)sv));
- CvWEAKOUTSIDE_on(
(CV*)sv
);
- SvREFCNT_dec(CvOUTSIDE(
(CV*)sv
));
+ if (CvOUTSIDE((
const CV
*)sv)) {
+ assert(!CvWEAKOUTSIDE((
const CV
*)sv));
+ CvWEAKOUTSIDE_on(
MUTABLE_CV(sv)
);
+ SvREFCNT_dec(CvOUTSIDE(
MUTABLE_CV(sv)
));
}
return ix;
}
}
return ix;
}
@@
-531,6
+542,8
@@
Perl_pad_check_dup(pTHX_ const char *name, bool is_our, const HV *ourstash)
SV **svp;
PADOFFSET top, off;
SV **svp;
PADOFFSET top, off;
+ PERL_ARGS_ASSERT_PAD_CHECK_DUP;
+
ASSERT_CURPAD_ACTIVE("pad_check_dup");
if (AvFILLp(PL_comppad_name) < 0 || !ckWARN(WARN_MISC))
return; /* nothing to check */
ASSERT_CURPAD_ACTIVE("pad_check_dup");
if (AvFILLp(PL_comppad_name) < 0 || !ckWARN(WARN_MISC))
return; /* nothing to check */
@@
-552,7
+565,7
@@
Perl_pad_check_dup(pTHX_ const char *name, bool is_our, const HV *ourstash)
break; /* "our" masking "our" */
Perl_warner(aTHX_ packWARN(WARN_MISC),
"\"%s\" variable %s masks earlier declaration in same %s",
break; /* "our" masking "our" */
Perl_warner(aTHX_ packWARN(WARN_MISC),
"\"%s\" variable %s masks earlier declaration in same %s",
- (is_our ? "our" : PL_in_my == KEY_my ? "my" : "state"),
+ (is_our ? "our" : PL_
parser->
in_my == KEY_my ? "my" : "state"),
name,
(COP_SEQ_RANGE_HIGH(sv) == PAD_MAX ? "scope" : "statement"));
--off;
name,
(COP_SEQ_RANGE_HIGH(sv) == PAD_MAX ? "scope" : "statement"));
--off;
@@
-567,7
+580,7
@@
Perl_pad_check_dup(pTHX_ const char *name, bool is_our, const HV *ourstash)
&& sv != &PL_sv_undef
&& !SvFAKE(sv)
&& (COP_SEQ_RANGE_HIGH(sv) == PAD_MAX || COP_SEQ_RANGE_HIGH(sv) == 0)
&& sv != &PL_sv_undef
&& !SvFAKE(sv)
&& (COP_SEQ_RANGE_HIGH(sv) == PAD_MAX || COP_SEQ_RANGE_HIGH(sv) == 0)
- && OURSTASH(sv) == ourstash
+ &&
Sv
OURSTASH(sv) == ourstash
&& strEQ(name, SvPVX_const(sv)))
{
Perl_warner(aTHX_ packWARN(WARN_MISC),
&& strEQ(name, SvPVX_const(sv)))
{
Perl_warner(aTHX_ packWARN(WARN_MISC),
@@
-604,6
+617,8
@@
Perl_pad_findmy(pTHX_ const char *name)
const AV *nameav;
SV **name_svp;
const AV *nameav;
SV **name_svp;
+ PERL_ARGS_ASSERT_PAD_FINDMY;
+
pad_peg("pad_findmy");
offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
NULL, &out_sv, &out_flags);
pad_peg("pad_findmy");
offset = pad_findlex(name, PL_compcv, PL_cop_seqmax, 1,
NULL, &out_sv, &out_flags);
@@
-685,6
+700,8
@@
S_pad_findlex(pTHX_ const char *name, const CV* cv, U32 seq, int warn,
SV **new_capturep;
const AV * const padlist = CvPADLIST(cv);
SV **new_capturep;
const AV * const padlist = CvPADLIST(cv);
+ PERL_ARGS_ASSERT_PAD_FINDLEX;
+
*out_flags = 0;
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
*out_flags = 0;
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
@@
-770,6
+787,7
@@
S_pad_findlex(pTHX_ const char *name, const CV* cv, U32 seq, int warn,
else {
int newwarn = warn;
if (!CvCOMPILED(cv) && (*out_flags & PAD_FAKELEX_MULTI)
else {
int newwarn = warn;
if (!CvCOMPILED(cv) && (*out_flags & PAD_FAKELEX_MULTI)
+ && !SvPAD_STATE(name_svp[offset])
&& warn && ckWARN(WARN_CLOSURE)) {
newwarn = 0;
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
&& warn && ckWARN(WARN_CLOSURE)) {
newwarn = 0;
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
@@
-798,7
+816,9
@@
S_pad_findlex(pTHX_ const char *name, const CV* cv, U32 seq, int warn,
"Pad findlex cv=0x%"UVxf" found lex=0x%"UVxf"\n",
PTR2UV(cv), PTR2UV(*out_capture)));
"Pad findlex cv=0x%"UVxf" found lex=0x%"UVxf"\n",
PTR2UV(cv), PTR2UV(*out_capture)));
- if (SvPADSTALE(*out_capture)) {
+ if (SvPADSTALE(*out_capture)
+ && !SvPAD_STATE(name_svp[offset]))
+ {
if (ckWARN(WARN_CLOSURE))
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
"Variable \"%s\" is not available", name);
if (ckWARN(WARN_CLOSURE))
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
"Variable \"%s\" is not available", name);
@@
-853,9
+873,9
@@
S_pad_findlex(pTHX_ const char *name, const CV* cv, U32 seq, int warn,
SvPVX_const(*out_name_sv),
SvPAD_TYPED(*out_name_sv)
? SvSTASH(*out_name_sv) : NULL,
SvPVX_const(*out_name_sv),
SvPAD_TYPED(*out_name_sv)
? SvSTASH(*out_name_sv) : NULL,
- OURSTASH(*out_name_sv),
+
Sv
OURSTASH(*out_name_sv),
1, /* fake */
1, /* fake */
-
0 /* not a state variable
*/
+
SvPAD_STATE(*out_name_sv) ? 1 : 0 /* state variable ?
*/
);
new_namesv = AvARRAY(PL_comppad_name)[new_offset];
);
new_namesv = AvARRAY(PL_comppad_name)[new_offset];
@@
-928,6
+948,9
@@
void
Perl_pad_setsv(pTHX_ PADOFFSET po, SV* sv)
{
dVAR;
Perl_pad_setsv(pTHX_ PADOFFSET po, SV* sv)
{
dVAR;
+
+ PERL_ARGS_ASSERT_PAD_SETSV;
+
ASSERT_CURPAD_ACTIVE("pad_setsv");
DEBUG_X(PerlIO_printf(Perl_debug_log,
ASSERT_CURPAD_ACTIVE("pad_setsv");
DEBUG_X(PerlIO_printf(Perl_debug_log,
@@
-1043,7
+1066,7
@@
Perl_pad_leavemy(pTHX)
&& !SvFAKE(sv) && ckWARN_d(WARN_INTERNAL))
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
"%"SVf" never introduced",
&& !SvFAKE(sv) && ckWARN_d(WARN_INTERNAL))
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
"%"SVf" never introduced",
-
(void*)sv
);
+
SVfARG(sv)
);
}
}
/* "Deintroduce" my variables that are leaving with this scope. */
}
}
/* "Deintroduce" my variables that are leaving with this scope. */
@@
-1317,6
+1340,8
@@
Perl_do_dump_pad(pTHX_ I32 level, PerlIO *file, PADLIST *padlist, int full)
SV **ppad;
I32 ix;
SV **ppad;
I32 ix;
+ PERL_ARGS_ASSERT_DO_DUMP_PAD;
+
if (!padlist) {
return;
}
if (!padlist) {
return;
}
@@
-1386,6
+1411,8
@@
S_cv_dump(pTHX_ const CV *cv, const char *title)
const CV * const outside = CvOUTSIDE(cv);
AV* const padlist = CvPADLIST(cv);
const CV * const outside = CvOUTSIDE(cv);
AV* const padlist = CvPADLIST(cv);
+ PERL_ARGS_ASSERT_CV_DUMP;
+
PerlIO_printf(Perl_debug_log,
" %s: CV=0x%"UVxf" (%s), OUTSIDE=0x%"UVxf" (%s)\n",
title,
PerlIO_printf(Perl_debug_log,
" %s: CV=0x%"UVxf" (%s), OUTSIDE=0x%"UVxf" (%s)\n",
title,
@@
-1439,6
+1466,8
@@
Perl_cv_clone(pTHX_ CV *proto)
CV* outside;
long depth;
CV* outside;
long depth;
+ PERL_ARGS_ASSERT_CV_CLONE;
+
assert(!CvUNIQUE(proto));
/* Since cloneable anon subs can be nested, CvOUTSIDE may point
assert(!CvUNIQUE(proto));
/* Since cloneable anon subs can be nested, CvOUTSIDE may point
@@
-1457,8
+1486,7
@@
Perl_cv_clone(pTHX_ CV *proto)
ENTER;
SAVESPTR(PL_compcv);
ENTER;
SAVESPTR(PL_compcv);
- cv = PL_compcv = (CV*)newSV(0);
- sv_upgrade((SV *)cv, SvTYPE(proto));
+ cv = PL_compcv = MUTABLE_CV(newSV_type(SvTYPE(proto)));
CvFLAGS(cv) = CvFLAGS(proto) & ~(CVf_CLONE|CVf_WEAKOUTSIDE);
CvCLONED_on(cv);
CvFLAGS(cv) = CvFLAGS(proto) & ~(CVf_CLONE|CVf_WEAKOUTSIDE);
CvCLONED_on(cv);
@@
-1474,7
+1502,7
@@
Perl_cv_clone(pTHX_ CV *proto)
CvROOT(cv) = OpREFCNT_inc(CvROOT(proto));
OP_REFCNT_UNLOCK;
CvSTART(cv) = CvSTART(proto);
CvROOT(cv) = OpREFCNT_inc(CvROOT(proto));
OP_REFCNT_UNLOCK;
CvSTART(cv) = CvSTART(proto);
- CvOUTSIDE(cv) =
(CV*)SvREFCNT_inc_simple(outside
);
+ CvOUTSIDE(cv) =
MUTABLE_CV(SvREFCNT_inc_simple(outside)
);
CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(proto);
if (SvPOK(proto))
CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(proto);
if (SvPOK(proto))
@@
-1497,17
+1525,17
@@
Perl_cv_clone(pTHX_ CV *proto)
if (SvFAKE(namesv)) { /* lexical from outside? */
sv = outpad[PARENT_PAD_INDEX(namesv)];
assert(sv);
if (SvFAKE(namesv)) { /* lexical from outside? */
sv = outpad[PARENT_PAD_INDEX(namesv)];
assert(sv);
- /* formats may have an inactive parent */
- if (SvTYPE(proto) == SVt_PVFM && SvPADSTALE(sv)) {
+ /* formats may have an inactive parent,
+ while my $x if $false can leave an active var marked as
+ stale. And state vars are always available */
+ if (SvPADSTALE(sv) && !SvPAD_STATE(namesv)) {
if (ckWARN(WARN_CLOSURE))
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
"Variable \"%s\" is not available", SvPVX_const(namesv));
sv = NULL;
}
if (ckWARN(WARN_CLOSURE))
Perl_warner(aTHX_ packWARN(WARN_CLOSURE),
"Variable \"%s\" is not available", SvPVX_const(namesv));
sv = NULL;
}
- else {
- assert(!SvPADSTALE(sv));
+ else
SvREFCNT_inc_simple_void_NN(sv);
SvREFCNT_inc_simple_void_NN(sv);
- }
}
if (!sv) {
const char sigil = SvPVX_const(namesv)[0];
}
if (!sv) {
const char sigil = SvPVX_const(namesv)[0];
@@
-1520,6
+1548,9
@@
Perl_cv_clone(pTHX_ CV *proto)
else
sv = newSV(0);
SvPADMY_on(sv);
else
sv = newSV(0);
SvPADMY_on(sv);
+ /* reset the 'assign only once' flag on each state var */
+ if (SvPAD_STATE(namesv))
+ SvPADSTALE_on(sv);
}
}
else if (IS_PADGV(ppad[ix]) || IS_PADCONST(ppad[ix])) {
}
}
else if (IS_PADGV(ppad[ix]) || IS_PADCONST(ppad[ix])) {
@@
-1580,6
+1611,8
@@
Perl_pad_fixup_inner_anons(pTHX_ PADLIST *padlist, CV *old_cv, CV *new_cv)
AV * const comppad = (AV*)AvARRAY(padlist)[1];
SV ** const namepad = AvARRAY(comppad_name);
SV ** const curpad = AvARRAY(comppad);
AV * const comppad = (AV*)AvARRAY(padlist)[1];
SV ** const namepad = AvARRAY(comppad_name);
SV ** const curpad = AvARRAY(comppad);
+
+ PERL_ARGS_ASSERT_PAD_FIXUP_INNER_ANONS;
PERL_UNUSED_ARG(old_cv);
for (ix = AvFILLp(comppad_name); ix > 0; ix--) {
PERL_UNUSED_ARG(old_cv);
for (ix = AvFILLp(comppad_name); ix > 0; ix--) {
@@
-1587,7
+1620,7
@@
Perl_pad_fixup_inner_anons(pTHX_ PADLIST *padlist, CV *old_cv, CV *new_cv)
if (namesv && namesv != &PL_sv_undef
&& *SvPVX_const(namesv) == '&')
{
if (namesv && namesv != &PL_sv_undef
&& *SvPVX_const(namesv) == '&')
{
- CV * const innercv =
(CV*)curpad[ix]
;
+ CV * const innercv =
MUTABLE_CV(curpad[ix])
;
assert(CvWEAKOUTSIDE(innercv));
assert(CvOUTSIDE(innercv) == old_cv);
CvOUTSIDE(innercv) = new_cv;
assert(CvWEAKOUTSIDE(innercv));
assert(CvOUTSIDE(innercv) == old_cv);
CvOUTSIDE(innercv) = new_cv;
@@
-1610,6
+1643,9
@@
void
Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
{
dVAR;
Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
{
dVAR;
+
+ PERL_ARGS_ASSERT_PAD_PUSH;
+
if (depth > AvFILLp(padlist)) {
SV** const svp = AvARRAY(padlist);
AV* const newpad = newAV();
if (depth > AvFILLp(padlist)) {
SV** const svp = AvARRAY(padlist);
AV* const newpad = newAV();
@@
-1622,7
+1658,10
@@
Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
for ( ;ix > 0; ix--) {
if (names_fill >= ix && names[ix] != &PL_sv_undef) {
const char sigil = SvPVX_const(names[ix])[0];
for ( ;ix > 0; ix--) {
if (names_fill >= ix && names[ix] != &PL_sv_undef) {
const char sigil = SvPVX_const(names[ix])[0];
- if ((SvFLAGS(names[ix]) & SVf_FAKE) || sigil == '&') {
+ if ((SvFLAGS(names[ix]) & SVf_FAKE)
+ || (SvFLAGS(names[ix]) & SVpad_STATE)
+ || sigil == '&')
+ {
/* outer lexical or anon code */
av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
}
/* outer lexical or anon code */
av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
}