diff options
-rw-r--r-- | dump.c | 6 | ||||
-rw-r--r-- | pad.c | 2 | ||||
-rw-r--r-- | pp_ctl.c | 10 | ||||
-rw-r--r-- | scope.c | 5 | ||||
-rw-r--r-- | sv.c | 6 | ||||
-rw-r--r-- | sv.h | 48 |
6 files changed, 47 insertions, 30 deletions
@@ -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); @@ -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; @@ -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); @@ -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: @@ -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. */ @@ -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) |