X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=scope.c;h=6e74978aeb6c5af81f9579c2721763a1bf24967f;hb=88e52f1cd82cd6da272e85a8b52d3a27cf1db31e;hp=ebea9e13e9124c793cd0063f9c6c7d8cea75f29e;hpb=72dc9ed5af65c946f73050becea29207a1af86c1;p=p5sagit%2Fp5-mst-13.2.git diff --git a/scope.c b/scope.c index ebea9e1..6e74978 100644 --- a/scope.c +++ b/scope.c @@ -1,7 +1,7 @@ /* scope.c * - * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + * 2001, 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. @@ -28,6 +28,9 @@ SV** Perl_stack_grow(pTHX_ SV **sp, SV **p, int n) { dVAR; + + PERL_ARGS_ASSERT_STACK_GROW; + PL_stack_sp = sp; #ifndef STRESS_REALLOC av_extend(PL_curstack, (p - PL_stack_base) + (n) + 128); @@ -165,11 +168,7 @@ S_save_scalar_at(pTHX_ SV **sptr) SV * const osv = *sptr; register SV * const sv = *sptr = newSV(0); -#ifdef PERL_MAD - /* FIXME for MAD - this is causing ext/Safe/t/safeops.t to abort. */ - if (PL_formfeed && sv == PL_formfeed) - abort(); -#endif + PERL_ARGS_ASSERT_SAVE_SCALAR_AT; if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) { if (SvGMAGICAL(osv)) { @@ -188,10 +187,9 @@ Perl_save_scalar(pTHX_ GV *gv) { dVAR; SV ** const sptr = &GvSVn(gv); -#ifdef PERL_MAD - if (PL_formfeed && *sptr == PL_formfeed) - abort(); -#endif + + PERL_ARGS_ASSERT_SAVE_SCALAR; + PL_localizing = 1; SvGETMAGIC(*sptr); PL_localizing = 0; @@ -208,10 +206,9 @@ void Perl_save_generic_svref(pTHX_ SV **sptr) { dVAR; -#ifdef PERL_MAD - if (PL_formfeed && *sptr == PL_formfeed) - abort(); -#endif + + PERL_ARGS_ASSERT_SAVE_GENERIC_SVREF; + SSCHECK(3); SSPUSHPTR(sptr); SSPUSHPTR(SvREFCNT_inc(*sptr)); @@ -225,6 +222,9 @@ void Perl_save_generic_pvref(pTHX_ char **str) { dVAR; + + PERL_ARGS_ASSERT_SAVE_GENERIC_PVREF; + SSCHECK(3); SSPUSHPTR(*str); SSPUSHPTR(str); @@ -238,6 +238,9 @@ void Perl_save_shared_pvref(pTHX_ char **str) { dVAR; + + PERL_ARGS_ASSERT_SAVE_SHARED_PVREF; + SSCHECK(3); SSPUSHPTR(str); SSPUSHPTR(*str); @@ -250,6 +253,9 @@ void Perl_save_set_svflags(pTHX_ SV* sv, U32 mask, U32 val) { dVAR; + + PERL_ARGS_ASSERT_SAVE_SET_SVFLAGS; + SSCHECK(4); SSPUSHPTR(sv); SSPUSHINT(mask); @@ -261,31 +267,32 @@ void Perl_save_gp(pTHX_ GV *gv, I32 empty) { dVAR; + + PERL_ARGS_ASSERT_SAVE_GP; + SSGROW(3); SSPUSHPTR(SvREFCNT_inc(gv)); SSPUSHPTR(GvGP(gv)); SSPUSHINT(SAVEt_GP); if (empty) { - register GP *gp; - - Newxz(gp, 1, GP); + GP *gp = Perl_newGP(aTHX_ gv); if (GvCVu(gv)) - PL_sub_generation++; /* taking a method out of circulation */ + mro_method_changed_in(GvSTASH(gv)); /* taking a method out of circulation ("local")*/ if (GvIOp(gv) && (IoFLAGS(GvIOp(gv)) & IOf_ARGV)) { gp->gp_io = newIO(); IoFLAGS(gp->gp_io) |= IOf_ARGV|IOf_START; } - GvGP(gv) = gp_ref(gp); -#ifndef PERL_DONT_CREATE_GVSV - GvSV(gv) = newSV(0); +#ifdef PERL_DONT_CREATE_GVSV + if (gv == PL_errgv) { + /* We could scatter this logic everywhere by changing the + definition of ERRSV from GvSV() to GvSVn(), but it seems more + efficient to do this check once here. */ + gp->gp_sv = newSV(0); + } #endif - GvLINE(gv) = CopLINE(PL_curcop); - /* XXX Ideally this cast would be replaced with a change to const char* - in the struct. */ - GvFILE(gv) = CopFILE(PL_curcop) ? CopFILE(PL_curcop) : (char *) ""; - GvEGV(gv) = gv; + GvGP(gv) = gp; } else { gp_ref(GvGP(gv)); @@ -300,6 +307,8 @@ Perl_save_ary(pTHX_ GV *gv) AV * const oav = GvAVn(gv); AV *av; + PERL_ARGS_ASSERT_SAVE_ARY; + if (!AvREAL(oav) && AvREIFY(oav)) av_reify(oav); SSCHECK(3); @@ -310,7 +319,7 @@ Perl_save_ary(pTHX_ GV *gv) GvAV(gv) = NULL; av = GvAVn(gv); if (SvMAGIC(oav)) - mg_localize((SV*)oav, (SV*)av); + mg_localize(MUTABLE_SV(oav), MUTABLE_SV(av)); return av; } @@ -320,6 +329,8 @@ Perl_save_hash(pTHX_ GV *gv) dVAR; HV *ohv, *hv; + PERL_ARGS_ASSERT_SAVE_HASH; + SSCHECK(3); SSPUSHPTR(gv); SSPUSHPTR(ohv = GvHVn(gv)); @@ -328,7 +339,7 @@ Perl_save_hash(pTHX_ GV *gv) GvHV(gv) = NULL; hv = GvHVn(gv); if (SvMAGIC(ohv)) - mg_localize((SV*)ohv, (SV*)hv); + mg_localize(MUTABLE_SV(ohv), MUTABLE_SV(hv)); return hv; } @@ -338,10 +349,7 @@ Perl_save_item(pTHX_ register SV *item) dVAR; register SV * const sv = newSVsv(item); -#ifdef PERL_MAD - if (PL_formfeed && item == PL_formfeed) - abort(); -#endif + PERL_ARGS_ASSERT_SAVE_ITEM; SSCHECK(3); SSPUSHPTR(item); /* remember the pointer */ @@ -353,6 +361,9 @@ void Perl_save_int(pTHX_ int *intp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_INT; + SSCHECK(3); SSPUSHINT(*intp); SSPUSHPTR(intp); @@ -363,6 +374,9 @@ void Perl_save_bool(pTHX_ bool *boolp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_BOOL; + SSCHECK(3); SSPUSHBOOL(*boolp); SSPUSHPTR(boolp); @@ -370,9 +384,38 @@ Perl_save_bool(pTHX_ bool *boolp) } void +Perl_save_I8(pTHX_ I8 *bytep) +{ + dVAR; + + PERL_ARGS_ASSERT_SAVE_I8; + + SSCHECK(3); + SSPUSHINT(*bytep); + SSPUSHPTR(bytep); + SSPUSHINT(SAVEt_I8); +} + +void +Perl_save_I16(pTHX_ I16 *intp) +{ + dVAR; + + PERL_ARGS_ASSERT_SAVE_I16; + + SSCHECK(3); + SSPUSHINT(*intp); + SSPUSHPTR(intp); + SSPUSHINT(SAVEt_I16); +} + +void Perl_save_I32(pTHX_ I32 *intp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_I32; + SSCHECK(3); SSPUSHINT(*intp); SSPUSHPTR(intp); @@ -386,6 +429,9 @@ void Perl_save_pptr(pTHX_ char **pptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_PPTR; + SSCHECK(3); SSPUSHPTR(*pptr); SSPUSHPTR(pptr); @@ -396,6 +442,9 @@ void Perl_save_vptr(pTHX_ void *ptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_VPTR; + SSCHECK(3); SSPUSHPTR(*(char**)ptr); SSPUSHPTR(ptr); @@ -406,6 +455,9 @@ void Perl_save_sptr(pTHX_ SV **sptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_SPTR; + SSCHECK(3); SSPUSHPTR(*sptr); SSPUSHPTR(sptr); @@ -413,21 +465,24 @@ Perl_save_sptr(pTHX_ SV **sptr) } void -Perl_save_padsv(pTHX_ PADOFFSET off) +Perl_save_padsv_and_mortalize(pTHX_ PADOFFSET off) { dVAR; SSCHECK(4); ASSERT_CURPAD_ACTIVE("save_padsv"); - SSPUSHPTR(PL_curpad[off]); + SSPUSHPTR(SvREFCNT_inc_simple_NN(PL_curpad[off])); SSPUSHPTR(PL_comppad); SSPUSHLONG((long)off); - SSPUSHINT(SAVEt_PADSV); + SSPUSHINT(SAVEt_PADSV_AND_MORTALIZE); } void Perl_save_hptr(pTHX_ HV **hptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_HPTR; + SSCHECK(3); SSPUSHPTR(*hptr); SSPUSHPTR(hptr); @@ -438,6 +493,9 @@ void Perl_save_aptr(pTHX_ AV **aptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_APTR; + SSCHECK(3); SSPUSHPTR(*aptr); SSPUSHPTR(aptr); @@ -457,6 +515,9 @@ void Perl_save_mortalizesv(pTHX_ SV *sv) { dVAR; + + PERL_ARGS_ASSERT_SAVE_MORTALIZESV; + SSCHECK(2); SSPUSHPTR(sv); SSPUSHINT(SAVEt_MORTALIZESV); @@ -484,6 +545,9 @@ void Perl_save_clearsv(pTHX_ SV **svp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_CLEARSV; + ASSERT_CURPAD_ACTIVE("save_clearsv"); SSCHECK(2); SSPUSHLONG((long)(svp-PL_curpad)); @@ -495,6 +559,9 @@ void Perl_save_delete(pTHX_ HV *hv, char *key, I32 klen) { dVAR; + + PERL_ARGS_ASSERT_SAVE_DELETE; + SSCHECK(4); SSPUSHINT(klen); SSPUSHPTR(key); @@ -503,6 +570,19 @@ Perl_save_delete(pTHX_ HV *hv, char *key, I32 klen) } void +Perl_save_destructor(pTHX_ DESTRUCTORFUNC_NOCONTEXT_t f, void* p) +{ + dVAR; + + PERL_ARGS_ASSERT_SAVE_DESTRUCTOR; + + SSCHECK(3); + SSPUSHDPTR(f); + SSPUSHPTR(p); + SSPUSHINT(SAVEt_DESTRUCTOR); +} + +void Perl_save_destructor_x(pTHX_ DESTRUCTORFUNC_t f, void* p) { dVAR; @@ -517,6 +597,9 @@ Perl_save_aelem(pTHX_ AV *av, I32 idx, SV **sptr) { dVAR; SV *sv; + + PERL_ARGS_ASSERT_SAVE_AELEM; + SvGETMAGIC(*sptr); SSCHECK(4); SSPUSHPTR(SvREFCNT_inc_simple(av)); @@ -541,10 +624,13 @@ Perl_save_helem(pTHX_ HV *hv, SV *key, SV **sptr) { dVAR; SV *sv; + + PERL_ARGS_ASSERT_SAVE_HELEM; + SvGETMAGIC(*sptr); SSCHECK(4); SSPUSHPTR(SvREFCNT_inc_simple(hv)); - SSPUSHPTR(SvREFCNT_inc_simple(key)); + SSPUSHPTR(newSVsv(key)); SSPUSHPTR(SvREFCNT_inc(*sptr)); SSPUSHINT(SAVEt_HELEM); save_scalar_at(sptr); @@ -561,10 +647,9 @@ SV* Perl_save_svref(pTHX_ SV **sptr) { dVAR; -#ifdef PERL_MAD - if (PL_formfeed && *sptr == PL_formfeed) - abort(); -#endif + + PERL_ARGS_ASSERT_SAVE_SVREF; + SvGETMAGIC(*sptr); SSCHECK(3); SSPUSHPTR(sptr); @@ -616,23 +701,20 @@ Perl_leave_scope(pTHX_ I32 base) while (PL_savestack_ix > base) { switch (SSPOPINT) { case SAVEt_ITEM: /* normal string */ - value = (SV*)SSPOPPTR; - sv = (SV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); + sv = MUTABLE_SV(SSPOPPTR); sv_replace(sv,value); PL_localizing = 2; SvSETMAGIC(sv); PL_localizing = 0; break; case SAVEt_SV: /* scalar reference */ - value = (SV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); gv = (GV*)SSPOPPTR; ptr = &GvSV(gv); - av = (AV*)gv; /* what to refcnt_dec */ + av = MUTABLE_AV(gv); /* what to refcnt_dec */ restore_sv: sv = *(SV**)ptr; - DEBUG_S(PerlIO_printf(Perl_debug_log, - "restore svref: %p %p:%s -> %p:%s\n", - ptr, sv, SvPEEK(sv), value, SvPEEK(value))); *(SV**)ptr = value; SvREFCNT_dec(sv); PL_localizing = 2; @@ -663,7 +745,7 @@ Perl_leave_scope(pTHX_ I32 base) } break; case SAVEt_GENERIC_SVREF: /* generic sv */ - value = (SV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); ptr = SSPOPPTR; sv = *(SV**)ptr; *(SV**)ptr = value; @@ -671,41 +753,28 @@ Perl_leave_scope(pTHX_ I32 base) SvREFCNT_dec(value); break; case SAVEt_AV: /* array reference */ - av = (AV*)SSPOPPTR; + av = MUTABLE_AV(SSPOPPTR); gv = (GV*)SSPOPPTR; if (GvAV(gv)) { - AV * const goner = GvAV(gv); - /* FIXME - this is a temporary hack until we work out what - the correct behaviour for magic should be. */ - sv_unmagic((SV*)goner, PERL_MAGIC_arylen_p); - SvMAGIC_set(av, SvMAGIC(goner)); - SvFLAGS((SV*)av) |= SvMAGICAL(goner); - SvMAGICAL_off(goner); - SvMAGIC_set(goner, NULL); - SvREFCNT_dec(goner); + SvREFCNT_dec(GvAV(gv)); } GvAV(gv) = av; if (SvMAGICAL(av)) { PL_localizing = 2; - SvSETMAGIC((SV*)av); + SvSETMAGIC(MUTABLE_SV(av)); PL_localizing = 0; } break; case SAVEt_HV: /* hash reference */ - hv = (HV*)SSPOPPTR; + hv = MUTABLE_HV(SSPOPPTR); gv = (GV*)SSPOPPTR; if (GvHV(gv)) { - HV * const goner = GvHV(gv); - SvMAGIC_set(hv, SvMAGIC(goner)); - SvFLAGS(hv) |= SvMAGICAL(goner); - SvMAGICAL_off(goner); - SvMAGIC_set(goner, NULL); - SvREFCNT_dec(goner); + SvREFCNT_dec(GvHV(gv)); } GvHV(gv) = hv; if (SvMAGICAL(hv)) { PL_localizing = 2; - SvSETMAGIC((SV*)hv); + SvSETMAGIC(MUTABLE_SV(hv)); PL_localizing = 0; } break; @@ -719,11 +788,19 @@ Perl_leave_scope(pTHX_ I32 base) break; case SAVEt_I32: /* I32 reference */ ptr = SSPOPPTR; +#ifdef PERL_DEBUG_READONLY_OPS + { + const I32 val = SSPOPINT; + if (*(I32*)ptr != val) + *(I32*)ptr = val; + } +#else *(I32*)ptr = (I32)SSPOPINT; +#endif break; case SAVEt_SPTR: /* SV* reference */ ptr = SSPOPPTR; - *(SV**)ptr = (SV*)SSPOPPTR; + *(SV**)ptr = MUTABLE_SV(SSPOPPTR); break; case SAVEt_VPTR: /* random* reference */ case SAVEt_PPTR: /* char* reference */ @@ -732,28 +809,29 @@ Perl_leave_scope(pTHX_ I32 base) break; case SAVEt_HPTR: /* HV* reference */ ptr = SSPOPPTR; - *(HV**)ptr = (HV*)SSPOPPTR; + *(HV**)ptr = MUTABLE_HV(SSPOPPTR); break; case SAVEt_APTR: /* AV* reference */ ptr = SSPOPPTR; - *(AV**)ptr = (AV*)SSPOPPTR; + *(AV**)ptr = MUTABLE_AV(SSPOPPTR); break; case SAVEt_GP: /* scalar reference */ ptr = SSPOPPTR; gv = (GV*)SSPOPPTR; gp_free(gv); GvGP(gv) = (GP*)ptr; - if (GvCVu(gv)) - PL_sub_generation++; /* putting a method back into circulation */ + /* putting a method back into circulation ("local")*/ + if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvNAME_get(hv)) + mro_method_changed_in(hv); SvREFCNT_dec(gv); break; case SAVEt_FREESV: ptr = SSPOPPTR; - SvREFCNT_dec((SV*)ptr); + SvREFCNT_dec(MUTABLE_SV(ptr)); break; case SAVEt_MORTALIZESV: ptr = SSPOPPTR; - sv_2mortal((SV*)ptr); + sv_2mortal(MUTABLE_SV(ptr)); break; case SAVEt_FREEOP: ptr = SSPOPPTR; @@ -764,10 +842,6 @@ Perl_leave_scope(pTHX_ I32 base) ptr = SSPOPPTR; Safefree(ptr); break; - case SAVEt_FREESHAREDPV: - ptr = SSPOPPTR; - PerlMemShared_free(ptr); - break; case SAVEt_CLEARSV: ptr = (void*)&PL_curpad[SSPOPLONG]; sv = *(SV**)ptr; @@ -798,10 +872,10 @@ Perl_leave_scope(pTHX_ I32 base) case SVt_NULL: break; case SVt_PVAV: - av_clear((AV*)sv); + av_clear(MUTABLE_AV(sv)); break; case SVt_PVHV: - hv_clear((HV*)sv); + hv_clear(MUTABLE_HV(sv)); break; case SVt_PVCV: Perl_croak(aTHX_ "panic: leave_scope pad code"); @@ -814,8 +888,8 @@ Perl_leave_scope(pTHX_ I32 base) else { /* Someone has a claim on this, so abandon it. */ const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP); switch (SvTYPE(sv)) { /* Console ourselves with a new value */ - case SVt_PVAV: *(SV**)ptr = (SV*)newAV(); break; - case SVt_PVHV: *(SV**)ptr = (SV*)newHV(); break; + case SVt_PVAV: *(SV**)ptr = MUTABLE_SV(newAV()); break; + case SVt_PVHV: *(SV**)ptr = MUTABLE_SV(newHV()); break; default: *(SV**)ptr = newSV(0); break; } SvREFCNT_dec(sv); /* Cast current value to the winds. */ @@ -826,7 +900,7 @@ Perl_leave_scope(pTHX_ I32 base) break; case SAVEt_DELETE: ptr = SSPOPPTR; - hv = (HV*)ptr; + hv = MUTABLE_HV(ptr); ptr = SSPOPPTR; (void)hv_delete(hv, (char*)ptr, (I32)SSPOPINT, G_DISCARD); SvREFCNT_dec(hv); @@ -845,17 +919,21 @@ Perl_leave_scope(pTHX_ I32 base) i = SSPOPINT; PL_stack_sp = PL_stack_base + i; break; + case SAVEt_STACK_CXPOS: /* blk_oldsp on context stack */ + i = SSPOPINT; + cxstack[i].blk_oldsp = SSPOPINT; + break; case SAVEt_AELEM: /* array element */ - value = (SV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); i = SSPOPINT; - av = (AV*)SSPOPPTR; + av = MUTABLE_AV(SSPOPPTR); + ptr = av_fetch(av,i,1); if (!AvREAL(av) && AvREIFY(av)) /* undo reify guard */ SvREFCNT_dec(value); - ptr = av_fetch(av,i,1); if (ptr) { sv = *(SV**)ptr; if (sv && sv != &PL_sv_undef) { - if (SvTIED_mg((SV*)av, PERL_MAGIC_tied)) + if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied)) SvREFCNT_inc_void_NN(sv); goto restore_sv; } @@ -864,18 +942,18 @@ Perl_leave_scope(pTHX_ I32 base) SvREFCNT_dec(value); break; case SAVEt_HELEM: /* hash element */ - value = (SV*)SSPOPPTR; - sv = (SV*)SSPOPPTR; - hv = (HV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); + sv = MUTABLE_SV(SSPOPPTR); + hv = MUTABLE_HV(SSPOPPTR); ptr = hv_fetch_ent(hv, sv, 1, 0); if (ptr) { const SV * const oval = HeVAL((HE*)ptr); if (oval && oval != &PL_sv_undef) { ptr = &HeVAL((HE*)ptr); - if (SvTIED_mg((SV*)hv, PERL_MAGIC_tied)) + if (SvTIED_mg((const SV *)hv, PERL_MAGIC_tied)) SvREFCNT_inc_void(*(SV**)ptr); SvREFCNT_dec(sv); - av = (AV*)hv; /* what to refcnt_dec */ + av = MUTABLE_AV(hv); /* what to refcnt_dec */ goto restore_sv; } } @@ -888,15 +966,15 @@ Perl_leave_scope(pTHX_ I32 base) break; case SAVEt_HINTS: if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) { - SvREFCNT_dec((SV*)GvHV(PL_hintgv)); + SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv))); GvHV(PL_hintgv) = NULL; } *(I32*)&PL_hints = (I32)SSPOPINT; - Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints); - PL_compiling.cop_hints = (struct refcounted_he *) SSPOPPTR; + Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash); + PL_compiling.cop_hints_hash = (struct refcounted_he *) SSPOPPTR; if (PL_hints & HINT_LOCALIZE_HH) { - SvREFCNT_dec((SV*)GvHV(PL_hintgv)); - GvHV(PL_hintgv) = (HV*)SSPOPPTR; + SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv))); + GvHV(PL_hintgv) = MUTABLE_HV(SSPOPPTR); assert(GvHV(PL_hintgv)); } else if (!GvHV(PL_hintgv)) { /* Need to add a new one manually, else gv_fetchpv() can @@ -927,19 +1005,25 @@ Perl_leave_scope(pTHX_ I32 base) else PL_curpad = NULL; break; - case SAVEt_PADSV: + case SAVEt_PADSV_AND_MORTALIZE: { const PADOFFSET off = (PADOFFSET)SSPOPLONG; + SV **svp; ptr = SSPOPPTR; - if (ptr) - AvARRAY((PAD*)ptr)[off] = (SV*)SSPOPPTR; + assert (ptr); + svp = AvARRAY((PAD*)ptr) + off; + /* This mortalizing used to be done by POPLOOP() via itersave. + But as we have all the information here, we can do it here, + save even having to have itersave in the struct. */ + sv_2mortal(*svp); + *svp = MUTABLE_SV(SSPOPPTR); } break; case SAVEt_SAVESWITCHSTACK: { dSP; - AV* const t = (AV*)SSPOPPTR; - AV* const f = (AV*)SSPOPPTR; + AV *const t = MUTABLE_AV(SSPOPPTR); + AV *const f = MUTABLE_AV(SSPOPPTR); SWITCHSTACK(t,f); PL_curstackinfo->si_stack = f; } @@ -948,21 +1032,34 @@ Perl_leave_scope(pTHX_ I32 base) { const U32 val = (U32)SSPOPINT; const U32 mask = (U32)SSPOPINT; - sv = (SV*)SSPOPPTR; + sv = MUTABLE_SV(SSPOPPTR); SvFLAGS(sv) &= ~mask; SvFLAGS(sv) |= val; } break; - /* These are only saved in mathoms.c */ + + /* This would be a mathom, but Perl_save_svref() calls a static + function, S_save_scalar_at(), so has to stay in this file. */ case SAVEt_SVREF: /* scalar reference */ - value = (SV*)SSPOPPTR; + value = MUTABLE_SV(SSPOPPTR); ptr = SSPOPPTR; av = NULL; /* what to refcnt_dec */ goto restore_sv; + + /* These are only saved in mathoms.c */ + case SAVEt_NSTAB: + gv = (GV*)SSPOPPTR; + (void)sv_clear(MUTABLE_SV(gv)); + break; case SAVEt_LONG: /* long reference */ ptr = SSPOPPTR; *(long*)ptr = (long)SSPOPLONG; break; + case SAVEt_IV: /* IV reference */ + ptr = SSPOPPTR; + *(IV*)ptr = (IV)SSPOPIV; + break; + case SAVEt_I16: /* I16 reference */ ptr = SSPOPPTR; *(I16*)ptr = (I16)SSPOPINT; @@ -971,14 +1068,6 @@ Perl_leave_scope(pTHX_ I32 base) ptr = SSPOPPTR; *(I8*)ptr = (I8)SSPOPINT; break; - case SAVEt_IV: /* IV reference */ - ptr = SSPOPPTR; - *(IV*)ptr = (IV)SSPOPIV; - break; - case SAVEt_NSTAB: - gv = (GV*)SSPOPPTR; - (void)sv_clear((SV*)gv); - break; case SAVEt_DESTRUCTOR: ptr = SSPOPPTR; (*SSPOPDPTR)(ptr); @@ -988,16 +1077,13 @@ Perl_leave_scope(pTHX_ I32 base) i = SSPOPINT; CopARYBASE_set((COP *)ptr, i); break; - case SAVEt_COP_WARNINGS: - { - COP *const cop = SSPOPPTR; - ptr = SSPOPPTR; + case SAVEt_COMPILE_WARNINGS: + ptr = SSPOPPTR; - if (!specialWARN(cop->cop_warnings)) - PerlMemShared_free(cop->cop_warnings); + if (!specialWARN(PL_compiling.cop_warnings)) + PerlMemShared_free(PL_compiling.cop_warnings); - cop->cop_warnings = ptr; - } + PL_compiling.cop_warnings = (STRLEN*)ptr; break; case SAVEt_RE_STATE: { @@ -1016,6 +1102,10 @@ Perl_leave_scope(pTHX_ I32 base) Copy(state, &PL_reg_state, 1, struct re_save_state); } break; + case SAVEt_PARSER: + ptr = SSPOPPTR; + parser_free((yy_parser *) ptr); + break; default: Perl_croak(aTHX_ "panic: leave_scope inconsistency"); } @@ -1026,6 +1116,9 @@ void Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) { dVAR; + + PERL_ARGS_ASSERT_CX_DUMP; + #ifdef DEBUGGING PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), PL_block_type[CxTYPE(cx)]); if (CxTYPE(cx) != CXt_SUBST) { @@ -1043,16 +1136,16 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) case CXt_BLOCK: break; case CXt_FORMAT: - PerlIO_printf(Perl_debug_log, "BLK_SUB.CV = 0x%"UVxf"\n", - PTR2UV(cx->blk_sub.cv)); - PerlIO_printf(Perl_debug_log, "BLK_SUB.GV = 0x%"UVxf"\n", - PTR2UV(cx->blk_sub.gv)); - PerlIO_printf(Perl_debug_log, "BLK_SUB.DFOUTGV = 0x%"UVxf"\n", - PTR2UV(cx->blk_sub.dfoutgv)); - PerlIO_printf(Perl_debug_log, "BLK_SUB.HASARGS = %d\n", - (int)cx->blk_sub.hasargs); - PerlIO_printf(Perl_debug_log, "BLK_SUB.RETOP = 0x%"UVxf"\n", - PTR2UV(cx->blk_sub.retop)); + PerlIO_printf(Perl_debug_log, "BLK_FORMAT.CV = 0x%"UVxf"\n", + PTR2UV(cx->blk_format.cv)); + PerlIO_printf(Perl_debug_log, "BLK_FORMAT.GV = 0x%"UVxf"\n", + PTR2UV(cx->blk_format.gv)); + PerlIO_printf(Perl_debug_log, "BLK_FORMAT.DFOUTGV = 0x%"UVxf"\n", + PTR2UV(cx->blk_format.dfoutgv)); + PerlIO_printf(Perl_debug_log, "BLK_FORMAT.HASARGS = %d\n", + (int)CxHASARGS(cx)); + PerlIO_printf(Perl_debug_log, "BLK_FORMAT.RETOP = 0x%"UVxf"\n", + PTR2UV(cx->blk_format.retop)); break; case CXt_SUB: PerlIO_printf(Perl_debug_log, "BLK_SUB.CV = 0x%"UVxf"\n", @@ -1060,18 +1153,17 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) PerlIO_printf(Perl_debug_log, "BLK_SUB.OLDDEPTH = %ld\n", (long)cx->blk_sub.olddepth); PerlIO_printf(Perl_debug_log, "BLK_SUB.HASARGS = %d\n", - (int)cx->blk_sub.hasargs); - PerlIO_printf(Perl_debug_log, "BLK_SUB.LVAL = %d\n", - (int)cx->blk_sub.lval); + (int)CxHASARGS(cx)); + PerlIO_printf(Perl_debug_log, "BLK_SUB.LVAL = %d\n", (int)CxLVAL(cx)); PerlIO_printf(Perl_debug_log, "BLK_SUB.RETOP = 0x%"UVxf"\n", PTR2UV(cx->blk_sub.retop)); break; case CXt_EVAL: PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_IN_EVAL = %ld\n", - (long)cx->blk_eval.old_in_eval); + (long)CxOLD_IN_EVAL(cx)); PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_OP_TYPE = %s (%s)\n", - PL_op_name[cx->blk_eval.old_op_type], - PL_op_desc[cx->blk_eval.old_op_type]); + PL_op_name[CxOLD_OP_TYPE(cx)], + PL_op_desc[CxOLD_OP_TYPE(cx)]); if (cx->blk_eval.old_namesv) PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n", SvPVX_const(cx->blk_eval.old_namesv)); @@ -1081,28 +1173,24 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) PTR2UV(cx->blk_eval.retop)); break; - case CXt_LOOP: - PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", - cx->blk_loop.label); + case CXt_LOOP_LAZYIV: + case CXt_LOOP_LAZYSV: + case CXt_LOOP_FOR: + case CXt_LOOP_PLAIN: + PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", CxLABEL(cx)); PerlIO_printf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n", (long)cx->blk_loop.resetsp); - PerlIO_printf(Perl_debug_log, "BLK_LOOP.REDO_OP = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.redo_op)); + PerlIO_printf(Perl_debug_log, "BLK_LOOP.MY_OP = 0x%"UVxf"\n", + PTR2UV(cx->blk_loop.my_op)); PerlIO_printf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.next_op)); - PerlIO_printf(Perl_debug_log, "BLK_LOOP.LAST_OP = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.last_op)); - PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n", - (long)cx->blk_loop.iterix); + PTR2UV(CX_LOOP_NEXTOP_GET(cx))); + /* XXX: not accurate for LAZYSV/IV */ PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.iterary)); + PTR2UV(cx->blk_loop.state_u.ary.ary)); + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n", + (long)cx->blk_loop.state_u.ary.ix); PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERVAR = 0x%"UVxf"\n", PTR2UV(CxITERVAR(cx))); - if (CxITERVAR(cx)) - PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.itersave)); - PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERLVAL = 0x%"UVxf"\n", - PTR2UV(cx->blk_loop.iterlval)); break; case CXt_SUBST: @@ -1113,7 +1201,7 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) PerlIO_printf(Perl_debug_log, "SB_RFLAGS = %ld\n", (long)cx->sb_rflags); PerlIO_printf(Perl_debug_log, "SB_ONCE = %ld\n", - (long)cx->sb_once); + (long)CxONCE(cx)); PerlIO_printf(Perl_debug_log, "SB_ORIG = %s\n", cx->sb_orig); PerlIO_printf(Perl_debug_log, "SB_DSTR = 0x%"UVxf"\n",