X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=cop.h;h=ef92d8e97df17d843728171483e3a59cb3d07a2d;hb=6fd99bb377a3671d990fd357b52cfe5b19de1e9c;hp=618da4dea2fe16b6ce36dfaa84527317bf807e2b;hpb=82f35e8b14e93ac697812d1b28d2e79e1ad82d84;p=p5sagit%2Fp5-mst-13.2.git diff --git a/cop.h b/cop.h index 618da4d..ef92d8e 100644 --- a/cop.h +++ b/cop.h @@ -1,7 +1,7 @@ /* cop.h * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, 2005, 2006 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. @@ -150,12 +150,10 @@ struct cop { SV * cop_io; /* lexical IO defaults */ }; -#define Nullcop Null(COP*) - #ifdef USE_ITHREADS # define CopFILE(c) ((c)->cop_file) # define CopFILEGV(c) (CopFILE(c) \ - ? gv_fetchfile(CopFILE(c)) : Nullgv) + ? gv_fetchfile(CopFILE(c)) : NULL) # ifdef NETWARE # define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) @@ -164,43 +162,54 @@ struct cop { # endif # define CopFILESV(c) (CopFILE(c) \ - ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) + ? GvSV(gv_fetchfile(CopFILE(c))) : NULL) # define CopFILEAV(c) (CopFILE(c) \ - ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) + ? GvAV(gv_fetchfile(CopFILE(c))) : NULL) +# ifdef DEBUGGING +# define CopFILEAVx(c) (assert(CopFILE(c)), \ + GvAV(gv_fetchfile(CopFILE(c)))) +# else +# define CopFILEAVx(c) (GvAV(gv_fetchfile(CopFILE(c)))) +# endif # define CopSTASHPV(c) ((c)->cop_stashpv) # ifdef NETWARE -# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) +# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : NULL)) # else # define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = savesharedpv(pv)) # endif # define CopSTASH(c) (CopSTASHPV(c) \ - ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) -# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME_get(hv) : Nullch) + ? 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)) # ifdef NETWARE # define CopSTASH_free(c) SAVECOPSTASH_FREE(c) # define CopFILE_free(c) SAVECOPFILE_FREE(c) # else # define CopSTASH_free(c) PerlMemShared_free(CopSTASHPV(c)) -# define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = Nullch)) +# define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL)) # endif #else # define CopFILEGV(c) ((c)->cop_filegv) # define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) # define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) -# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) -# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) -# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) +# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL) +# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL) +# ifdef DEBUGGING +# define CopFILEAVx(c) (assert(CopFILEGV(c)), GvAV(CopFILEGV(c))) +# else +# define CopFILEAVx(c) (GvAV(CopFILEGV(c))) +# endif +# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : NULL) # define CopSTASH(c) ((c)->cop_stash) # define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) -# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : Nullch) +# 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 CopSTASH_free(c) -# define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = Nullgv)) +# define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL)) #endif /* USE_ITHREADS */ @@ -228,7 +237,7 @@ struct block_sub { GV * dfoutgv; AV * savearray; AV * argarray; - long olddepth; + I32 olddepth; U8 hasargs; U8 lval; /* XXX merge lval and hasargs? */ PAD *oldcomppad; @@ -243,10 +252,10 @@ struct block_sub { cx->blk_sub.cv = cv; \ cx->blk_sub.olddepth = CvDEPTH(cv); \ cx->blk_sub.hasargs = hasargs; \ - cx->blk_sub.retop = Nullop; \ + cx->blk_sub.retop = NULL; \ if (!CvDEPTH(cv)) { \ - (void)SvREFCNT_inc(cv); \ - (void)SvREFCNT_inc(cv); \ + SvREFCNT_inc_void(cv); \ + SvREFCNT_inc_void(cv); \ SAVEFREESV(cv); \ } @@ -265,10 +274,10 @@ struct block_sub { #define PUSHFORMAT(cx) \ cx->blk_sub.cv = cv; \ cx->blk_sub.gv = gv; \ - cx->blk_sub.retop = Nullop; \ + cx->blk_sub.retop = NULL; \ cx->blk_sub.hasargs = 0; \ cx->blk_sub.dfoutgv = PL_defoutgv; \ - (void)SvREFCNT_inc(cx->blk_sub.dfoutgv) + SvREFCNT_inc_void(cx->blk_sub.dfoutgv) #define POP_SAVEARRAY() \ STMT_START { \ @@ -304,7 +313,7 @@ struct block_sub { } \ sv = (SV*)cx->blk_sub.cv; \ if (sv && (CvDEPTH((CV*)sv) = cx->blk_sub.olddepth)) \ - sv = Nullsv; \ + sv = NULL; \ } STMT_END #define LEAVESUB(sv) \ @@ -333,11 +342,11 @@ struct block_eval { STMT_START { \ cx->blk_eval.old_in_eval = PL_in_eval; \ cx->blk_eval.old_op_type = PL_op->op_type; \ - cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : Nullsv); \ + cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : NULL); \ cx->blk_eval.old_eval_root = PL_eval_root; \ cx->blk_eval.cur_text = PL_linestr; \ - cx->blk_eval.cv = Nullcv; /* set by doeval(), as applicable */ \ - cx->blk_eval.retop = Nullop; \ + cx->blk_eval.cv = NULL; /* set by doeval(), as applicable */ \ + cx->blk_eval.retop = NULL; \ cx->blk_eval.cur_top_env = PL_top_env; \ } STMT_END @@ -383,14 +392,14 @@ struct block_loop { if ((cx->blk_loop.iterdata = (idata))) \ cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \ else \ - cx->blk_loop.itersave = Nullsv; + cx->blk_loop.itersave = NULL; #else # define CxITERVAR(c) ((c)->blk_loop.itervar) # define CX_ITERDATA_SET(cx,ivar) \ if ((cx->blk_loop.itervar = (SV**)(ivar))) \ cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \ else \ - cx->blk_loop.itersave = Nullsv; + cx->blk_loop.itersave = NULL; #endif #define PUSHLOOP(cx, dat, s) \ @@ -399,8 +408,8 @@ struct block_loop { cx->blk_loop.redo_op = cLOOP->op_redoop; \ cx->blk_loop.next_op = cLOOP->op_nextop; \ cx->blk_loop.last_op = cLOOP->op_lastop; \ - cx->blk_loop.iterlval = Nullsv; \ - cx->blk_loop.iterary = Nullav; \ + cx->blk_loop.iterlval = NULL; \ + cx->blk_loop.iterary = NULL; \ cx->blk_loop.iterix = -1; \ CX_ITERDATA_SET(cx,dat); @@ -419,6 +428,16 @@ struct block_loop { if (cx->blk_loop.iterary && cx->blk_loop.iterary != PL_curstack)\ SvREFCNT_dec(cx->blk_loop.iterary); +/* given/when context */ +struct block_givwhen { + OP *leave_op; +}; + +#define PUSHGIVEN(cx) \ + cx->blk_givwhen.leave_op = cLOGOP->op_other; + +#define PUSHWHEN PUSHGIVEN + /* context common to subroutines, evals and loops */ struct block { I32 blku_oldsp; /* stack pointer to copy stuff down to */ @@ -432,6 +451,7 @@ struct block { struct block_sub blku_sub; struct block_eval blku_eval; struct block_loop blku_loop; + struct block_givwhen blku_givwhen; } blk_u; }; #define blk_oldsp cx_u.cx_blk.blku_oldsp @@ -443,6 +463,7 @@ struct block { #define blk_sub cx_u.cx_blk.blk_u.blku_sub #define blk_eval cx_u.cx_blk.blk_u.blku_eval #define blk_loop cx_u.cx_blk.blk_u.blku_loop +#define blk_givwhen cx_u.cx_blk.blk_u.blku_givwhen /* Enter a block. */ #define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \ @@ -521,7 +542,7 @@ struct subst { cx->sb_s = s, \ cx->sb_m = m, \ cx->sb_strend = strend, \ - cx->sb_rxres = Null(void*), \ + cx->sb_rxres = NULL, \ cx->sb_rx = rx, \ cx->cx_type = CXt_SUBST; \ rxres_save(&cx->sb_rxres, rx) @@ -545,6 +566,8 @@ struct context { #define CXt_SUBST 4 #define CXt_BLOCK 5 #define CXt_FORMAT 6 +#define CXt_GIVEN 7 +#define CXt_WHEN 8 /* private flags for CXt_SUB and CXt_NULL */ #define CXp_MULTICALL 0x00000400 /* part of a multicall (so don't @@ -554,8 +577,10 @@ struct context { #define CXp_REAL 0x00000100 /* truly eval'', not a lookalike */ #define CXp_TRYBLOCK 0x00000200 /* eval{}, not eval'' or similar */ -#ifdef USE_ITHREADS /* private flags for CXt_LOOP */ +#define CXp_FOREACH 0x00000200 /* a foreach loop */ +#define CXp_FOR_DEF 0x00000400 /* foreach using $_ */ +#ifdef USE_ITHREADS # define CXp_PADVAR 0x00000100 /* itervar lives on pad, iterdata has pad offset; if not set, iterdata holds GV* */ @@ -570,6 +595,10 @@ struct context { == (CXt_EVAL|CXp_REAL)) #define CxTRYBLOCK(c) (((c)->cx_type & (CXt_EVAL|CXp_TRYBLOCK)) \ == (CXt_EVAL|CXp_TRYBLOCK)) +#define CxFOREACH(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH)) \ + == (CXt_LOOP|CXp_FOREACH)) +#define CxFOREACHDEF(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF))\ + == (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF)) #define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc())) @@ -741,9 +770,9 @@ See L. #define PUSH_MULTICALL(the_cv) \ STMT_START { \ - CV *_nOnclAshIngNamE_ = the_cv; \ - CV *cv = _nOnclAshIngNamE_; \ - AV* padlist = CvPADLIST(cv); \ + CV * const _nOnclAshIngNamE_ = the_cv; \ + CV * const cv = _nOnclAshIngNamE_; \ + AV * const padlist = CvPADLIST(cv); \ ENTER; \ multicall_oldcatch = CATCH_GET; \ SAVETMPS; SAVEVPTR(PL_op); \