Attached is a test program with some macros allowing code like:
TRY { some(); } CATCH { clean_up(); RETHROW; }
some() { ... THROW(NULL_PMC_ACCESS); }
The actual implementation would need either an explicit Parrot_Interp argument or assume an C<interpreter> is around. malloc()/free() would be replaced by a free_list handling like in C<new_internal_exception>. On interpreter creation a few of these C<Parrot_exception>s would be created and put onto the C<interpreter->exc_free_list>.
Some questions: - are these macros ok? (Yes I know - debugging :) - Can the macro names interfer with existing ones? - do we need an additional message text like now in internal_exception?
leo
#include <setjmp.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h>
typedef struct e { jmp_buf dest; int err; struct e *prev; } exc; exc * exceptions; #define TRY \ do { \ exc * ex = malloc(sizeof(*ex)); \ ex->prev = exceptions; \ exceptions = ex; \ if (!setjmp(ex->dest)) #define CATCH \ else #define ENDTRY \ } while(0); \ do { \ exc *e = exceptions; \ exceptions = e->prev; \ free(e); \ } while(0) #define THROW(e) \ do { \ exceptions->err = e; \ longjmp(exceptions->dest, 1); \ } while(0) #define RETHROW \ do { \ exc *e = exceptions; \ int er = e->err; \ exceptions = e->prev; \ free(e); \ if (exceptions) \ THROW(er); \ else \ puts("uncaught exception"); \ } while(0) void run(int e) { if (e == 1) THROW(1); else if (e == 2){ TRY { run(e-1); } CATCH { puts("e2"); RETHROW; } ENDTRY; } } int main(int argc, char *argv[]) { int i = 1; if (argc > 1) i = atoi(argv[1]); puts("S"); TRY { run(i); } CATCH { puts("exception"); } ENDTRY; puts("E"); return 0; }