/* 
   Copyright 1994-2003 Free Software Foundation, Inc.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
   USA

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
*/
#ifdef win32
#include <windows.h>
#else
typedef long	LONG ;
#define	PASCAL _stdcall
typedef void * PEXCEPTION_RECORD, * PCONTEXT ;
#endif
#include "_rtti.h"

#define OUR_CPP_EXC_CODE 0xEEFABCD

extern void *_xceptblockchain ;

void __call_terminate() ;
LONG ___xceptionhandle(PEXCEPTION_RECORD p, void *record, PCONTEXT context, void *param) ;

#ifdef win32
#pragma startup initCPPxcept 1

void __global_unwind(PEXCEPTION_POINTERS p, void *record) ;

extern LONG (* ___cppxcept)(PEXCEPTION_RECORD p, void *record , CONTEXT *context, void *param ) ;

LONG ___cppxceptionhandle(PEXCEPTION_RECORD p, void *record, PCONTEXT context, void *param)
{
	if (p->ExceptionCode == OUR_CPP_EXC_CODE) {
#ifdef win32
		__global_unwind(p,record) ;
#endif
		__call_terminate() ;
	}
	return 1 ; // continue search
}
static void initCPPxcept()
{
	___cppxcept = ___cppxceptionhandle ;
}
#endif
void __raise_throw()
{
#ifdef win32
	RaiseException(OUR_CPP_EXC_CODE,EXCEPTION_NONCONTINUABLE,0,0) ;
#endif
}
void _InitExceptBlock()
{
   asm mov ecx,[eax+4]              // get offset of frame data XCEPTDATA struct
   asm add ecx,ebp
   asm mov edx,fs:[0]               // 0 = old xcept chain
   asm mov [ecx],edx
   asm mov edx,___xceptionhandle    // 4 = windows xception handle func
   asm mov [ecx+4],edx
   asm mov dword ptr [ecx+8],XC_SIG // 8 = signature
   asm mov dword ptr [ecx+12],0     // 12 = ESP of throw block, zero for now
   asm mov [ecx+16],ebp             // 16 = EBP of this func
   asm mov edx,[esp]                // 20 = EIP the offsets in the table are based from
   asm mov [ecx+20],edx              
   asm mov [ecx+24],eax             // 24 = pointer to the xception block
   asm mov dword ptr [ecx+28],0     // 28 = flags, mark no xcept in progress
                                    // there are more bytes but they are 
                                    // used by throw() and not initted here
   asm mov fs:[0],ecx
}

void _RundownExceptBlock()
{
   asm mov ecx,fs:[0]
   asm mov ecx,[ecx]
   asm mov fs:[0],ecx
}