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

882 lines
24 KiB
C

/*
* @(#) $(JCGO)/include/jcgobase.c --
* a part of the JCGO runtime subsystem.
**
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
* Copyright (C) 2001-2013 Ivan Maidanski <ivmai@mail.ru>
* 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).
*/
/*
* Used control macros: JCGO_CLINITCHK, JCGO_ERRSTDOUT, JCGO_ERRTOLOG,
* JCGO_GCALLINTER, JCGO_GCRESETDLS, JCGO_NOCREATJVM, JCGO_NOFATALMSG,
* JCGO_NOGC, JCGO_NOJNI, JCGO_SEHTRY, JCGO_SEPARATED, JCGO_STDCLINIT,
* JCGO_THREADS, JCGO_TOLOGFORCE, JCGO_WMAIN.
* Macros for tuning: GCBSSFIRSTSYM, GCBSSLASTSYM, GCDATAFIRSTSYM,
* GCDATALASTSYM.
*/
/*
* 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 <stdlib.h> */
/* void exit(int); */
#ifndef JCGO_THREADS
#define JCGO_CRITMOD_BEGIN(mutexvar) {
#define JCGO_CRITMOD_END(mutexvar) }
#define JCGO_GET_CURTCB(ptcb) (void)(*(void **)(ptcb) = (void *)&jcgo_mainTCB)
struct jcgo_tcb_s
{
jvtable jcgo_methods;
JCGO_MON_DEFN
JNIEnv jniEnv;
jObject thread;
jObject nativeExc;
#ifndef JCGO_NOJNI
jObjectArr localObjs;
#endif
#ifdef JCGO_SEHTRY
jObject throwable;
#ifndef JCGO_NOCREATJVM
unsigned insideJniCall;
#endif
#else
struct jcgo_try_s *pCurTry;
#endif
unsigned insideCallback;
int interruptReq;
#ifdef JCGO_SEHTRY
#ifdef OBJT_java_lang_VMThrowable
jmp_buf jbuf;
#endif
#endif
};
JCGO_NOSEP_GCDATA struct jcgo_tcb_s jcgo_mainTCB ATTRIBGCBSS = { NULL };
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_setSyncSignals( void );
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_checkStop(
struct jcgo_tcb_s *tcb );
#ifndef JCGO_NOJNI
JCGO_NOSEP_INLINE int CFASTCALL jcgo_restoreTCB( struct jcgo_tcb_s *tcb )
{
return &jcgo_mainTCB == tcb ? 0 : -1;
}
#endif /* ! JCGO_NOJNI */
#endif /* ! JCGO_THREADS */
#define JCGO_PTR_RESERVED ((void *)&((volatile char *)NULL)[-1])
#define JCGO_CAST_NUMTOPTR(value) ((void *)((ptrdiff_t)(value)))
#ifndef JCGO_CAST_PFUNCTOUINT
#define JCGO_CAST_PFUNCTOUINT(pfunc) ((unsigned)((ptrdiff_t)(pfunc)))
#endif
#define JCGO_JNI_GETTCB(pJniEnv) ((struct jcgo_tcb_s *)((volatile char *)pJniEnv - JCGO_OFFSET_OF(struct jcgo_tcb_s, jniEnv)))
#define JCGO_ACCMOD_FINAL 0x10
#ifdef JCGO_SEHTRY
#define JCGO_TRY_CATCHIGNOREALL(tcb) { if (tcb->throwable != jnull) { tcb->throwable = jnull; goto jcgo_tryallcaught; } } JCGO_TRY_SEHNOP; jcgo_tryallcaught:;
#else
#define JCGO_TRY_CATCHIGNOREALL(tcb) /* empty */
#endif
#ifdef JCGO_SEHTRY
#define JCGO_CALLBACK_BEGIN { struct jcgo_tcb_s *jcgo_tcbsave; jObject jcgo_throwable; int jcgo_interruptReq; JCGO_GET_CURTCB(&jcgo_tcbsave); jcgo_throwable = jcgo_tcbsave->throwable; jcgo_tcbsave->throwable = jnull; jcgo_interruptReq = jcgo_tcbsave->interruptReq; jcgo_tcbsave->interruptReq = 0; jcgo_tcbsave->insideCallback++; { JCGO_TRY_BLOCK {
#define JCGO_CALLBACK_END } JCGO_TRY_LEAVE JCGO_TRY_CATCHIGNOREALL(jcgo_tcbsave) } jcgo_tcbsave->insideCallback--; jcgo_tcbsave->interruptReq = jcgo_interruptReq; jcgo_tcbsave->throwable = jcgo_throwable; }
#else
#define JCGO_CALLBACK_BEGIN { struct jcgo_tcb_s *jcgo_tcbsave; int jcgo_interruptReq; JCGO_GET_CURTCB(&jcgo_tcbsave); jcgo_interruptReq = jcgo_tcbsave->interruptReq; jcgo_tcbsave->interruptReq = 0; jcgo_tcbsave->insideCallback++; { JCGO_TRY_BLOCK {
#define JCGO_CALLBACK_END } JCGO_TRY_LEAVE JCGO_TRY_CATCHIGNOREALL(jcgo_tcbsave) } jcgo_tcbsave->insideCallback--; jcgo_tcbsave->interruptReq = jcgo_interruptReq; }
#endif
#ifndef GCDATAFIRSTSYM
#define GCDATAFIRSTSYM java_lang_String__class
#ifdef JCGO_SEPARATED
#ifndef GCDATALASTSYM
#ifndef GCBSSFIRSTSYM
#ifndef GCBSSLASTSYM
#ifndef JCGO_GCRESETDLS
#define JCGO_MAIN_OMITSETROOTS
#endif
#endif
#endif
#endif
#endif
#endif
#ifndef GCDATALASTSYM
#define GCDATALASTSYM jcgo_noTypesClassArr
#endif
#ifndef GCBSSFIRSTSYM
#define GCBSSFIRSTSYM jcgo_initialized
#endif
#ifndef GCBSSLASTSYM
#define GCBSSLASTSYM jcgo_globData
#endif
#ifdef JCGO_WMAIN
#define JCGO_MAIN_TCHAR wchar_t
#define JCGO_MAIN_TINITINOUT JCGO_JNI_FUNC(jcgo_JavaInitInOutW)
#define JCGO_MAIN_TCONVERTCMDARG JCGO_JNI_FUNC(jcgo_JavaConvertCmdArgW)
#else
#define JCGO_MAIN_TCHAR char
#define JCGO_MAIN_TINITINOUT JCGO_JNI_FUNC(jcgo_JavaInitInOutA)
#define JCGO_MAIN_TCONVERTCMDARG JCGO_JNI_FUNC(jcgo_JavaConvertCmdArgA)
#endif
#ifdef JCGO_ERRTOLOG
#ifdef JCGO_TOLOGFORCE
#ifdef JCGO_ERRSTDOUT
#define JCGO_MAIN_OUTREDIRECT 0x7
#else
#define JCGO_MAIN_OUTREDIRECT 0x5
#endif
#else
#ifdef JCGO_ERRSTDOUT
#define JCGO_MAIN_OUTREDIRECT 0x3
#else
#define JCGO_MAIN_OUTREDIRECT 0x1
#endif
#endif
#else
#define JCGO_MAIN_OUTREDIRECT 0
#endif
#ifdef JCGO_SEHTRY
#ifdef OBJT_java_lang_VMThrowable
#define JCGO_MAIN_TRYINITSEHIF if (!setjmp(jcgo_mainSehJmpBuf()))
#else
#define JCGO_MAIN_TRYINITSEHIF /* empty */
#endif
#else
#define JCGO_MAIN_TRYINITSEHIF /* empty */
#endif
#ifdef JCGO_THREADS
#define JCGO_MAIN_EXITEND if (*(void *volatile *)&jcgo_noTypesClassArr.jcgo_methods != NULL) exit(0);
#else
#ifdef JCGO_NOGC
#define JCGO_MAIN_EXITEND /* empty */
#else
#define JCGO_MAIN_EXITEND *(volatile int *)&jcgo_trashVar = 0;
#endif
#endif
#define JCGO_MAIN_ARGVFIX(argc, targv) (void)((argc) > 0 && (targv) != NULL && (targv)[argc] != NULL ? ((targv)[(argc) - 1] = NULL, 0) : 0)
#ifdef JCGO_NOGC
#define JCGO_MAIN_LAUNCH(argc, targv) { JCGO_MAIN_ARGVFIX(argc, targv); JCGO_MAIN_TRYINITSEHIF jcgo_tmainBody(jcgo_tinitialize(targv)); JCGO_MAIN_EXITEND }
#else
#ifdef JCGO_GCRESETDLS
#define JCGO_MAIN_GCSETNODLS GC_set_no_dls(1)
#else
#define JCGO_MAIN_GCSETNODLS (void)0
#endif
#ifdef JCGO_GCALLINTER
#define JCGO_MAIN_GCNOINTERIOR (void)0
#else
#define JCGO_MAIN_GCNOINTERIOR GC_set_all_interior_pointers(0)
#endif
#define JCGO_MAIN_LAUNCH(argc, targv) { void (*volatile jcgo_fnLaunch)(void **) = &jcgo_tmainBody; JCGO_MAIN_ARGVFIX(argc, targv); JCGO_MAIN_GCSETNODLS; JCGO_MAIN_GCNOINTERIOR; GC_INIT(); JCGO_MAIN_TRYINITSEHIF (*jcgo_fnLaunch)(jcgo_tinitialize(targv)); JCGO_MAIN_EXITEND }
#endif
#ifndef OBJT_java_lang_Throwable
struct java_lang_Throwable_s
{
CONST struct java_lang_Object_methods_s *JCGO_IMMFLD_CONST jcgo_methods;
JCGO_MON_DEFN
};
#endif
#ifdef OBJT_java_lang_ref_SoftReference
struct jcgo_refkeeper_s;
#endif
struct jcgo_globData_s
{
jObject nullExc;
#ifdef OBJT_java_lang_ref_SoftReference
struct jcgo_refkeeper_s *refKeeperList;
#endif
#ifndef JCGO_NOJNI
jObjectArr jniGlobalRefsQue;
#ifndef JCGO_FNLZDATA_OMITREFQUE
jObjectArr jniWeakRefsList;
#endif
jObjectArr jniAllocatedDataList;
struct jcgo_tcb_s *jniNewTCB;
#endif
#ifdef JCGO_STDCLINIT
#ifdef JCGO_THREADS
jObjectArr clinitActiveList;
#endif
#endif
};
JCGO_NOSEP_GCDATA struct jcgo_globData_s jcgo_globData ATTRIBGCBSS =
{
jnull
#ifdef OBJT_java_lang_ref_SoftReference
, NULL
#endif
#ifndef JCGO_NOJNI
, jnull,
#ifndef JCGO_FNLZDATA_OMITREFQUE
jnull,
#endif
jnull,
NULL
#endif
#ifdef JCGO_STDCLINIT
#ifdef JCGO_THREADS
, jnull
#endif
#endif
};
JCGO_NOSEP_GCDATA struct jcgo_jobjectarr_s jcgo_noTypesClassArr ATTRIBGCDATA =
{
(jvtable)&jObjectArr2_methods,
JCGO_MON_INIT
1,
JCGO_CLASSREF_OF(java_lang_Class__class),
{
jnull
}
};
STATICDATA JCGO_MAIN_TCHAR *jcgo_targv0 = NULL;
#ifdef JCGO_SEPARATED
jlong jcgo_trashVar;
#endif
#ifdef EXPAND_WILDCARDS
EXPAND_WILDCARDS
#else
#ifdef __MINGW32__
int _CRT_glob = 1;
#endif
#endif
#ifndef JCGO_NOGC
#ifndef JCGO_MAIN_OMITSETROOTS
JCGO_NOSEP_GCDATA void *jcgo_pDataFirstSym = (void *)(&GCDATAFIRSTSYM);
#endif
#endif
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initFP( void );
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initAsyncSignals( void );
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_unregSignalHandlers( void );
JNIIMPORT JCGO_MAIN_TCHAR **JNICALL JCGO_MAIN_TINITINOUT(
JCGO_MAIN_TCHAR **targv, jint redirect );
JNIIMPORT jstring JNICALL JCGO_MAIN_TCONVERTCMDARG( JNIEnv *pJniEnv,
CONST JCGO_MAIN_TCHAR *tstr );
#ifdef JCGO_NOFATALMSG
#define JCGO_FATAL_ABORT(msg) JCGO_ABORT_EXIT
#else /* JCGO_NOFATALMSG */
JNIIMPORT void JNICALL JCGO_JNI_FUNC(jcgo_JavaWriteLnToStderr)(
CONST char *cstr, CONST char *cstr2 );
STATIC void CFASTCALL jcgo_printFatalMsg( CONST char *msg )
{
JCGO_JNI_FUNC(jcgo_JavaWriteLnToStderr)((jcgo_initialized >> 1) != 0 ?
" !!! FATAL ERROR: " : " !!! FATAL INITIALIZER ERROR: ", msg);
}
#define JCGO_FATAL_ABORT(msg) (jcgo_printFatalMsg(msg), JCGO_ABORT_EXIT)
#endif /* ! JCGO_NOFATALMSG */
JCGO_NOSEP_STATIC void CFASTCALL jcgo_jniNoNativeFunc( void )
{
#ifdef OBJT_java_lang_VMThrowable
java_lang_VMThrowable__throwUnsatisfiedLinkError0X__();
#else
JCGO_FATAL_ABORT("Missing native function called!");
#endif
}
#ifdef JCGO_NOJNI
JCGO_NOSEP_INLINE JNIEnv *JCGO_INLFRW_FASTCALL jcgo_jniEnter( void )
{
struct jcgo_tcb_s *tcb;
JCGO_GET_CURTCB(&tcb);
#ifdef JCGO_THREADS
jcgo_saveTCB();
#endif
tcb->jniEnv = JCGO_PTR_RESERVED;
return &tcb->jniEnv;
}
JCGO_NOSEP_STATIC jObject CFASTCALL jcgo_jniLeave( JNIEnv *pJniEnv,
jobject obj )
{
struct jcgo_tcb_s *tcb = JCGO_JNI_GETTCB(pJniEnv);
jObject ex = tcb->nativeExc;
tcb->jniEnv = NULL;
tcb->nativeExc = jnull;
#ifdef JCGO_THREADS
(void)jcgo_restoreTCB(tcb);
#endif
jcgo_checkStop(tcb);
if (JCGO_EXPECT_FALSE(ex != jnull))
JCGO_THROW_EXC(ex);
return (jObject)obj;
}
#ifndef JCGO_NATSEP
EXTRASTATIC
#endif
jint *JNICALL jcgo_jnuStringLengthPtr( jstring str )
{
return &JCGO_FIELD_NZACCESS((java_lang_String)str, count);
}
#ifndef JCGO_NATSEP
EXTRASTATIC
#endif
jchar *JNICALL jcgo_jnuStringChars( jstring str, int *pisbytes )
{
jchar *chars;
jObject value =
(jObject)JCGO_FIELD_NZACCESS((java_lang_String)str, value);
if (JCGO_METHODS_OF(value)->jcgo_typeid == OBJT_jarray + OBJT_jbyte)
{
*pisbytes = 1;
chars = (jchar *)((volatile void *)&JCGO_ARR_INTERNALACC(jbyte,
(jbyteArr)value, JCGO_FIELD_NZACCESS((java_lang_String)str,
offset)));
}
else
{
*pisbytes = 0;
chars = &JCGO_ARR_INTERNALACC(jchar, (jcharArr)value,
JCGO_FIELD_NZACCESS((java_lang_String)str, offset));
}
return chars;
}
#ifndef JCGO_NATSEP
EXTRASTATIC
#endif
jstring JNICALL jcgo_jnuStringCreate( JNIEnv *pJniEnv, jint len )
{
jstring JCGO_TRY_VOLATILE str = NULL;
jcharArr arr;
struct jcgo_tcb_s *tcb;
#ifdef JCGO_SEHTRY
jObject throwable;
#else
struct jcgo_try_s jcgo_try;
#endif
if (JCGO_EXPECT_TRUE(pJniEnv != NULL) &&
(tcb = JCGO_JNI_GETTCB(pJniEnv))->nativeExc == jnull)
{
#ifndef JCGO_SEHTRY
jcgo_try.throwable = jnull;
#endif
#ifdef JCGO_THREADS
tcb->insideCallback++;
(void)jcgo_restoreTCB(tcb);
#endif
#ifndef JCGO_SEHTRY
jcgo_try.last = tcb->pCurTry;
*(struct jcgo_try_s *volatile *)&tcb->pCurTry = &jcgo_try;
#ifdef JCGO_THREADS
jcgo_try.pCurMon = tcb->pCurMon;
tcb->pCurMon = NULL;
#endif
#endif
#ifdef JCGO_THREADS
tcb->insideCallback--;
#endif
tcb->jniEnv = NULL;
{
#ifdef JCGO_SEHTRY
JCGO_TRY_BLOCK
#else
if (!setjmp(jcgo_try.jbuf))
#endif
{
arr = (jcharArr)jcgo_newArray(JCGO_CORECLASS_FOR(OBJT_jchar), 0, len);
str = (jstring)jcgo_newObject((jvtable)&java_lang_String_methods);
JCGO_FIELD_NZACCESS((java_lang_String)str, value) = (void *)arr;
}
#ifdef JCGO_SEHTRY
JCGO_TRY_LEAVE
JCGO_TRY_CATCHALLSTORE(&throwable)
#endif
}
#ifndef JCGO_SEHTRY
#ifdef JCGO_THREADS
tcb->pCurMon = jcgo_try.pCurMon;
#endif
tcb->pCurTry = jcgo_try.last;
#endif
tcb->jniEnv = JCGO_PTR_RESERVED;
#ifdef JCGO_THREADS
jcgo_saveTCB();
#endif
#ifdef JCGO_SEHTRY
tcb->nativeExc = throwable;
#else
tcb->nativeExc = jcgo_try.throwable;
#endif
}
return (jstring)str;
}
#else /* JCGO_NOJNI */
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initJni( void );
STATIC void CFASTCALL jcgo_jniOnLoad( void );
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_jniOnUnload( void );
#endif /* ! JCGO_NOJNI */
#ifdef JCGO_STDCLINIT
#ifdef JCGO_THREADS
#ifdef OBJT_java_lang_VMThread
JCGO_NOSEP_STATIC jint CFASTCALL
java_lang_VMThread__notify0__LoI( java_lang_Object obj, jint all );
JCGO_NOSEP_STATIC jint CFASTCALL
java_lang_VMThread__wait0__LoJI( java_lang_Object obj, jlong ms, jint ns );
#endif
#endif
JCGO_NOSEP_STATIC void CFASTCALL jcgo_clinitTrig( java_lang_Class aclass )
{
void (CFASTCALL *rtn)(void);
#ifdef JCGO_THREADS
struct jcgo_tcb_s *tcb;
jObjectArr prevEntry;
JCGO_TRY_VOLATILE int noerr;
int flags;
if (JCGO_EXPECT_TRUE((*(volatile jint *)&JCGO_FIELD_NZACCESS(aclass,
modifiers) & (JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT)) == 0))
{
return;
}
/* FIXME: use atomic operation to re-check modifiers. */
noerr = 0;
{
JCGO_SYNC_BLOCKSAFENZ(aclass)
{
jObjectArr listEntry;
flags = (int)(*(volatile jint *)&JCGO_FIELD_NZACCESS(aclass, modifiers)) &
(JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT);
if (flags == JCGO_ACCMOD_TRANSIENT)
{
JCGO_CRITMOD_BEGIN(jcgo_clinitListMutex)
listEntry = jcgo_globData.clinitActiveList;
while (listEntry != jnull &&
JCGO_ARR_INTERNALACC(jObject, listEntry, 0) != (jObject)aclass)
listEntry = (jObjectArr)JCGO_ARR_INTERNALACC(jObject, listEntry, 1);
JCGO_CRITMOD_END(jcgo_clinitListMutex)
JCGO_GET_CURTCB(&tcb);
if (listEntry == jnull ||
JCGO_ARR_INTERNALACC(jObject, listEntry, 2) == (jObject)tcb)
{
#ifndef JCGO_SEHTRY
JCGO_SYNC_JUMPLEAVE(0);
#endif
return;
}
do
{
#ifdef OBJT_java_lang_VMThread
java_lang_VMThread__wait0__LoJI((java_lang_Object)aclass, (jlong)0L, 0);
#endif
flags = (int)JCGO_FIELD_NZACCESS(aclass, modifiers) &
(JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT);
} while (flags == JCGO_ACCMOD_TRANSIENT);
}
if (!flags)
{
#ifndef JCGO_SEHTRY
JCGO_SYNC_JUMPLEAVE(0);
#endif
return;
}
if (JCGO_EXPECT_FALSE(flags == JCGO_ACCMOD_VOLATILE))
{
#ifdef OBJT_java_lang_VMThrowable
JCGO_THROW_EXC(java_lang_VMThrowable__createNoClassDefFoundError0X__LsI(
JCGO_FIELD_NZACCESS(aclass, name), 1));
#else
#ifndef JCGO_SEHTRY
JCGO_SYNC_JUMPLEAVE(0);
#endif
return;
#endif
}
listEntry = (jObjectArr)jcgo_newArray(
JCGO_CLASSREF_OF(java_lang_Object__class), 0, 3);
JCGO_GET_CURTCB(&tcb);
JCGO_ARR_INTERNALACC(jObject, listEntry, 0) = (jObject)aclass;
JCGO_ARR_INTERNALACC(jObject, listEntry, 2) = (jObject)tcb;
JCGO_CRITMOD_BEGIN(jcgo_clinitListMutex)
JCGO_ARR_INTERNALACC(jObject, listEntry, 1) =
(jObject)jcgo_globData.clinitActiveList;
jcgo_globData.clinitActiveList = listEntry;
JCGO_CRITMOD_END(jcgo_clinitListMutex)
JCGO_FIELD_NZACCESS(aclass, modifiers) &= ~(jint)JCGO_ACCMOD_VOLATILE;
}
JCGO_SYNC_END
}
{
JCGO_TRY_BLOCK
{
#ifdef OBJT_java_lang_Throwable
JCGO_TRY_BLOCK
#endif
{
if ((rtn = ((jvtable)&JCGO_METHODS_OF(JCGO_FIELD_NZACCESS(aclass,
vmdata)))->jcgo_clinitRtn) != 0)
(*rtn)();
noerr = 1;
}
#ifdef OBJT_java_lang_Throwable
JCGO_TRY_LEAVE
JCGO_TRY_CATCHES(1)
JCGO_TRY_CATCH(OBJT_java_lang_Throwable, MAXT_java_lang_Throwable)
{
#ifdef OBJT_java_lang_VMThrowable
java_lang_VMThrowable__throwExceptionInInitializer0X__LoLc(
(java_lang_Object)JCGO_TRY_THROWABLE(0), aclass);
#endif
}
JCGO_TRY_RETHROW(1)
#endif
}
JCGO_TRY_LEAVE
{
JCGO_SYNC_BLOCKSAFENZ(aclass)
{
jObjectArr listEntry;
if (noerr)
JCGO_FIELD_NZACCESS(aclass, modifiers) &= ~(jint)JCGO_ACCMOD_TRANSIENT;
else JCGO_FIELD_NZACCESS(aclass, modifiers) =
(JCGO_FIELD_NZACCESS(aclass, modifiers) &
~(jint)JCGO_ACCMOD_TRANSIENT) | (jint)JCGO_ACCMOD_VOLATILE;
prevEntry = jnull;
JCGO_CRITMOD_BEGIN(jcgo_clinitListMutex)
listEntry = jcgo_globData.clinitActiveList;
while (listEntry != jnull &&
JCGO_ARR_INTERNALACC(jObject, listEntry, 0) != (jObject)aclass)
{
prevEntry = listEntry;
listEntry = (jObjectArr)JCGO_ARR_INTERNALACC(jObject, listEntry, 1);
}
if (listEntry != jnull)
{
if (prevEntry != jnull)
JCGO_ARR_INTERNALACC(jObject, prevEntry, 1) =
JCGO_ARR_INTERNALACC(jObject, listEntry, 1);
else jcgo_globData.clinitActiveList =
(jObjectArr)JCGO_ARR_INTERNALACC(jObject, listEntry, 1);
}
JCGO_CRITMOD_END(jcgo_clinitListMutex)
#ifdef OBJT_java_lang_VMThread
java_lang_VMThread__notify0__LoI((java_lang_Object)aclass, 1);
#endif
}
JCGO_SYNC_END
}
JCGO_TRY_FINALLYEND
}
#else
if ((JCGO_FIELD_NZACCESS(aclass, modifiers) & JCGO_ACCMOD_VOLATILE) == 0)
return;
#ifdef OBJT_java_lang_VMThrowable
if (JCGO_EXPECT_FALSE((JCGO_FIELD_NZACCESS(aclass,
modifiers) & JCGO_ACCMOD_TRANSIENT) == 0))
JCGO_THROW_EXC(java_lang_VMThrowable__createNoClassDefFoundError0X__LsI(
JCGO_FIELD_NZACCESS(aclass, name), 1));
#endif
if ((rtn = ((jvtable)&JCGO_METHODS_OF(JCGO_FIELD_NZACCESS(aclass,
vmdata)))->jcgo_clinitRtn) != 0)
{
#ifdef OBJT_java_lang_Throwable
JCGO_TRY_BLOCK
#endif
{
JCGO_FIELD_NZACCESS(aclass, modifiers) &= ~(jint)JCGO_ACCMOD_VOLATILE;
(*rtn)();
JCGO_FIELD_NZACCESS(aclass, modifiers) &=
~(jint)(JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT);
}
#ifdef OBJT_java_lang_Throwable
JCGO_TRY_LEAVE
JCGO_TRY_CATCHES(2)
JCGO_TRY_CATCH(OBJT_java_lang_Throwable, MAXT_java_lang_Throwable)
{
JCGO_FIELD_NZACCESS(aclass, modifiers) =
(JCGO_FIELD_NZACCESS(aclass, modifiers) & ~(jint)JCGO_ACCMOD_TRANSIENT) |
(jint)JCGO_ACCMOD_VOLATILE;
#ifdef OBJT_java_lang_VMThrowable
java_lang_VMThrowable__throwExceptionInInitializer0X__LoLc(
(java_lang_Object)JCGO_TRY_THROWABLE(0), aclass);
#endif
}
JCGO_TRY_RETHROW(2)
#endif
}
else JCGO_FIELD_NZACCESS(aclass, modifiers) &=
~(jint)(JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT);
#endif
}
#else /* JCGO_STDCLINIT */
#ifdef JCGO_CLINITCHK
JCGO_NOSEP_STATIC void CFASTCALL jcgo_clinitCheckOrder(
java_lang_Class aclass )
{
#ifdef JCGO_THREADS
jint mods = *(volatile jint *)&JCGO_FIELD_NZACCESS(aclass, modifiers);
struct jcgo_tcb_s *tcb;
if ((mods & (JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT)) == 0)
return;
if ((mods & (JCGO_ACCMOD_VOLATILE | JCGO_ACCMOD_TRANSIENT)) ==
(jint)JCGO_ACCMOD_TRANSIENT)
{
JCGO_GET_CURTCB(&tcb);
if (tcb == &jcgo_mainTCB)
return;
}
#else
if ((JCGO_FIELD_NZACCESS(aclass, modifiers) & JCGO_ACCMOD_VOLATILE) == 0)
return;
#endif
JCGO_FATAL_ABORT("Invalid class initialization order!");
}
#endif /* JCGO_CLINITCHK */
#endif /* ! JCGO_STDCLINIT */
#ifdef JCGO_SEHTRY
EXTRASTATIC void *CFASTCALL jcgo_mainSehJmpBuf( void )
{
#ifdef OBJT_java_lang_VMThrowable
return jcgo_mainTCB.jbuf;
#else
return NULL;
#endif
}
#endif /* JCGO_SEHTRY */
EXTRASTATIC void **CFASTCALL jcgo_tinitialize( JCGO_MAIN_TCHAR **targv )
{
#ifndef JCGO_MAIN_OMITSETROOTS
#ifndef JCGO_NOGC
void *pDataFirstSym = jcgo_pDataFirstSym;
#endif
#endif
if (!jcgo_initialized)
{
*(volatile int *)&jcgo_initialized = 1;
jcgo_initFP();
JCGO_MEM_POSTINIT(0);
#ifndef JCGO_NOGC
#ifdef JCGO_GCRESETDLS
GC_clear_roots();
#endif
#ifndef JCGO_MAIN_OMITSETROOTS
GC_add_roots(pDataFirstSym < (void *)(&GCDATALASTSYM) ? pDataFirstSym :
(void *)(&GCDATALASTSYM), pDataFirstSym < (void *)(&GCDATALASTSYM) ?
(char *)(&GCDATALASTSYM) + sizeof(GCDATALASTSYM) :
(char *)pDataFirstSym + sizeof(GCDATAFIRSTSYM));
GC_add_roots((void *)(&GCBSSFIRSTSYM) < (void *)(&GCBSSLASTSYM) ?
(char *)(&GCBSSFIRSTSYM) : (char *)(&GCBSSLASTSYM),
(void *)(&GCBSSFIRSTSYM) < (void *)(&GCBSSLASTSYM) ?
(char *)(&GCBSSLASTSYM) + sizeof(GCBSSLASTSYM) :
(char *)(&GCBSSFIRSTSYM) + sizeof(GCBSSFIRSTSYM));
*(void *volatile *)&jcgo_pDataFirstSym = NULL;
#endif
#endif
if (JCGO_ARRAY_NZLENGTH(JCGO_OBJREF_OF(jcgo_noTypesClassArr)))
jcgo_mainTCB.jcgo_methods = (jvtable)&java_lang_Object_methods;
if ((targv = JCGO_MAIN_TINITINOUT(targv, JCGO_MAIN_OUTREDIRECT)) != NULL)
jcgo_targv0 = targv[0];
#ifdef JCGO_THREADS
if (jcgo_threadsInit() < 0)
JCGO_FATAL_ABORT("Could not initialize main thread!");
#endif
jcgo_setSyncSignals();
}
#ifndef JCGO_NOJNI
else if (jcgo_initialized < 0)
JCGO_FATAL_ABORT("Cannot re-initialize destroyed JavaVM");
#endif
return (void **)targv;
}
JCGO_NOSEP_INLINE jObjectArr CFASTCALL jcgo_tconvertArgs(
JCGO_MAIN_TCHAR **targv )
{
#ifdef JCGO_MAINARGS_NOTUSED
return (jObjectArr)jcgo_newArray(JCGO_CLASSREF_OF(java_lang_String__class),
0, 0);
#else
jObjectArr argArr;
int i;
int argc = 0;
if (targv != NULL)
while (targv[argc] != NULL)
argc++;
argArr = (jObjectArr)jcgo_newArray(JCGO_CLASSREF_OF(java_lang_String__class),
0, (jint)(argc > 0 ? argc - 1 : 0));
for (i = 1; i < argc; i++)
{
JCGO_JNI_BLOCK(0)
JCGO_ARR_INTERNALACC(jObject, argArr, i - 1) = jcgo_jniLeave(jcgo_pJniEnv,
(jobject)JCGO_MAIN_TCONVERTCMDARG(jcgo_pJniEnv, targv[i]));
}
return argArr;
#endif
}
EXTRASTATIC jObjectArr CFASTCALL jcgo_tpostInit( void **targv )
{
jObjectArr argArr;
if (jcgo_initialized == 1)
{
jcgo_initAsyncSignals();
#ifndef JCGO_NOJNI
jcgo_initJni();
#endif
#ifdef JCGO_STDCLINIT
JCGO_CLINIT_TRIG(java_lang_String__class);
#ifdef OBJT_java_lang_VMThrowable
JCGO_CLINIT_TRIG(java_lang_VMThrowable__class);
#endif
#ifdef OBJT_java_lang_VMThread_ExitMain
JCGO_CLINIT_TRIG(java_lang_VMThread_ExitMain__class);
#endif
#ifdef OBJT_java_lang_System
JCGO_CLINIT_TRIG(java_lang_System__class);
#endif
#else
jcgo_initClasses();
#ifndef JCGO_NOJNI
jcgo_jniOnLoad();
#endif
#endif
}
else if (((jcgo_initialized + 1) >> 1) == 0)
return jnull;
argArr = jcgo_tconvertArgs((JCGO_MAIN_TCHAR **)targv);
*(volatile int *)&jcgo_initialized = 2;
return argArr;
}
JCGO_NOSEP_INLINE void CFASTCALL jcgo_atExit( jObject throwable )
{
#ifndef JCGO_NOJNI
jcgo_jniOnUnload();
#endif
if (((jcgo_initialized + 1) >> 1) != 0)
{
*(volatile int *)&jcgo_initialized = -1;
#ifdef OBJT_java_lang_VMThrowable
if (throwable != jnull)
{
#ifdef OBJT_java_lang_OutOfMemoryError
if (jcgo_instanceOf0(OBJT_java_lang_OutOfMemoryError,
MAXT_java_lang_OutOfMemoryError, throwable))
{
JCGO_MEM_HEAPDESTROY;
JCGO_FATAL_ABORT("Out of memory!");
}
#endif
JCGO_FATAL_ABORT("Internal error in main thread!");
}
#endif
JCGO_MEM_HEAPDESTROY;
}
}
EXTRASTATIC void CFASTCALL jcgo_destroyJavaVM( jObject throwable )
{
#ifdef OBJT_java_lang_VMThread
jObject ex;
{
JCGO_TRY_BLOCK
{
java_lang_VMThread__destroyJavaVM0X__LoI((java_lang_Object)throwable,
(jint)(jcgo_initialized == 1));
}
JCGO_TRY_LEAVE
JCGO_TRY_CATCHALLSTORE(&ex)
}
jcgo_atExit(ex);
#else
jcgo_atExit(throwable);
#endif
jcgo_unregSignalHandlers();
#ifdef JCGO_THREADS
(void)JCGO_THREAD_CLOSEHND(&jcgo_mainTCB.thrhandle);
(void)JCGO_THREADT_CLEAR(&jcgo_mainTCB.thrhandle);
#endif
}
#endif