source: trunk/third/perl/cop.h @ 20075

Revision 20075, 17.9 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20074, which included commits to RCS files with non-trunk default branches.
Line 
1/*    cop.h
2 *
3 *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 *    2000, 2001, 2002, 2003, by Larry Wall and others
5 *
6 *    You may distribute under the terms of either the GNU General Public
7 *    License or the Artistic License, as specified in the README file.
8 *
9 * Control ops (cops) are one of the three ops OP_NEXTSTATE, OP_DBSTATE,
10 * and OP_SETSTATE that (loosely speaking) are separate statements.
11 * They hold information important for lexical state and error reporting.
12 * At run time, PL_curcop is set to point to the most recently executed cop,
13 * and thus can be used to determine our current state.
14 */
15
16struct cop {
17    BASEOP
18    char *      cop_label;      /* label for this construct */
19#ifdef USE_ITHREADS
20    char *      cop_stashpv;    /* package line was compiled in */
21    char *      cop_file;       /* file name the following line # is from */
22#else
23    HV *        cop_stash;      /* package line was compiled in */
24    GV *        cop_filegv;     /* file the following line # is from */
25#endif
26    U32         cop_seq;        /* parse sequence number */
27    I32         cop_arybase;    /* array base this line was compiled with */
28    line_t      cop_line;       /* line # of this command */
29    SV *        cop_warnings;   /* lexical warnings bitmask */
30    SV *        cop_io;         /* lexical IO defaults */
31};
32
33#define Nullcop Null(COP*)
34
35#ifdef USE_ITHREADS
36#  define CopFILE(c)            ((c)->cop_file)
37#  define CopFILEGV(c)          (CopFILE(c) \
38                                 ? gv_fetchfile(CopFILE(c)) : Nullgv)
39                                 
40#  ifdef NETWARE
41#    define CopFILE_set(c,pv)   ((c)->cop_file = savepv(pv))
42#  else
43#    define CopFILE_set(c,pv)   ((c)->cop_file = savesharedpv(pv))
44#  endif
45
46#  define CopFILESV(c)          (CopFILE(c) \
47                                 ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv)
48#  define CopFILEAV(c)          (CopFILE(c) \
49                                 ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav)
50#  define CopSTASHPV(c)         ((c)->cop_stashpv)
51
52#  ifdef NETWARE
53#    define CopSTASHPV_set(c,pv)        ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch))
54#  else
55#    define CopSTASHPV_set(c,pv)        ((c)->cop_stashpv = savesharedpv(pv))
56#  endif
57
58#  define CopSTASH(c)           (CopSTASHPV(c) \
59                                 ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv)
60#  define CopSTASH_set(c,hv)    CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch)
61#  define CopSTASH_eq(c,hv)     ((hv)                                   \
62                                 && (CopSTASHPV(c) == HvNAME(hv)        \
63                                     || (CopSTASHPV(c) && HvNAME(hv)    \
64                                         && strEQ(CopSTASHPV(c), HvNAME(hv)))))
65#  ifdef NETWARE
66#    define CopSTASH_free(c) SAVECOPSTASH_FREE(c)
67#  else
68#    define CopSTASH_free(c)    PerlMemShared_free(CopSTASHPV(c))     
69#  endif
70
71#  ifdef NETWARE
72#    define CopFILE_free(c) SAVECOPFILE_FREE(c)
73#  else
74#    define CopFILE_free(c)     (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = Nullch))     
75#  endif
76#else
77#  define CopFILEGV(c)          ((c)->cop_filegv)
78#  define CopFILEGV_set(c,gv)   ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv))
79#  define CopFILE_set(c,pv)     CopFILEGV_set((c), gv_fetchfile(pv))
80#  define CopFILESV(c)          (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv)
81#  define CopFILEAV(c)          (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav)
82#  define CopFILE(c)            (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch)
83#  define CopSTASH(c)           ((c)->cop_stash)
84#  define CopSTASH_set(c,hv)    ((c)->cop_stash = (hv))
85#  define CopSTASHPV(c)         (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch)
86   /* cop_stash is not refcounted */
87#  define CopSTASHPV_set(c,pv)  CopSTASH_set((c), gv_stashpv(pv,GV_ADD))
88#  define CopSTASH_eq(c,hv)     (CopSTASH(c) == (hv))
89#  define CopSTASH_free(c)     
90#  define CopFILE_free(c)       (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = Nullgv))
91
92#endif /* USE_ITHREADS */
93
94#define CopSTASH_ne(c,hv)       (!CopSTASH_eq(c,hv))
95#define CopLINE(c)              ((c)->cop_line)
96#define CopLINE_inc(c)          (++CopLINE(c))
97#define CopLINE_dec(c)          (--CopLINE(c))
98#define CopLINE_set(c,l)        (CopLINE(c) = (l))
99
100/* OutCopFILE() is CopFILE for output (caller, die, warn, etc.) */
101#ifdef MACOS_TRADITIONAL
102#  define OutCopFILE(c) MacPerl_MPWFileName(CopFILE(c))
103#else
104#  define OutCopFILE(c) CopFILE(c)
105#endif
106
107/*
108 * Here we have some enormously heavy (or at least ponderous) wizardry.
109 */
110
111/* subroutine context */
112struct block_sub {
113    CV *        cv;
114    GV *        gv;
115    GV *        dfoutgv;
116#ifndef USE_5005THREADS
117    AV *        savearray;
118#endif /* USE_5005THREADS */
119    AV *        argarray;
120    long        olddepth;
121    U8          hasargs;
122    U8          lval;           /* XXX merge lval and hasargs? */
123    PAD         *oldcomppad;
124};
125
126/* base for the next two macros. Don't use directly */
127#define PUSHSUB_BASE(cx)                                                \
128        cx->blk_sub.cv = cv;                                            \
129        cx->blk_sub.olddepth = CvDEPTH(cv);                             \
130        cx->blk_sub.hasargs = hasargs;
131
132#define PUSHSUB(cx)                                                     \
133        PUSHSUB_BASE(cx)                                                \
134        cx->blk_sub.lval = PL_op->op_private &                          \
135                              (OPpLVAL_INTRO|OPpENTERSUB_INARGS);
136
137/* variant for use by OP_DBSTATE, where op_private holds hint bits */
138#define PUSHSUB_DB(cx)                                                  \
139        PUSHSUB_BASE(cx)                                                \
140        cx->blk_sub.lval = 0;
141
142
143#define PUSHFORMAT(cx)                                                  \
144        cx->blk_sub.cv = cv;                                            \
145        cx->blk_sub.gv = gv;                                            \
146        cx->blk_sub.hasargs = 0;                                        \
147        cx->blk_sub.dfoutgv = PL_defoutgv;                              \
148        (void)SvREFCNT_inc(cx->blk_sub.dfoutgv)
149
150#ifdef USE_5005THREADS
151#  define POP_SAVEARRAY() NOOP
152#else
153#  define POP_SAVEARRAY()                                               \
154    STMT_START {                                                        \
155        SvREFCNT_dec(GvAV(PL_defgv));                                   \
156        GvAV(PL_defgv) = cx->blk_sub.savearray;                         \
157    } STMT_END
158#endif /* USE_5005THREADS */
159
160/* junk in @_ spells trouble when cloning CVs and in pp_caller(), so don't
161 * leave any (a fast av_clear(ary), basically) */
162#define CLEAR_ARGARRAY(ary) \
163    STMT_START {                                                        \
164        AvMAX(ary) += AvARRAY(ary) - AvALLOC(ary);                      \
165        SvPVX(ary) = (char*)AvALLOC(ary);                               \
166        AvFILLp(ary) = -1;                                              \
167    } STMT_END
168
169#define POPSUB(cx,sv)                                                   \
170    STMT_START {                                                        \
171        if (cx->blk_sub.hasargs) {                                      \
172            POP_SAVEARRAY();                                            \
173            /* abandon @_ if it got reified */                          \
174            if (AvREAL(cx->blk_sub.argarray)) {                         \
175                SSize_t fill = AvFILLp(cx->blk_sub.argarray);           \
176                SvREFCNT_dec(cx->blk_sub.argarray);                     \
177                cx->blk_sub.argarray = newAV();                         \
178                av_extend(cx->blk_sub.argarray, fill);                  \
179                AvFLAGS(cx->blk_sub.argarray) = AVf_REIFY;              \
180                CX_CURPAD_SV(cx->blk_sub, 0) = (SV*)cx->blk_sub.argarray;       \
181            }                                                           \
182            else {                                                      \
183                CLEAR_ARGARRAY(cx->blk_sub.argarray);                   \
184            }                                                           \
185        }                                                               \
186        sv = (SV*)cx->blk_sub.cv;                                       \
187        if (sv && (CvDEPTH((CV*)sv) = cx->blk_sub.olddepth))            \
188            sv = Nullsv;                                                \
189    } STMT_END
190
191#define LEAVESUB(sv)                                                    \
192    STMT_START {                                                        \
193        if (sv)                                                         \
194            SvREFCNT_dec(sv);                                           \
195    } STMT_END
196
197#define POPFORMAT(cx)                                                   \
198        setdefout(cx->blk_sub.dfoutgv);                                 \
199        SvREFCNT_dec(cx->blk_sub.dfoutgv);
200
201/* eval context */
202struct block_eval {
203    I32         old_in_eval;
204    I32         old_op_type;
205    SV *        old_namesv;
206    OP *        old_eval_root;
207    SV *        cur_text;
208    CV *        cv;
209};
210
211#define PUSHEVAL(cx,n,fgv)                                              \
212    STMT_START {                                                        \
213        cx->blk_eval.old_in_eval = PL_in_eval;                          \
214        cx->blk_eval.old_op_type = PL_op->op_type;                      \
215        cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : Nullsv);          \
216        cx->blk_eval.old_eval_root = PL_eval_root;                      \
217        cx->blk_eval.cur_text = PL_linestr;                             \
218        cx->blk_eval.cv = Nullcv; /* set by doeval(), as applicable */  \
219    } STMT_END
220
221#define POPEVAL(cx)                                                     \
222    STMT_START {                                                        \
223        PL_in_eval = cx->blk_eval.old_in_eval;                          \
224        optype = cx->blk_eval.old_op_type;                              \
225        PL_eval_root = cx->blk_eval.old_eval_root;                      \
226        if (cx->blk_eval.old_namesv)                                    \
227            sv_2mortal(cx->blk_eval.old_namesv);                        \
228    } STMT_END
229
230/* loop context */
231struct block_loop {
232    char *      label;
233    I32         resetsp;
234    OP *        redo_op;
235    OP *        next_op;
236    OP *        last_op;
237#ifdef USE_ITHREADS
238    void *      iterdata;
239    PAD         *oldcomppad;
240#else
241    SV **       itervar;
242#endif
243    SV *        itersave;
244    SV *        iterlval;
245    AV *        iterary;
246    IV          iterix;
247    IV          itermax;
248};
249
250#ifdef USE_ITHREADS
251#  define CxITERVAR(c)                                                  \
252        ((c)->blk_loop.iterdata                                         \
253         ? (CxPADLOOP(cx)                                               \
254            ? &CX_CURPAD_SV( (c)->blk_loop,                             \
255                    INT2PTR(PADOFFSET, (c)->blk_loop.iterdata))         \
256            : &GvSV((GV*)(c)->blk_loop.iterdata))                       \
257         : (SV**)NULL)
258#  define CX_ITERDATA_SET(cx,idata)                                     \
259        CX_CURPAD_SAVE(cx->blk_loop);                                   \
260        if ((cx->blk_loop.iterdata = (idata)))                          \
261            cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx));       \
262        else                                                            \
263            cx->blk_loop.itersave = Nullsv;
264#else
265#  define CxITERVAR(c)          ((c)->blk_loop.itervar)
266#  define CX_ITERDATA_SET(cx,ivar)                                      \
267        if ((cx->blk_loop.itervar = (SV**)(ivar)))                      \
268            cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx));       \
269        else                                                            \
270            cx->blk_loop.itersave = Nullsv;
271#endif
272
273#define PUSHLOOP(cx, dat, s)                                            \
274        cx->blk_loop.label = PL_curcop->cop_label;                      \
275        cx->blk_loop.resetsp = s - PL_stack_base;                       \
276        cx->blk_loop.redo_op = cLOOP->op_redoop;                        \
277        cx->blk_loop.next_op = cLOOP->op_nextop;                        \
278        cx->blk_loop.last_op = cLOOP->op_lastop;                        \
279        cx->blk_loop.iterlval = Nullsv;                                 \
280        cx->blk_loop.iterary = Nullav;                                  \
281        cx->blk_loop.iterix = -1;                                       \
282        CX_ITERDATA_SET(cx,dat);
283
284#define POPLOOP(cx)                                                     \
285        SvREFCNT_dec(cx->blk_loop.iterlval);                            \
286        if (CxITERVAR(cx)) {                                            \
287            SV **s_v_p = CxITERVAR(cx);                                 \
288            sv_2mortal(*s_v_p);                                         \
289            *s_v_p = cx->blk_loop.itersave;                             \
290        }                                                               \
291        if (cx->blk_loop.iterary && cx->blk_loop.iterary != PL_curstack)\
292            SvREFCNT_dec(cx->blk_loop.iterary);
293
294/* context common to subroutines, evals and loops */
295struct block {
296    I32         blku_oldsp;     /* stack pointer to copy stuff down to */
297    COP *       blku_oldcop;    /* old curcop pointer */
298    I32         blku_oldretsp;  /* return stack index */
299    I32         blku_oldmarksp; /* mark stack index */
300    I32         blku_oldscopesp;        /* scope stack index */
301    PMOP *      blku_oldpm;     /* values of pattern match vars */
302    U8          blku_gimme;     /* is this block running in list context? */
303
304    union {
305        struct block_sub        blku_sub;
306        struct block_eval       blku_eval;
307        struct block_loop       blku_loop;
308    } blk_u;
309};
310#define blk_oldsp       cx_u.cx_blk.blku_oldsp
311#define blk_oldcop      cx_u.cx_blk.blku_oldcop
312#define blk_oldretsp    cx_u.cx_blk.blku_oldretsp
313#define blk_oldmarksp   cx_u.cx_blk.blku_oldmarksp
314#define blk_oldscopesp  cx_u.cx_blk.blku_oldscopesp
315#define blk_oldpm       cx_u.cx_blk.blku_oldpm
316#define blk_gimme       cx_u.cx_blk.blku_gimme
317#define blk_sub         cx_u.cx_blk.blk_u.blku_sub
318#define blk_eval        cx_u.cx_blk.blk_u.blku_eval
319#define blk_loop        cx_u.cx_blk.blk_u.blku_loop
320
321/* Enter a block. */
322#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix],            \
323        cx->cx_type             = t,                                    \
324        cx->blk_oldsp           = sp - PL_stack_base,                   \
325        cx->blk_oldcop          = PL_curcop,                            \
326        cx->blk_oldmarksp       = PL_markstack_ptr - PL_markstack,      \
327        cx->blk_oldscopesp      = PL_scopestack_ix,                     \
328        cx->blk_oldretsp        = PL_retstack_ix,                       \
329        cx->blk_oldpm           = PL_curpm,                             \
330        cx->blk_gimme           = (U8)gimme;                            \
331        DEBUG_l( PerlIO_printf(Perl_debug_log, "Entering block %ld, type %s\n", \
332                    (long)cxstack_ix, PL_block_type[CxTYPE(cx)]); )
333
334/* Exit a block (RETURN and LAST). */
335#define POPBLOCK(cx,pm) cx = &cxstack[cxstack_ix--],                    \
336        newsp            = PL_stack_base + cx->blk_oldsp,               \
337        PL_curcop        = cx->blk_oldcop,                              \
338        PL_markstack_ptr = PL_markstack + cx->blk_oldmarksp,            \
339        PL_scopestack_ix = cx->blk_oldscopesp,                          \
340        PL_retstack_ix   = cx->blk_oldretsp,                            \
341        pm               = cx->blk_oldpm,                               \
342        gimme            = cx->blk_gimme;                               \
343        DEBUG_SCOPE("POPBLOCK");                                        \
344        DEBUG_l( PerlIO_printf(Perl_debug_log, "Leaving block %ld, type %s\n",          \
345                    (long)cxstack_ix+1,PL_block_type[CxTYPE(cx)]); )
346
347/* Continue a block elsewhere (NEXT and REDO). */
348#define TOPBLOCK(cx) cx  = &cxstack[cxstack_ix],                        \
349        PL_stack_sp      = PL_stack_base + cx->blk_oldsp,               \
350        PL_markstack_ptr = PL_markstack + cx->blk_oldmarksp,            \
351        PL_scopestack_ix = cx->blk_oldscopesp,                          \
352        PL_retstack_ix   = cx->blk_oldretsp,                            \
353        PL_curpm         = cx->blk_oldpm;                               \
354        DEBUG_SCOPE("TOPBLOCK");
355
356/* substitution context */
357struct subst {
358    I32         sbu_iters;
359    I32         sbu_maxiters;
360    I32         sbu_rflags;
361    I32         sbu_oldsave;
362    bool        sbu_once;
363    bool        sbu_rxtainted;
364    char *      sbu_orig;
365    SV *        sbu_dstr;
366    SV *        sbu_targ;
367    char *      sbu_s;
368    char *      sbu_m;
369    char *      sbu_strend;
370    void *      sbu_rxres;
371    REGEXP *    sbu_rx;
372};
373#define sb_iters        cx_u.cx_subst.sbu_iters
374#define sb_maxiters     cx_u.cx_subst.sbu_maxiters
375#define sb_rflags       cx_u.cx_subst.sbu_rflags
376#define sb_oldsave      cx_u.cx_subst.sbu_oldsave
377#define sb_once         cx_u.cx_subst.sbu_once
378#define sb_rxtainted    cx_u.cx_subst.sbu_rxtainted
379#define sb_orig         cx_u.cx_subst.sbu_orig
380#define sb_dstr         cx_u.cx_subst.sbu_dstr
381#define sb_targ         cx_u.cx_subst.sbu_targ
382#define sb_s            cx_u.cx_subst.sbu_s
383#define sb_m            cx_u.cx_subst.sbu_m
384#define sb_strend       cx_u.cx_subst.sbu_strend
385#define sb_rxres        cx_u.cx_subst.sbu_rxres
386#define sb_rx           cx_u.cx_subst.sbu_rx
387
388#define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix],                 \
389        cx->sb_iters            = iters,                                \
390        cx->sb_maxiters         = maxiters,                             \
391        cx->sb_rflags           = r_flags,                              \
392        cx->sb_oldsave          = oldsave,                              \
393        cx->sb_once             = once,                                 \
394        cx->sb_rxtainted        = rxtainted,                            \
395        cx->sb_orig             = orig,                                 \
396        cx->sb_dstr             = dstr,                                 \
397        cx->sb_targ             = targ,                                 \
398        cx->sb_s                = s,                                    \
399        cx->sb_m                = m,                                    \
400        cx->sb_strend           = strend,                               \
401        cx->sb_rxres            = Null(void*),                          \
402        cx->sb_rx               = rx,                                   \
403        cx->cx_type             = CXt_SUBST;                            \
404        rxres_save(&cx->sb_rxres, rx)
405
406#define POPSUBST(cx) cx = &cxstack[cxstack_ix--];                       \
407        rxres_free(&cx->sb_rxres)
408
409struct context {
410    U32         cx_type;        /* what kind of context this is */
411    union {
412        struct block    cx_blk;
413        struct subst    cx_subst;
414    } cx_u;
415};
416
417#define CXTYPEMASK      0xff
418#define CXt_NULL        0
419#define CXt_SUB         1
420#define CXt_EVAL        2
421#define CXt_LOOP        3
422#define CXt_SUBST       4
423#define CXt_BLOCK       5
424#define CXt_FORMAT      6
425
426/* private flags for CXt_EVAL */
427#define CXp_REAL        0x00000100      /* truly eval'', not a lookalike */
428#define CXp_TRYBLOCK    0x00000200      /* eval{}, not eval'' or similar */
429
430#ifdef USE_ITHREADS
431/* private flags for CXt_LOOP */
432#  define CXp_PADVAR    0x00000100      /* itervar lives on pad, iterdata
433                                           has pad offset; if not set,
434                                           iterdata holds GV* */
435#  define CxPADLOOP(c)  (((c)->cx_type & (CXt_LOOP|CXp_PADVAR))         \
436                         == (CXt_LOOP|CXp_PADVAR))
437#endif
438
439#define CxTYPE(c)       ((c)->cx_type & CXTYPEMASK)
440#define CxREALEVAL(c)   (((c)->cx_type & (CXt_EVAL|CXp_REAL))           \
441                         == (CXt_EVAL|CXp_REAL))
442#define CxTRYBLOCK(c)   (((c)->cx_type & (CXt_EVAL|CXp_TRYBLOCK))       \
443                         == (CXt_EVAL|CXp_TRYBLOCK))
444
445#define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
446
447/*
448=head1 "Gimme" Values
449*/
450
451/*
452=for apidoc AmU||G_SCALAR
453Used to indicate scalar context.  See C<GIMME_V>, C<GIMME>, and
454L<perlcall>.
455
456=for apidoc AmU||G_ARRAY
457Used to indicate list context.  See C<GIMME_V>, C<GIMME> and
458L<perlcall>.
459
460=for apidoc AmU||G_VOID
461Used to indicate void context.  See C<GIMME_V> and L<perlcall>.
462
463=for apidoc AmU||G_DISCARD
464Indicates that arguments returned from a callback should be discarded.  See
465L<perlcall>.
466
467=for apidoc AmU||G_EVAL
468
469Used to force a Perl C<eval> wrapper around a callback.  See
470L<perlcall>.
471
472=for apidoc AmU||G_NOARGS
473
474Indicates that no arguments are being sent to a callback.  See
475L<perlcall>.
476
477=cut
478*/
479
480#define G_SCALAR        0
481#define G_ARRAY         1
482#define G_VOID          128     /* skip this bit when adding flags below */
483
484/* extra flags for Perl_call_* routines */
485#define G_DISCARD       2       /* Call FREETMPS. */
486#define G_EVAL          4       /* Assume eval {} around subroutine call. */
487#define G_NOARGS        8       /* Don't construct a @_ array. */
488#define G_KEEPERR      16       /* Append errors to $@, don't overwrite it */
489#define G_NODEBUG      32       /* Disable debugging at toplevel.  */
490#define G_METHOD       64       /* Calling method. */
491
492/* flag bits for PL_in_eval */
493#define EVAL_NULL       0       /* not in an eval */
494#define EVAL_INEVAL     1       /* some enclosing scope is an eval */
495#define EVAL_WARNONLY   2       /* used by yywarn() when calling yyerror() */
496#define EVAL_KEEPERR    4       /* set by Perl_call_sv if G_KEEPERR */
497#define EVAL_INREQUIRE  8       /* The code is being required. */
498
499/* Support for switching (stack and block) contexts.
500 * This ensures magic doesn't invalidate local stack and cx pointers.
501 */
502
503#define PERLSI_UNKNOWN          -1
504#define PERLSI_UNDEF            0
505#define PERLSI_MAIN             1
506#define PERLSI_MAGIC            2
507#define PERLSI_SORT             3
508#define PERLSI_SIGNAL           4
509#define PERLSI_OVERLOAD         5
510#define PERLSI_DESTROY          6
511#define PERLSI_WARNHOOK         7
512#define PERLSI_DIEHOOK          8
513#define PERLSI_REQUIRE          9
514
515struct stackinfo {
516    AV *                si_stack;       /* stack for current runlevel */
517    PERL_CONTEXT *      si_cxstack;     /* context stack for runlevel */
518    I32                 si_cxix;        /* current context index */
519    I32                 si_cxmax;       /* maximum allocated index */
520    I32                 si_type;        /* type of runlevel */
521    struct stackinfo *  si_prev;
522    struct stackinfo *  si_next;
523    I32                 si_markoff;     /* offset where markstack begins for us.
524                                         * currently used only with DEBUGGING,
525                                         * but not #ifdef-ed for bincompat */
526};
527
528typedef struct stackinfo PERL_SI;
529
530#define cxstack         (PL_curstackinfo->si_cxstack)
531#define cxstack_ix      (PL_curstackinfo->si_cxix)
532#define cxstack_max     (PL_curstackinfo->si_cxmax)
533
534#ifdef DEBUGGING
535#  define       SET_MARK_OFFSET \
536    PL_curstackinfo->si_markoff = PL_markstack_ptr - PL_markstack
537#else
538#  define       SET_MARK_OFFSET NOOP
539#endif
540
541#define PUSHSTACKi(type) \
542    STMT_START {                                                        \
543        PERL_SI *next = PL_curstackinfo->si_next;                       \
544        if (!next) {                                                    \
545            next = new_stackinfo(32, 2048/sizeof(PERL_CONTEXT) - 1);    \
546            next->si_prev = PL_curstackinfo;                            \
547            PL_curstackinfo->si_next = next;                            \
548        }                                                               \
549        next->si_type = type;                                           \
550        next->si_cxix = -1;                                             \
551        AvFILLp(next->si_stack) = 0;                                    \
552        SWITCHSTACK(PL_curstack,next->si_stack);                        \
553        PL_curstackinfo = next;                                         \
554        SET_MARK_OFFSET;                                                \
555    } STMT_END
556
557#define PUSHSTACK PUSHSTACKi(PERLSI_UNKNOWN)
558
559/* POPSTACK works with PL_stack_sp, so it may need to be bracketed by
560 * PUTBACK/SPAGAIN to flush/refresh any local SP that may be active */
561#define POPSTACK \
562    STMT_START {                                                        \
563        dSP;                                                            \
564        PERL_SI *prev = PL_curstackinfo->si_prev;                       \
565        if (!prev) {                                                    \
566            PerlIO_printf(Perl_error_log, "panic: POPSTACK\n");         \
567            my_exit(1);                                                 \
568        }                                                               \
569        SWITCHSTACK(PL_curstack,prev->si_stack);                        \
570        /* don't free prev here, free them all at the END{} */          \
571        PL_curstackinfo = prev;                                         \
572    } STMT_END
573
574#define POPSTACK_TO(s) \
575    STMT_START {                                                        \
576        while (PL_curstack != s) {                                      \
577            dounwind(-1);                                               \
578            POPSTACK;                                                   \
579        }                                                               \
580    } STMT_END
581
582#define IN_PERL_COMPILETIME     (PL_curcop == &PL_compiling)
583#define IN_PERL_RUNTIME         (PL_curcop != &PL_compiling)
584
Note: See TracBrowser for help on using the repository browser.