⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multicall.h

📁 source of perl for linux application,
💻 H
字号:
/*    multicall.h		(version 1.0) * * Implements a poor-man's MULTICALL interface for old versions * of perl that don't offer a proper one. Intended to be compatible * with 5.6.0 and later. * */#ifdef dMULTICALL#define REAL_MULTICALL#else#undef REAL_MULTICALL/* In versions of perl where MULTICALL is not defined (i.e. prior * to 5.9.4), Perl_pad_push is not exported either. It also has * an extra argument in older versions; certainly in the 5.8 series. * So we redefine it here. */#ifndef AVf_REIFY#  ifdef SVpav_REIFY#    define AVf_REIFY SVpav_REIFY#  else#    error Neither AVf_REIFY nor SVpav_REIFY is defined#  endif#endif#ifndef AvFLAGS#  define AvFLAGS SvFLAGS#endifstatic voidmulticall_pad_push(pTHX_ AV *padlist, int depth){    if (depth <= AvFILLp(padlist))	return;    {	SV** const svp = AvARRAY(padlist);	AV* const newpad = newAV();	SV** const oldpad = AvARRAY(svp[depth-1]);	I32 ix = AvFILLp((AV*)svp[1]);        const I32 names_fill = AvFILLp((AV*)svp[0]);	SV** const names = AvARRAY(svp[0]);	AV *av;	for ( ;ix > 0; ix--) {	    if (names_fill >= ix && names[ix] != &PL_sv_undef) {		const char sigil = SvPVX(names[ix])[0];		if ((SvFLAGS(names[ix]) & SVf_FAKE) || sigil == '&') {		    /* outer lexical or anon code */		    av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));		}		else {		/* our own lexical */		    SV *sv; 		    if (sigil == '@')			sv = (SV*)newAV();		    else if (sigil == '%')			sv = (SV*)newHV();		    else			sv = NEWSV(0, 0);		    av_store(newpad, ix, sv);		    SvPADMY_on(sv);		}	    }	    else if (IS_PADGV(oldpad[ix]) || IS_PADCONST(oldpad[ix])) {		av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));	    }	    else {		/* save temporaries on recursion? */		SV * const sv = NEWSV(0, 0);		av_store(newpad, ix, sv);		SvPADTMP_on(sv);	    }	}	av = newAV();	av_extend(av, 0);	av_store(newpad, 0, (SV*)av);	AvFLAGS(av) = AVf_REIFY;	av_store(padlist, depth, (SV*)newpad);	AvFILLp(padlist) = depth;    }}#define dMULTICALL \    SV **newsp;			/* set by POPBLOCK */			\    PERL_CONTEXT *cx;							\    CV *multicall_cv;							\    OP *multicall_cop;							\    bool multicall_oldcatch;						\    U8 hasargs = 0/* Between 5.9.1 and 5.9.2 the retstack was removed, and the   return op is now stored on the cxstack. */#define HAS_RETSTACK (\  PERL_REVISION < 5 || \  (PERL_REVISION == 5 && PERL_VERSION < 9) || \  (PERL_REVISION == 5 && PERL_VERSION == 9 && PERL_SUBVERSION < 2) \)/* PUSHSUB is defined so differently on different versions of perl * that it's easier to define our own version than code for all the * different possibilities. */#if HAS_RETSTACK#  define PUSHSUB_RETSTACK(cx)#else#  define PUSHSUB_RETSTACK(cx) cx->blk_sub.retop = Nullop;#endif#define MULTICALL_PUSHSUB(cx, the_cv) \        cx->blk_sub.cv = the_cv;					\        cx->blk_sub.olddepth = CvDEPTH(the_cv);				\        cx->blk_sub.hasargs = hasargs;					\        cx->blk_sub.lval = PL_op->op_private &				\                              (OPpLVAL_INTRO|OPpENTERSUB_INARGS);	\	PUSHSUB_RETSTACK(cx)						\        if (!CvDEPTH(the_cv)) {						\            (void)SvREFCNT_inc(the_cv);					\            (void)SvREFCNT_inc(the_cv);					\            SAVEFREESV(the_cv);						\        }#define PUSH_MULTICALL(the_cv) \    STMT_START {							\	CV *_nOnclAshIngNamE_ = the_cv;					\	AV* padlist = CvPADLIST(_nOnclAshIngNamE_);			\	multicall_cv = _nOnclAshIngNamE_;				\	ENTER;								\ 	multicall_oldcatch = CATCH_GET;					\	SAVESPTR(CvROOT(multicall_cv)->op_ppaddr);			\	CvROOT(multicall_cv)->op_ppaddr = PL_ppaddr[OP_NULL];		\	SAVETMPS; SAVEVPTR(PL_op);					\	CATCH_SET(TRUE);						\	PUSHSTACKi(PERLSI_SORT);					\	PUSHBLOCK(cx, CXt_SUB, PL_stack_sp);				\	MULTICALL_PUSHSUB(cx, multicall_cv);				\	if (++CvDEPTH(multicall_cv) >= 2) {				\	    PERL_STACK_OVERFLOW_CHECK();				\	    multicall_pad_push(aTHX_ padlist, CvDEPTH(multicall_cv));	\	}								\	SAVECOMPPAD();							\	PL_comppad = (AV*) (AvARRAY(padlist)[CvDEPTH(multicall_cv)]);	\	PL_curpad = AvARRAY(PL_comppad);				\	multicall_cop = CvSTART(multicall_cv);				\    } STMT_END#define MULTICALL \    STMT_START {							\	PL_op = multicall_cop;						\	CALLRUNOPS(aTHX);						\    } STMT_END#define POP_MULTICALL \    STMT_START {							\	CvDEPTH(multicall_cv)--;					\	LEAVESUB(multicall_cv);						\	POPBLOCK(cx,PL_curpm);						\	POPSTACK;							\	CATCH_SET(multicall_oldcatch);					\	LEAVE;								\        SPAGAIN;                                                        \    } STMT_END#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -