home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl560.zip / cop.h < prev    next >
C/C++ Source or Header  |  2000-03-20  |  16KB  |  515 lines

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