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;
}
