mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
809 lines
20 KiB
C
809 lines
20 KiB
C
/*
|
|
* @(#) $(JCGO)/include/jcgojnie.c --
|
|
* a part of the JCGO runtime subsystem.
|
|
**
|
|
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
|
|
* Copyright (C) 2001-2012 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_NOCREATJVM, JCGO_NOGC, JCGO_SEHTRY, JCGO_THREADS.
|
|
* Macros for tuning: JNICALL_INVOKE, JNIEXPORT_INVOKE, JNIONLOADDECLS,
|
|
* JNIONLOADLIST, JNIONUNLOADLIST.
|
|
*/
|
|
|
|
/*
|
|
* 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
|
|
|
|
#ifndef JNICALL_INVOKE
|
|
#define JNICALL_INVOKE JNICALL
|
|
#endif
|
|
|
|
#ifndef JNIEXPORT_INVOKE
|
|
#define JNIEXPORT_INVOKE JNIEXPORT
|
|
#endif
|
|
|
|
STATICDATA int jcgo_jniOnLoadDone = 0;
|
|
|
|
typedef jint (JNICALL *jcgo_jnionload_t)(JavaVM *, void *);
|
|
typedef void (JNICALL *jcgo_jnionunload_t)(JavaVM *, void *);
|
|
|
|
#ifdef JNIONLOADDECLS
|
|
#define JNIONLOAD(func) JNIIMPORT jint JNICALL func(JavaVM *, void *);
|
|
#define JNIONUNLOAD(func) JNIIMPORT void JNICALL func(JavaVM *, void *);
|
|
JNIONLOADDECLS
|
|
#endif
|
|
|
|
STATICDATA jcgo_jnionload_t /* CONST */ jcgo_jniOnLoadList[] =
|
|
{
|
|
#ifdef JNIONLOADLIST
|
|
JNIONLOADLIST,
|
|
#endif
|
|
0
|
|
};
|
|
|
|
STATICDATA jcgo_jnionunload_t /* CONST */ jcgo_jniOnUnloadList[] =
|
|
{
|
|
#ifdef JNIONUNLOADLIST
|
|
JNIONUNLOADLIST,
|
|
#endif
|
|
0
|
|
};
|
|
|
|
STATIC jint JNICALL jcgo_JniGetJavaVM( JNIEnv *pJniEnv, JavaVM **pvm );
|
|
|
|
STATICDATA CONST struct JNINativeInterface_ jcgo_jniNatIface =
|
|
{
|
|
0, 0, 0, 0,
|
|
jcgo_JniGetVersion,
|
|
jcgo_JniDefineClass,
|
|
jcgo_JniFindClass,
|
|
jcgo_JniFromReflectedMethod,
|
|
jcgo_JniFromReflectedField,
|
|
jcgo_JniToReflectedMethod,
|
|
jcgo_JniGetSuperclass,
|
|
jcgo_JniIsAssignableFrom,
|
|
jcgo_JniToReflectedField,
|
|
jcgo_JniThrow,
|
|
jcgo_JniThrowNew,
|
|
jcgo_JniExceptionOccurred,
|
|
jcgo_JniExceptionDescribe,
|
|
jcgo_JniExceptionClear,
|
|
jcgo_JniFatalError,
|
|
jcgo_JniPushLocalFrame,
|
|
jcgo_JniPopLocalFrame,
|
|
jcgo_JniNewGlobalRef,
|
|
jcgo_JniDeleteGlobalRef,
|
|
jcgo_JniDeleteLocalRef,
|
|
jcgo_JniIsSameObject,
|
|
jcgo_JniNewLocalRef,
|
|
jcgo_JniEnsureLocalCapacity,
|
|
jcgo_JniAllocObject,
|
|
jcgo_JniNewObject,
|
|
jcgo_JniNewObjectV,
|
|
jcgo_JniNewObjectA,
|
|
jcgo_JniGetObjectClass,
|
|
jcgo_JniIsInstanceOf,
|
|
jcgo_JniGetMethodID,
|
|
jcgo_JniCallObjectMethod,
|
|
jcgo_JniCallObjectMethodV,
|
|
jcgo_JniCallObjectMethodA,
|
|
jcgo_JniCallBooleanMethod,
|
|
jcgo_JniCallBooleanMethodV,
|
|
jcgo_JniCallBooleanMethodA,
|
|
jcgo_JniCallByteMethod,
|
|
jcgo_JniCallByteMethodV,
|
|
jcgo_JniCallByteMethodA,
|
|
jcgo_JniCallCharMethod,
|
|
jcgo_JniCallCharMethodV,
|
|
jcgo_JniCallCharMethodA,
|
|
jcgo_JniCallShortMethod,
|
|
jcgo_JniCallShortMethodV,
|
|
jcgo_JniCallShortMethodA,
|
|
jcgo_JniCallIntMethod,
|
|
jcgo_JniCallIntMethodV,
|
|
jcgo_JniCallIntMethodA,
|
|
jcgo_JniCallLongMethod,
|
|
jcgo_JniCallLongMethodV,
|
|
jcgo_JniCallLongMethodA,
|
|
jcgo_JniCallFloatMethod,
|
|
jcgo_JniCallFloatMethodV,
|
|
jcgo_JniCallFloatMethodA,
|
|
jcgo_JniCallDoubleMethod,
|
|
jcgo_JniCallDoubleMethodV,
|
|
jcgo_JniCallDoubleMethodA,
|
|
jcgo_JniCallVoidMethod,
|
|
jcgo_JniCallVoidMethodV,
|
|
jcgo_JniCallVoidMethodA,
|
|
jcgo_JniCallNonvirtualObjectMethod,
|
|
jcgo_JniCallNonvirtualObjectMethodV,
|
|
jcgo_JniCallNonvirtualObjectMethodA,
|
|
jcgo_JniCallNonvirtualBooleanMethod,
|
|
jcgo_JniCallNonvirtualBooleanMethodV,
|
|
jcgo_JniCallNonvirtualBooleanMethodA,
|
|
jcgo_JniCallNonvirtualByteMethod,
|
|
jcgo_JniCallNonvirtualByteMethodV,
|
|
jcgo_JniCallNonvirtualByteMethodA,
|
|
jcgo_JniCallNonvirtualCharMethod,
|
|
jcgo_JniCallNonvirtualCharMethodV,
|
|
jcgo_JniCallNonvirtualCharMethodA,
|
|
jcgo_JniCallNonvirtualShortMethod,
|
|
jcgo_JniCallNonvirtualShortMethodV,
|
|
jcgo_JniCallNonvirtualShortMethodA,
|
|
jcgo_JniCallNonvirtualIntMethod,
|
|
jcgo_JniCallNonvirtualIntMethodV,
|
|
jcgo_JniCallNonvirtualIntMethodA,
|
|
jcgo_JniCallNonvirtualLongMethod,
|
|
jcgo_JniCallNonvirtualLongMethodV,
|
|
jcgo_JniCallNonvirtualLongMethodA,
|
|
jcgo_JniCallNonvirtualFloatMethod,
|
|
jcgo_JniCallNonvirtualFloatMethodV,
|
|
jcgo_JniCallNonvirtualFloatMethodA,
|
|
jcgo_JniCallNonvirtualDoubleMethod,
|
|
jcgo_JniCallNonvirtualDoubleMethodV,
|
|
jcgo_JniCallNonvirtualDoubleMethodA,
|
|
jcgo_JniCallNonvirtualVoidMethod,
|
|
jcgo_JniCallNonvirtualVoidMethodV,
|
|
jcgo_JniCallNonvirtualVoidMethodA,
|
|
jcgo_JniGetFieldID,
|
|
jcgo_JniGetObjectField,
|
|
jcgo_JniGetBooleanField,
|
|
jcgo_JniGetByteField,
|
|
jcgo_JniGetCharField,
|
|
jcgo_JniGetShortField,
|
|
jcgo_JniGetIntField,
|
|
jcgo_JniGetLongField,
|
|
jcgo_JniGetFloatField,
|
|
jcgo_JniGetDoubleField,
|
|
jcgo_JniSetObjectField,
|
|
jcgo_JniSetBooleanField,
|
|
jcgo_JniSetByteField,
|
|
jcgo_JniSetCharField,
|
|
jcgo_JniSetShortField,
|
|
jcgo_JniSetIntField,
|
|
jcgo_JniSetLongField,
|
|
jcgo_JniSetFloatField,
|
|
jcgo_JniSetDoubleField,
|
|
jcgo_JniGetStaticMethodID,
|
|
jcgo_JniCallStaticObjectMethod,
|
|
jcgo_JniCallStaticObjectMethodV,
|
|
jcgo_JniCallStaticObjectMethodA,
|
|
jcgo_JniCallStaticBooleanMethod,
|
|
jcgo_JniCallStaticBooleanMethodV,
|
|
jcgo_JniCallStaticBooleanMethodA,
|
|
jcgo_JniCallStaticByteMethod,
|
|
jcgo_JniCallStaticByteMethodV,
|
|
jcgo_JniCallStaticByteMethodA,
|
|
jcgo_JniCallStaticCharMethod,
|
|
jcgo_JniCallStaticCharMethodV,
|
|
jcgo_JniCallStaticCharMethodA,
|
|
jcgo_JniCallStaticShortMethod,
|
|
jcgo_JniCallStaticShortMethodV,
|
|
jcgo_JniCallStaticShortMethodA,
|
|
jcgo_JniCallStaticIntMethod,
|
|
jcgo_JniCallStaticIntMethodV,
|
|
jcgo_JniCallStaticIntMethodA,
|
|
jcgo_JniCallStaticLongMethod,
|
|
jcgo_JniCallStaticLongMethodV,
|
|
jcgo_JniCallStaticLongMethodA,
|
|
jcgo_JniCallStaticFloatMethod,
|
|
jcgo_JniCallStaticFloatMethodV,
|
|
jcgo_JniCallStaticFloatMethodA,
|
|
jcgo_JniCallStaticDoubleMethod,
|
|
jcgo_JniCallStaticDoubleMethodV,
|
|
jcgo_JniCallStaticDoubleMethodA,
|
|
jcgo_JniCallStaticVoidMethod,
|
|
jcgo_JniCallStaticVoidMethodV,
|
|
jcgo_JniCallStaticVoidMethodA,
|
|
jcgo_JniGetStaticFieldID,
|
|
jcgo_JniGetStaticObjectField,
|
|
jcgo_JniGetStaticBooleanField,
|
|
jcgo_JniGetStaticByteField,
|
|
jcgo_JniGetStaticCharField,
|
|
jcgo_JniGetStaticShortField,
|
|
jcgo_JniGetStaticIntField,
|
|
jcgo_JniGetStaticLongField,
|
|
jcgo_JniGetStaticFloatField,
|
|
jcgo_JniGetStaticDoubleField,
|
|
jcgo_JniSetStaticObjectField,
|
|
jcgo_JniSetStaticBooleanField,
|
|
jcgo_JniSetStaticByteField,
|
|
jcgo_JniSetStaticCharField,
|
|
jcgo_JniSetStaticShortField,
|
|
jcgo_JniSetStaticIntField,
|
|
jcgo_JniSetStaticLongField,
|
|
jcgo_JniSetStaticFloatField,
|
|
jcgo_JniSetStaticDoubleField,
|
|
jcgo_JniNewString,
|
|
jcgo_JniGetStringLength,
|
|
jcgo_JniGetStringChars,
|
|
jcgo_JniReleaseStringChars,
|
|
jcgo_JniNewStringUTF,
|
|
jcgo_JniGetStringUTFLength,
|
|
jcgo_JniGetStringUTFChars,
|
|
jcgo_JniReleaseStringUTFChars,
|
|
jcgo_JniGetArrayLength,
|
|
jcgo_JniNewObjectArray,
|
|
jcgo_JniGetObjectArrayElement,
|
|
jcgo_JniSetObjectArrayElement,
|
|
jcgo_JniNewBooleanArray,
|
|
jcgo_JniNewByteArray,
|
|
jcgo_JniNewCharArray,
|
|
jcgo_JniNewShortArray,
|
|
jcgo_JniNewIntArray,
|
|
jcgo_JniNewLongArray,
|
|
jcgo_JniNewFloatArray,
|
|
jcgo_JniNewDoubleArray,
|
|
jcgo_JniGetBooleanArrayElements,
|
|
jcgo_JniGetByteArrayElements,
|
|
jcgo_JniGetCharArrayElements,
|
|
jcgo_JniGetShortArrayElements,
|
|
jcgo_JniGetIntArrayElements,
|
|
jcgo_JniGetLongArrayElements,
|
|
jcgo_JniGetFloatArrayElements,
|
|
jcgo_JniGetDoubleArrayElements,
|
|
jcgo_JniReleaseBooleanArrayElements,
|
|
jcgo_JniReleaseByteArrayElements,
|
|
jcgo_JniReleaseCharArrayElements,
|
|
jcgo_JniReleaseShortArrayElements,
|
|
jcgo_JniReleaseIntArrayElements,
|
|
jcgo_JniReleaseLongArrayElements,
|
|
jcgo_JniReleaseFloatArrayElements,
|
|
jcgo_JniReleaseDoubleArrayElements,
|
|
jcgo_JniGetBooleanArrayRegion,
|
|
jcgo_JniGetByteArrayRegion,
|
|
jcgo_JniGetCharArrayRegion,
|
|
jcgo_JniGetShortArrayRegion,
|
|
jcgo_JniGetIntArrayRegion,
|
|
jcgo_JniGetLongArrayRegion,
|
|
jcgo_JniGetFloatArrayRegion,
|
|
jcgo_JniGetDoubleArrayRegion,
|
|
jcgo_JniSetBooleanArrayRegion,
|
|
jcgo_JniSetByteArrayRegion,
|
|
jcgo_JniSetCharArrayRegion,
|
|
jcgo_JniSetShortArrayRegion,
|
|
jcgo_JniSetIntArrayRegion,
|
|
jcgo_JniSetLongArrayRegion,
|
|
jcgo_JniSetFloatArrayRegion,
|
|
jcgo_JniSetDoubleArrayRegion,
|
|
jcgo_JniRegisterNatives,
|
|
jcgo_JniUnregisterNatives,
|
|
jcgo_JniMonitorEnter,
|
|
jcgo_JniMonitorExit,
|
|
jcgo_JniGetJavaVM,
|
|
jcgo_JniGetStringRegion,
|
|
jcgo_JniGetStringUTFRegion,
|
|
jcgo_JniGetPrimitiveArrayCritical,
|
|
jcgo_JniReleasePrimitiveArrayCritical,
|
|
jcgo_JniGetStringCritical,
|
|
jcgo_JniReleaseStringCritical,
|
|
jcgo_JniNewWeakGlobalRef,
|
|
jcgo_JniDeleteWeakGlobalRef,
|
|
jcgo_JniExceptionCheck,
|
|
jcgo_JniNewDirectByteBuffer,
|
|
jcgo_JniGetDirectBufferAddress,
|
|
jcgo_JniGetDirectBufferCapacity,
|
|
jcgo_JniGetObjectRefType
|
|
};
|
|
|
|
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_initJni( void )
|
|
{
|
|
#ifdef JCGO_THREADS
|
|
jcgo_globData.jniNewTCB = jcgo_memAlloc(sizeof(struct jcgo_tcb_s),
|
|
JCGO_PTR_RESERVED);
|
|
#endif
|
|
}
|
|
|
|
#ifdef JCGO_THREADS
|
|
|
|
JCGO_NOSEP_INLINE void CFASTCALL jcgo_jniPrepareNewTCB(struct jcgo_tcb_s *tcb)
|
|
{
|
|
struct jcgo_tcb_s *JCGO_TRY_VOLATILE othertcb = NULL;
|
|
{
|
|
JCGO_TRY_BLOCK
|
|
{
|
|
othertcb = jcgo_memAlloc(sizeof(struct jcgo_tcb_s), JCGO_PTR_RESERVED);
|
|
}
|
|
JCGO_TRY_LEAVE
|
|
JCGO_TRY_CATCHIGNOREALL(tcb)
|
|
}
|
|
JCGO_CRITMOD_BEGIN(jcgo_jniMiscAttachMutex)
|
|
jcgo_globData.jniNewTCB = (struct jcgo_tcb_s *)othertcb;
|
|
JCGO_CRITMOD_END(jcgo_jniMiscAttachMutex)
|
|
}
|
|
|
|
#endif /* JCGO_THREADS */
|
|
|
|
#ifndef JCGO_NOCREATJVM
|
|
|
|
STATIC JNIEnv *CFASTCALL jcgo_jniVmAttachThread( JavaVM *vm,
|
|
JavaVMAttachArgs *args, int daemon )
|
|
{
|
|
#ifdef JCGO_THREADS
|
|
#ifndef JCGO_NOGC
|
|
struct GC_stack_base stackbase;
|
|
#endif
|
|
jObjectArr JCGO_TRY_VOLATILE localObjs;
|
|
#ifdef OBJT_java_lang_VMThread
|
|
java_lang_Object groupObj = jnull;
|
|
#endif
|
|
#endif
|
|
struct jcgo_tcb_s *tcb;
|
|
if (JCGO_EXPECT_FALSE(((jcgo_initialized + 1) >> 1) == 0))
|
|
return NULL;
|
|
#ifdef JCGO_THREADS
|
|
tcb = jcgo_getSelfTCB();
|
|
if (JCGO_EXPECT_TRUE(tcb == NULL))
|
|
{
|
|
if (args != NULL && args->version != JNI_VERSION_1_2 &&
|
|
args->version != JNI_VERSION_1_4 && args->version != JNI_VERSION_1_6)
|
|
return NULL;
|
|
for (;;)
|
|
{
|
|
JCGO_CRITMOD_BEGIN(jcgo_jniMiscAttachMutex)
|
|
if ((tcb = (struct jcgo_tcb_s *)(
|
|
*(void *volatile *)&jcgo_globData.jniNewTCB)) != NULL)
|
|
jcgo_globData.jniNewTCB = JCGO_PTR_RESERVED;
|
|
JCGO_CRITMOD_END(jcgo_jniMiscAttachMutex)
|
|
if (JCGO_EXPECT_TRUE(tcb != JCGO_PTR_RESERVED))
|
|
break;
|
|
JCGO_THREAD_YIELD;
|
|
}
|
|
if (JCGO_EXPECT_FALSE(tcb == NULL))
|
|
return NULL;
|
|
if (jcgo_threadInitHandle(tcb) < 0)
|
|
{
|
|
JCGO_CRITMOD_BEGIN(jcgo_jniMiscAttachMutex)
|
|
jcgo_globData.jniNewTCB = NULL;
|
|
JCGO_CRITMOD_END(jcgo_jniMiscAttachMutex)
|
|
return NULL;
|
|
}
|
|
tcb->jcgo_methods = (jvtable)&java_lang_Object_methods;
|
|
(void)JCGO_MUTEX_LOCK(&jcgo_nonParallelMutex);
|
|
#ifndef JCGO_NOGC
|
|
if (GC_get_stack_base(&stackbase))
|
|
stackbase.mem_base = (void *)&stackbase;
|
|
tcb->gcAttached = !GC_register_my_thread(&stackbase);
|
|
#endif
|
|
#ifdef OBJT_java_lang_VMThread
|
|
if (args != NULL)
|
|
groupObj = (java_lang_Object)jcgo_jniDeRef(args->group);
|
|
#endif
|
|
#ifdef JCGO_SEHTRY
|
|
#ifdef OBJT_java_lang_VMThrowable
|
|
if (!setjmp(tcb->jbuf))
|
|
#endif
|
|
#endif
|
|
{
|
|
jcgo_threadAttachTCB(tcb);
|
|
jcgo_jniPrepareNewTCB(tcb);
|
|
localObjs = jnull;
|
|
{
|
|
JCGO_TRY_BLOCK
|
|
{
|
|
localObjs = (jObjectArr)jcgo_newArray(
|
|
JCGO_CLASSREF_OF(java_lang_Object__class), 0,
|
|
(jint)(JCGO_JNI_DEFLOCALREFS + 1));
|
|
#ifdef OBJT_java_lang_VMThread
|
|
tcb->thread =
|
|
(jObject)java_lang_VMThread__createAttachedThread0X__LoLsLoI(groupObj,
|
|
args != NULL && args->name != NULL ? jcgo_utfMakeString(args->name) :
|
|
jnull, JCGO_OBJREF_OF(*(java_lang_Object)tcb), (jint)daemon);
|
|
#endif
|
|
}
|
|
JCGO_TRY_LEAVE
|
|
JCGO_TRY_CATCHIGNOREALL(tcb)
|
|
}
|
|
if (JCGO_EXPECT_FALSE(localObjs == jnull
|
|
#ifdef OBJT_java_lang_VMThread
|
|
|| tcb->thread == jnull
|
|
#endif
|
|
))
|
|
{
|
|
jcgo_threadDetachTCB(tcb);
|
|
(void)JCGO_THREAD_CLOSEHND(&tcb->thrhandle);
|
|
(void)JCGO_THREADT_CLEAR(&tcb->thrhandle);
|
|
return NULL;
|
|
}
|
|
tcb->localObjs = (jObjectArr)localObjs;
|
|
}
|
|
jcgo_saveTCB();
|
|
tcb->jniEnv = &jcgo_jniNatIface;
|
|
}
|
|
#else
|
|
tcb = &jcgo_mainTCB;
|
|
#endif
|
|
if (tcb->jniEnv == NULL)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
return &tcb->jniEnv;
|
|
}
|
|
|
|
#endif /* ! JCGO_NOCREATJVM */
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniVmDestroyJavaVM( JavaVM *vm )
|
|
{
|
|
#ifndef JCGO_NOCREATJVM
|
|
struct jcgo_tcb_s *tcb;
|
|
jObject ex;
|
|
if (JCGO_EXPECT_TRUE(((jcgo_initialized + 1) >> 1) != 0))
|
|
{
|
|
#ifdef JCGO_THREADS
|
|
tcb = jcgo_getSelfTCB();
|
|
if (JCGO_EXPECT_FALSE(tcb == NULL))
|
|
return (jint)JNI_ERR;
|
|
#else
|
|
tcb = &jcgo_mainTCB;
|
|
#endif
|
|
if (tcb->jniEnv == NULL)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
tcb->jniEnv = NULL;
|
|
ex = tcb->nativeExc;
|
|
tcb->nativeExc = jnull;
|
|
tcb->localObjs = jnull;
|
|
if (jcgo_restoreTCB(tcb) < 0)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
#ifdef JCGO_SEHTRY
|
|
#ifdef OBJT_java_lang_VMThrowable
|
|
if (!setjmp(tcb->jbuf))
|
|
#endif
|
|
#endif
|
|
{
|
|
jcgo_destroyJavaVM(ex);
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
return (jint)JNI_ERR;
|
|
}
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniVmAttachCurrentThread( JavaVM *vm, void **penv, void *args )
|
|
{
|
|
#ifdef JCGO_NOCREATJVM
|
|
*penv = NULL;
|
|
return (jint)JNI_ERR;
|
|
#else
|
|
return (jint)((*(JNIEnv **)penv = jcgo_jniVmAttachThread(vm,
|
|
(JavaVMAttachArgs *)args, 0)) != NULL ? 0 : JNI_ERR);
|
|
#endif
|
|
}
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniVmAttachCurrentThreadAsDaemon( JavaVM *vm, void **penv, void *args )
|
|
{
|
|
#ifdef JCGO_NOCREATJVM
|
|
*penv = NULL;
|
|
return (jint)JNI_ERR;
|
|
#else
|
|
return (jint)((*(JNIEnv **)penv = jcgo_jniVmAttachThread(vm,
|
|
(JavaVMAttachArgs *)args, 1)) != NULL ? 0 : JNI_ERR);
|
|
#endif
|
|
}
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniVmDetachCurrentThread( JavaVM *vm )
|
|
{
|
|
#ifndef JCGO_NOCREATJVM
|
|
#ifdef JCGO_THREADS
|
|
struct jcgo_tcb_s *tcb;
|
|
#ifdef OBJT_java_lang_VMThread
|
|
jObject ex;
|
|
#endif
|
|
if (JCGO_EXPECT_TRUE(((jcgo_initialized + 1) >> 1) != 0))
|
|
{
|
|
tcb = jcgo_getSelfTCB();
|
|
if (JCGO_EXPECT_FALSE(tcb == NULL || tcb == &jcgo_mainTCB))
|
|
return 0;
|
|
if (tcb->jniEnv == NULL)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
tcb->jniEnv = NULL;
|
|
#ifdef OBJT_java_lang_VMThread
|
|
ex = tcb->nativeExc;
|
|
#endif
|
|
tcb->nativeExc = jnull;
|
|
tcb->localObjs = jnull;
|
|
if (jcgo_restoreTCB(tcb) < 0)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
#ifdef OBJT_java_lang_VMThread
|
|
#ifdef JCGO_SEHTRY
|
|
#ifdef OBJT_java_lang_VMThrowable
|
|
if (!setjmp(tcb->jbuf))
|
|
#endif
|
|
#endif
|
|
{
|
|
JCGO_TRY_BLOCK
|
|
{
|
|
java_lang_VMThread__detachThread0X__Lo((java_lang_Object)ex);
|
|
}
|
|
JCGO_TRY_LEAVE
|
|
JCGO_TRY_CATCHIGNOREALL(tcb)
|
|
}
|
|
#endif
|
|
jcgo_threadDetachTCB(tcb);
|
|
(void)JCGO_THREAD_CLOSEHND(&tcb->thrhandle);
|
|
(void)JCGO_THREADT_CLEAR(&tcb->thrhandle);
|
|
return 0;
|
|
}
|
|
#endif
|
|
#endif
|
|
return (jint)JNI_ERR;
|
|
}
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniVmGetEnv( JavaVM *vm, void **penv, jint version )
|
|
{
|
|
struct jcgo_tcb_s *tcb;
|
|
if (JCGO_EXPECT_FALSE(!jcgo_initialized))
|
|
{
|
|
*penv = NULL;
|
|
return (jint)JNI_EDETACHED;
|
|
}
|
|
#ifdef JCGO_THREADS
|
|
tcb = jcgo_getSelfTCB();
|
|
if (JCGO_EXPECT_FALSE(tcb == NULL))
|
|
{
|
|
*penv = NULL;
|
|
return (jint)JNI_EDETACHED;
|
|
}
|
|
#else
|
|
tcb = &jcgo_mainTCB;
|
|
#endif
|
|
if (JCGO_EXPECT_FALSE(version < (jint)JNI_VERSION_1_1 ||
|
|
version > (jint)JNI_VERSION_1_6))
|
|
{
|
|
*penv = NULL;
|
|
return (jint)JNI_EVERSION;
|
|
}
|
|
if (tcb->jniEnv == NULL)
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
*(JNIEnv **)penv = &tcb->jniEnv;
|
|
return 0;
|
|
}
|
|
|
|
STATICDATA CONST struct JNIInvokeInterface_ jcgo_jniInvokeIface =
|
|
{
|
|
0, 0, 0,
|
|
jcgo_JniVmDestroyJavaVM,
|
|
jcgo_JniVmAttachCurrentThread,
|
|
jcgo_JniVmDetachCurrentThread,
|
|
jcgo_JniVmGetEnv,
|
|
jcgo_JniVmAttachCurrentThreadAsDaemon
|
|
};
|
|
|
|
STATICDATA JavaVM CONST jcgo_jniJavaVM = &jcgo_jniInvokeIface;
|
|
|
|
STATIC jint JNICALL
|
|
jcgo_JniGetJavaVM( JNIEnv *pJniEnv, JavaVM **pvm )
|
|
{
|
|
*pvm = (JavaVM *)&jcgo_jniJavaVM;
|
|
return 0;
|
|
}
|
|
|
|
#ifndef JCGO_NOCREATJVM
|
|
|
|
JNIEXPORT_INVOKE jint JNICALL_INVOKE
|
|
JNI_GetDefaultJavaVMInitArgs( void *args )
|
|
{
|
|
JavaVMInitArgs *pInitArgs = (JavaVMInitArgs *)args;
|
|
if (pInitArgs->version != (jint)JNI_VERSION_1_2 &&
|
|
pInitArgs->version != (jint)JNI_VERSION_1_4 &&
|
|
pInitArgs->version != (jint)JNI_VERSION_1_6)
|
|
return (jint)JNI_EVERSION;
|
|
pInitArgs->version = (jint)JNI_VERSION_1_6;
|
|
pInitArgs->nOptions = 0;
|
|
pInitArgs->options = NULL;
|
|
pInitArgs->ignoreUnrecognized = (jboolean)JNI_TRUE;
|
|
return 0;
|
|
}
|
|
|
|
EXTRASTATIC int /* CFASTCALL */
|
|
jcgo_jniTCreateJavaVM( void **targv )
|
|
{
|
|
jObject throwable;
|
|
{
|
|
JCGO_TRY_BLOCK
|
|
{
|
|
(void)jcgo_tpostInit(targv);
|
|
jcgo_mainTCB.localObjs = (jObjectArr)jcgo_newArray(
|
|
JCGO_CLASSREF_OF(java_lang_Object__class), 0,
|
|
(jint)(JCGO_JNI_DEFLOCALREFS + 1));
|
|
}
|
|
JCGO_TRY_LEAVE
|
|
JCGO_TRY_CATCHALLSTORE(&throwable)
|
|
}
|
|
if (JCGO_EXPECT_FALSE(throwable != jnull))
|
|
{
|
|
jcgo_destroyJavaVM(throwable);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
JNIEXPORT_INVOKE jint JNICALL_INVOKE
|
|
JNI_CreateJavaVM( JavaVM **pvm, void **penv, void *args )
|
|
{
|
|
#ifdef JCGO_NOGC
|
|
int (*fnLaunch)(void **);
|
|
#else
|
|
int (*volatile fnLaunch)(void **);
|
|
#endif
|
|
if (JCGO_EXPECT_TRUE(!jcgo_initialized))
|
|
{
|
|
fnLaunch = &jcgo_jniTCreateJavaVM;
|
|
#ifndef JCGO_NOGC
|
|
JCGO_MAIN_GCSETNODLS;
|
|
JCGO_MAIN_GCNOINTERIOR;
|
|
GC_INIT();
|
|
#endif
|
|
#ifdef JCGO_SEHTRY
|
|
#ifdef OBJT_java_lang_VMThrowable
|
|
if (!setjmp(jcgo_mainTCB.jbuf))
|
|
#endif
|
|
#endif
|
|
{
|
|
if ((*fnLaunch)(jcgo_tinitialize(NULL)) >= 0)
|
|
{
|
|
#ifdef JCGO_THREADS
|
|
jcgo_saveTCB();
|
|
#endif
|
|
jcgo_mainTCB.jniEnv = &jcgo_jniNatIface;
|
|
*(JNIEnv **)penv = &jcgo_mainTCB.jniEnv;
|
|
*pvm = (JavaVM *)&jcgo_jniJavaVM;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
*pvm = NULL;
|
|
*penv = NULL;
|
|
return (jint)JNI_ERR;
|
|
}
|
|
|
|
#endif /* ! JCGO_NOCREATJVM */
|
|
|
|
JNIEXPORT_INVOKE jint JNICALL_INVOKE
|
|
JNI_GetCreatedJavaVMs( JavaVM **vmBuf, jsize bufLen, jsize *nVMs )
|
|
{
|
|
if (JCGO_EXPECT_FALSE(((jcgo_initialized + 1) >> 1) == 0))
|
|
{
|
|
*nVMs = 0;
|
|
return 0;
|
|
}
|
|
*nVMs = 1;
|
|
if (JCGO_EXPECT_TRUE((jint)bufLen > 0))
|
|
vmBuf[0] = (JavaVM *)&jcgo_jniJavaVM;
|
|
return 0;
|
|
}
|
|
|
|
JCGO_NOSEP_STATIC JNIEnv *CFASTCALL jcgo_jniEnterX( jObjectArr localObjs )
|
|
{
|
|
struct jcgo_tcb_s *tcb;
|
|
JCGO_GET_CURTCB(&tcb);
|
|
*(jvtable *)&JCGO_METHODS_OF(localObjs) = (jvtable)&jObjectArr_methods;
|
|
JCGO_FIELD_NZACCESS(localObjs, jcgo_component) =
|
|
JCGO_CLASSREF_OF(java_lang_Object__class);
|
|
#ifdef JCGO_SEHTRY
|
|
#ifndef JCGO_NOCREATJVM
|
|
tcb->insideJniCall++;
|
|
#endif
|
|
#endif
|
|
tcb->localObjs = localObjs;
|
|
#ifdef JCGO_THREADS
|
|
jcgo_saveTCB();
|
|
#endif
|
|
tcb->jniEnv = &jcgo_jniNatIface;
|
|
return &tcb->jniEnv;
|
|
}
|
|
|
|
JCGO_NOSEP_STATIC jObject CFASTCALL jcgo_jniLeave( JNIEnv *pJniEnv,
|
|
jobject obj )
|
|
{
|
|
jObject ex;
|
|
jObject jobj = jcgo_jniDeRef(obj);
|
|
struct jcgo_tcb_s *tcb;
|
|
if ((tcb = JCGO_JNI_GETTCB(pJniEnv))->jniEnv != &jcgo_jniNatIface ||
|
|
(tcb->jniEnv = NULL, ex = tcb->nativeExc, tcb->nativeExc = jnull,
|
|
tcb->localObjs = jnull, jcgo_restoreTCB(tcb) < 0))
|
|
jcgo_abortOnJniEnvCorrupted();
|
|
else
|
|
{
|
|
#ifdef JCGO_SEHTRY
|
|
#ifndef JCGO_NOCREATJVM
|
|
tcb->insideJniCall--;
|
|
#endif
|
|
#endif
|
|
jcgo_checkStop(tcb);
|
|
if (JCGO_EXPECT_FALSE(ex != jnull))
|
|
JCGO_THROW_EXC(ex);
|
|
}
|
|
return jobj;
|
|
}
|
|
|
|
STATIC void CFASTCALL jcgo_jniOnLoad( void )
|
|
{
|
|
int i;
|
|
if (!jcgo_jniOnLoadDone && ((jcgo_initialized + 1) >> 1) != 0)
|
|
{
|
|
i = 0;
|
|
JCGO_CRITMOD_BEGIN(jcgo_jniMiscAttachMutex)
|
|
if (JCGO_EXPECT_TRUE(!(*(volatile int *)&jcgo_jniOnLoadDone)))
|
|
{
|
|
*(volatile int *)&jcgo_jniOnLoadDone = 1;
|
|
i = -1;
|
|
}
|
|
JCGO_CRITMOD_END(jcgo_jniMiscAttachMutex)
|
|
if (JCGO_EXPECT_TRUE(i < 0))
|
|
{
|
|
while (jcgo_jniOnLoadList[++i])
|
|
{
|
|
JCGO_JNI_BLOCK(0)
|
|
(*jcgo_jniOnLoadList[i])((JavaVM *)&jcgo_jniJavaVM, NULL);
|
|
jcgo_jniLeave(jcgo_pJniEnv, NULL);
|
|
}
|
|
jcgo_jniOnLoadDone = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
JCGO_NOSEP_INLINE void JCGO_INLFRW_FASTCALL jcgo_jniOnUnload( void )
|
|
{
|
|
#ifdef JCGO_SEHTRY
|
|
struct jcgo_tcb_s *tcb;
|
|
#endif
|
|
int i;
|
|
if (JCGO_EXPECT_TRUE(jcgo_jniOnLoadDone > 1))
|
|
{
|
|
*(volatile int *)&jcgo_jniOnLoadDone = -1;
|
|
#ifdef JCGO_SEHTRY
|
|
JCGO_GET_CURTCB(&tcb);
|
|
#endif
|
|
for (i = 0; jcgo_jniOnUnloadList[i]; i++)
|
|
{
|
|
JCGO_TRY_BLOCK
|
|
{
|
|
JCGO_JNI_BLOCK(0)
|
|
(*jcgo_jniOnUnloadList[i])((JavaVM *)&jcgo_jniJavaVM, NULL);
|
|
jcgo_jniLeave(jcgo_pJniEnv, NULL);
|
|
}
|
|
JCGO_TRY_LEAVE
|
|
JCGO_TRY_CATCHIGNOREALL(tcb)
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|