📄 cop.h
字号:
? (CxPADLOOP(cx) \ ? &CX_CURPAD_SV( (c)->blk_loop, \ INT2PTR(PADOFFSET, (c)->blk_loop.iterdata)) \ : &GvSV((GV*)(c)->blk_loop.iterdata)) \ : (SV**)NULL)# define CX_ITERDATA_SET(cx,idata) \ CX_CURPAD_SAVE(cx->blk_loop); \ if ((cx->blk_loop.iterdata = (idata))) \ cx->blk_loop.itersave = SvREFCNT_inc(*CxITERVAR(cx)); \ else \ cx->blk_loop.itersave = NULL;#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)); \ else \ cx->blk_loop.itersave = NULL;#endif#ifdef USE_ITHREADS# define PUSHLOOP_OP_NEXT /* No need to do anything. */# define CX_LOOP_NEXTOP_GET(cx) ((cx)->blk_loop.my_op->op_nextop + 0)#else# define PUSHLOOP_OP_NEXT cx->blk_loop.next_op = cLOOP->op_nextop# define CX_LOOP_NEXTOP_GET(cx) ((cx)->blk_loop.next_op + 0)#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.my_op = cLOOP; \ PUSHLOOP_OP_NEXT; \ cx->blk_loop.iterlval = NULL; \ cx->blk_loop.iterary = NULL; \ cx->blk_loop.iterix = -1; \ CX_ITERDATA_SET(cx,dat);#define POPLOOP(cx) \ SvREFCNT_dec(cx->blk_loop.iterlval); \ if (CxITERVAR(cx)) { \ if (SvPADMY(cx->blk_loop.itersave)) { \ SV ** const s_v_p = CxITERVAR(cx); \ sv_2mortal(*s_v_p); \ *s_v_p = cx->blk_loop.itersave; \ } \ else { \ SvREFCNT_dec(cx->blk_loop.itersave); \ } \ } \ if (cx->blk_loop.iterary && cx->blk_loop.iterary != PL_curstack)\ SvREFCNT_dec(cx->blk_loop.iterary);/* given/when context */struct block_givwhen { OP *leave_op;};#define PUSHGIVEN(cx) \ cx->blk_givwhen.leave_op = cLOGOP->op_other;#define PUSHWHEN PUSHGIVEN/* context common to subroutines, evals and loops */struct block { U16 blku_type; /* what kind of context this is */ U8 blku_gimme; /* is this block running in list context? */ U8 blku_spare; /* Padding to match with struct subst */ I32 blku_oldsp; /* stack pointer to copy stuff down to */ COP * blku_oldcop; /* old curcop pointer */ I32 blku_oldmarksp; /* mark stack index */ I32 blku_oldscopesp; /* scope stack index */ PMOP * blku_oldpm; /* values of pattern match vars */ union { struct block_sub blku_sub; struct block_eval blku_eval; struct block_loop blku_loop; struct block_givwhen blku_givwhen; } blk_u;};#define blk_oldsp cx_u.cx_blk.blku_oldsp#define blk_oldcop cx_u.cx_blk.blku_oldcop#define blk_oldmarksp cx_u.cx_blk.blku_oldmarksp#define blk_oldscopesp cx_u.cx_blk.blku_oldscopesp#define blk_oldpm cx_u.cx_blk.blku_oldpm#define blk_gimme cx_u.cx_blk.blku_gimme#define blk_sub cx_u.cx_blk.blk_u.blku_sub#define blk_eval cx_u.cx_blk.blk_u.blku_eval#define blk_loop cx_u.cx_blk.blk_u.blku_loop#define blk_givwhen cx_u.cx_blk.blk_u.blku_givwhen/* Enter a block. */#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \ cx->cx_type = t, \ cx->blk_oldsp = sp - PL_stack_base, \ cx->blk_oldcop = PL_curcop, \ cx->blk_oldmarksp = PL_markstack_ptr - PL_markstack, \ cx->blk_oldscopesp = PL_scopestack_ix, \ cx->blk_oldpm = PL_curpm, \ cx->blk_gimme = (U8)gimme; \ DEBUG_l( PerlIO_printf(Perl_debug_log, "Entering block %ld, type %s\n", \ (long)cxstack_ix, PL_block_type[CxTYPE(cx)]); )/* Exit a block (RETURN and LAST). */#define POPBLOCK(cx,pm) cx = &cxstack[cxstack_ix--], \ newsp = PL_stack_base + cx->blk_oldsp, \ PL_curcop = cx->blk_oldcop, \ PL_markstack_ptr = PL_markstack + cx->blk_oldmarksp, \ PL_scopestack_ix = cx->blk_oldscopesp, \ pm = cx->blk_oldpm, \ gimme = cx->blk_gimme; \ DEBUG_SCOPE("POPBLOCK"); \ DEBUG_l( PerlIO_printf(Perl_debug_log, "Leaving block %ld, type %s\n", \ (long)cxstack_ix+1,PL_block_type[CxTYPE(cx)]); )/* Continue a block elsewhere (NEXT and REDO). */#define TOPBLOCK(cx) cx = &cxstack[cxstack_ix], \ PL_stack_sp = PL_stack_base + cx->blk_oldsp, \ PL_markstack_ptr = PL_markstack + cx->blk_oldmarksp, \ PL_scopestack_ix = cx->blk_oldscopesp, \ PL_curpm = cx->blk_oldpm; \ DEBUG_SCOPE("TOPBLOCK");/* substitution context */struct subst { U16 sbu_type; /* what kind of context this is */ U8 sbu_once; /* Actually both booleans, but U8 to matches */ U8 sbu_rxtainted; /* struct block */ I32 sbu_iters; I32 sbu_maxiters; I32 sbu_rflags; I32 sbu_oldsave; char * sbu_orig; SV * sbu_dstr; SV * sbu_targ; char * sbu_s; char * sbu_m; char * sbu_strend; void * sbu_rxres; REGEXP * sbu_rx;};#define sb_iters cx_u.cx_subst.sbu_iters#define sb_maxiters cx_u.cx_subst.sbu_maxiters#define sb_rflags cx_u.cx_subst.sbu_rflags#define sb_oldsave cx_u.cx_subst.sbu_oldsave#define sb_once cx_u.cx_subst.sbu_once#define sb_rxtainted cx_u.cx_subst.sbu_rxtainted#define sb_orig cx_u.cx_subst.sbu_orig#define sb_dstr cx_u.cx_subst.sbu_dstr#define sb_targ cx_u.cx_subst.sbu_targ#define sb_s cx_u.cx_subst.sbu_s#define sb_m cx_u.cx_subst.sbu_m#define sb_strend cx_u.cx_subst.sbu_strend#define sb_rxres cx_u.cx_subst.sbu_rxres#define sb_rx cx_u.cx_subst.sbu_rx#define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \ cx->sb_iters = iters, \ cx->sb_maxiters = maxiters, \ cx->sb_rflags = r_flags, \ cx->sb_oldsave = oldsave, \ cx->sb_once = once, \ cx->sb_rxtainted = rxtainted, \ cx->sb_orig = orig, \ cx->sb_dstr = dstr, \ cx->sb_targ = targ, \ cx->sb_s = s, \ cx->sb_m = m, \ cx->sb_strend = strend, \ cx->sb_rxres = NULL, \ cx->sb_rx = rx, \ cx->cx_type = CXt_SUBST; \ rxres_save(&cx->sb_rxres, rx); \ (void)ReREFCNT_inc(rx)#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \ rxres_free(&cx->sb_rxres); \ ReREFCNT_dec(cx->sb_rx)struct context { union { struct block cx_blk; struct subst cx_subst; } cx_u;};#define cx_type cx_u.cx_subst.sbu_type#define CXTYPEMASK 0xff#define CXt_NULL 0#define CXt_SUB 1#define CXt_EVAL 2#define CXt_LOOP 3#define CXt_SUBST 4#define CXt_BLOCK 5#define CXt_FORMAT 6#define CXt_GIVEN 7#define CXt_WHEN 8/* private flags for CXt_SUB and CXt_NULL */#define CXp_MULTICALL 0x00000400 /* part of a multicall (so don't tear down context on exit). */ /* private flags for CXt_EVAL */#define CXp_REAL 0x00000100 /* truly eval'', not a lookalike */#define CXp_TRYBLOCK 0x00000200 /* eval{}, not eval'' or similar *//* private flags for CXt_LOOP */#define CXp_FOREACH 0x00000200 /* a foreach loop */#define CXp_FOR_DEF 0x00000400 /* foreach using $_ */#ifdef USE_ITHREADS# 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 CxMULTICALL(c) (((c)->cx_type & CXp_MULTICALL) \ == CXp_MULTICALL)#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 CxFOREACH(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH)) \ == (CXt_LOOP|CXp_FOREACH))#define CxFOREACHDEF(c) (((c)->cx_type & (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF))\ == (CXt_LOOP|CXp_FOREACH|CXp_FOR_DEF))#define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))/* =head1 "Gimme" Values*//*=for apidoc AmU||G_SCALARUsed to indicate scalar context. See C<GIMME_V>, C<GIMME>, andL<perlcall>.=for apidoc AmU||G_ARRAYUsed to indicate list context. See C<GIMME_V>, C<GIMME> andL<perlcall>.=for apidoc AmU||G_VOIDUsed to indicate void context. See C<GIMME_V> and L<perlcall>.=for apidoc AmU||G_DISCARDIndicates that arguments returned from a callback should be discarded. SeeL<perlcall>.=for apidoc AmU||G_EVALUsed to force a Perl C<eval> wrapper around a callback. SeeL<perlcall>.=for apidoc AmU||G_NOARGSIndicates that no arguments are being sent to a callback. SeeL<perlcall>.=cut*/#define G_SCALAR 0#define G_ARRAY 1#define G_VOID 128 /* skip this bit when adding flags below *//* extra flags for Perl_call_* routines */#define G_DISCARD 2 /* Call FREETMPS. Don't change this without consulting the hash actions codes defined in hv.h */#define G_EVAL 4 /* Assume eval {} around subroutine call. */#define G_NOARGS 8 /* Don't construct a @_ array. */#define G_KEEPERR 16 /* Append errors to $@, don't overwrite it */#define G_NODEBUG 32 /* Disable debugging at toplevel. */#define G_METHOD 64 /* Calling method. */#define G_FAKINGEVAL 256 /* Faking an eval context for call_sv or fold_constants. *//* flag bits for PL_in_eval */#define EVAL_NULL 0 /* not in an eval */#define EVAL_INEVAL 1 /* some enclosing scope is an eval */#define EVAL_WARNONLY 2 /* used by yywarn() when calling yyerror() */#define EVAL_KEEPERR 4 /* set by Perl_call_sv if G_KEEPERR */#define EVAL_INREQUIRE 8 /* The code is being required. *//* Support for switching (stack and block) contexts. * This ensures magic doesn't invalidate local stack and cx pointers. */#define PERLSI_UNKNOWN -1#define PERLSI_UNDEF 0#define PERLSI_MAIN 1#define PERLSI_MAGIC 2#define PERLSI_SORT 3#define PERLSI_SIGNAL 4#define PERLSI_OVERLOAD 5#define PERLSI_DESTROY 6#define PERLSI_WARNHOOK 7#define PERLSI_DIEHOOK 8#define PERLSI_REQUIRE 9struct stackinfo { AV * si_stack; /* stack for current runlevel */ PERL_CONTEXT * si_cxstack; /* context stack for runlevel */ struct stackinfo * si_prev; struct stackinfo * si_next; I32 si_cxix; /* current context index */ I32 si_cxmax; /* maximum allocated index */ I32 si_type; /* type of runlevel */ I32 si_markoff; /* offset where markstack begins for us. * currently used only with DEBUGGING, * but not #ifdef-ed for bincompat */};typedef struct stackinfo PERL_SI;#define cxstack (PL_curstackinfo->si_cxstack)#define cxstack_ix (PL_curstackinfo->si_cxix)#define cxstack_max (PL_curstackinfo->si_cxmax)#ifdef DEBUGGING# define SET_MARK_OFFSET \ PL_curstackinfo->si_markoff = PL_markstack_ptr - PL_markstack#else# define SET_MARK_OFFSET NOOP#endif#define PUSHSTACKi(type) \ STMT_START { \ PERL_SI *next = PL_curstackinfo->si_next; \ if (!next) { \ next = new_stackinfo(32, 2048/sizeof(PERL_CONTEXT) - 1); \ next->si_prev = PL_curstackinfo; \ PL_curstackinfo->si_next = next; \ } \ next->si_type = type; \ next->si_cxix = -1; \ AvFILLp(next->si_stack) = 0; \ SWITCHSTACK(PL_curstack,next->si_stack); \ PL_curstackinfo = next; \ SET_MARK_OFFSET; \ } STMT_END#define PUSHSTACK PUSHSTACKi(PERLSI_UNKNOWN)/* POPSTACK works with PL_stack_sp, so it may need to be bracketed by * PUTBACK/SPAGAIN to flush/refresh any local SP that may be active */#define POPSTACK \ STMT_START { \ dSP; \ PERL_SI * const prev = PL_curstackinfo->si_prev; \ if (!prev) { \ PerlIO_printf(Perl_error_log, "panic: POPSTACK\n"); \ my_exit(1); \ } \ SWITCHSTACK(PL_curstack,prev->si_stack); \ /* don't free prev here, free them all at the END{} */ \ PL_curstackinfo = prev; \ } STMT_END#define POPSTACK_TO(s) \ STMT_START { \ while (PL_curstack != s) { \ dounwind(-1); \ POPSTACK; \ } \ } STMT_END#define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling)#define IN_PERL_RUNTIME (PL_curcop != &PL_compiling)/*=head1 Multicall Functions=for apidoc Ams||dMULTICALLDeclare local variables for a multicall. See L<perlcall/Lightweight Callbacks>.=for apidoc Ams||PUSH_MULTICALLOpening bracket for a lightweight callback.See L<perlcall/Lightweight Callbacks>.=for apidoc Ams||MULTICALLMake a lightweight callback. See L<perlcall/Lightweight Callbacks>.=for apidoc Ams||POP_MULTICALLClosing bracket for a lightweight callback.See L<perlcall/Lightweight Callbacks>.=cut*/#define dMULTICALL \ SV **newsp; /* set by POPBLOCK */ \ PERL_CONTEXT *cx; \ CV *multicall_cv; \ OP *multicall_cop; \ bool multicall_oldcatch; \ U8 hasargs = 0 /* used by PUSHSUB */#define PUSH_MULTICALL(the_cv) \ STMT_START { \ CV * const _nOnclAshIngNamE_ = the_cv; \ CV * const cv = _nOnclAshIngNamE_; \ AV * const padlist = CvPADLIST(cv); \ ENTER; \ multicall_oldcatch = CATCH_GET; \ SAVETMPS; SAVEVPTR(PL_op); \ CATCH_SET(TRUE); \ PUSHBLOCK(cx, CXt_SUB|CXp_MULTICALL, PL_stack_sp); \ PUSHSUB(cx); \ if (++CvDEPTH(cv) >= 2) { \ PERL_STACK_OVERFLOW_CHECK(); \ Perl_pad_push(aTHX_ padlist, CvDEPTH(cv)); \ } \ SAVECOMPPAD(); \ PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv)); \ multicall_cv = cv; \ multicall_cop = CvSTART(cv); \ } STMT_END#define MULTICALL \ STMT_START { \ PL_op = multicall_cop; \ CALLRUNOPS(aTHX); \ } STMT_END#define POP_MULTICALL \ STMT_START { \ LEAVESUB(multicall_cv); \ CvDEPTH(multicall_cv)--; \ POPBLOCK(cx,PL_curpm); \ CATCH_SET(multicall_oldcatch); \ LEAVE; \ } STMT_END/* * Local variables: * c-indentation-style: bsd * c-basic-offset: 4 * indent-tabs-mode: t * End: * * ex: set ts=8 sts=4 sw=4 noet: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -