X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=cop.h;h=e588675012abf4a2fa6782d4162517b95168e7a2;hb=83bb2f05018534d7d0cc69340baccd0359dfcdf2;hp=88627d684e5b4be1525395f93e5e13f9efcf91b2;hpb=ce2f7c3be671853dd8e435baa8ec8d4453b3bb86;p=p5sagit%2Fp5-mst-13.2.git diff --git a/cop.h b/cop.h index 88627d6..e588675 100644 --- a/cop.h +++ b/cop.h @@ -1,6 +1,6 @@ /* cop.h * - * Copyright (c) 1991-1999, Larry Wall + * Copyright (c) 1991-2000, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -96,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); \ @@ -118,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)) \ @@ -138,22 +149,28 @@ struct block_sub { struct block_eval { I32 old_in_eval; I32 old_op_type; - char * old_name; + SV * old_namesv; OP * old_eval_root; SV * cur_text; }; #define PUSHEVAL(cx,n,fgv) \ + 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_name = n; \ + cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : Nullsv); \ cx->blk_eval.old_eval_root = PL_eval_root; \ - cx->blk_eval.cur_text = PL_linestr; + cx->blk_eval.cur_text = PL_linestr; \ + } STMT_END #define POPEVAL(cx) \ + STMT_START { \ 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; \ + if (cx->blk_eval.old_namesv) \ + sv_2mortal(cx->blk_eval.old_namesv); \ + } STMT_END /* loop context */ struct block_loop { @@ -162,7 +179,12 @@ struct block_loop { OP * redo_op; OP * next_op; OP * last_op; +#ifdef USE_ITHREADS + void * iterdata; + SV ** oldcurpad; +#else SV ** itervar; +#endif SV * itersave; SV * iterlval; AV * iterary; @@ -170,23 +192,41 @@ struct block_loop { IV itermax; }; -#define PUSHLOOP(cx, ivar, s) \ +#ifdef USE_ITHREADS +# define CxITERVAR(c) \ + ((c)->blk_loop.iterdata \ + ? (CxPADLOOP(cx) \ + ? &((c)->blk_loop.oldcurpad)[(PADOFFSET)(c)->blk_loop.iterdata] \ + : &GvSV((GV*)(c)->blk_loop.iterdata)) \ + : (SV**)NULL) +# define CX_ITERDATA_SET(cx,idata) \ + cx->blk_loop.oldcurpad = PL_curpad; \ + 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); @@ -319,16 +359,60 @@ 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 */ +#define CXp_TRYBLOCK 0x00000200 /* eval{}, not eval'' or similar */ + +#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 CxTRYBLOCK(c) (((c)->cx_type & (CXt_EVAL|CXp_TRYBLOCK)) \ + == (CXt_EVAL|CXp_TRYBLOCK)) #define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc())) /* "gimme" values */ + +/* +=for apidoc AmU||G_SCALAR +Used to indicate scalar context. See C, C, and +L. + +=for apidoc AmU||G_ARRAY +Used to indicate array context. See C, C and +L. + +=for apidoc AmU||G_VOID +Used to indicate void context. See C and L. + +=for apidoc AmU||G_DISCARD +Indicates that arguments returned from a callback should be discarded. See +L. + +=for apidoc AmU||G_EVAL + +Used to force a Perl C wrapper around a callback. See +L. + +=for apidoc AmU||G_NOARGS + +Indicates that no arguments are being sent to a callback. See +L. + +=cut +*/ + #define G_SCALAR 0 #define G_ARRAY 1 #define G_VOID 128 /* skip this bit when adding flags below */