scope.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
#define SAVEt_ITEM 0
#define SAVEt_SV 1
#define SAVEt_AV 2
#define SAVEt_HV 3
#define SAVEt_INT 4
#define SAVEt_LONG 5
#define SAVEt_I32 6
#define SAVEt_IV 7
#define SAVEt_SPTR 8
#define SAVEt_APTR 9
#define SAVEt_HPTR 10
#define SAVEt_PPTR 11
#define SAVEt_NSTAB 12
#define SAVEt_SVREF 13
#define SAVEt_GP 14
#define SAVEt_FREESV 15
#define SAVEt_FREEOP 16
#define SAVEt_FREEPV 17
#define SAVEt_CLEARSV 18
#define SAVEt_DELETE 19
#define SAVEt_DESTRUCTOR 20
#define SAVEt_REGCONTEXT 21
#define SAVEt_STACK_POS 22
#define SAVEt_I16 23
#define SAVEt_AELEM 24
#define SAVEt_HELEM 25
#define SAVEt_OP 26
#define SAVEt_HINTS 27
#define SAVEt_ALLOC 28
#define SAVEt_GENERIC_SVREF 29
#define SAVEt_DESTRUCTOR_X 30
#define SAVEt_VPTR 31
#define SAVEt_I8 32
#define SAVEt_COMPPAD 33
#define SAVEt_GENERIC_PVREF 34
#define SAVEt_PADSV 35
#define SAVEt_MORTALIZESV 36
/*
=for apidoc Ams||SAVETMPS
Opening bracket for temporaries on a callback. See C<FREETMPS> and
L<perlcall>.
=for apidoc Ams||FREETMPS
Closing bracket for temporaries on a callback. See C<SAVETMPS> and
L<perlcall>.
=for apidoc Ams||ENTER
Opening bracket on a callback. See C<LEAVE> and L<perlcall>.
=for apidoc Ams||LEAVE
Closing bracket on a callback. See C<ENTER> and L<perlcall>.
=cut
*/
#ifdef DEBUGGING
#define ENTER \
STMT_START { \
push_scope(); \
} STMT_END
#define LEAVE \
STMT_START { \
pop_scope(); \
} STMT_END
#else
#define ENTER push_scope()
#endif
/*
* Not using SOFT_CAST on SAVESPTR, SAVEGENERICSV and SAVEFREESV
* because these are used for several kinds of pointer values
*/
#define SAVEPADSV(s) save_padsv(s)
#define SAVEGENERICPV(s) save_generic_pvref((char**)&(s))
#define SAVEDELETE(h,k,l) \
#define SAVEDESTRUCTOR(f,p) \
#define SAVEDESTRUCTOR_X(f,p) \
#define SAVESTACK_POS() \
STMT_START { \
SSCHECK(2); \
} STMT_END
#define SAVEHINTS() \
STMT_START { \
if (PL_hints & HINT_LOCALIZE_HH) \
save_hints(); \
else { \
SSCHECK(2); \
SSPUSHINT(SAVEt_HINTS); \
} \
} STMT_END
#define SAVECOMPPAD() \
STMT_START { \
SSCHECK(2); \
} \
else { \
SAVESPTR(PL_comppad); \
} \
} STMT_END
#ifdef USE_ITHREADS
#else
#endif
/* SSNEW() temporarily allocates a specified number of bytes of data on the
* savestack. It returns an integer index into the savestack, because a
* pointer would get broken if the savestack is moved on reallocation.
* SSNEWa() works like SSNEW(), but also aligns the data to the specified
* number of bytes. MEM_ALIGNBYTES is perhaps the most useful. The
* alignment will be preserved therough savestack reallocation *only* if
* realloc returns data aligned to a size divisible by `align'!
*
*/
/* A jmpenv packages the state required to perform a proper non-local jump.
* Note that there is a start_env initialized when perl starts, and top_env
* points to this initially, so top_env should always be non-null.
*
* Existence of a non-null top_env->je_prev implies it is valid to call
* longjmp() at that runlevel (we make sure start_env.je_prev is always
* null to ensure this).
*
* je_mustcatch, when set at any runlevel to TRUE, means eval ops must
* establish a local jmpenv to handle exception traps. Care must be taken
* to restore the previous value of je_mustcatch before exiting the
* stack frame iff JMPENV_PUSH was not called in that stack frame.
* GSAR 97-03-27
*/
struct jmpenv {
int je_ret; /* last exception thrown */
bool je_mustcatch; /* need to call longjmp()? */
#ifdef PERL_FLEXIBLE_EXCEPTIONS
void (*je_throw)(int v); /* last for bincompat */
bool je_noset; /* no need for setjmp() */
#endif
};
#ifdef OP_IN_REGISTER
#else
#define OP_REG_TO_MEM NOOP
#define OP_MEM_TO_REG NOOP
#endif
/*
* How to build the first jmpenv.
*
* top_env needs to be non-zero. It points to an area
* in which longjmp() stuff is stored, as C callstack
* info there at least is thread specific this has to
* be per-thread. Otherwise a 'die' in a thread gives
* that thread the C stack of last thread to do an eval {}!
*/
#define JMPENV_BOOTSTRAP \
STMT_START { \
PL_top_env = &PL_start_env; \
} STMT_END
#ifdef PERL_FLEXIBLE_EXCEPTIONS
/*
* These exception-handling macros are split up to
* ease integration with C++ exceptions.
*
* To use C++ try+catch to catch Perl exceptions, an extension author
* needs to first write an extern "C" function to throw an appropriate
* exception object; typically it will be or contain an integer,
* because Perl's internals use integers to track exception types:
* extern "C" { static void thrower(int i) { throw i; } }
*
* Then (as shown below) the author needs to use, not the simple
* JMPENV_PUSH, but several of its constitutent macros, to arrange for
* the Perl internals to call thrower() rather than longjmp() to
* report exceptions:
*
* dJMPENV;
* JMPENV_PUSH_INIT(thrower);
* try {
* ... stuff that may throw exceptions ...
* }
* catch (int why) { // or whatever matches thrower()
* JMPENV_POST_CATCH;
* EXCEPT_SET(why);
* switch (why) {
* ... // handle various Perl exception codes
* }
* }
* JMPENV_POP; // don't forget this!
*/
/*
* body of protected processing.
*/
int *, protect_body_t, ...);
STMT_START { \
PL_top_env = &(ce); \
} STMT_END
#define JMPENV_POST_CATCH_ENV(ce) \
STMT_START { \
PL_top_env = &(ce); \
} STMT_END
#define JMPENV_PUSH_ENV(ce,v) \
STMT_START { \
ce, PL_top_env)); \
} \
else \
EXCEPT_SET_ENV(ce,0); \
(v) = EXCEPT_GET_ENV(ce); \
} STMT_END
#define JMPENV_POP_ENV(ce) \
STMT_START { \
if (PL_top_env == &(ce)) \
} STMT_END
#define JMPENV_JUMP(v) \
STMT_START { \
if (PL_top_env->je_prev) { \
if (PL_top_env->je_throw) \
PL_top_env->je_throw(v); \
else \
} \
if ((v) == 2) \
PerlProc_exit(1); \
} STMT_END
#else /* !PERL_FLEXIBLE_EXCEPTIONS */
#define JMPENV_PUSH(v) \
STMT_START { \
&cur_env, PL_top_env)); \
PL_top_env = &cur_env; \
} STMT_END
#define JMPENV_POP \
#define JMPENV_JUMP(v) \
STMT_START { \
if (PL_top_env->je_prev) \
if ((v) == 2) \
PerlProc_exit(1); \
} STMT_END
#endif /* PERL_FLEXIBLE_EXCEPTIONS */