X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/128165928a7fa68e9b3adbdf3695141c97adb115..e050cc0e6db974512bccc84746c68ba4ed3e4079:/scope.c diff --git a/scope.c b/scope.c index c0f3428..35caf3f 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 + * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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,6 +267,9 @@ void Perl_save_gp(pTHX_ GV *gv, I32 empty) { dVAR; + + PERL_ARGS_ASSERT_SAVE_GP; + SSGROW(3); SSPUSHPTR(SvREFCNT_inc(gv)); SSPUSHPTR(GvGP(gv)); @@ -270,11 +279,19 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty) 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; } +#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 GvGP(gv) = gp; } else { @@ -290,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,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,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 */ @@ -343,6 +361,9 @@ void Perl_save_int(pTHX_ int *intp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_INT; + SSCHECK(3); SSPUSHINT(*intp); SSPUSHPTR(intp); @@ -353,6 +374,9 @@ void Perl_save_bool(pTHX_ bool *boolp) { dVAR; + + PERL_ARGS_ASSERT_SAVE_BOOL; + SSCHECK(3); SSPUSHBOOL(*boolp); SSPUSHPTR(boolp); @@ -360,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); @@ -376,6 +429,9 @@ void Perl_save_pptr(pTHX_ char **pptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_PPTR; + SSCHECK(3); SSPUSHPTR(*pptr); SSPUSHPTR(pptr); @@ -386,6 +442,9 @@ void Perl_save_vptr(pTHX_ void *ptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_VPTR; + SSCHECK(3); SSPUSHPTR(*(char**)ptr); SSPUSHPTR(ptr); @@ -396,6 +455,9 @@ void Perl_save_sptr(pTHX_ SV **sptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_SPTR; + SSCHECK(3); SSPUSHPTR(*sptr); SSPUSHPTR(sptr); @@ -403,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); @@ -428,6 +493,9 @@ void Perl_save_aptr(pTHX_ AV **aptr) { dVAR; + + PERL_ARGS_ASSERT_SAVE_APTR; + SSCHECK(3); SSPUSHPTR(*aptr); SSPUSHPTR(aptr); @@ -447,6 +515,9 @@ void Perl_save_mortalizesv(pTHX_ SV *sv) { dVAR; + + PERL_ARGS_ASSERT_SAVE_MORTALIZESV; + SSCHECK(2); SSPUSHPTR(sv); SSPUSHINT(SAVEt_MORTALIZESV); @@ -474,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)); @@ -485,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); @@ -493,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; @@ -507,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)); @@ -531,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); @@ -551,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); @@ -620,9 +715,6 @@ Perl_leave_scope(pTHX_ I32 base) av = (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; @@ -664,15 +756,7 @@ Perl_leave_scope(pTHX_ I32 base) av = (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)) { @@ -685,12 +769,7 @@ Perl_leave_scope(pTHX_ I32 base) hv = (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)) { @@ -709,7 +788,15 @@ 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; @@ -733,8 +820,9 @@ Perl_leave_scope(pTHX_ I32 base) 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: @@ -831,6 +919,10 @@ 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; i = SSPOPINT; @@ -878,8 +970,8 @@ Perl_leave_scope(pTHX_ I32 base) 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; @@ -913,12 +1005,18 @@ 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 = (SV*)SSPOPPTR; } break; case SAVEt_SAVESWITCHSTACK: @@ -980,7 +1078,7 @@ Perl_leave_scope(pTHX_ I32 base) if (!specialWARN(PL_compiling.cop_warnings)) PerlMemShared_free(PL_compiling.cop_warnings); - PL_compiling.cop_warnings = ptr; + PL_compiling.cop_warnings = (STRLEN*)ptr; break; case SAVEt_RE_STATE: { @@ -999,6 +1097,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"); } @@ -1009,6 +1111,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) { @@ -1026,16 +1131,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", @@ -1043,18 +1148,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)); @@ -1064,28 +1168,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: @@ -1096,7 +1196,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",