/*     `
   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
*/
#include <stdio.h>
#include <stdlib.h>
#include <exception>
#include "_rtti.h"

#pragma startup __init_cppdata 119
#pragma rundown __rundown_cppdata 6

namespace __dls {

const char _RTL_DATA *__dls_NoNamedException = "No Named Exception" ;
const char _RTL_DATA *__dls_BadException = "Bad Exception" ;

} ;

namespace std {
   _RTL_FUNC exception::~exception ()  throw ()
   {
   }  
   _RTL_FUNC bad_exception::~bad_exception ()  throw()
   {
   }
} ;

void _RTL_FUNC terminate()
{
   abort() ;
}
extern "C" void _RTL_FUNC __call_terminate()
{
   try {
      std::flushall() ;
      asm mov eax,fs:[4]
      asm mov eax,[eax-4]
      asm mov eax,[eax+0] ; // term address
      asm call eax
   } catch (...) {
   } 
   abort() ;
}
void _RTL_FUNC unexpected()
{
   __call_terminate() ;
}
terminate_handler _RTL_FUNC set_terminate(terminate_handler __t)
{
   asm mov ecx,fs:[4]
   asm mov ecx,[ecx-4]
   asm mov eax,[ecx+0]
   asm mov edx,[ebp+8]
   asm test edx,edx
   asm jz noset
   asm mov [ecx],edx
noset:
}
unexpected_handler _RTL_FUNC set_unexpected(unexpected_handler __u)
{
   asm mov ecx,fs:[4]
   asm mov ecx,[ecx-4]
   asm mov eax,[ecx+4]
   asm mov edx,[ebp+8]
   asm test edx,edx
   asm jz noset
   asm mov [ecx+4],edx
noset:
}
extern "C" void _RTL_FUNC __call_unexpected()
{
      asm mov eax,fs:[4]
      asm mov eax,[eax-4]
      asm mov eax,[eax+4]  ; // unexpected address
      asm call eax
}
extern "C" void _RTL_FUNC __init_cppdata()
{
   CPPDATA *block ;
   block = (CPPDATA *)malloc(sizeof(CPPDATA)) ;
   if (!block)
      exit(1) ;
   asm mov eax,fs:[4]
   asm mov edx,[block]
   asm mov [eax-4],edx
   block->term = terminate ;
   block->unexpected = unexpected ;
}
extern "C" void _RTL_FUNC __rundown_cppdata()
{
   void *block ;
   asm mov eax,fs:[4]
   asm mov eax,[eax-4]
   asm mov [block],eax
   free(block) ;
}