summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dump.c6
-rw-r--r--pad.c2
-rw-r--r--pp_ctl.c10
-rw-r--r--scope.c5
-rw-r--r--sv.c6
-rw-r--r--sv.h48
6 files changed, 47 insertions, 30 deletions
diff --git a/dump.c b/dump.c
index 9990c8de87..3281031213 100644
--- a/dump.c
+++ b/dump.c
@@ -1527,10 +1527,12 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
if (!((flags & SVpad_NAME) == SVpad_NAME
&& (type == SVt_PVMG || type == SVt_PVNV))) {
- if (flags & SVs_PADSTALE) sv_catpv(d, "PADSTALE,");
+ if ((flags & SVs_PADMY) && (flags & SVs_PADSTALE))
+ sv_catpv(d, "PADSTALE,");
}
if (!((flags & SVpad_NAME) == SVpad_NAME && type == SVt_PVMG)) {
- if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,");
+ if (!(flags & SVs_PADMY) && (flags & SVs_PADTMP))
+ sv_catpv(d, "PADTMP,");
if (flags & SVs_PADMY) sv_catpv(d, "PADMY,");
}
append_flags(d, flags, first_sv_flags_names);
diff --git a/pad.c b/pad.c
index 763e01bb63..c767b550c1 100644
--- a/pad.c
+++ b/pad.c
@@ -1720,7 +1720,7 @@ Perl_pad_free(pTHX_ PADOFFSET po)
);
if (PL_curpad[po] && PL_curpad[po] != &PL_sv_undef) {
- SvPADTMP_off(PL_curpad[po]);
+ SvFLAGS(PL_curpad[po]) &= ~SVs_PADTMP; /* also clears SVs_PADSTALE */
}
if ((I32)po < PL_padix)
PL_padix = po - 1;
diff --git a/pp_ctl.c b/pp_ctl.c
index 692fdebd0d..24067618e3 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2082,11 +2082,17 @@ PP(pp_dbstate)
STATIC SV **
S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 flags)
{
+ bool padtmp = 0;
PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE;
+ if (flags & SVs_PADTMP) {
+ flags &= ~SVs_PADTMP;
+ padtmp = 1;
+ }
if (gimme == G_SCALAR) {
if (MARK < SP)
- *++newsp = (SvFLAGS(*SP) & flags) ? *SP : sv_mortalcopy(*SP);
+ *++newsp = ((SvFLAGS(*SP) & flags) || (padtmp && SvPADTMP(*SP)))
+ ? *SP : sv_mortalcopy(*SP);
else {
/* MEXTEND() only updates MARK, so reuse it instead of newsp. */
MARK = newsp;
@@ -2098,7 +2104,7 @@ S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 fla
else if (gimme == G_ARRAY) {
/* in case LEAVE wipes old return values */
while (++MARK <= SP) {
- if (SvFLAGS(*MARK) & flags)
+ if ((SvFLAGS(*MARK) & flags) || (padtmp && SvPADTMP(*MARK)))
*++newsp = *MARK;
else {
*++newsp = sv_mortalcopy(*MARK);
diff --git a/scope.c b/scope.c
index 9ed6475d6c..14664a26c5 100644
--- a/scope.c
+++ b/scope.c
@@ -922,7 +922,8 @@ Perl_leave_scope(pTHX_ I32 base)
SvPADSTALE_on(sv); /* mark as no longer live */
}
else { /* Someone has a claim on this, so abandon it. */
- const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
+ assert( SvFLAGS(sv) & SVs_PADMY);
+ assert(!(SvFLAGS(sv) & SVs_PADTMP));
switch (SvTYPE(sv)) { /* Console ourselves with a new value */
case SVt_PVAV: *(SV**)ptr = MUTABLE_SV(newAV()); break;
case SVt_PVHV: *(SV**)ptr = MUTABLE_SV(newHV()); break;
@@ -931,7 +932,7 @@ Perl_leave_scope(pTHX_ I32 base)
SvREFCNT_dec(sv); /* Cast current value to the winds. */
/* preserve pad nature, but also mark as not live
* for any closure capturing */
- SvFLAGS(*(SV**)ptr) |= padflags | SVs_PADSTALE;
+ SvFLAGS(*(SV**)ptr) |= (SVs_PADMY|SVs_PADSTALE);
}
break;
case SAVEt_DELETE:
diff --git a/sv.c b/sv.c
index 3360bf4f1b..e92ed2b525 100644
--- a/sv.c
+++ b/sv.c
@@ -2228,7 +2228,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
if (isGV_with_GP(sv))
return glob_2number(MUTABLE_GV(sv));
- if (!(SvFLAGS(sv) & SVs_PADTMP)) {
+ if (!SvPADTMP(sv)) {
if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
}
@@ -2613,7 +2613,7 @@ Perl_sv_2nv_flags(pTHX_ register SV *const sv, const I32 flags)
return 0.0;
}
- if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
+ if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
assert (SvTYPE(sv) >= SVt_NV);
/* Typically the caller expects that sv_any is not NULL now. */
@@ -2975,7 +2975,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags
*lp = 0;
if (flags & SV_UNDEF_RETURNS_NULL)
return NULL;
- if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
+ if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
if (SvTYPE(sv) < SVt_PV)
/* Typically the caller expects that sv_any is not NULL now. */
diff --git a/sv.h b/sv.h
index bbf41c84f6..5324256d24 100644
--- a/sv.h
+++ b/sv.h
@@ -310,9 +310,10 @@ perform the upgrade if necessary. See C<svtype>.
CvIMPORTED_CV_ON() if it needs to be
expanded to a real GV */
-#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */
#define SVpad_STATE 0x00010000 /* pad name is a "state" var */
-#define SVs_PADTMP 0x00020000 /* in use as tmp */
+#define SVs_PADTMP 0x00020000 /* in use as tmp; only if ! SVs_PADMY */
+#define SVs_PADSTALE 0x00020000 /* lexical has gone out of scope;
+ only valid for SVs_PADMY */
#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */
#define SVs_PADMY 0x00040000 /* in use a "my" variable */
#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */
@@ -909,34 +910,41 @@ the scalar's value cannot change unless written to.
#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST)
-#define SvPADSTALE(sv) (SvFLAGS(sv) & SVs_PADSTALE)
-#define SvPADSTALE_off(sv) (SvFLAGS(sv) &= ~SVs_PADSTALE)
+#define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY)
+#define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY)
-#define SvPADTMP(sv) (SvFLAGS(sv) & SVs_PADTMP)
-#define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP)
+/* SVs_PADTMP and SVs_PADSTALE share the same bit, mediated by SVs_PADMY */
-#define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY)
+#define SvPADTMP(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP)) == SVs_PADTMP)
+#define SvPADSTALE(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADSTALE)) \
+ == (SVs_PADMY|SVs_PADSTALE))
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-# define SvPADTMP_on(sv) ({ \
- SV *const _svpad = MUTABLE_SV(sv); \
- assert(!(SvFLAGS(_svpad) & (SVs_PADMY|SVs_PADSTALE))); \
- (SvFLAGS(_svpad) |= SVs_PADTMP); \
+# define SvPADTMP_on(sv) ({ \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(!(SvFLAGS(_svpad) & SVs_PADMY)); \
+ SvFLAGS(_svpad) |= SVs_PADTMP; \
})
-# define SvPADMY_on(sv) ({ \
- SV *const _svpad = MUTABLE_SV(sv); \
- assert(!(SvFLAGS(_svpad) & SVs_PADTMP)); \
- (SvFLAGS(_svpad) |= SVs_PADMY); \
+# define SvPADTMP_off(sv) ({ \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(!(SvFLAGS(_svpad) & SVs_PADMY)); \
+ SvFLAGS(_svpad) &= ~SVs_PADTMP; \
})
-# define SvPADSTALE_on(sv) ({ \
- SV *const _svpad = MUTABLE_SV(sv); \
- assert(!(SvFLAGS(_svpad) & SVs_PADTMP)); \
- (SvFLAGS(_svpad) |= SVs_PADSTALE); \
+# define SvPADSTALE_on(sv) ({ \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(SvFLAGS(_svpad) & SVs_PADMY); \
+ SvFLAGS(_svpad) |= SVs_PADSTALE; \
+ })
+# define SvPADSTALE_off(sv) ({ \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(SvFLAGS(_svpad) & SVs_PADMY); \
+ SvFLAGS(_svpad) &= ~SVs_PADSTALE; \
})
#else
# define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP)
-# define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY)
+# define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP)
# define SvPADSTALE_on(sv) (SvFLAGS(sv) |= SVs_PADSTALE)
+# define SvPADSTALE_off(sv) (SvFLAGS(sv) &= ~SVs_PADSTALE)
#endif
#define SvTEMP(sv) (SvFLAGS(sv) & SVs_TEMP)