brender-1997/std/brexcept.c
2022-05-03 14:31:40 -07:00

112 lines
2.1 KiB
C

/*
* Copyright (c) 1995 Argonaut Technologies Limited. All rights reserved.
*
* $Id: brexcept.c 2.2 1996/09/30 17:57:56 sam Exp $
* $Locker: $
*
* Simple exception handling
*/
#include <setjmp.h>
#include "brddi.h"
BR_RCS_ID("$Id: brexcept.c 2.2 1996/09/30 17:57:56 sam Exp $")
/*
* Current head of exception handler chain
*/
static br_exception_handler *_BrExceptionHandler = NULL;
/*
* Temporary global used to pass exception value
*/
static void * exceptionValue;
/*
* Add an exception handler to the stack - returns a point to exception handler
* into which the caller should save context
*/
br_exception_handler * BR_RESIDENT_ENTRY _BrExceptionBegin(void)
{
br_exception_handler *h;
/*
* Create an anchor resource
*/
h = BrResAllocate(0,sizeof(*h), BR_MEMORY_EXCEPTION_HANDLER);
h->prev = _BrExceptionHandler;
_BrExceptionHandler = h;
return _BrExceptionHandler;
}
void BR_RESIDENT_ENTRY _BrExceptionEnd(void)
{
br_exception_handler *old;
if(_BrExceptionHandler == NULL)
BR_ERROR("Unhandled exception: %d");
old = _BrExceptionHandler;
_BrExceptionHandler = _BrExceptionHandler->prev;
/*
* Release all the attached resources
*/
BrResFree(old);
}
/*
* Unwind back to the last exception handler, passing a type and value
*/
void BR_RESIDENT_ENTRY _BrExceptionThrow(br_int_32 type, void *value)
{
br_exception_handler h,*old;
/*
* Make sure exception stack does not underflow
*/
if(_BrExceptionHandler == NULL)
BR_ERROR("Unhandled exception: %d");
h = *_BrExceptionHandler;
old = _BrExceptionHandler;
_BrExceptionHandler = _BrExceptionHandler->prev;
/*
* Release all the attached resources
*/
BrResFree(old);
/*
* Pop stack back down to handler context
*/
exceptionValue = value;
longjmp(h.context, type);
}
/*
* Wrapper function used in BrExceptionCatch() macro to stash the
* value
*
*
*/
br_exception BR_RESIDENT_ENTRY _BrExceptionValueFetch(br_exception type, void **evp)
{
/*
* If type is a valid exception, save the exception value
*/
if(type && evp)
*evp = exceptionValue;
return type;
}
void * BR_RESIDENT_ENTRY _BrExceptionResource(void)
{
return _BrExceptionHandler;
}