X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=cop.h;h=ede2fce591bf177cec85dc707f0bbfad712ce68f;hb=79d01fbf58287276b77349e580651d9897f9b25c;hp=238c677bb4d8393513c50ba4e9cf8fa523fcf81a;hpb=cc49e20bd7575d1d37e92731860d63daa4d52ecc;p=p5sagit%2Fp5-mst-13.2.git diff --git a/cop.h b/cop.h index 238c677..ede2fce 100644 --- a/cop.h +++ b/cop.h @@ -10,8 +10,13 @@ struct cop { BASEOP char * cop_label; /* label for this construct */ +#ifdef USE_ITHREADS + char * cop_stashpv; /* package line was compiled in */ + char * cop_file; /* file name the following line # is from */ +#else HV * cop_stash; /* package line was compiled in */ GV * cop_filegv; /* file the following line # is from */ +#endif U32 cop_seq; /* parse sequence number */ I32 cop_arybase; /* array base this line was compiled with */ line_t cop_line; /* line # of this command */ @@ -20,13 +25,43 @@ struct cop { #define Nullcop Null(COP*) -#define CopFILEGV(c) (c)->cop_filegv -#define CopFILEGV_set(c,gv) ((c)->cop_filegv = gv) -#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) +#ifdef USE_ITHREADS +# define CopFILE(c) ((c)->cop_file) +# define CopFILEGV(c) (CopFILE(c) \ + ? gv_fetchfile(CopFILE(c)) : Nullgv) +# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) /* XXX */ +# define CopFILESV(c) (CopFILE(c) \ + ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) +# define CopFILEAV(c) (CopFILE(c) \ + ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) +# define CopSTASHPV(c) ((c)->cop_stashpv) +# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = savepv(pv)) /* XXX */ +# define CopSTASH(c) (CopSTASHPV(c) \ + ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) +# define CopSTASH_set(c,hv) CopSTASHPV_set(c, HvNAME(hv)) +# define CopSTASH_eq(c,hv) (hv \ + && (CopSTASHPV(c) == HvNAME(hv) \ + || (CopSTASHPV(c) && HvNAME(hv) \ + && strEQ(CopSTASHPV(c), HvNAME(hv))))) +#else +# define CopFILEGV(c) ((c)->cop_filegv) +# define CopFILEGV_set(c,gv) ((c)->cop_filegv = gv) +# define CopFILE_set(c,pv) ((c)->cop_filegv = 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 CopSTASH(c) ((c)->cop_stash) +# define CopSTASH_set(c,hv) ((c)->cop_stash = hv) +# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) +# define CopSTASHPV_set(c,pv) CopSTASH_set(c, gv_stashpv(pv,GV_ADD)) +# define CopSTASH_eq(c,hv) (CopSTASH(c) == hv) +#endif /* USE_ITHREADS */ + +#define CopSTASH_ne(c,hv) (!CopSTASH_eq(c,hv)) #define CopLINE(c) ((c)->cop_line) -#define CopLINE_set(c,l) ((c)->cop_line = (l)) +#define CopLINE_inc(c) (++CopLINE(c)) +#define CopLINE_dec(c) (--CopLINE(c)) +#define CopLINE_set(c,l) (CopLINE(c) = (l)) /* * Here we have some enormously heavy (or at least ponderous) wizardry. @@ -61,19 +96,27 @@ struct block_sub { (void)SvREFCNT_inc(cx->blk_sub.dfoutgv) #ifdef USE_THREADS -#define POPSAVEARRAY() NOOP +# define POP_SAVEARRAY() NOOP #else -#define POPSAVEARRAY() \ +# define POP_SAVEARRAY() \ STMT_START { \ SvREFCNT_dec(GvAV(PL_defgv)); \ GvAV(PL_defgv) = cx->blk_sub.savearray; \ } STMT_END #endif /* USE_THREADS */ +#ifdef USE_ITHREADS + /* junk in @_ spells trouble when cloning CVs, so don't leave any */ +# define CLEAR_ARGARRAY() av_clear(cx->blk_sub.argarray) +#else +# define CLEAR_ARGARRAY() NOOP +#endif /* USE_ITHREADS */ + + #define POPSUB(cx,sv) \ STMT_START { \ if (cx->blk_sub.hasargs) { \ - POPSAVEARRAY(); \ + POP_SAVEARRAY(); \ /* abandon @_ if it got reified */ \ if (AvREAL(cx->blk_sub.argarray)) { \ SSize_t fill = AvFILLp(cx->blk_sub.argarray); \ @@ -83,6 +126,9 @@ struct block_sub { AvFLAGS(cx->blk_sub.argarray) = AVf_REIFY; \ PL_curpad[0] = (SV*)cx->blk_sub.argarray; \ } \ + else { \ + CLEAR_ARGARRAY(); \ + } \ } \ sv = (SV*)cx->blk_sub.cv; \ if (sv && (CvDEPTH((CV*)sv) = cx->blk_sub.olddepth)) \ @@ -111,14 +157,15 @@ struct block_eval { #define PUSHEVAL(cx,n,fgv) \ cx->blk_eval.old_in_eval = PL_in_eval; \ cx->blk_eval.old_op_type = PL_op->op_type; \ - cx->blk_eval.old_name = n; \ + cx->blk_eval.old_name = (n ? savepv(n) : Nullch); \ cx->blk_eval.old_eval_root = PL_eval_root; \ cx->blk_eval.cur_text = PL_linestr; #define POPEVAL(cx) \ PL_in_eval = cx->blk_eval.old_in_eval; \ optype = cx->blk_eval.old_op_type; \ - PL_eval_root = cx->blk_eval.old_eval_root; + PL_eval_root = cx->blk_eval.old_eval_root; \ + Safefree(cx->blk_eval.old_name); /* loop context */ struct block_loop { @@ -127,7 +174,11 @@ struct block_loop { OP * redo_op; OP * next_op; OP * last_op; +#ifdef USE_ITHREADS + void * iterdata; +#else SV ** itervar; +#endif SV * itersave; SV * iterlval; AV * iterary; @@ -135,23 +186,40 @@ struct block_loop { IV itermax; }; -#define PUSHLOOP(cx, ivar, s) \ +#ifdef USE_ITHREADS +# define CxITERVAR(c) \ + ((c)->blk_loop.iterdata \ + ? (CxPADLOOP(cx) \ + ? &PL_curpad[(PADOFFSET)(c)->blk_loop.iterdata] \ + : &GvSV((GV*)(c)->blk_loop.iterdata)) \ + : (SV**)NULL) +# define CX_ITERDATA_SET(cx,idata) \ + if (cx->blk_loop.iterdata = (idata)) \ + cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); +#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)); +#endif + +#define PUSHLOOP(cx, dat, s) \ cx->blk_loop.label = PL_curcop->cop_label; \ cx->blk_loop.resetsp = s - PL_stack_base; \ cx->blk_loop.redo_op = cLOOP->op_redoop; \ cx->blk_loop.next_op = cLOOP->op_nextop; \ cx->blk_loop.last_op = cLOOP->op_lastop; \ - if (cx->blk_loop.itervar = (ivar)) \ - cx->blk_loop.itersave = SvREFCNT_inc(*cx->blk_loop.itervar);\ cx->blk_loop.iterlval = Nullsv; \ cx->blk_loop.iterary = Nullav; \ - cx->blk_loop.iterix = -1; + cx->blk_loop.iterix = -1; \ + CX_ITERDATA_SET(cx,dat); #define POPLOOP(cx) \ SvREFCNT_dec(cx->blk_loop.iterlval); \ - if (cx->blk_loop.itervar) { \ - sv_2mortal(*(cx->blk_loop.itervar)); \ - *(cx->blk_loop.itervar) = cx->blk_loop.itersave; \ + if (CxITERVAR(cx)) { \ + SV **s_v_p = CxITERVAR(cx); \ + sv_2mortal(*s_v_p); \ + *s_v_p = cx->blk_loop.itersave; \ } \ if (cx->blk_loop.iterary && cx->blk_loop.iterary != PL_curstack)\ SvREFCNT_dec(cx->blk_loop.iterary); @@ -284,12 +352,23 @@ struct context { #define CXt_LOOP 3 #define CXt_SUBST 4 #define CXt_BLOCK 5 +#define CXt_FORMAT 6 /* private flags for CXt_EVAL */ #define CXp_REAL 0x00000100 /* truly eval'', not a lookalike */ +#ifdef USE_ITHREADS +/* private flags for CXt_LOOP */ +# define CXp_PADVAR 0x00000100 /* itervar lives on pad, iterdata + has pad offset; if not set, + iterdata holds GV* */ +# define CxPADLOOP(c) (((c)->cx_type & (CXt_LOOP|CXp_PADVAR)) \ + == (CXt_LOOP|CXp_PADVAR)) +#endif + #define CxTYPE(c) ((c)->cx_type & CXTYPEMASK) -#define CxREALEVAL(c) (((c)->cx_type & (CXt_EVAL|CXp_REAL)) == (CXt_EVAL|CXp_REAL)) +#define CxREALEVAL(c) (((c)->cx_type & (CXt_EVAL|CXp_REAL)) \ + == (CXt_EVAL|CXp_REAL)) #define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc())) @@ -335,7 +414,7 @@ struct stackinfo { I32 si_type; /* type of runlevel */ struct stackinfo * si_prev; struct stackinfo * si_next; - I32 * si_markbase; /* where markstack begins for us. + I32 si_markoff; /* offset where markstack begins for us. * currently used only with DEBUGGING, * but not #ifdef-ed for bincompat */ }; @@ -347,9 +426,10 @@ typedef struct stackinfo PERL_SI; #define cxstack_max (PL_curstackinfo->si_cxmax) #ifdef DEBUGGING -# define SET_MARKBASE PL_curstackinfo->si_markbase = PL_markstack_ptr +# define SET_MARK_OFFSET \ + PL_curstackinfo->si_markoff = PL_markstack_ptr - PL_markstack #else -# define SET_MARKBASE NOOP +# define SET_MARK_OFFSET NOOP #endif #define PUSHSTACKi(type) \ @@ -365,7 +445,7 @@ typedef struct stackinfo PERL_SI; AvFILLp(next->si_stack) = 0; \ SWITCHSTACK(PL_curstack,next->si_stack); \ PL_curstackinfo = next; \ - SET_MARKBASE; \ + SET_MARK_OFFSET; \ } STMT_END #define PUSHSTACK PUSHSTACKi(PERLSI_UNKNOWN)