From: Dave Mitchell Date: Mon, 2 May 2005 13:29:17 +0000 (+0000) Subject: move the SETJMP exception-handing definitions from scope.h to cop.h X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0d2925a66a645be5c94e85ffc665c445ed1ca94c;p=p5sagit%2Fp5-mst-13.2.git move the SETJMP exception-handing definitions from scope.h to cop.h so that a JMPENV* entry can be added to struct block_eval p4raw-id: //depot/perl@24361 --- diff --git a/cop.h b/cop.h index bddc328..172c265 100644 --- a/cop.h +++ b/cop.h @@ -13,6 +13,126 @@ * and thus can be used to determine our current state. */ +/* 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 { + struct jmpenv * je_prev; + Sigjmp_buf je_buf; /* only for use if !je_throw */ + int je_ret; /* last exception thrown */ + bool je_mustcatch; /* need to call longjmp()? */ +}; + +typedef struct jmpenv JMPENV; + +#ifdef OP_IN_REGISTER +#define OP_REG_TO_MEM PL_opsave = op +#define OP_MEM_TO_REG op = PL_opsave +#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 { \ + Zero(&PL_start_env, 1, JMPENV); \ + PL_start_env.je_ret = -1; \ + PL_start_env.je_mustcatch = TRUE; \ + PL_top_env = &PL_start_env; \ + } STMT_END + +/* + * PERL_FLEXIBLE_EXCEPTIONS + * + * All the flexible exceptions code has been removed. + * See the following threads for details: + * + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2004-07/msg00378.html + * + * Joshua's original patches (which weren't applied) and discussion: + * + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01396.html + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01489.html + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01491.html + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01608.html + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg02144.html + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg02998.html + * + * Chip's reworked patch and discussion: + * + * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-03/msg00520.html + * + * The flaw in these patches (which went unnoticed at the time) was + * that they moved some code that could potentially die() out of the + * region protected by the setjmp()s. This caused exceptions within + * END blocks and such to not be handled by the correct setjmp(). + * + * The original patches that introduces flexible exceptions were: + * + * http://public.activestate.com/cgi-bin/perlbrowse?patch=3386 + * http://public.activestate.com/cgi-bin/perlbrowse?patch=5162 + */ + +#define dJMPENV JMPENV cur_env + +#define JMPENV_PUSH(v) \ + STMT_START { \ + DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p\n", \ + &cur_env, PL_top_env)); \ + cur_env.je_prev = PL_top_env; \ + OP_REG_TO_MEM; \ + cur_env.je_ret = PerlProc_setjmp(cur_env.je_buf, SCOPE_SAVES_SIGNAL_MASK); \ + OP_MEM_TO_REG; \ + PL_top_env = &cur_env; \ + cur_env.je_mustcatch = FALSE; \ + (v) = cur_env.je_ret; \ + } STMT_END + +#define JMPENV_POP \ + STMT_START { \ + DEBUG_l(Perl_deb(aTHX_ "popping jumplevel was %p, now %p\n", \ + PL_top_env, cur_env.je_prev)); \ + PL_top_env = cur_env.je_prev; \ + } STMT_END + +#define JMPENV_JUMP(v) \ + STMT_START { \ + OP_REG_TO_MEM; \ + if (PL_top_env->je_prev) \ + PerlProc_longjmp(PL_top_env->je_buf, (v)); \ + if ((v) == 2) \ + PerlProc_exit(STATUS_NATIVE_EXPORT); \ + PerlIO_printf(PerlIO_stderr(), "panic: top_env\n"); \ + PerlProc_exit(1); \ + } STMT_END + +#define CATCH_GET (PL_top_env->je_mustcatch) +#define CATCH_SET(v) (PL_top_env->je_mustcatch = (v)) + + + struct cop { BASEOP char * cop_label; /* label for this construct */ diff --git a/scope.h b/scope.h index 2fa7f60..c83b13d 100644 --- a/scope.h +++ b/scope.h @@ -214,121 +214,3 @@ Closing bracket on a callback. See C and L. #define SSPTR(off,type) ((type) ((char*)PL_savestack + off)) #define SSPTRt(off,type) ((type*) ((char*)PL_savestack + off)) -/* 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 { - struct jmpenv * je_prev; - Sigjmp_buf je_buf; /* only for use if !je_throw */ - int je_ret; /* last exception thrown */ - bool je_mustcatch; /* need to call longjmp()? */ -}; - -typedef struct jmpenv JMPENV; - -#ifdef OP_IN_REGISTER -#define OP_REG_TO_MEM PL_opsave = op -#define OP_MEM_TO_REG op = PL_opsave -#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 { \ - Zero(&PL_start_env, 1, JMPENV); \ - PL_start_env.je_ret = -1; \ - PL_start_env.je_mustcatch = TRUE; \ - PL_top_env = &PL_start_env; \ - } STMT_END - -/* - * PERL_FLEXIBLE_EXCEPTIONS - * - * All the flexible exceptions code has been removed. - * See the following threads for details: - * - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2004-07/msg00378.html - * - * Joshua's original patches (which weren't applied) and discussion: - * - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01396.html - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01489.html - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01491.html - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg01608.html - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg02144.html - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1998-02/msg02998.html - * - * Chip's reworked patch and discussion: - * - * http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1999-03/msg00520.html - * - * The flaw in these patches (which went unnoticed at the time) was - * that they moved some code that could potentially die() out of the - * region protected by the setjmp()s. This caused exceptions within - * END blocks and such to not be handled by the correct setjmp(). - * - * The original patches that introduces flexible exceptions were: - * - * http://public.activestate.com/cgi-bin/perlbrowse?patch=3386 - * http://public.activestate.com/cgi-bin/perlbrowse?patch=5162 - */ - -#define dJMPENV JMPENV cur_env - -#define JMPENV_PUSH(v) \ - STMT_START { \ - DEBUG_l(Perl_deb(aTHX_ "Setting up jumplevel %p, was %p\n", \ - &cur_env, PL_top_env)); \ - cur_env.je_prev = PL_top_env; \ - OP_REG_TO_MEM; \ - cur_env.je_ret = PerlProc_setjmp(cur_env.je_buf, SCOPE_SAVES_SIGNAL_MASK); \ - OP_MEM_TO_REG; \ - PL_top_env = &cur_env; \ - cur_env.je_mustcatch = FALSE; \ - (v) = cur_env.je_ret; \ - } STMT_END - -#define JMPENV_POP \ - STMT_START { \ - DEBUG_l(Perl_deb(aTHX_ "popping jumplevel was %p, now %p\n", \ - PL_top_env, cur_env.je_prev)); \ - PL_top_env = cur_env.je_prev; \ - } STMT_END - -#define JMPENV_JUMP(v) \ - STMT_START { \ - OP_REG_TO_MEM; \ - if (PL_top_env->je_prev) \ - PerlProc_longjmp(PL_top_env->je_buf, (v)); \ - if ((v) == 2) \ - PerlProc_exit(STATUS_NATIVE_EXPORT); \ - PerlIO_printf(PerlIO_stderr(), "panic: top_env\n"); \ - PerlProc_exit(1); \ - } STMT_END - -#define CATCH_GET (PL_top_env->je_mustcatch) -#define CATCH_SET(v) (PL_top_env->je_mustcatch = (v)) -