X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=cop.h;h=13ce794ce20097285391d40e261154483bd2502d;hb=0100440d3c83cbbd0295cecf65f71318c7bebf25;hp=8cfc88df8100b680ae30f777ccb5b4cd84a3a0cd;hpb=6b75f04219345928d4af5de9535cb69db219287f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/cop.h b/cop.h index 8cfc88d..13ce794 100644 --- a/cop.h +++ b/cop.h @@ -1,13 +1,13 @@ /* cop.h * - * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 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, 2009 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. * - * Control ops (cops) are one of the three ops OP_NEXTSTATE, OP_DBSTATE, - * and OP_SETSTATE that (loosely speaking) are separate statements. + * Control ops (cops) are one of the two ops OP_NEXTSTATE and OP_DBSTATE, + * that (loosely speaking) are separate statements. * They hold information important for lexical state and error reporting. * At run time, PL_curcop is set to point to the most recently executed cop, * and thus can be used to determine our current state. @@ -99,8 +99,9 @@ typedef struct jmpenv JMPENV; #define JMPENV_PUSH(v) \ STMT_START { \ - DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p\n", \ - (void*)&cur_env, (void*)PL_top_env)); \ + DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p at %s:%d\n", \ + (void*)&cur_env, (void*)PL_top_env, \ + __FILE__, __LINE__)); \ cur_env.je_prev = PL_top_env; \ OP_REG_TO_MEM; \ cur_env.je_ret = PerlProc_setjmp(cur_env.je_buf, SCOPE_SAVES_SIGNAL_MASK); \ @@ -112,8 +113,10 @@ typedef struct jmpenv JMPENV; #define JMPENV_POP \ STMT_START { \ - DEBUG_l(Perl_deb(aTHX_ "popping jumplevel was %p, now %p\n", \ - (void*)PL_top_env, (void*)cur_env.je_prev)); \ + DEBUG_l(Perl_deb(aTHX_ "popping jumplevel was %p, now %p at %s:%d\n", \ + (void*)PL_top_env, (void*)cur_env.je_prev, \ + __FILE__, __LINE__)); \ + assert(PL_top_env == &cur_env); \ PL_top_env = cur_env.je_prev; \ } STMT_END @@ -139,7 +142,7 @@ struct cop { /* On LP64 putting this here takes advantage of the fact that BASEOP isn't an exact multiple of 8 bytes to save structure padding. */ line_t cop_line; /* line # of this command */ - char * cop_label; /* label for this construct */ + /* label for this construct is now stored in cop_hints_hash */ #ifdef USE_ITHREADS char * cop_stashpv; /* package line was compiled in */ char * cop_file; /* file name the following line # is from */ @@ -191,18 +194,12 @@ struct cop { ? gv_stashpv(CopSTASHPV(c),GV_ADD) : NULL) # define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME_get(hv) : NULL) # define CopSTASH_eq(c,hv) ((hv) && stashpv_hvname_match(c,hv)) -# define CopLABEL(c) ((c)->cop_label) -# define CopLABEL_set(c,pv) (CopLABEL(c) = (pv)) # ifdef NETWARE # define CopSTASH_free(c) SAVECOPSTASH_FREE(c) # define CopFILE_free(c) SAVECOPFILE_FREE(c) -# define CopLABEL_free(c) SAVECOPLABEL_FREE(c) -# define CopLABEL_alloc(pv) ((pv)?savepv(pv):NULL) # else # define CopSTASH_free(c) PerlMemShared_free(CopSTASHPV(c)) # define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL)) -# define CopLABEL_free(c) (PerlMemShared_free(CopLABEL(c)),(CopLABEL(c) = NULL)) -# define CopLABEL_alloc(pv) ((pv)?savesharedpv(pv):NULL) # endif #else # define CopFILEGV(c) ((c)->cop_filegv) @@ -219,19 +216,17 @@ struct cop { # define CopFILE(c) (CopFILEGV(c) && GvSV(CopFILEGV(c)) \ ? SvPVX(GvSV(CopFILEGV(c))) : NULL) # define CopSTASH(c) ((c)->cop_stash) -# define CopLABEL(c) ((c)->cop_label) # define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) # define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL) /* cop_stash is not refcounted */ # define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) # define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) -# define CopLABEL_alloc(pv) ((pv)?savepv(pv):NULL) -# define CopLABEL_set(c,pv) (CopLABEL(c) = (pv)) # define CopSTASH_free(c) # define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL)) -# define CopLABEL_free(c) (Safefree(CopLABEL(c)),(CopLABEL(c) = NULL)) #endif /* USE_ITHREADS */ +#define CopLABEL(c) Perl_fetch_cop_label(aTHX_ (c)->cop_hints_hash, NULL, NULL) +#define CopLABEL_alloc(pv) ((pv)?savepv(pv):NULL) #define CopSTASH_ne(c,hv) (!CopSTASH_eq(c,hv)) #define CopLINE(c) ((c)->cop_line) @@ -240,11 +235,7 @@ struct cop { #define CopLINE_set(c,l) (CopLINE(c) = (l)) /* OutCopFILE() is CopFILE for output (caller, die, warn, etc.) */ -#ifdef MACOS_TRADITIONAL -# define OutCopFILE(c) MacPerl_MPWFileName(CopFILE(c)) -#else -# define OutCopFILE(c) CopFILE(c) -#endif +#define OutCopFILE(c) CopFILE(c) /* If $[ is non-zero, it's stored in cop_hints under the key "$[", and HINT_ARYBASE is set to indicate this. @@ -258,12 +249,17 @@ struct cop { #define CopARYBASE_set(c, b) STMT_START { \ if (b || ((c)->cop_hints & HINT_ARYBASE)) { \ (c)->cop_hints |= HINT_ARYBASE; \ - if ((c) == &PL_compiling) \ - PL_hints |= HINT_LOCALIZE_HH | HINT_ARYBASE; \ - (c)->cop_hints_hash \ - = Perl_refcounted_he_new(aTHX_ (c)->cop_hints_hash, \ + if ((c) == &PL_compiling) { \ + SV *val = newSViv(b); \ + (void)hv_stores(GvHV(PL_hintgv), "$[", val); \ + mg_set(val); \ + PL_hints |= HINT_ARYBASE; \ + } else { \ + (c)->cop_hints_hash \ + = Perl_refcounted_he_new(aTHX_ (c)->cop_hints_hash, \ newSVpvs_flags("$[", SVs_TEMP), \ sv_2mortal(newSViv(b))); \ + } \ } \ } STMT_END @@ -306,8 +302,8 @@ struct block_format { #define PUSHSUB_BASE(cx) \ ENTRY_PROBE(GvENAME(CvGV(cv)), \ - CopFILE((COP*)CvSTART(cv)), \ - CopLINE((COP*)CvSTART(cv))); \ + CopFILE((const COP *)CvSTART(cv)), \ + CopLINE((const COP *)CvSTART(cv))); \ \ cx->blk_sub.cv = cv; \ cx->blk_sub.olddepth = CvDEPTH(cv); \ @@ -355,9 +351,9 @@ struct block_format { #define POPSUB(cx,sv) \ STMT_START { \ - RETURN_PROBE(GvENAME(CvGV((CV*)cx->blk_sub.cv)), \ - CopFILE((COP*)CvSTART((CV*)cx->blk_sub.cv)), \ - CopLINE((COP*)CvSTART((CV*)cx->blk_sub.cv))); \ + RETURN_PROBE(GvENAME(CvGV((const CV*)cx->blk_sub.cv)), \ + CopFILE((COP*)CvSTART((const CV*)cx->blk_sub.cv)), \ + CopLINE((COP*)CvSTART((const CV*)cx->blk_sub.cv))); \ \ if (CxHASARGS(cx)) { \ POP_SAVEARRAY(); \ @@ -368,14 +364,14 @@ struct block_format { cx->blk_sub.argarray = newAV(); \ av_extend(cx->blk_sub.argarray, fill); \ AvREIFY_only(cx->blk_sub.argarray); \ - CX_CURPAD_SV(cx->blk_sub, 0) = (SV*)cx->blk_sub.argarray; \ + CX_CURPAD_SV(cx->blk_sub, 0) = MUTABLE_SV(cx->blk_sub.argarray); \ } \ else { \ CLEAR_ARGARRAY(cx->blk_sub.argarray); \ } \ } \ - sv = (SV*)cx->blk_sub.cv; \ - if (sv && (CvDEPTH((CV*)sv) = cx->blk_sub.olddepth)) \ + sv = MUTABLE_SV(cx->blk_sub.cv); \ + if (sv && (CvDEPTH((const CV*)sv) = cx->blk_sub.olddepth)) \ sv = NULL; \ } STMT_END @@ -476,7 +472,7 @@ struct block_loop { # define CX_ITERDATA_SET(cx,ivar,o) \ cx->blk_loop.itervar = (SV**)(ivar); #endif -#define CxLABEL(c) (0 + (c)->blk_oldcop->cop_label) +#define CxLABEL(c) (0 + CopLABEL((c)->blk_oldcop)) #define CxHASARGS(c) (((c)->cx_type & CXp_HASARGS) == CXp_HASARGS) #define CxLVAL(c) (0 + (c)->blk_u16) @@ -618,7 +614,8 @@ struct subst { #define sb_rxres cx_u.cx_subst.sbu_rxres #define sb_rx cx_u.cx_subst.sbu_rx -#define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \ +#ifdef PERL_CORE +# define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \ cx->sb_iters = iters, \ cx->sb_maxiters = maxiters, \ cx->sb_rflags = r_flags, \ @@ -636,11 +633,12 @@ struct subst { rxres_save(&cx->sb_rxres, rx); \ (void)ReREFCNT_inc(rx) -#define CxONCE(cx) ((cx)->cx_type & CXp_ONCE) - -#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \ +# define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \ rxres_free(&cx->sb_rxres); \ ReREFCNT_dec(cx->sb_rx) +#endif + +#define CxONCE(cx) ((cx)->cx_type & CXp_ONCE) struct context { union { @@ -650,20 +648,27 @@ struct context { }; #define cx_type cx_u.cx_subst.sbu_type +/* If you re-order these, there is also an array of uppercase names in perl.h + and a static array of context names in pp_ctl.c */ #define CXTYPEMASK 0xf #define CXt_NULL 0 -#define CXt_SUB 1 -#define CXt_EVAL 2 -#define CXt_WHEN 3 -#define CXt_SUBST 4 -#define CXt_BLOCK 5 -#define CXt_FORMAT 6 -#define CXt_GIVEN 7 +#define CXt_WHEN 1 +#define CXt_BLOCK 2 +/* When micro-optimising :-) keep GIVEN next to the LOOPs, as these 5 share a + jump table in pp_ctl.c + The first 4 don't have a 'case' in at least one switch statement in pp_ctl.c +*/ +#define CXt_GIVEN 3 /* This is first so that CXt_LOOP_FOR|CXt_LOOP_LAZYIV is CXt_LOOP_LAZYIV */ -#define CXt_LOOP_FOR 8 -#define CXt_LOOP_PLAIN 9 -#define CXt_LOOP_LAZYSV 10 -#define CXt_LOOP_LAZYIV 11 +#define CXt_LOOP_FOR 4 +#define CXt_LOOP_PLAIN 5 +#define CXt_LOOP_LAZYSV 6 +#define CXt_LOOP_LAZYIV 7 +#define CXt_SUB 8 +#define CXt_FORMAT 9 +#define CXt_EVAL 10 +#define CXt_SUBST 11 +/* SUBST doesn't feature in all switch statements. */ /* private flags for CXt_SUB and CXt_NULL However, this is checked in many places which do not check the type, so @@ -689,7 +694,7 @@ struct context { #define CXp_ONCE 0x10 /* What was sbu_once in struct subst */ #define CxTYPE(c) ((c)->cx_type & CXTYPEMASK) -#define CxTYPE_is_LOOP(c) (((c)->cx_type & 0xC) == 0x8) +#define CxTYPE_is_LOOP(c) (((c)->cx_type & 0xC) == 0x4) #define CxMULTICALL(c) (((c)->cx_type & CXp_MULTICALL) \ == CXp_MULTICALL) #define CxREALEVAL(c) (((c)->cx_type & (CXTYPEMASK|CXp_REAL)) \ @@ -882,6 +887,7 @@ See L. multicall_oldcatch = CATCH_GET; \ SAVETMPS; SAVEVPTR(PL_op); \ CATCH_SET(TRUE); \ + PUSHSTACKi(PERLSI_SORT); \ PUSHBLOCK(cx, CXt_SUB|CXp_MULTICALL, PL_stack_sp); \ PUSHSUB(cx); \ if (++CvDEPTH(cv) >= 2) { \ @@ -905,8 +911,10 @@ See L. LEAVESUB(multicall_cv); \ CvDEPTH(multicall_cv)--; \ POPBLOCK(cx,PL_curpm); \ + POPSTACK; \ CATCH_SET(multicall_oldcatch); \ LEAVE; \ + SPAGAIN; \ } STMT_END /*