deep-c-rsc/JCGO/include/jcgoxcpt.c

404 lines
9.3 KiB
C

/*
* @(#) $(JCGO)/include/jcgoxcpt.c --
* a part of the JCGO runtime subsystem.
**
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
* Copyright (C) 2001-2012 Ivan Maidanski <ivmai@ivmaisoft.com>
* All rights reserved.
*/
/**
* This file is compiled together with the files produced by the JCGO
* translator (do not include and/or compile this file directly).
*/
/*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
**
* This software 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
* General Public License (GPL) for more details.
**
* Linking this library statically or dynamically with other modules is
* making a combined work based on this library. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
**
* As a special exception, the copyright holders of this library give you
* permission to link this library with independent modules to produce an
* executable, regardless of the license terms of these independent
* modules, and to copy and distribute the resulting executable under
* terms of your choice, provided that you also meet, for each linked
* independent module, the terms and conditions of the license of that
* module. An independent module is a module which is not derived from
* or based on this library. If you modify this library, you may extend
* this exception to your version of the library, but you are not
* obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#ifdef JCGO_VER
/* #include <setjmp.h> */
/* void longjmp(jmp_buf, int); */
/* #include <signal.h> */
/* void (*signal(int, void (*)(int)))(int); */
#ifndef JCGO_NOSEGV
#ifndef SIGBUS
#ifndef SIGSEGV
#define JCGO_NOSEGV
#endif
#endif
#endif
#ifdef SIG_ACK
#define JCGO_SIGNAL_RESET(sig, func) (signal(sig, func) != SIG_DFL ? (void)signal(sig, SIG_ACK) : (void)0)
#else
#define JCGO_SIGNAL_RESET(sig, func) ((void)signal(sig, func))
#endif
#ifndef JCGO_NOCTRLC
STATICDATA int jcgo_sigTermNum = 0;
STATIC void CLIBDECL jcgo_catchSigTerm( int sig )
{
JCGO_SIGNAL_RESET(sig, jcgo_catchSigTerm);
jcgo_sigTermNum = sig;
}
#endif /* ! JCGO_NOCTRLC */
#ifndef JCGO_NOSEGV
STATIC void CLIBDECL jcgo_catchSigSegV( int sig )
{
JCGO_SIGNAL_RESET(sig, jcgo_catchSigSegV);
JCGO_THROW_EXC(jcgo_globData.nullExc);
}
#endif /* ! JCGO_NOSEGV */
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_setSyncSignals( void )
{
#ifndef JCGO_NOSEGV
#ifdef SIGSEGV
signal(SIGSEGV, jcgo_catchSigSegV);
#endif
#ifdef SIGBUS
signal(SIGBUS, jcgo_catchSigSegV);
#endif
#endif
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
}
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initAsyncSignals( void )
{
#ifndef JCGO_NOCTRLC
#ifdef SIGTERM
signal(SIGTERM, jcgo_catchSigTerm);
#endif
#ifdef SIGINT
signal(SIGINT, jcgo_catchSigTerm);
#endif
#ifdef SIGHUP
signal(SIGHUP, jcgo_catchSigTerm);
#endif
#endif
}
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_unregSignalHandlers( void )
{
#ifndef JCGO_NOSEGV
#ifndef JCGO_PARALLEL
#ifdef SIGSEGV
signal(SIGSEGV, SIG_DFL);
#endif
#ifdef SIGBUS
signal(SIGBUS, SIG_DFL);
#endif
#endif
#endif
#ifndef JCGO_NOCTRLC
#ifdef SIGTERM
signal(SIGTERM, SIG_DFL);
#endif
#ifdef SIGINT
signal(SIGINT, SIG_DFL);
#endif
#ifdef SIGHUP
signal(SIGHUP, SIG_DFL);
#endif
#endif
}
#ifdef JCGO_THREADS
#ifdef JCGO_PARALLEL
#ifdef JCGO_NOCTRLC
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL
#else
STATIC void CFASTCALL
#endif
#else
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL
#endif
#else
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL
#endif
jcgo_checkStop( struct jcgo_tcb_s *tcb )
{
#ifdef JCGO_THREADS
jObject ex;
#endif
#ifndef JCGO_NOCTRLC
int sig = jcgo_sigTermNum;
if (JCGO_EXPECT_FALSE(sig > 0) && !tcb->insideCallback)
{
*(volatile int *)&jcgo_sigTermNum = 0;
JCGO_CALLBACK_BEGIN
java_lang_VMRuntime__handleSigTerm0X__I((jint)sig);
JCGO_CALLBACK_END
}
#endif
#ifdef JCGO_THREADS
ex = tcb->stopExc;
if (JCGO_EXPECT_FALSE(ex != jnull) && !tcb->insideCallback)
{
tcb->stopExc = jnull;
JCGO_THROW_EXC(ex);
}
#endif
}
#ifdef JCGO_SEHTRY
JCGO_NOSEP_STATIC jObject *CFASTCALL jcgo_tryCatches( void )
{
struct jcgo_tcb_s *tcb;
JCGO_GET_CURTCB(&tcb);
#ifdef JCGO_THREADS
#ifdef JCGO_PARALLEL
if (JCGO_EXPECT_FALSE(tcb->suspended != 0) && !tcb->insideCallback)
do
{
(void)JCGO_EVENT_WAIT(&tcb->resumeEvent);
} while (tcb->suspended);
#ifdef OBJT_java_lang_VMThrowable
if (JCGO_EXPECT_FALSE(tcb->stopExc != jnull) && !tcb->insideCallback &&
tcb->throwable == jnull && (tcb->throwable =
(jObject)(*(jObject volatile *)&tcb->stopExc)) != jnull)
{
tcb->stopExc = jnull;
longjmp(tcb->jbuf, 1);
}
#endif
#endif
#endif
return &tcb->throwable;
}
EXTRASTATIC jObject CFASTCALL jcgo_tryCatchAll( void )
{
jObject ex;
struct jcgo_tcb_s *tcb;
JCGO_GET_CURTCB(&tcb);
ex = tcb->throwable;
tcb->throwable = jnull;
return ex;
}
#else /* JCGO_SEHTRY */
JCGO_NOSEP_EXTRASTATIC void CFASTCALL jcgo_tryEnter(
struct jcgo_try_s *pCurTry )
{
struct jcgo_tcb_s *tcb;
JCGO_GET_CURTCB(&tcb);
pCurTry->throwable = jnull;
pCurTry->last = tcb->pCurTry;
*(struct jcgo_try_s *volatile *)&tcb->pCurTry = pCurTry;
#ifdef JCGO_THREADS
pCurTry->pCurMon = tcb->pCurMon;
tcb->pCurMon = NULL;
#endif
}
JCGO_NOSEP_EXTRASTATIC void CFASTCALL jcgo_tryLeave( void )
{
struct jcgo_tcb_s *tcb;
#ifdef JCGO_THREADS
struct jcgo_try_s *pCurTry;
#endif
JCGO_GET_CURTCB(&tcb);
#ifdef JCGO_THREADS
#ifdef JCGO_PARALLEL
if (JCGO_EXPECT_FALSE(tcb->suspended != 0) && !tcb->insideCallback)
do
{
(void)JCGO_EVENT_WAIT(&tcb->resumeEvent);
} while (tcb->suspended);
if (JCGO_EXPECT_FALSE(tcb->stopExc != jnull) && !tcb->insideCallback &&
tcb->pCurTry->throwable == jnull)
{
tcb->pCurTry->throwable = tcb->stopExc;
tcb->stopExc = jnull;
}
#endif
tcb->pCurMon = (pCurTry = tcb->pCurTry)->pCurMon;
tcb->pCurTry = pCurTry->last;
#else
tcb->pCurTry = tcb->pCurTry->last;
#endif
}
#endif /* ! JCGO_SEHTRY */
#ifdef OBJT_java_lang_VMThrowable
#define jcgo_throwArithmeticExc java_lang_VMThrowable__throwArithmeticException0X__
#define jcgo_throwArrayIndexExc java_lang_VMThrowable__throwArrayIndexOutOfBoundsException0X__
#define jcgo_throwClassCastExc java_lang_VMThrowable__throwClassCastException0X__
#else /* OBJT_java_lang_VMThrowable */
STATIC void CFASTCALL jcgo_throwArithmeticExc( void )
{
JCGO_FATAL_ABORT("Arithmetic divide-by-zero exception!");
}
STATIC void CFASTCALL jcgo_throwArrayIndexExc( void )
{
JCGO_FATAL_ABORT("Array index out of bounds exception!");
}
STATIC void CFASTCALL jcgo_throwClassCastExc( void )
{
JCGO_FATAL_ABORT("Class cast exception!");
}
#endif /* ! OBJT_java_lang_VMThrowable */
#ifdef JCGO_INDEXCHK
#ifdef JCGO_RTASSERT
STATIC void CFASTCALL jcgo_throwArrayIndexExcX( void )
{
JCGO_FATAL_ABORT("Array index bounds assertion!");
}
#else /* JCGO_RTASSERT */
#define jcgo_throwArrayIndexExcX jcgo_throwArrayIndexExc
#endif /* ! JCGO_RTASSERT */
#endif /* JCGO_INDEXCHK */
#ifdef JCGO_CHKCAST
#ifdef JCGO_RTASSERT
STATIC void CFASTCALL jcgo_throwClassCastExcX( void )
{
JCGO_FATAL_ABORT("Class cast assertion!");
}
#else /* JCGO_RTASSERT */
#define jcgo_throwClassCastExcX jcgo_throwClassCastExc
#endif /* ! JCGO_RTASSERT */
JCGO_NOSEP_INLINE void CFASTCALL jcgo_throwArrayStoreExcX( void )
{
#ifdef JCGO_RTASSERT
JCGO_FATAL_ABORT("Array store assertion!");
#else
#ifdef OBJT_java_lang_VMThrowable
java_lang_VMThrowable__throwArrayStoreException0X__();
#else
JCGO_FATAL_ABORT("Array store exception!");
#endif
#endif
}
#endif /* JCGO_CHKCAST */
JCGO_NOSEP_STATIC void CFASTCALL jcgo_throwNullPtrExcX( void )
{
#ifdef JCGO_RTASSERT
JCGO_FATAL_ABORT("Null pointer assertion!");
#else
JCGO_THROW_EXC(jnull);
#endif
}
JCGO_NOSEP_STATIC void CFASTCALL jcgo_throwNullPtrExc( void )
{
JCGO_THROW_EXC(jnull);
}
JCGO_NOSEP_STATIC void CFASTCALL jcgo_throwExc( jObject throwable )
{
#ifdef OBJT_java_lang_VMThrowable
struct jcgo_tcb_s *tcb;
#ifndef JCGO_SEHTRY
struct jcgo_try_s *pCurTry;
#ifdef JCGO_THREADS
struct jcgo_curmon_s *pCurMon;
jObject obj;
#endif
#endif
JCGO_GET_CURTCB(&tcb);
if (JCGO_EXPECT_FALSE(throwable == jnull) && tcb->jniEnv == NULL)
throwable =
(jObject)java_lang_VMThrowable__createNullPointerException0X__();
#ifdef JCGO_SEHTRY
if (JCGO_EXPECT_TRUE(tcb->jniEnv == NULL))
{
tcb->throwable = throwable;
longjmp(tcb->jbuf, 1);
}
#else
pCurTry = tcb->pCurTry;
if (JCGO_EXPECT_TRUE(pCurTry != NULL) && tcb->jniEnv == NULL)
{
#ifdef JCGO_THREADS
for (pCurMon = tcb->pCurMon; pCurMon != NULL; pCurMon = pCurMon->last)
if ((obj = pCurMon->monObj) != jnull)
jcgo_monLeaveInner(obj, tcb);
#endif
pCurTry->throwable = throwable;
longjmp(pCurTry->jbuf, 1);
}
#endif
#endif
/* if (jcgo_noTypesClassArr.jcgo_methods != NULL) */
{
#ifndef JCGO_NOFATALMSG
#ifdef JCGO_NOSEGV
jcgo_printFatalMsg("Null pointer exception!");
#else
#ifndef OBJT_java_lang_VMThrowable
struct jcgo_tcb_s *tcb;
JCGO_GET_CURTCB(&tcb);
#endif
jcgo_printFatalMsg(tcb->jniEnv != NULL ?
"[JNI] Segmentation fault detected!" : "Null pointer exception!");
#endif
#endif
JCGO_ABORT_EXIT;
}
}
#endif