diff options
Diffstat (limited to 'pod/perlguts.pod')
-rw-r--r-- | pod/perlguts.pod | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/pod/perlguts.pod b/pod/perlguts.pod index fb52ecfcb7..dce6ca5752 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -1252,6 +1252,79 @@ is being used. For a complete description of the PerlIO abstraction, consult L<perlapio>. +=head2 Exception Trapping (JMPENV API) + +As of 5.005, the internal exception trapping mechanism is replaceable +at run-time. + +For a concrete example of usage, see perl.c in the perl source +distribution. Only a general outline is presented here. + +The C<TRYBLOCK()> macro is used to set up a exception handling switch. +C<TRYBLOCK()> takes two arguments. The first argument is a table of +exception handlers: + + struct tryvtbl { + /* [0] executed before JMPENV_POP + [1] executed after JMPENV_POP + (NULL pointers are OK) */ + char *try_context; + void (*try_normal [2]) _((CPERLproto_ void*)); + void (*try_abnormal [2]) _((CPERLproto_ void*)); + void (*try_exception [2]) _((CPERLproto_ void*)); + void (*try_myexit [2]) _((CPERLproto_ void*)); + }; + typedef struct tryvtbl TRYVTBL; + +Each of the functions correspond to the exception types that +are currently supported. The two functions in each array are meant +to be run before and after the exception context is exited, respectively, +via C<JMPENV_POP()>. + +The second argument to C<TRYBLOCK()> is an opaque pointer that is passed +as a first argument to each of the handler functions. This is usually +a structure specific to each particular exception switch containing both +the return value and the arguments to the handler functions. + +Any of the handler function pointers can be C<NULL> except for +C<try_normal[0]>, which is the only thing executed by C<TRYBLOCK()> +after setting up the exception context. Any code executed by +C<try_normal[0]> is free to throw one of the three supported exceptions +using C<JMPENV_JUMP()>. C<JMPENV_JUMP()> can be called with one of the +following values: + + #define JMP_ABNORMAL 1 /* shouldn't happen */ + #define JMP_MYEXIT 2 /* exit */ + #define JMP_EXCEPTION 3 /* die */ + +Control then resumes at the exception switch, which calls the handler +corresponding to the type of exception that was thrown. More exceptions +can be thrown while in the handler, and the process repeats until one of +the handlers return normally. + +In other words, depending on how C<JMPENV_JUMP()> is called, either +C<try_abnormal[0]>, C<try_exception[0]>, or C<try_myexit[0]> are executed. +If C<JMPENV_JUMP()> is invoked yet again before the try handler completes +then execution will B<restart> at the try handler which corresponds to the +most recent C<JMPENV_JUMP()>. Care should be taken to avoid infinite +loops. + +Once the try handler[0] finishes, execution moves on to one of the try +handlers that are run after the exception context is exited (i.e. +handler[1]). However, the difference between the two types of handlers +is that exceptions raised in handlers run after exiting the exception +context are no longer caught by the C<TRYBLOCK()>. Of course, they may +be caught at some outer exception trap set up for the purpose. Therefore, +C<JMPENV_JUMP()> at this point will not be trapped; it will jump to the +previous C<TRYBLOCK()>. This is useful for propagating exceptions to the +top of the stack. + +WARNING: At the time of this writing, the C<CC.pm> compiler backend +does not support exception traps that are configurable at runtime. It +only knows how to handle exceptions thrown with longjmp() (which is what +the default exception mechanism in perl provides). This will be corrected +in a future release. + =head2 Putting a C value on Perl stack A lot of opcodes (this is an elementary operation in the internal perl |