Exception Handling

Exception Handling

Contents

except.h

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

except.c

#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

aux.s

.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; restore
Goto the Contents


Tue Apr 2 14:07:50 EST 1996