extern void throw( int exception ); /* Raise an exception. */ extern void trycatch(void (*func)(void), int exception, void (*handler)(void) ); /* Similar to the simplified C++ mechanism * * try { * * func(); * } * catch ( exception ) { * handler() * } * * Try to execute "func()". If an exception is thrown, execute "handler()" directly. */Goto the Contents
#include <stdlib.h> #include <stdio.h> #include "except.h" #define MAX_EXCEPTIONS 10000 extern void *GetParentSp(); typedef struct exception { void *sp; void (*handler)(void); int exception; } Exception; static Exception Exceptions[MAX_EXCEPTIONS]; static int top = -1; int FindException(int exception) { int finder = top; while (finder>=0 && Exceptions[finder].exception!=exception) { finder--; } return finder; } void throw(int exception) { void (*handler)(void); void *sp; int found; if ((found=FindException(exception)) < 0) { fprintf(stderr,"Exception %d not found-- exiting!\n",exception); exit(exception); } else { handler = Exceptions[found].handler; sp = Exceptions[found].sp; top = found - 1; (*handler)(); ResumeAt(sp); } } void RegisterException(int exception, void (*handler)(void), void *sp) { if (top++ >= MAX_EXCEPTIONS) { fprintf(stderr,"Registered too many exceptions\n"); exit(-1); } Exceptions[top].handler = handler; Exceptions[top].exception = exception; Exceptions[top].sp = sp; } void PopException(int exception) { if (top==-1) { fprintf(stderr,"Popping exception from empty stack\n"); exit(-1); } if (Exceptions[top].exception != exception) { fprintf(stderr,"Error! top exception expected %d, found %d\n", exception,Exceptions[top].exception); exit(-1); } top--; } void trycatch( void (*func)(void), int exception, void (*handler)(void)) { void *sp; sp = GetParentSp(); RegisterException(exception,handler,sp); (*func)(); PopException(exception); }Goto the Contents
.seg "text" .global _GetParentSp .align 4 .proc 4 _GetParentSp: jmpl %o7+8,%g0; mov %fp,%o0 .global _ResumeAt .align 4 .proc 4 _ResumeAt: ba L1; mov %o0,%g4 L2: restore L1: cmp %g4,%fp bne L2; nop ret; restoreGoto the Contents