Introduced thr->threadsvp and THREADSV() for faster per-thread
[p5sagit/p5-mst-13.2.git] / cop.h
CommitLineData
a0d0e21e 1/* cop.h
79072805 2 *
9607fc9c 3 * Copyright (c) 1991-1997, Larry Wall
79072805 4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
79072805 8 */
9
79072805 10struct cop {
11 BASEOP
a0d0e21e 12 char * cop_label; /* label for this construct */
79072805 13 HV * cop_stash; /* package line was compiled in */
14 GV * cop_filegv; /* file the following line # is from */
a0d0e21e 15 U32 cop_seq; /* parse sequence number */
16 I32 cop_arybase; /* array base this line was compiled with */
79072805 17 line_t cop_line; /* line # of this command */
79072805 18};
19
20#define Nullcop Null(COP*)
21
22/*
23 * Here we have some enormously heavy (or at least ponderous) wizardry.
24 */
25
26/* subroutine context */
27struct block_sub {
28 CV * cv;
29 GV * gv;
463ee0b2 30 GV * dfoutgv;
6d4ff0d2 31#ifndef USE_THREADS
79072805 32 AV * savearray;
6d4ff0d2 33#endif /* USE_THREADS */
79072805 34 AV * argarray;
35 U16 olddepth;
36 U8 hasargs;
37};
38
39#define PUSHSUB(cx) \
40 cx->blk_sub.cv = cv; \
79072805 41 cx->blk_sub.olddepth = CvDEPTH(cv); \
42 cx->blk_sub.hasargs = hasargs;
43
44#define PUSHFORMAT(cx) \
45 cx->blk_sub.cv = cv; \
46 cx->blk_sub.gv = gv; \
4633a7c4 47 cx->blk_sub.hasargs = 0; \
463ee0b2 48 cx->blk_sub.dfoutgv = defoutgv; \
4633a7c4 49 (void)SvREFCNT_inc(cx->blk_sub.dfoutgv)
79072805 50
51#define POPSUB(cx) \
f86702cc 52 { struct block_sub cxsub; \
53 POPSUB1(cx); \
54 POPSUB2(); }
55
56#define POPSUB1(cx) \
57 cxsub = cx->blk_sub; /* because DESTROY may clobber *cx */
58
6d4ff0d2 59#ifdef USE_THREADS
60#define POPSAVEARRAY() NOOP
61#else
62#define POPSAVEARRAY() \
63 STMT_START { \
64 SvREFCNT_dec(GvAV(defgv)); \
65 GvAV(defgv) = cxsub.savearray; \
66 } STMT_END
67#endif /* USE_THREADS */
68
f86702cc 69#define POPSUB2() \
70 if (cxsub.hasargs) { \
6d4ff0d2 71 POPSAVEARRAY(); \
774d564b 72 /* destroy arg array */ \
f86702cc 73 av_clear(cxsub.argarray); \
74 AvREAL_off(cxsub.argarray); \
79072805 75 } \
f86702cc 76 if (cxsub.cv) { \
77 if (!(CvDEPTH(cxsub.cv) = cxsub.olddepth)) \
78 SvREFCNT_dec(cxsub.cv); \
79072805 79 }
80
81#define POPFORMAT(cx) \
4633a7c4 82 setdefout(cx->blk_sub.dfoutgv); \
83 SvREFCNT_dec(cx->blk_sub.dfoutgv);
79072805 84
85/* eval context */
86struct block_eval {
87 I32 old_in_eval;
88 I32 old_op_type;
89 char * old_name;
90 OP * old_eval_root;
748a9306 91 SV * cur_text;
79072805 92};
93
8990e307 94#define PUSHEVAL(cx,n,fgv) \
79072805 95 cx->blk_eval.old_in_eval = in_eval; \
96 cx->blk_eval.old_op_type = op->op_type; \
97 cx->blk_eval.old_name = n; \
748a9306 98 cx->blk_eval.old_eval_root = eval_root; \
99 cx->blk_eval.cur_text = linestr;
79072805 100
101#define POPEVAL(cx) \
102 in_eval = cx->blk_eval.old_in_eval; \
103 optype = cx->blk_eval.old_op_type; \
104 eval_root = cx->blk_eval.old_eval_root;
105
106/* loop context */
107struct block_loop {
108 char * label;
109 I32 resetsp;
110 OP * redo_op;
111 OP * next_op;
112 OP * last_op;
113 SV ** itervar;
114 SV * itersave;
5f05dabc 115 SV * iterlval;
79072805 116 AV * iterary;
117 I32 iterix;
118};
119
120#define PUSHLOOP(cx, ivar, s) \
121 cx->blk_loop.label = curcop->cop_label; \
122 cx->blk_loop.resetsp = s - stack_base; \
123 cx->blk_loop.redo_op = cLOOP->op_redoop; \
124 cx->blk_loop.next_op = cLOOP->op_nextop; \
125 cx->blk_loop.last_op = cLOOP->op_lastop; \
7a4c00b4 126 if (cx->blk_loop.itervar = (ivar)) \
44a8e56a 127 cx->blk_loop.itersave = SvREFCNT_inc(*cx->blk_loop.itervar);\
128 cx->blk_loop.iterlval = Nullsv; \
129 cx->blk_loop.iterary = Nullav; \
130 cx->blk_loop.iterix = -1;
79072805 131
132#define POPLOOP(cx) \
f86702cc 133 { struct block_loop cxloop; \
134 POPLOOP1(cx); \
135 POPLOOP2(); }
136
137#define POPLOOP1(cx) \
4fdae800 138 cxloop = cx->blk_loop; /* because DESTROY may clobber *cx */ \
139 newsp = stack_base + cxloop.resetsp;
f86702cc 140
141#define POPLOOP2() \
f86702cc 142 SvREFCNT_dec(cxloop.iterlval); \
143 if (cxloop.itervar) { \
144 SvREFCNT_dec(*cxloop.itervar); \
145 *cxloop.itervar = cxloop.itersave; \
44a8e56a 146 } \
f86702cc 147 if (cxloop.iterary && cxloop.iterary != curstack) \
148 SvREFCNT_dec(cxloop.iterary);
79072805 149
150/* context common to subroutines, evals and loops */
151struct block {
152 I32 blku_oldsp; /* stack pointer to copy stuff down to */
153 COP * blku_oldcop; /* old curcop pointer */
154 I32 blku_oldretsp; /* return stack index */
155 I32 blku_oldmarksp; /* mark stack index */
156 I32 blku_oldscopesp; /* scope stack index */
157 PMOP * blku_oldpm; /* values of pattern match vars */
158 U8 blku_gimme; /* is this block running in list context? */
159
160 union {
161 struct block_sub blku_sub;
162 struct block_eval blku_eval;
163 struct block_loop blku_loop;
164 } blk_u;
165};
166#define blk_oldsp cx_u.cx_blk.blku_oldsp
167#define blk_oldcop cx_u.cx_blk.blku_oldcop
168#define blk_oldretsp cx_u.cx_blk.blku_oldretsp
169#define blk_oldmarksp cx_u.cx_blk.blku_oldmarksp
170#define blk_oldscopesp cx_u.cx_blk.blku_oldscopesp
171#define blk_oldpm cx_u.cx_blk.blku_oldpm
172#define blk_gimme cx_u.cx_blk.blku_gimme
173#define blk_sub cx_u.cx_blk.blk_u.blku_sub
174#define blk_eval cx_u.cx_blk.blk_u.blku_eval
175#define blk_loop cx_u.cx_blk.blk_u.blku_loop
176
177/* Enter a block. */
8990e307 178#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \
79072805 179 cx->cx_type = t, \
8990e307 180 cx->blk_oldsp = sp - stack_base, \
79072805 181 cx->blk_oldcop = curcop, \
182 cx->blk_oldmarksp = markstack_ptr - markstack, \
183 cx->blk_oldscopesp = scopestack_ix, \
184 cx->blk_oldretsp = retstack_ix, \
185 cx->blk_oldpm = curpm, \
186 cx->blk_gimme = gimme; \
760ac839 187 DEBUG_l( PerlIO_printf(PerlIO_stderr(), "Entering block %ld, type %s\n", \
a0d0e21e 188 (long)cxstack_ix, block_type[t]); )
79072805 189
190/* Exit a block (RETURN and LAST). */
a0d0e21e 191#define POPBLOCK(cx,pm) cx = &cxstack[cxstack_ix--], \
79072805 192 newsp = stack_base + cx->blk_oldsp, \
193 curcop = cx->blk_oldcop, \
194 markstack_ptr = markstack + cx->blk_oldmarksp, \
195 scopestack_ix = cx->blk_oldscopesp, \
196 retstack_ix = cx->blk_oldretsp, \
a0d0e21e 197 pm = cx->blk_oldpm, \
79072805 198 gimme = cx->blk_gimme; \
760ac839 199 DEBUG_l( PerlIO_printf(PerlIO_stderr(), "Leaving block %ld, type %s\n", \
a0d0e21e 200 (long)cxstack_ix+1,block_type[cx->cx_type]); )
79072805 201
202/* Continue a block elsewhere (NEXT and REDO). */
203#define TOPBLOCK(cx) cx = &cxstack[cxstack_ix], \
204 stack_sp = stack_base + cx->blk_oldsp, \
205 markstack_ptr = markstack + cx->blk_oldmarksp, \
206 scopestack_ix = cx->blk_oldscopesp, \
207 retstack_ix = cx->blk_oldretsp
208
209/* substitution context */
210struct subst {
211 I32 sbu_iters;
212 I32 sbu_maxiters;
213 I32 sbu_safebase;
4633a7c4 214 I32 sbu_oldsave;
71be2cbc 215 bool sbu_once;
216 bool sbu_rxtainted;
79072805 217 char * sbu_orig;
218 SV * sbu_dstr;
219 SV * sbu_targ;
220 char * sbu_s;
221 char * sbu_m;
222 char * sbu_strend;
c90c0ff4 223 void * sbu_rxres;
c07a80fd 224 REGEXP * sbu_rx;
79072805 225};
226#define sb_iters cx_u.cx_subst.sbu_iters
227#define sb_maxiters cx_u.cx_subst.sbu_maxiters
228#define sb_safebase cx_u.cx_subst.sbu_safebase
4633a7c4 229#define sb_oldsave cx_u.cx_subst.sbu_oldsave
71be2cbc 230#define sb_once cx_u.cx_subst.sbu_once
231#define sb_rxtainted cx_u.cx_subst.sbu_rxtainted
79072805 232#define sb_orig cx_u.cx_subst.sbu_orig
233#define sb_dstr cx_u.cx_subst.sbu_dstr
234#define sb_targ cx_u.cx_subst.sbu_targ
235#define sb_s cx_u.cx_subst.sbu_s
236#define sb_m cx_u.cx_subst.sbu_m
237#define sb_strend cx_u.cx_subst.sbu_strend
c90c0ff4 238#define sb_rxres cx_u.cx_subst.sbu_rxres
c07a80fd 239#define sb_rx cx_u.cx_subst.sbu_rx
79072805 240
241#define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \
242 cx->sb_iters = iters, \
243 cx->sb_maxiters = maxiters, \
244 cx->sb_safebase = safebase, \
4633a7c4 245 cx->sb_oldsave = oldsave, \
71be2cbc 246 cx->sb_once = once, \
247 cx->sb_rxtainted = rxtainted, \
79072805 248 cx->sb_orig = orig, \
249 cx->sb_dstr = dstr, \
250 cx->sb_targ = targ, \
251 cx->sb_s = s, \
252 cx->sb_m = m, \
253 cx->sb_strend = strend, \
c90c0ff4 254 cx->sb_rxres = Null(void*), \
c07a80fd 255 cx->sb_rx = rx, \
c90c0ff4 256 cx->cx_type = CXt_SUBST; \
257 rxres_save(&cx->sb_rxres, rx)
79072805 258
c90c0ff4 259#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \
260 rxres_free(&cx->sb_rxres)
79072805 261
262struct context {
263 I32 cx_type; /* what kind of context this is */
264 union {
265 struct block cx_blk;
266 struct subst cx_subst;
267 } cx_u;
268};
269#define CXt_NULL 0
270#define CXt_SUB 1
271#define CXt_EVAL 2
272#define CXt_LOOP 3
273#define CXt_SUBST 4
274#define CXt_BLOCK 5
275
276#define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
277
278/* "gimme" values */
a0d0e21e 279#define G_SCALAR 0
280#define G_ARRAY 1
54310121 281#define G_VOID 128 /* skip this bit when adding flags below */
79072805 282
a0d0e21e 283/* extra flags for perl_call_* routines */
284#define G_DISCARD 2 /* Call FREETMPS. */
285#define G_EVAL 4 /* Assume eval {} around subroutine call. */
286#define G_NOARGS 8 /* Don't construct a @_ array. */
54310121 287#define G_KEEPERR 16 /* Append errors to $@, don't overwrite it */