diff options
author | Andrew Haley <aph@redhat.com> | 2016-09-30 16:24:48 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2016-09-30 16:24:48 +0000 |
commit | 07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch) | |
tree | 3f22b3241c513ad168c8353805614ae1249410f4 /libjava/jni.cc | |
parent | eae993948bae8b788c53772bcb9217c063716f93 (diff) | |
download | gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz |
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com>
* Makefile.def: Remove libjava.
* Makefile.tpl: Likewise.
* Makefile.in: Regenerate.
* configure.ac: Likewise.
* configure: Likewise.
* gcc/java: Remove.
* libjava: Likewise.
From-SVN: r240662
Diffstat (limited to 'libjava/jni.cc')
-rw-r--r-- | libjava/jni.cc | 2904 |
1 files changed, 0 insertions, 2904 deletions
diff --git a/libjava/jni.cc b/libjava/jni.cc deleted file mode 100644 index 86a4dc5b261..00000000000 --- a/libjava/jni.cc +++ /dev/null @@ -1,2904 +0,0 @@ -// jni.cc - JNI implementation, including the jump table. - -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -#include <config.h> - -#include <stdio.h> -#include <stddef.h> -#include <string.h> - -#include <gcj/cni.h> -#include <jvm.h> -#include <java-assert.h> -#include <jni.h> -#ifdef ENABLE_JVMPI -#include <jvmpi.h> -#endif -#ifdef INTERPRETER -#include <jvmti.h> -#include "jvmti-int.h" -#endif -#include <java/lang/Class.h> -#include <java/lang/ClassLoader.h> -#include <java/lang/Throwable.h> -#include <java/lang/ArrayIndexOutOfBoundsException.h> -#include <java/lang/StringIndexOutOfBoundsException.h> -#include <java/lang/StringBuffer.h> -#include <java/lang/UnsatisfiedLinkError.h> -#include <java/lang/InstantiationException.h> -#include <java/lang/NoSuchFieldError.h> -#include <java/lang/NoSuchMethodError.h> -#include <java/lang/reflect/Constructor.h> -#include <java/lang/reflect/Method.h> -#include <java/lang/reflect/Modifier.h> -#include <java/lang/OutOfMemoryError.h> -#include <java/lang/Integer.h> -#include <java/lang/ThreadGroup.h> -#include <java/lang/Thread.h> -#include <java/lang/IllegalAccessError.h> -#include <java/nio/Buffer.h> -#include <java/nio/DirectByteBufferImpl.h> -#include <java/nio/DirectByteBufferImpl$ReadWrite.h> -#include <java/util/IdentityHashMap.h> -#include <gnu/gcj/RawData.h> -#include <java/lang/ClassNotFoundException.h> - -#include <gcj/method.h> -#include <gcj/field.h> - -#include <java-interp.h> -#include <java-threads.h> - -using namespace gcj; - -// This enum is used to select different template instantiations in -// the invocation code. -enum invocation_type -{ - normal, - nonvirtual, - static_type, - constructor -}; - -// Forward declarations. -extern struct JNINativeInterface_ _Jv_JNIFunctions; -extern struct JNIInvokeInterface_ _Jv_JNI_InvokeFunctions; - -// Number of slots in the default frame. The VM must allow at least -// 16. -#define FRAME_SIZE 16 - -// Mark value indicating this is an overflow frame. -#define MARK_NONE 0 -// Mark value indicating this is a user frame. -#define MARK_USER 1 -// Mark value indicating this is a system frame. -#define MARK_SYSTEM 2 - -// This structure is used to keep track of local references. -struct _Jv_JNI_LocalFrame -{ - // This is one of the MARK_ constants. - unsigned char marker; - - // Flag to indicate some locals were allocated. - bool allocated_p; - - // Number of elements in frame. - int size; - - // The class loader of the JNI method that allocated this frame. - ::java::lang::ClassLoader *loader; - - // Next frame in chain. - _Jv_JNI_LocalFrame *next; - - // The elements. These are allocated using the C "struct hack". - jobject vec[0]; -}; - -// This holds a reference count for all local references. -static java::util::IdentityHashMap *local_ref_table; -// This holds a reference count for all global references. -static java::util::IdentityHashMap *global_ref_table; - -// The only VM. -JavaVM *_Jv_the_vm; - -#ifdef ENABLE_JVMPI -// The only JVMPI interface description. -static JVMPI_Interface _Jv_JVMPI_Interface; - -static jint -jvmpiEnableEvent (jint event_type, void *) -{ - switch (event_type) - { - case JVMPI_EVENT_OBJECT_ALLOC: - _Jv_JVMPI_Notify_OBJECT_ALLOC = _Jv_JVMPI_Interface.NotifyEvent; - break; - - case JVMPI_EVENT_THREAD_START: - _Jv_JVMPI_Notify_THREAD_START = _Jv_JVMPI_Interface.NotifyEvent; - break; - - case JVMPI_EVENT_THREAD_END: - _Jv_JVMPI_Notify_THREAD_END = _Jv_JVMPI_Interface.NotifyEvent; - break; - - default: - return JVMPI_NOT_AVAILABLE; - } - - return JVMPI_SUCCESS; -} - -static jint -jvmpiDisableEvent (jint event_type, void *) -{ - switch (event_type) - { - case JVMPI_EVENT_OBJECT_ALLOC: - _Jv_JVMPI_Notify_OBJECT_ALLOC = NULL; - break; - - default: - return JVMPI_NOT_AVAILABLE; - } - - return JVMPI_SUCCESS; -} -#endif - - - -void -_Jv_JNI_Init (void) -{ - local_ref_table = new java::util::IdentityHashMap; - global_ref_table = new java::util::IdentityHashMap; - -#ifdef ENABLE_JVMPI - _Jv_JVMPI_Interface.version = 1; - _Jv_JVMPI_Interface.EnableEvent = &jvmpiEnableEvent; - _Jv_JVMPI_Interface.DisableEvent = &jvmpiDisableEvent; - _Jv_JVMPI_Interface.EnableGC = &_Jv_EnableGC; - _Jv_JVMPI_Interface.DisableGC = &_Jv_DisableGC; - _Jv_JVMPI_Interface.RunGC = &_Jv_RunGC; -#endif -} - -// Tell the GC that a certain pointer is live. -static void -mark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table) -{ - JvSynchronize sync (ref_table); - - using namespace java::lang; - Integer *refcount = (Integer *) ref_table->get (obj); - jint val = (refcount == NULL) ? 0 : refcount->intValue (); - // FIXME: what about out of memory error? - ref_table->put (obj, new Integer (val + 1)); -} - -// Unmark a pointer. -static void -unmark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table) -{ - JvSynchronize sync (ref_table); - - using namespace java::lang; - Integer *refcount = (Integer *) ref_table->get (obj); - JvAssert (refcount); - jint val = refcount->intValue () - 1; - JvAssert (val >= 0); - if (val == 0) - ref_table->remove (obj); - else - // FIXME: what about out of memory error? - ref_table->put (obj, new Integer (val)); -} - -// "Unwrap" some random non-reference type. This exists to simplify -// other template functions. -template<typename T> -static T -unwrap (T val) -{ - return val; -} - -// Unwrap a weak reference, if required. -template<typename T> -static T * -unwrap (T *obj) -{ - using namespace gnu::gcj::runtime; - // We can compare the class directly because JNIWeakRef is `final'. - // Doing it this way is much faster. - if (obj == NULL || obj->getClass () != &JNIWeakRef::class$) - return obj; - JNIWeakRef *wr = reinterpret_cast<JNIWeakRef *> (obj); - return reinterpret_cast<T *> (wr->get ()); -} - -jobject -_Jv_UnwrapJNIweakReference (jobject obj) -{ - return unwrap (obj); -} - - - -static jobject JNICALL -_Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj) -{ - // This seems weird but I think it is correct. - obj = unwrap (obj); - mark_for_gc (obj, global_ref_table); - return obj; -} - -static void JNICALL -_Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj) -{ - // This seems weird but I think it is correct. - obj = unwrap (obj); - - // NULL is ok here -- the JNI specification doesn't say so, but this - // is a no-op. - if (! obj) - return; - - unmark_for_gc (obj, global_ref_table); -} - -static void JNICALL -_Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj) -{ - _Jv_JNI_LocalFrame *frame; - - // This seems weird but I think it is correct. - obj = unwrap (obj); - - // NULL is ok here -- the JNI specification doesn't say so, but this - // is a no-op. - if (! obj) - return; - - for (frame = env->locals; frame != NULL; frame = frame->next) - { - for (int i = 0; i < frame->size; ++i) - { - if (frame->vec[i] == obj) - { - frame->vec[i] = NULL; - unmark_for_gc (obj, local_ref_table); - return; - } - } - - // Don't go past a marked frame. - JvAssert (frame->marker == MARK_NONE); - } - - JvAssert (0); -} - -static jint JNICALL -_Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size) -{ - // It is easier to just always allocate a new frame of the requested - // size. This isn't the most efficient thing, but for now we don't - // care. Note that _Jv_JNI_PushLocalFrame relies on this right now. - - _Jv_JNI_LocalFrame *frame; - try - { - frame = (_Jv_JNI_LocalFrame *) _Jv_Malloc (sizeof (_Jv_JNI_LocalFrame) - + size * sizeof (jobject)); - } - catch (jthrowable t) - { - env->ex = t; - return JNI_ERR; - } - - frame->marker = MARK_NONE; - frame->size = size; - frame->allocated_p = false; - memset (&frame->vec[0], 0, size * sizeof (jobject)); - frame->loader = env->locals->loader; - frame->next = env->locals; - env->locals = frame; - - return 0; -} - -static jint JNICALL -_Jv_JNI_PushLocalFrame (JNIEnv *env, jint size) -{ - jint r = _Jv_JNI_EnsureLocalCapacity (env, size); - if (r < 0) - return r; - - // The new frame is on top. - env->locals->marker = MARK_USER; - - return 0; -} - -static jobject JNICALL -_Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj) -{ - // This seems weird but I think it is correct. - obj = unwrap (obj); - - // Try to find an open slot somewhere in the topmost frame. - _Jv_JNI_LocalFrame *frame = env->locals; - bool done = false, set = false; - for (; frame != NULL && ! done; frame = frame->next) - { - for (int i = 0; i < frame->size; ++i) - { - if (frame->vec[i] == NULL) - { - set = true; - done = true; - frame->vec[i] = obj; - frame->allocated_p = true; - break; - } - } - - // If we found a slot, or if the frame we just searched is the - // mark frame, then we are done. - if (done || frame == NULL || frame->marker != MARK_NONE) - break; - } - - if (! set) - { - // No slots, so we allocate a new frame. According to the spec - // we could just die here. FIXME: return value. - _Jv_JNI_EnsureLocalCapacity (env, 16); - // We know the first element of the new frame will be ok. - env->locals->vec[0] = obj; - env->locals->allocated_p = true; - } - - mark_for_gc (obj, local_ref_table); - return obj; -} - -static jobject JNICALL -_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop) -{ - _Jv_JNI_LocalFrame *rf = env->locals; - - bool done = false; - while (rf != NULL && ! done) - { - for (int i = 0; i < rf->size; ++i) - if (rf->vec[i] != NULL) - unmark_for_gc (rf->vec[i], local_ref_table); - - // If the frame we just freed is the marker frame, we are done. - done = (rf->marker == stop); - - _Jv_JNI_LocalFrame *n = rf->next; - // When N==NULL, we've reached the reusable bottom_locals, and we must - // not free it. However, we must be sure to clear all its elements. - if (n == NULL) - { - if (rf->allocated_p) - memset (&rf->vec[0], 0, rf->size * sizeof (jobject)); - rf->allocated_p = false; - rf = NULL; - break; - } - - _Jv_Free (rf); - rf = n; - } - - // Update the local frame information. - env->locals = rf; - - return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result); -} - -static jobject JNICALL -_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result) -{ - return _Jv_JNI_PopLocalFrame (env, result, MARK_USER); -} - -// Make sure an array's type is compatible with the type of the -// destination. -template<typename T> -static bool -_Jv_JNI_check_types (JNIEnv *env, JArray<T> *array, jclass K) -{ - jclass klass = array->getClass()->getComponentType(); - if (__builtin_expect (klass != K, false)) - { - env->ex = new java::lang::IllegalAccessError (); - return false; - } - else - return true; -} - -// Pop a `system' frame from the stack. This is `extern "C"' as it is -// used by the compiler. -extern "C" void -_Jv_JNI_PopSystemFrame (JNIEnv *env) -{ - // Only enter slow path when we're not at the bottom, or there have been - // allocations. Usually this is false and we can just null out the locals - // field. - - if (__builtin_expect ((env->locals->next - || env->locals->allocated_p), false)) - _Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM); - else - env->locals = NULL; - -#ifdef INTERPRETER - if (__builtin_expect (env->ex != NULL, false)) - { - jthrowable t = env->ex; - env->ex = NULL; - if (JVMTI_REQUESTED_EVENT (Exception)) - _Jv_ReportJVMTIExceptionThrow (t); - throw t; - } -#endif -} - -template<typename T> T extract_from_jvalue(jvalue const & t); -template<> jboolean extract_from_jvalue(jvalue const & jv) { return jv.z; } -template<> jbyte extract_from_jvalue(jvalue const & jv) { return jv.b; } -template<> jchar extract_from_jvalue(jvalue const & jv) { return jv.c; } -template<> jshort extract_from_jvalue(jvalue const & jv) { return jv.s; } -template<> jint extract_from_jvalue(jvalue const & jv) { return jv.i; } -template<> jlong extract_from_jvalue(jvalue const & jv) { return jv.j; } -template<> jfloat extract_from_jvalue(jvalue const & jv) { return jv.f; } -template<> jdouble extract_from_jvalue(jvalue const & jv) { return jv.d; } -template<> jobject extract_from_jvalue(jvalue const & jv) { return jv.l; } - - -// This function is used from other template functions. It wraps the -// return value appropriately; we specialize it so that object returns -// are turned into local references. -template<typename T> -static T -wrap_value (JNIEnv *, T value) -{ - return value; -} - -// This specialization is used for jobject, jclass, jstring, jarray, -// etc. -template<typename R, typename T> -static T * -wrap_value (JNIEnv *env, T *value) -{ - return (value == NULL - ? value - : (T *) _Jv_JNI_NewLocalRef (env, (jobject) value)); -} - - - -static jint JNICALL -_Jv_JNI_GetVersion (JNIEnv *) -{ - return JNI_VERSION_1_4; -} - -static jclass JNICALL -_Jv_JNI_DefineClass (JNIEnv *env, const char *name, jobject loader, - const jbyte *buf, jsize bufLen) -{ - try - { - loader = unwrap (loader); - - jstring sname = JvNewStringUTF (name); - jbyteArray bytes = JvNewByteArray (bufLen); - - jbyte *elts = elements (bytes); - memcpy (elts, buf, bufLen * sizeof (jbyte)); - - java::lang::ClassLoader *l - = reinterpret_cast<java::lang::ClassLoader *> (loader); - - jclass result = l->defineClass (sname, bytes, 0, bufLen); - return (jclass) wrap_value (env, result); - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -static jclass JNICALL -_Jv_JNI_FindClass (JNIEnv *env, const char *name) -{ - // FIXME: assume that NAME isn't too long. - int len = strlen (name); - char s[len + 1]; - for (int i = 0; i <= len; ++i) - s[i] = (name[i] == '/') ? '.' : name[i]; - - jclass r = NULL; - try - { - // This might throw an out of memory exception. - jstring n = JvNewStringUTF (s); - - java::lang::ClassLoader *loader = NULL; - if (env->locals->loader != NULL) - loader = env->locals->loader; - - if (loader == NULL) - { - // FIXME: should use getBaseClassLoader, but we don't have that - // yet. - loader = java::lang::ClassLoader::getSystemClassLoader (); - } - - r = loader->loadClass (n); - _Jv_InitClass (r); - } - catch (jthrowable t) - { - env->ex = t; - } - - return (jclass) wrap_value (env, r); -} - -static jclass JNICALL -_Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz) -{ - return (jclass) wrap_value (env, unwrap (clazz)->getSuperclass ()); -} - -static jboolean JNICALL -_Jv_JNI_IsAssignableFrom (JNIEnv *, jclass clazz1, jclass clazz2) -{ - return unwrap (clazz2)->isAssignableFrom (unwrap (clazz1)); -} - -static jint JNICALL -_Jv_JNI_Throw (JNIEnv *env, jthrowable obj) -{ - // We check in case the user did some funky cast. - obj = unwrap (obj); - JvAssert (obj != NULL && java::lang::Throwable::class$.isInstance (obj)); - env->ex = obj; - return 0; -} - -static jint JNICALL -_Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message) -{ - using namespace java::lang::reflect; - - clazz = unwrap (clazz); - JvAssert (java::lang::Throwable::class$.isAssignableFrom (clazz)); - - int r = JNI_OK; - try - { - JArray<jclass> *argtypes - = (JArray<jclass> *) JvNewObjectArray (1, &java::lang::Class::class$, - NULL); - - jclass *elts = elements (argtypes); - elts[0] = &java::lang::String::class$; - - Constructor *cons = clazz->getConstructor (argtypes); - - jobjectArray values = JvNewObjectArray (1, &java::lang::String::class$, - NULL); - jobject *velts = elements (values); - velts[0] = JvNewStringUTF (message); - - jobject obj = cons->newInstance (values); - - env->ex = reinterpret_cast<jthrowable> (obj); - } - catch (jthrowable t) - { - env->ex = t; - r = JNI_ERR; - } - - return r; -} - -static jthrowable JNICALL -_Jv_JNI_ExceptionOccurred (JNIEnv *env) -{ - return (jthrowable) wrap_value (env, env->ex); -} - -static void JNICALL -_Jv_JNI_ExceptionDescribe (JNIEnv *env) -{ - if (env->ex != NULL) - env->ex->printStackTrace(); -} - -static void JNICALL -_Jv_JNI_ExceptionClear (JNIEnv *env) -{ - env->ex = NULL; -} - -static jboolean JNICALL -_Jv_JNI_ExceptionCheck (JNIEnv *env) -{ - return env->ex != NULL; -} - -static void JNICALL -_Jv_JNI_FatalError (JNIEnv *, const char *message) -{ - JvFail (message); -} - - - -static jboolean JNICALL -_Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2) -{ - return unwrap (obj1) == unwrap (obj2); -} - -static jobject JNICALL -_Jv_JNI_AllocObject (JNIEnv *env, jclass clazz) -{ - jobject obj = NULL; - using namespace java::lang::reflect; - - try - { - clazz = unwrap (clazz); - JvAssert (clazz && ! clazz->isArray ()); - if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers())) - env->ex = new java::lang::InstantiationException (); - else - obj = _Jv_AllocObject (clazz); - } - catch (jthrowable t) - { - env->ex = t; - } - - return wrap_value (env, obj); -} - -static jclass JNICALL -_Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj) -{ - obj = unwrap (obj); - JvAssert (obj); - return (jclass) wrap_value (env, obj->getClass()); -} - -static jboolean JNICALL -_Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz) -{ - return unwrap (clazz)->isInstance(unwrap (obj)); -} - - - -// -// This section concerns method invocation. -// - -template<jboolean is_static> -static jmethodID JNICALL -_Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz, - const char *name, const char *sig) -{ - try - { - clazz = unwrap (clazz); - _Jv_InitClass (clazz); - - _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1); - - // FIXME: assume that SIG isn't too long. - int len = strlen (sig); - char s[len + 1]; - for (int i = 0; i <= len; ++i) - s[i] = (sig[i] == '/') ? '.' : sig[i]; - _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) s, -1); - - JvAssert (! clazz->isPrimitive()); - - using namespace java::lang::reflect; - - while (clazz != NULL) - { - jint count = JvNumMethods (clazz); - jmethodID meth = JvGetFirstMethod (clazz); - - for (jint i = 0; i < count; ++i) - { - if (((is_static && Modifier::isStatic (meth->accflags)) - || (! is_static && ! Modifier::isStatic (meth->accflags))) - && _Jv_equalUtf8Consts (meth->name, name_u) - && _Jv_equalUtf8Consts (meth->signature, sig_u)) - return meth; - - meth = meth->getNextMethod(); - } - - clazz = clazz->getSuperclass (); - } - - java::lang::StringBuffer *name_sig = - new java::lang::StringBuffer (JvNewStringUTF (name)); - name_sig->append ((jchar) ' '); - name_sig->append (JvNewStringUTF (s)); - env->ex = new java::lang::NoSuchMethodError (name_sig->toString ()); - } - catch (jthrowable t) - { - env->ex = t; - } - - return NULL; -} - -// This is a helper function which turns a va_list into an array of -// `jvalue's. It needs signature information in order to do its work. -// The array of values must already be allocated. -static void -array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs) -{ - jclass *arg_elts = elements (arg_types); - for (int i = 0; i < arg_types->length; ++i) - { - // Here we assume that sizeof(int) >= sizeof(jint), because we - // use `int' when decoding the varargs. Likewise for - // float, and double. Also we assume that sizeof(jlong) >= - // sizeof(int), i.e. that jlong values are not further - // promoted. - JvAssert (sizeof (int) >= sizeof (jint)); - JvAssert (sizeof (jlong) >= sizeof (int)); - JvAssert (sizeof (double) >= sizeof (jfloat)); - JvAssert (sizeof (double) >= sizeof (jdouble)); - if (arg_elts[i] == JvPrimClass (byte)) - values[i].b = (jbyte) va_arg (vargs, int); - else if (arg_elts[i] == JvPrimClass (short)) - values[i].s = (jshort) va_arg (vargs, int); - else if (arg_elts[i] == JvPrimClass (int)) - values[i].i = (jint) va_arg (vargs, int); - else if (arg_elts[i] == JvPrimClass (long)) - values[i].j = (jlong) va_arg (vargs, jlong); - else if (arg_elts[i] == JvPrimClass (float)) - values[i].f = (jfloat) va_arg (vargs, double); - else if (arg_elts[i] == JvPrimClass (double)) - values[i].d = (jdouble) va_arg (vargs, double); - else if (arg_elts[i] == JvPrimClass (boolean)) - values[i].z = (jboolean) va_arg (vargs, int); - else if (arg_elts[i] == JvPrimClass (char)) - values[i].c = (jchar) va_arg (vargs, int); - else - { - // An object. - values[i].l = unwrap (va_arg (vargs, jobject)); - } - } -} - -// This can call any sort of method: virtual, "nonvirtual", static, or -// constructor. -template<typename T, invocation_type style> -static T JNICALL -_Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass, - jmethodID id, va_list vargs) -{ - obj = unwrap (obj); - klass = unwrap (klass); - - jclass decl_class = klass ? klass : obj->getClass (); - JvAssert (decl_class != NULL); - - jclass return_type; - JArray<jclass> *arg_types; - - try - { - _Jv_GetTypesFromSignature (id, decl_class, - &arg_types, &return_type); - - jvalue args[arg_types->length]; - array_from_valist (args, arg_types, vargs); - - // For constructors we need to pass the Class we are instantiating. - if (style == constructor) - return_type = klass; - - jvalue result; - _Jv_CallAnyMethodA (obj, return_type, id, - style == constructor, - style == normal, - arg_types, args, &result); - - return wrap_value (env, extract_from_jvalue<T>(result)); - } - catch (jthrowable t) - { - env->ex = t; - } - - return wrap_value (env, (T) 0); -} - -template<typename T, invocation_type style> -static T JNICALL -_Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass, - jmethodID method, ...) -{ - va_list args; - T result; - - va_start (args, method); - result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args); - va_end (args); - - return result; -} - -template<typename T, invocation_type style> -static T JNICALL -_Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass, - jmethodID id, const jvalue *args) -{ - obj = unwrap (obj); - klass = unwrap (klass); - - jclass decl_class = klass ? klass : obj->getClass (); - JvAssert (decl_class != NULL); - - jclass return_type; - JArray<jclass> *arg_types; - try - { - _Jv_GetTypesFromSignature (id, decl_class, - &arg_types, &return_type); - - // For constructors we need to pass the Class we are instantiating. - if (style == constructor) - return_type = klass; - - // Unwrap arguments as required. Eww. - jclass *type_elts = elements (arg_types); - jvalue arg_copy[arg_types->length]; - for (int i = 0; i < arg_types->length; ++i) - { - if (type_elts[i]->isPrimitive ()) - arg_copy[i] = args[i]; - else - arg_copy[i].l = unwrap (args[i].l); - } - - jvalue result; - _Jv_CallAnyMethodA (obj, return_type, id, - style == constructor, - style == normal, - arg_types, arg_copy, &result); - - return wrap_value (env, extract_from_jvalue<T>(result)); - } - catch (jthrowable t) - { - env->ex = t; - } - - return wrap_value (env, (T) 0); -} - -template<invocation_type style> -static void JNICALL -_Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass, - jmethodID id, va_list vargs) -{ - obj = unwrap (obj); - klass = unwrap (klass); - - jclass decl_class = klass ? klass : obj->getClass (); - JvAssert (decl_class != NULL); - - jclass return_type; - JArray<jclass> *arg_types; - try - { - _Jv_GetTypesFromSignature (id, decl_class, - &arg_types, &return_type); - - jvalue args[arg_types->length]; - array_from_valist (args, arg_types, vargs); - - // For constructors we need to pass the Class we are instantiating. - if (style == constructor) - return_type = klass; - - _Jv_CallAnyMethodA (obj, return_type, id, - style == constructor, - style == normal, - arg_types, args, NULL); - } - catch (jthrowable t) - { - env->ex = t; - } -} - -template<invocation_type style> -static void JNICALL -_Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass, - jmethodID method, ...) -{ - va_list args; - - va_start (args, method); - _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args); - va_end (args); -} - -template<invocation_type style> -static void JNICALL -_Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass, - jmethodID id, const jvalue *args) -{ - jclass decl_class = klass ? klass : obj->getClass (); - JvAssert (decl_class != NULL); - - jclass return_type; - JArray<jclass> *arg_types; - try - { - _Jv_GetTypesFromSignature (id, decl_class, - &arg_types, &return_type); - - // Unwrap arguments as required. Eww. - jclass *type_elts = elements (arg_types); - jvalue arg_copy[arg_types->length]; - for (int i = 0; i < arg_types->length; ++i) - { - if (type_elts[i]->isPrimitive ()) - arg_copy[i] = args[i]; - else - arg_copy[i].l = unwrap (args[i].l); - } - - _Jv_CallAnyMethodA (obj, return_type, id, - style == constructor, - style == normal, - arg_types, args, NULL); - } - catch (jthrowable t) - { - env->ex = t; - } -} - -// Functions with this signature are used to implement functions in -// the CallMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallMethodV (JNIEnv *env, jobject obj, - jmethodID id, va_list args) -{ - return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args); -} - -// Functions with this signature are used to implement functions in -// the CallMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...) -{ - va_list args; - T result; - - va_start (args, id); - result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args); - va_end (args); - - return result; -} - -// Functions with this signature are used to implement functions in -// the CallMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, - jmethodID id, const jvalue *args) -{ - return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args); -} - -static void JNICALL -_Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, - jmethodID id, va_list args) -{ - _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args); -} - -static void JNICALL -_Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...) -{ - va_list args; - - va_start (args, id); - _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args); - va_end (args); -} - -static void JNICALL -_Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, - jmethodID id, const jvalue *args) -{ - _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args); -} - -// Functions with this signature are used to implement functions in -// the CallStaticMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass, - jmethodID id, va_list args) -{ - JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC)); - JvAssert (java::lang::Class::class$.isInstance (unwrap (klass))); - - return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args); -} - -// Functions with this signature are used to implement functions in -// the CallStaticMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, - jmethodID id, ...) -{ - va_list args; - T result; - - JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC)); - JvAssert (java::lang::Class::class$.isInstance (unwrap (klass))); - - va_start (args, id); - result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, - id, args); - va_end (args); - - return result; -} - -// Functions with this signature are used to implement functions in -// the CallStaticMethod family. -template<typename T> -static T JNICALL -_Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id, - const jvalue *args) -{ - JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC)); - JvAssert (java::lang::Class::class$.isInstance (unwrap (klass))); - - return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args); -} - -static void JNICALL -_Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, - jmethodID id, va_list args) -{ - _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args); -} - -static void JNICALL -_Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass, - jmethodID id, ...) -{ - va_list args; - - va_start (args, id); - _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args); - va_end (args); -} - -static void JNICALL -_Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, - jmethodID id, const jvalue *args) -{ - _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args); -} - -static jobject JNICALL -_Jv_JNI_NewObjectV (JNIEnv *env, jclass klass, - jmethodID id, va_list args) -{ - JvAssert (klass && ! klass->isArray ()); - JvAssert (! strcmp (id->name->chars(), "<init>") - && id->signature->len() > 2 - && id->signature->chars()[0] == '(' - && ! strcmp (&id->signature->chars()[id->signature->len() - 2], - ")V")); - - return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass, - id, args); -} - -static jobject JNICALL -_Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...) -{ - JvAssert (klass && ! klass->isArray ()); - JvAssert (! strcmp (id->name->chars(), "<init>") - && id->signature->len() > 2 - && id->signature->chars()[0] == '(' - && ! strcmp (&id->signature->chars()[id->signature->len() - 2], - ")V")); - - va_list args; - jobject result; - - va_start (args, id); - result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass, - id, args); - va_end (args); - - return result; -} - -static jobject JNICALL -_Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id, - const jvalue *args) -{ - JvAssert (klass && ! klass->isArray ()); - JvAssert (! strcmp (id->name->chars(), "<init>") - && id->signature->len() > 2 - && id->signature->chars()[0] == '(' - && ! strcmp (&id->signature->chars()[id->signature->len() - 2], - ")V")); - - return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass, - id, args); -} - - - -template<typename T> -static T JNICALL -_Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field) -{ - obj = unwrap (obj); - JvAssert (obj); - T *ptr = (T *) ((char *) obj + field->getOffset ()); - return wrap_value (env, *ptr); -} - -template<typename T> -static void JNICALL -_Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value) -{ - obj = unwrap (obj); - value = unwrap (value); - - JvAssert (obj); - T *ptr = (T *) ((char *) obj + field->getOffset ()); - *ptr = value; -} - -template<jboolean is_static> -static jfieldID JNICALL -_Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz, - const char *name, const char *sig) -{ - try - { - clazz = unwrap (clazz); - - _Jv_InitClass (clazz); - - _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1); - - // FIXME: assume that SIG isn't too long. - int len = strlen (sig); - char s[len + 1]; - for (int i = 0; i <= len; ++i) - s[i] = (sig[i] == '/') ? '.' : sig[i]; - java::lang::ClassLoader *loader = clazz->getClassLoaderInternal (); - jclass field_class = _Jv_FindClassFromSignature ((char *) s, loader); - if (! field_class) - throw new java::lang::ClassNotFoundException(JvNewStringUTF(s)); - - while (clazz != NULL) - { - // We acquire the class lock so that fields aren't resolved - // while we are running. - JvSynchronize sync (clazz); - - jint count = (is_static - ? JvNumStaticFields (clazz) - : JvNumInstanceFields (clazz)); - jfieldID field = (is_static - ? JvGetFirstStaticField (clazz) - : JvGetFirstInstanceField (clazz)); - for (jint i = 0; i < count; ++i) - { - _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz); - - // The field might be resolved or it might not be. It - // is much simpler to always resolve it. - _Jv_Linker::resolve_field (field, loader); - if (_Jv_equalUtf8Consts (f_name, a_name) - && field->getClass() == field_class) - return field; - - field = field->getNextField (); - } - - clazz = clazz->getSuperclass (); - } - - env->ex = new java::lang::NoSuchFieldError (); - } - catch (jthrowable t) - { - env->ex = t; - } - return NULL; -} - -template<typename T> -static T JNICALL -_Jv_JNI_GetStaticField (JNIEnv *env, jclass, jfieldID field) -{ - T *ptr = (T *) field->u.addr; - return wrap_value (env, *ptr); -} - -template<typename T> -static void JNICALL -_Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value) -{ - value = unwrap (value); - T *ptr = (T *) field->u.addr; - *ptr = value; -} - -static jstring JNICALL -_Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len) -{ - try - { - jstring r = _Jv_NewString (unichars, len); - return (jstring) wrap_value (env, r); - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -static jsize JNICALL -_Jv_JNI_GetStringLength (JNIEnv *, jstring string) -{ - return unwrap (string)->length(); -} - -static const jchar * JNICALL -_Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy) -{ - string = unwrap (string); - jchar *result = _Jv_GetStringChars (string); - mark_for_gc (string, global_ref_table); - if (isCopy) - *isCopy = false; - return (const jchar *) result; -} - -static void JNICALL -_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *) -{ - unmark_for_gc (unwrap (string), global_ref_table); -} - -static jstring JNICALL -_Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes) -{ - try - { - // For compatibility with the JDK. - if (!bytes) - return NULL; - jstring result = JvNewStringUTF (bytes); - return (jstring) wrap_value (env, result); - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -static jsize JNICALL -_Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string) -{ - return JvGetStringUTFLength (unwrap (string)); -} - -static const char * JNICALL -_Jv_JNI_GetStringUTFChars (JNIEnv *env, jstring string, - jboolean *isCopy) -{ - try - { - string = unwrap (string); - if (string == NULL) - return NULL; - jsize len = JvGetStringUTFLength (string); - char *r = (char *) _Jv_Malloc (len + 1); - JvGetStringUTFRegion (string, 0, string->length(), r); - r[len] = '\0'; - - if (isCopy) - *isCopy = true; - - return (const char *) r; - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -static void JNICALL -_Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf) -{ - _Jv_Free ((void *) utf); -} - -static void JNICALL -_Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, - jsize len, jchar *buf) -{ - string = unwrap (string); - jchar *result = _Jv_GetStringChars (string); - if (start < 0 || start > string->length () - || len < 0 || start + len > string->length ()) - { - try - { - env->ex = new java::lang::StringIndexOutOfBoundsException (); - } - catch (jthrowable t) - { - env->ex = t; - } - } - else - memcpy (buf, &result[start], len * sizeof (jchar)); -} - -static void JNICALL -_Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start, - jsize len, char *buf) -{ - str = unwrap (str); - - if (start < 0 || start > str->length () - || len < 0 || start + len > str->length ()) - { - try - { - env->ex = new java::lang::StringIndexOutOfBoundsException (); - } - catch (jthrowable t) - { - env->ex = t; - } - } - else - _Jv_GetStringUTFRegion (str, start, len, buf); -} - -static const jchar * JNICALL -_Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy) -{ - jchar *result = _Jv_GetStringChars (unwrap (str)); - if (isCopy) - *isCopy = false; - return result; -} - -static void JNICALL -_Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *) -{ - // Nothing. -} - -static jsize JNICALL -_Jv_JNI_GetArrayLength (JNIEnv *, jarray array) -{ - return unwrap (array)->length; -} - -static jobjectArray JNICALL -_Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, - jclass elementClass, jobject init) -{ - try - { - elementClass = unwrap (elementClass); - init = unwrap (init); - - _Jv_CheckCast (elementClass, init); - jarray result = JvNewObjectArray (length, elementClass, init); - return (jobjectArray) wrap_value (env, result); - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -static jobject JNICALL -_Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, - jsize index) -{ - if ((unsigned) index >= (unsigned) array->length) - _Jv_ThrowBadArrayIndex (index); - jobject *elts = elements (unwrap (array)); - return wrap_value (env, elts[index]); -} - -static void JNICALL -_Jv_JNI_SetObjectArrayElement (JNIEnv *env, jobjectArray array, - jsize index, jobject value) -{ - try - { - array = unwrap (array); - value = unwrap (value); - - _Jv_CheckArrayStore (array, value); - if ((unsigned) index >= (unsigned) array->length) - _Jv_ThrowBadArrayIndex (index); - jobject *elts = elements (array); - elts[index] = value; - } - catch (jthrowable t) - { - env->ex = t; - } -} - -template<typename T, jclass K> -static JArray<T> * JNICALL -_Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length) -{ - try - { - return (JArray<T> *) wrap_value (env, _Jv_NewPrimArray (K, length)); - } - catch (jthrowable t) - { - env->ex = t; - return NULL; - } -} - -template<typename T, jclass K> -static T * JNICALL -_Jv_JNI_GetPrimitiveArrayElements (JNIEnv *env, JArray<T> *array, - jboolean *isCopy) -{ - array = unwrap (array); - if (! _Jv_JNI_check_types (env, array, K)) - return NULL; - T *elts = elements (array); - if (isCopy) - { - // We elect never to copy. - *isCopy = false; - } - mark_for_gc (array, global_ref_table); - return elts; -} - -template<typename T, jclass K> -static void JNICALL -_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *env, JArray<T> *array, - T *, jint /* mode */) -{ - array = unwrap (array); - _Jv_JNI_check_types (env, array, K); - // Note that we ignore MODE. We can do this because we never copy - // the array elements. My reading of the JNI documentation is that - // this is an option for the implementor. - unmark_for_gc (array, global_ref_table); -} - -template<typename T, jclass K> -static void JNICALL -_Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, - jsize start, jsize len, - T *buf) -{ - array = unwrap (array); - if (! _Jv_JNI_check_types (env, array, K)) - return; - - // The cast to unsigned lets us save a comparison. - if (start < 0 || len < 0 - || (unsigned long) (start + len) > (unsigned long) array->length) - { - try - { - // FIXME: index. - env->ex = new java::lang::ArrayIndexOutOfBoundsException (); - } - catch (jthrowable t) - { - // Could have thown out of memory error. - env->ex = t; - } - } - else - { - T *elts = elements (array) + start; - memcpy (buf, elts, len * sizeof (T)); - } -} - -template<typename T, jclass K> -static void JNICALL -_Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, - jsize start, jsize len, const T *buf) -{ - array = unwrap (array); - if (! _Jv_JNI_check_types (env, array, K)) - return; - - // The cast to unsigned lets us save a comparison. - if (start < 0 || len < 0 - || (unsigned long) (start + len) > (unsigned long) array->length) - { - try - { - // FIXME: index. - env->ex = new java::lang::ArrayIndexOutOfBoundsException (); - } - catch (jthrowable t) - { - env->ex = t; - } - } - else - { - T *elts = elements (array) + start; - memcpy (elts, buf, len * sizeof (T)); - } -} - -static void * JNICALL -_Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array, - jboolean *isCopy) -{ - array = unwrap (array); - // FIXME: does this work? - jclass klass = array->getClass()->getComponentType(); - JvAssert (klass->isPrimitive ()); - char *r = _Jv_GetArrayElementFromElementType (array, klass); - if (isCopy) - *isCopy = false; - return r; -} - -static void JNICALL -_Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint) -{ - // Nothing. -} - -static jint JNICALL -_Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj) -{ - try - { - _Jv_MonitorEnter (unwrap (obj)); - return 0; - } - catch (jthrowable t) - { - env->ex = t; - } - return JNI_ERR; -} - -static jint JNICALL -_Jv_JNI_MonitorExit (JNIEnv *env, jobject obj) -{ - try - { - _Jv_MonitorExit (unwrap (obj)); - return 0; - } - catch (jthrowable t) - { - env->ex = t; - } - return JNI_ERR; -} - -// JDK 1.2 -jobject JNICALL -_Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID, - jboolean) -{ - try - { - cls = unwrap (cls); - java::lang::reflect::Field *field = new java::lang::reflect::Field(); - field->declaringClass = cls; - field->offset = (char*) fieldID - (char *) cls->fields; - field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls)); - return wrap_value (env, field); - } - catch (jthrowable t) - { - env->ex = t; - } - return NULL; -} - -// JDK 1.2 -static jfieldID JNICALL -_Jv_JNI_FromReflectedField (JNIEnv *, jobject f) -{ - using namespace java::lang::reflect; - - f = unwrap (f); - Field *field = reinterpret_cast<Field *> (f); - return _Jv_FromReflectedField (field); -} - -jobject JNICALL -_Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id, - jboolean) -{ - using namespace java::lang::reflect; - - jobject result = NULL; - klass = unwrap (klass); - - try - { - if (_Jv_equalUtf8Consts (id->name, init_name)) - { - // A constructor. - Constructor *cons = new Constructor (); - cons->offset = (char *) id - (char *) &klass->methods; - cons->declaringClass = klass; - result = cons; - } - else - { - Method *meth = new Method (); - meth->offset = (char *) id - (char *) &klass->methods; - meth->declaringClass = klass; - result = meth; - } - } - catch (jthrowable t) - { - env->ex = t; - } - - return wrap_value (env, result); -} - -static jmethodID JNICALL -_Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method) -{ - using namespace java::lang::reflect; - method = unwrap (method); - if (Method::class$.isInstance (method)) - return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method)); - return - _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method)); -} - -// JDK 1.2. -jweak JNICALL -_Jv_JNI_NewWeakGlobalRef (JNIEnv *env, jobject obj) -{ - using namespace gnu::gcj::runtime; - JNIWeakRef *ref = NULL; - - try - { - // This seems weird but I think it is correct. - obj = unwrap (obj); - ref = new JNIWeakRef (obj); - mark_for_gc (ref, global_ref_table); - } - catch (jthrowable t) - { - env->ex = t; - } - - return reinterpret_cast<jweak> (ref); -} - -void JNICALL -_Jv_JNI_DeleteWeakGlobalRef (JNIEnv *, jweak obj) -{ - // JDK compatibility. - if (obj == NULL) - return; - - using namespace gnu::gcj::runtime; - JNIWeakRef *ref = reinterpret_cast<JNIWeakRef *> (obj); - unmark_for_gc (ref, global_ref_table); - ref->clear (); -} - - - -// Direct byte buffers. - -static jobject JNICALL -_Jv_JNI_NewDirectByteBuffer (JNIEnv *, void *address, jlong length) -{ - using namespace gnu::gcj; - using namespace java::nio; - return new DirectByteBufferImpl$ReadWrite - (reinterpret_cast<RawData *> (address), length); -} - -static void * JNICALL -_Jv_JNI_GetDirectBufferAddress (JNIEnv *, jobject buffer) -{ - using namespace java::nio; - if (! _Jv_IsInstanceOf (buffer, &Buffer::class$)) - return NULL; - Buffer *tmp = static_cast<Buffer *> (buffer); - return reinterpret_cast<void *> (tmp->address); -} - -static jlong JNICALL -_Jv_JNI_GetDirectBufferCapacity (JNIEnv *, jobject buffer) -{ - using namespace java::nio; - if (! _Jv_IsInstanceOf (buffer, &Buffer::class$)) - return -1; - Buffer *tmp = static_cast<Buffer *> (buffer); - if (tmp->address == NULL) - return -1; - return tmp->capacity(); -} - -static jobjectRefType JNICALL -_Jv_JNI_GetObjectRefType (JNIEnv *, MAYBE_UNUSED jobject object) -{ - JvFail("GetObjectRefType not implemented"); - return JNIInvalidRefType; -} - - - -struct NativeMethodCacheEntry : public JNINativeMethod -{ - char *className; -}; - -// Hash table of native methods. -static NativeMethodCacheEntry *nathash; -// Number of slots used. -static int nathash_count = 0; -// Number of slots available. Must be power of 2. -static int nathash_size = 0; - -#define DELETED_ENTRY ((char *) (~0)) - -// Compute a hash value for a native method descriptor. -static int -hash (const NativeMethodCacheEntry *method) -{ - char *ptr; - int hash = 0; - - ptr = method->className; - while (*ptr) - hash = (31 * hash) + *ptr++; - - ptr = method->name; - while (*ptr) - hash = (31 * hash) + *ptr++; - - ptr = method->signature; - while (*ptr) - hash = (31 * hash) + *ptr++; - - return hash; -} - -// Find the slot where a native method goes. -static NativeMethodCacheEntry * -nathash_find_slot (const NativeMethodCacheEntry *method) -{ - jint h = hash (method); - int step = (h ^ (h >> 16)) | 1; - int w = h & (nathash_size - 1); - int del = -1; - - for (;;) - { - NativeMethodCacheEntry *slotp = &nathash[w]; - if (slotp->name == NULL) - { - if (del >= 0) - return &nathash[del]; - else - return slotp; - } - else if (slotp->name == DELETED_ENTRY) - del = w; - else if (! strcmp (slotp->name, method->name) - && ! strcmp (slotp->signature, method->signature) - && ! strcmp (slotp->className, method->className)) - return slotp; - w = (w + step) & (nathash_size - 1); - } -} - -// Find a method. Return NULL if it isn't in the hash table. -static void * -nathash_find (NativeMethodCacheEntry *method) -{ - if (nathash == NULL) - return NULL; - NativeMethodCacheEntry *slot = nathash_find_slot (method); - if (slot->name == NULL || slot->name == DELETED_ENTRY) - return NULL; - return slot->fnPtr; -} - -static void -natrehash () -{ - if (nathash == NULL) - { - nathash_size = 1024; - nathash = - (NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size - * sizeof (NativeMethodCacheEntry)); - } - else - { - int savesize = nathash_size; - NativeMethodCacheEntry *savehash = nathash; - nathash_size *= 2; - nathash = - (NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size - * sizeof (NativeMethodCacheEntry)); - - for (int i = 0; i < savesize; ++i) - { - if (savehash[i].name != NULL && savehash[i].name != DELETED_ENTRY) - { - NativeMethodCacheEntry *slot = nathash_find_slot (&savehash[i]); - *slot = savehash[i]; - } - } - } -} - -static void -nathash_add (const NativeMethodCacheEntry *method) -{ - if (3 * nathash_count >= 2 * nathash_size) - natrehash (); - NativeMethodCacheEntry *slot = nathash_find_slot (method); - // If the slot has a real entry in it, then there is no work to do. - if (slot->name != NULL && slot->name != DELETED_ENTRY) - return; - // FIXME: memory leak? - slot->name = strdup (method->name); - slot->className = strdup (method->className); - // This was already strduped in _Jv_JNI_RegisterNatives. - slot->signature = method->signature; - slot->fnPtr = method->fnPtr; -} - -static jint JNICALL -_Jv_JNI_RegisterNatives (JNIEnv *env, jclass klass, - const JNINativeMethod *methods, - jint nMethods) -{ - // Synchronize while we do the work. This must match - // synchronization in some other functions that manipulate or use - // the nathash table. - JvSynchronize sync (global_ref_table); - - NativeMethodCacheEntry dottedMethod; - - // Look at each descriptor given us, and find the corresponding - // method in the class. - for (int j = 0; j < nMethods; ++j) - { - bool found = false; - - _Jv_Method *imeths = JvGetFirstMethod (klass); - for (int i = 0; i < JvNumMethods (klass); ++i) - { - _Jv_Method *self = &imeths[i]; - - // Copy this JNINativeMethod and do a slash to dot - // conversion on the signature. - dottedMethod.name = methods[j].name; - // FIXME: we leak a little memory here if the method - // is not found. - dottedMethod.signature = strdup (methods[j].signature); - dottedMethod.fnPtr = methods[j].fnPtr; - dottedMethod.className = _Jv_GetClassNameUtf8 (klass)->chars(); - char *c = dottedMethod.signature; - while (*c) - { - if (*c == '/') - *c = '.'; - c++; - } - - if (! strcmp (self->name->chars (), dottedMethod.name) - && ! strcmp (self->signature->chars (), dottedMethod.signature)) - { - if (! (self->accflags & java::lang::reflect::Modifier::NATIVE)) - break; - - // Found a match that is native. - found = true; - nathash_add (&dottedMethod); - - break; - } - } - - if (! found) - { - jstring m = JvNewStringUTF (methods[j].name); - try - { - env->ex = new java::lang::NoSuchMethodError (m); - } - catch (jthrowable t) - { - env->ex = t; - } - return JNI_ERR; - } - } - - return JNI_OK; -} - -static jint JNICALL -_Jv_JNI_UnregisterNatives (JNIEnv *, jclass) -{ - // FIXME -- we could implement this. - return JNI_ERR; -} - - - -// Add a character to the buffer, encoding properly. -static void -add_char (char *buf, jchar c, int *here) -{ - if (c == '_') - { - buf[(*here)++] = '_'; - buf[(*here)++] = '1'; - } - else if (c == ';') - { - buf[(*here)++] = '_'; - buf[(*here)++] = '2'; - } - else if (c == '[') - { - buf[(*here)++] = '_'; - buf[(*here)++] = '3'; - } - - // Also check for `.' here because we might be passed an internal - // qualified class name like `foo.bar'. - else if (c == '/' || c == '.') - buf[(*here)++] = '_'; - else if ((c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z')) - buf[(*here)++] = (char) c; - else - { - // "Unicode" character. - buf[(*here)++] = '_'; - buf[(*here)++] = '0'; - for (int i = 0; i < 4; ++i) - { - int val = c & 0x0f; - buf[(*here) + 3 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val); - c >>= 4; - } - *here += 4; - } -} - -// Compute a mangled name for a native function. This computes the -// long name, and also returns an index which indicates where a NUL -// can be placed to create the short name. This function assumes that -// the buffer is large enough for its results. -static void -mangled_name (jclass klass, _Jv_Utf8Const *func_name, - _Jv_Utf8Const *signature, char *buf, int *long_start) -{ - strcpy (buf, "Java_"); - int here = 5; - - // Add fully qualified class name. - jchar *chars = _Jv_GetStringChars (klass->getName ()); - jint len = klass->getName ()->length (); - for (int i = 0; i < len; ++i) - add_char (buf, chars[i], &here); - - // Don't use add_char because we need a literal `_'. - buf[here++] = '_'; - - const unsigned char *fn = (const unsigned char *) func_name->chars (); - const unsigned char *limit = fn + func_name->len (); - for (int i = 0; ; ++i) - { - int ch = UTF8_GET (fn, limit); - if (ch < 0) - break; - add_char (buf, ch, &here); - } - - // This is where the long signature begins. - *long_start = here; - buf[here++] = '_'; - buf[here++] = '_'; - - const unsigned char *sig = (const unsigned char *) signature->chars (); - limit = sig + signature->len (); - JvAssert (sig[0] == '('); - ++sig; - while (1) - { - int ch = UTF8_GET (sig, limit); - if (ch == ')' || ch < 0) - break; - add_char (buf, ch, &here); - } - - buf[here] = '\0'; -} - -JNIEnv * -_Jv_GetJNIEnvNewFrameWithLoader (::java::lang::ClassLoader *loader) -{ - JNIEnv *env = _Jv_GetCurrentJNIEnv (); - if (__builtin_expect (env == NULL, false)) - { - env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv)); - env->functions = &_Jv_JNIFunctions; - env->locals = NULL; - // We set env->ex below. - - // Set up the bottom, reusable frame. - env->bottom_locals = (_Jv_JNI_LocalFrame *) - _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame) - + (FRAME_SIZE - * sizeof (jobject))); - - env->bottom_locals->marker = MARK_SYSTEM; - env->bottom_locals->size = FRAME_SIZE; - env->bottom_locals->next = NULL; - env->bottom_locals->allocated_p = false; - // We set the klass field below. - memset (&env->bottom_locals->vec[0], 0, - env->bottom_locals->size * sizeof (jobject)); - - _Jv_SetCurrentJNIEnv (env); - } - - // If we're in a simple JNI call (non-nested), we can just reuse the - // locals frame we allocated many calls ago, back when the env was first - // built, above. - - if (__builtin_expect (env->locals == NULL, true)) - { - env->locals = env->bottom_locals; - env->locals->loader = loader; - } - else - { - // Alternatively, we might be re-entering JNI, in which case we can't - // reuse the bottom_locals frame, because it is already underneath - // us. So we need to make a new one. - _Jv_JNI_LocalFrame *frame - = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame) - + (FRAME_SIZE - * sizeof (jobject))); - - frame->marker = MARK_SYSTEM; - frame->size = FRAME_SIZE; - frame->allocated_p = false; - frame->next = env->locals; - frame->loader = loader; - - memset (&frame->vec[0], 0, - frame->size * sizeof (jobject)); - - env->locals = frame; - } - - env->ex = NULL; - - return env; -} - -// Return the current thread's JNIEnv; if one does not exist, create -// it. Also create a new system frame for use. This is `extern "C"' -// because the compiler calls it. -extern "C" JNIEnv * -_Jv_GetJNIEnvNewFrame (jclass klass) -{ - return _Jv_GetJNIEnvNewFrameWithLoader (klass->getClassLoaderInternal()); -} - -// Destroy the env's reusable resources. This is called from the thread -// destructor "finalize_native" in natThread.cc -void -_Jv_FreeJNIEnv (_Jv_JNIEnv *env) -{ - if (env == NULL) - return; - - if (env->bottom_locals != NULL) - _Jv_Free (env->bottom_locals); - - _Jv_Free (env); -} - -// Return the function which implements a particular JNI method. If -// we can't find the function, we throw the appropriate exception. -// This is `extern "C"' because the compiler uses it. -extern "C" void * -_Jv_LookupJNIMethod (jclass klass, _Jv_Utf8Const *name, - _Jv_Utf8Const *signature, MAYBE_UNUSED int args_size) -{ - int name_length = name->len(); - int sig_length = signature->len(); - char buf[10 + 6 * (name_length + sig_length) + 12]; - int long_start; - void *function; - - // Synchronize on something convenient. Right now we use the hash. - JvSynchronize sync (global_ref_table); - - // First see if we have an override in the hash table. - strncpy (buf, name->chars (), name_length); - buf[name_length] = '\0'; - strncpy (buf + name_length + 1, signature->chars (), sig_length); - buf[name_length + sig_length + 1] = '\0'; - NativeMethodCacheEntry meth; - meth.name = buf; - meth.signature = buf + name_length + 1; - meth.className = _Jv_GetClassNameUtf8(klass)->chars(); - function = nathash_find (&meth); - if (function != NULL) - return function; - - // If there was no override, then look in the symbol table. - buf[0] = '_'; - mangled_name (klass, name, signature, buf + 1, &long_start); - char c = buf[long_start + 1]; - buf[long_start + 1] = '\0'; - - function = _Jv_FindSymbolInExecutable (buf + 1); -#ifdef WIN32 - // On Win32, we use the "stdcall" calling convention (see JNICALL - // in jni.h). - // - // For a function named 'fooBar' that takes 'nn' bytes as arguments, - // by default, MinGW GCC exports it as 'fooBar@nn', MSVC exports it - // as '_fooBar@nn' and Borland C exports it as 'fooBar'. We try to - // take care of all these variations here. - - char asz_buf[12]; /* '@' + '2147483647' (32-bit INT_MAX) + '\0' */ - char long_nm_sv[11]; /* Ditto, except for the '\0'. */ - - if (function == NULL) - { - // We have tried searching for the 'fooBar' form (BCC) - now - // try the others. - - // First, save the part of the long name that will be damaged - // by appending '@nn'. - memcpy (long_nm_sv, (buf + long_start + 1 + 1), sizeof (long_nm_sv)); - - sprintf (asz_buf, "@%d", args_size); - strcat (buf, asz_buf); - - // Search for the '_fooBar@nn' form (MSVC). - function = _Jv_FindSymbolInExecutable (buf); - - if (function == NULL) - { - // Search for the 'fooBar@nn' form (MinGW GCC). - function = _Jv_FindSymbolInExecutable (buf + 1); - } - } -#endif /* WIN32 */ - - if (function == NULL) - { - buf[long_start + 1] = c; -#ifdef WIN32 - // Restore the part of the long name that was damaged by - // appending the '@nn'. - memcpy ((buf + long_start + 1 + 1), long_nm_sv, sizeof (long_nm_sv)); -#endif /* WIN32 */ - function = _Jv_FindSymbolInExecutable (buf + 1); - if (function == NULL) - { -#ifdef WIN32 - strcat (buf, asz_buf); - function = _Jv_FindSymbolInExecutable (buf); - if (function == NULL) - function = _Jv_FindSymbolInExecutable (buf + 1); - - if (function == NULL) -#endif /* WIN32 */ - { - jstring str = JvNewStringUTF (name->chars ()); - throw new java::lang::UnsatisfiedLinkError (str); - } - } - } - - return function; -} - -#ifdef INTERPRETER - -// This function is the stub which is used to turn an ordinary (CNI) -// method call into a JNI call. -void -_Jv_JNIMethod::call (ffi_cif *, void *ret, INTERP_FFI_RAW_TYPE *args, - void *__this) -{ - _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this; - - JNIEnv *env = _Jv_GetJNIEnvNewFrame (_this->defining_class); - - // FIXME: we should mark every reference parameter as a local. For - // now we assume a conservative GC, and we assume that the - // references are on the stack somewhere. - - // We cache the value that we find, of course, but if we don't find - // a value we don't cache that fact -- we might subsequently load a - // library which finds the function in question. - { - // Synchronize on a convenient object to ensure sanity in case two - // threads reach this point for the same function at the same - // time. - JvSynchronize sync (global_ref_table); - if (_this->function == NULL) - { - int args_size = sizeof (JNIEnv *) + _this->args_raw_size; - - if (_this->self->accflags & java::lang::reflect::Modifier::STATIC) - args_size += sizeof (_this->defining_class); - - _this->function = _Jv_LookupJNIMethod (_this->defining_class, - _this->self->name, - _this->self->signature, - args_size); - } - } - - JvAssert (_this->args_raw_size % sizeof (INTERP_FFI_RAW_TYPE) == 0); - INTERP_FFI_RAW_TYPE - real_args[2 + _this->args_raw_size / sizeof (INTERP_FFI_RAW_TYPE)]; - int offset = 0; - - // First argument is always the environment pointer. - real_args[offset++].ptr = env; - - // For a static method, we pass in the Class. For non-static - // methods, the `this' argument is already handled. - if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC)) - real_args[offset++].ptr = _this->defining_class; - - // In libgcj, the callee synchronizes. - jobject sync = NULL; - if ((_this->self->accflags & java::lang::reflect::Modifier::SYNCHRONIZED)) - { - if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC)) - sync = _this->defining_class; - else - sync = (jobject) args[0].ptr; - _Jv_MonitorEnter (sync); - } - - // Copy over passed-in arguments. - memcpy (&real_args[offset], args, _this->args_raw_size); - - // Add a frame to the composite (interpreted + JNI) call stack - java::lang::Thread *thread = java::lang::Thread::currentThread(); - _Jv_NativeFrame nat_frame (_this, thread); - - // The actual call to the JNI function. -#if FFI_NATIVE_RAW_API - ffi_raw_call (&_this->jni_cif, (void (*)()) _this->function, - ret, real_args); -#else - ffi_java_raw_call (&_this->jni_cif, (void (*)()) _this->function, - ret, real_args); -#endif - - // We might need to unwrap a JNI weak reference here. - if (_this->jni_cif.rtype == &ffi_type_pointer) - { - _Jv_value *val = (_Jv_value *) ret; - val->object_value = unwrap (val->object_value); - } - - if (sync != NULL) - _Jv_MonitorExit (sync); - - _Jv_JNI_PopSystemFrame (env); -} - -#endif /* INTERPRETER */ - - - -// -// Invocation API. -// - -// An internal helper function. -static jint -_Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, - void *args, jboolean is_daemon) -{ - JavaVMAttachArgs *attach = reinterpret_cast<JavaVMAttachArgs *> (args); - java::lang::ThreadGroup *group = NULL; - - if (attach) - { - // FIXME: do we really want to support 1.1? - if (attach->version != JNI_VERSION_1_4 - && attach->version != JNI_VERSION_1_2 - && attach->version != JNI_VERSION_1_1) - return JNI_EVERSION; - - JvAssert (java::lang::ThreadGroup::class$.isInstance (attach->group)); - group = reinterpret_cast<java::lang::ThreadGroup *> (attach->group); - } - - // Attaching an already-attached thread is a no-op. - JNIEnv *env = _Jv_GetCurrentJNIEnv (); - if (env != NULL) - { - *penv = reinterpret_cast<void *> (env); - return 0; - } - - env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv)); - if (env == NULL) - return JNI_ERR; - env->functions = &_Jv_JNIFunctions; - env->ex = NULL; - env->bottom_locals - = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame) - + (FRAME_SIZE - * sizeof (jobject))); - env->locals = env->bottom_locals; - if (env->locals == NULL) - { - _Jv_Free (env); - return JNI_ERR; - } - - env->locals->allocated_p = false; - env->locals->marker = MARK_SYSTEM; - env->locals->size = FRAME_SIZE; - env->locals->loader = NULL; - env->locals->next = NULL; - - for (int i = 0; i < env->locals->size; ++i) - env->locals->vec[i] = NULL; - - *penv = reinterpret_cast<void *> (env); - - // This thread might already be a Java thread -- this function might - // have been called simply to set the new JNIEnv. - if (_Jv_ThreadCurrent () == NULL) - { - try - { - if (is_daemon) - _Jv_AttachCurrentThreadAsDaemon (name, group); - else - _Jv_AttachCurrentThread (name, group); - } - catch (jthrowable t) - { - return JNI_ERR; - } - } - _Jv_SetCurrentJNIEnv (env); - - return 0; -} - -// This is the one actually used by JNI. -jint JNICALL -_Jv_JNI_AttachCurrentThread (JavaVM *vm, void **penv, void *args) -{ - return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, false); -} - -static jint JNICALL -_Jv_JNI_AttachCurrentThreadAsDaemon (JavaVM *vm, void **penv, - void *args) -{ - return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, true); -} - -static jint JNICALL -_Jv_JNI_DestroyJavaVM (JavaVM *vm) -{ - JvAssert (_Jv_the_vm && vm == _Jv_the_vm); - - union - { - JNIEnv *env; - void *env_p; - }; - - if (_Jv_ThreadCurrent () != NULL) - { - jstring main_name; - // This sucks. - try - { - main_name = JvNewStringLatin1 ("main"); - } - catch (jthrowable t) - { - return JNI_ERR; - } - - jint r = _Jv_JNI_AttachCurrentThread (vm, main_name, &env_p, - NULL, false); - if (r < 0) - return r; - } - else - env = _Jv_GetCurrentJNIEnv (); - - _Jv_ThreadWait (); - - // Docs say that this always returns an error code. - return JNI_ERR; -} - -jint JNICALL -_Jv_JNI_DetachCurrentThread (JavaVM *) -{ - jint code = _Jv_DetachCurrentThread (); - return code ? JNI_EDETACHED : 0; -} - -static jint JNICALL -_Jv_JNI_GetEnv (JavaVM *, void **penv, jint version) -{ - if (_Jv_ThreadCurrent () == NULL) - { - *penv = NULL; - return JNI_EDETACHED; - } - -#ifdef ENABLE_JVMPI - // Handle JVMPI requests. - if (version == JVMPI_VERSION_1) - { - *penv = (void *) &_Jv_JVMPI_Interface; - return 0; - } -#endif - -#ifdef INTERPRETER - // Handle JVMTI requests - if (version == JVMTI_VERSION_1_0) - { - *penv = (void *) _Jv_GetJVMTIEnv (); - return 0; - } -#endif - - // FIXME: do we really want to support 1.1? - if (version != JNI_VERSION_1_4 && version != JNI_VERSION_1_2 - && version != JNI_VERSION_1_1) - { - *penv = NULL; - return JNI_EVERSION; - } - - *penv = (void *) _Jv_GetCurrentJNIEnv (); - return 0; -} - -JavaVM * -_Jv_GetJavaVM () -{ - // FIXME: synchronize - if (! _Jv_the_vm) - { - JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM)); - if (nvm != NULL) - nvm->functions = &_Jv_JNI_InvokeFunctions; - _Jv_the_vm = nvm; - } - - // If this is a Java thread, we want to make sure it has an - // associated JNIEnv. - if (_Jv_ThreadCurrent () != NULL) - { - void *ignore; - _Jv_JNI_AttachCurrentThread (_Jv_the_vm, &ignore, NULL); - } - - return _Jv_the_vm; -} - -static jint JNICALL -_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm) -{ - *vm = _Jv_GetJavaVM (); - return *vm == NULL ? JNI_ERR : JNI_OK; -} - - - -#define RESERVED NULL - -struct JNINativeInterface_ _Jv_JNIFunctions = -{ - RESERVED, - RESERVED, - RESERVED, - RESERVED, - _Jv_JNI_GetVersion, // GetVersion - _Jv_JNI_DefineClass, // DefineClass - _Jv_JNI_FindClass, // FindClass - _Jv_JNI_FromReflectedMethod, // FromReflectedMethod - _Jv_JNI_FromReflectedField, // FromReflectedField - _Jv_JNI_ToReflectedMethod, // ToReflectedMethod - _Jv_JNI_GetSuperclass, // GetSuperclass - _Jv_JNI_IsAssignableFrom, // IsAssignableFrom - _Jv_JNI_ToReflectedField, // ToReflectedField - _Jv_JNI_Throw, // Throw - _Jv_JNI_ThrowNew, // ThrowNew - _Jv_JNI_ExceptionOccurred, // ExceptionOccurred - _Jv_JNI_ExceptionDescribe, // ExceptionDescribe - _Jv_JNI_ExceptionClear, // ExceptionClear - _Jv_JNI_FatalError, // FatalError - - _Jv_JNI_PushLocalFrame, // PushLocalFrame - _Jv_JNI_PopLocalFrame, // PopLocalFrame - _Jv_JNI_NewGlobalRef, // NewGlobalRef - _Jv_JNI_DeleteGlobalRef, // DeleteGlobalRef - _Jv_JNI_DeleteLocalRef, // DeleteLocalRef - - _Jv_JNI_IsSameObject, // IsSameObject - - _Jv_JNI_NewLocalRef, // NewLocalRef - _Jv_JNI_EnsureLocalCapacity, // EnsureLocalCapacity - - _Jv_JNI_AllocObject, // AllocObject - _Jv_JNI_NewObject, // NewObject - _Jv_JNI_NewObjectV, // NewObjectV - _Jv_JNI_NewObjectA, // NewObjectA - _Jv_JNI_GetObjectClass, // GetObjectClass - _Jv_JNI_IsInstanceOf, // IsInstanceOf - _Jv_JNI_GetAnyMethodID<false>, // GetMethodID - - _Jv_JNI_CallMethod<jobject>, // CallObjectMethod - _Jv_JNI_CallMethodV<jobject>, // CallObjectMethodV - _Jv_JNI_CallMethodA<jobject>, // CallObjectMethodA - _Jv_JNI_CallMethod<jboolean>, // CallBooleanMethod - _Jv_JNI_CallMethodV<jboolean>, // CallBooleanMethodV - _Jv_JNI_CallMethodA<jboolean>, // CallBooleanMethodA - _Jv_JNI_CallMethod<jbyte>, // CallByteMethod - _Jv_JNI_CallMethodV<jbyte>, // CallByteMethodV - _Jv_JNI_CallMethodA<jbyte>, // CallByteMethodA - _Jv_JNI_CallMethod<jchar>, // CallCharMethod - _Jv_JNI_CallMethodV<jchar>, // CallCharMethodV - _Jv_JNI_CallMethodA<jchar>, // CallCharMethodA - _Jv_JNI_CallMethod<jshort>, // CallShortMethod - _Jv_JNI_CallMethodV<jshort>, // CallShortMethodV - _Jv_JNI_CallMethodA<jshort>, // CallShortMethodA - _Jv_JNI_CallMethod<jint>, // CallIntMethod - _Jv_JNI_CallMethodV<jint>, // CallIntMethodV - _Jv_JNI_CallMethodA<jint>, // CallIntMethodA - _Jv_JNI_CallMethod<jlong>, // CallLongMethod - _Jv_JNI_CallMethodV<jlong>, // CallLongMethodV - _Jv_JNI_CallMethodA<jlong>, // CallLongMethodA - _Jv_JNI_CallMethod<jfloat>, // CallFloatMethod - _Jv_JNI_CallMethodV<jfloat>, // CallFloatMethodV - _Jv_JNI_CallMethodA<jfloat>, // CallFloatMethodA - _Jv_JNI_CallMethod<jdouble>, // CallDoubleMethod - _Jv_JNI_CallMethodV<jdouble>, // CallDoubleMethodV - _Jv_JNI_CallMethodA<jdouble>, // CallDoubleMethodA - _Jv_JNI_CallVoidMethod, // CallVoidMethod - _Jv_JNI_CallVoidMethodV, // CallVoidMethodV - _Jv_JNI_CallVoidMethodA, // CallVoidMethodA - - // Nonvirtual method invocation functions follow. - _Jv_JNI_CallAnyMethod<jobject, nonvirtual>, // CallNonvirtualObjectMethod - _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>, // CallNonvirtualObjectMethodV - _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>, // CallNonvirtualObjectMethodA - _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>, // CallNonvirtualBooleanMethod - _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>, // CallNonvirtualBooleanMethodV - _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>, // CallNonvirtualBooleanMethodA - _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>, // CallNonvirtualByteMethod - _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>, // CallNonvirtualByteMethodV - _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>, // CallNonvirtualByteMethodA - _Jv_JNI_CallAnyMethod<jchar, nonvirtual>, // CallNonvirtualCharMethod - _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>, // CallNonvirtualCharMethodV - _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>, // CallNonvirtualCharMethodA - _Jv_JNI_CallAnyMethod<jshort, nonvirtual>, // CallNonvirtualShortMethod - _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>, // CallNonvirtualShortMethodV - _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>, // CallNonvirtualShortMethodA - _Jv_JNI_CallAnyMethod<jint, nonvirtual>, // CallNonvirtualIntMethod - _Jv_JNI_CallAnyMethodV<jint, nonvirtual>, // CallNonvirtualIntMethodV - _Jv_JNI_CallAnyMethodA<jint, nonvirtual>, // CallNonvirtualIntMethodA - _Jv_JNI_CallAnyMethod<jlong, nonvirtual>, // CallNonvirtualLongMethod - _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>, // CallNonvirtualLongMethodV - _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>, // CallNonvirtualLongMethodA - _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>, // CallNonvirtualFloatMethod - _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>, // CallNonvirtualFloatMethodV - _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>, // CallNonvirtualFloatMethodA - _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>, // CallNonvirtualDoubleMethod - _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>, // CallNonvirtualDoubleMethodV - _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>, // CallNonvirtualDoubleMethodA - _Jv_JNI_CallAnyVoidMethod<nonvirtual>, // CallNonvirtualVoidMethod - _Jv_JNI_CallAnyVoidMethodV<nonvirtual>, // CallNonvirtualVoidMethodV - _Jv_JNI_CallAnyVoidMethodA<nonvirtual>, // CallNonvirtualVoidMethodA - - _Jv_JNI_GetAnyFieldID<false>, // GetFieldID - _Jv_JNI_GetField<jobject>, // GetObjectField - _Jv_JNI_GetField<jboolean>, // GetBooleanField - _Jv_JNI_GetField<jbyte>, // GetByteField - _Jv_JNI_GetField<jchar>, // GetCharField - _Jv_JNI_GetField<jshort>, // GetShortField - _Jv_JNI_GetField<jint>, // GetIntField - _Jv_JNI_GetField<jlong>, // GetLongField - _Jv_JNI_GetField<jfloat>, // GetFloatField - _Jv_JNI_GetField<jdouble>, // GetDoubleField - _Jv_JNI_SetField, // SetObjectField - _Jv_JNI_SetField, // SetBooleanField - _Jv_JNI_SetField, // SetByteField - _Jv_JNI_SetField, // SetCharField - _Jv_JNI_SetField, // SetShortField - _Jv_JNI_SetField, // SetIntField - _Jv_JNI_SetField, // SetLongField - _Jv_JNI_SetField, // SetFloatField - _Jv_JNI_SetField, // SetDoubleField - _Jv_JNI_GetAnyMethodID<true>, // GetStaticMethodID - - _Jv_JNI_CallStaticMethod<jobject>, // CallStaticObjectMethod - _Jv_JNI_CallStaticMethodV<jobject>, // CallStaticObjectMethodV - _Jv_JNI_CallStaticMethodA<jobject>, // CallStaticObjectMethodA - _Jv_JNI_CallStaticMethod<jboolean>, // CallStaticBooleanMethod - _Jv_JNI_CallStaticMethodV<jboolean>, // CallStaticBooleanMethodV - _Jv_JNI_CallStaticMethodA<jboolean>, // CallStaticBooleanMethodA - _Jv_JNI_CallStaticMethod<jbyte>, // CallStaticByteMethod - _Jv_JNI_CallStaticMethodV<jbyte>, // CallStaticByteMethodV - _Jv_JNI_CallStaticMethodA<jbyte>, // CallStaticByteMethodA - _Jv_JNI_CallStaticMethod<jchar>, // CallStaticCharMethod - _Jv_JNI_CallStaticMethodV<jchar>, // CallStaticCharMethodV - _Jv_JNI_CallStaticMethodA<jchar>, // CallStaticCharMethodA - _Jv_JNI_CallStaticMethod<jshort>, // CallStaticShortMethod - _Jv_JNI_CallStaticMethodV<jshort>, // CallStaticShortMethodV - _Jv_JNI_CallStaticMethodA<jshort>, // CallStaticShortMethodA - _Jv_JNI_CallStaticMethod<jint>, // CallStaticIntMethod - _Jv_JNI_CallStaticMethodV<jint>, // CallStaticIntMethodV - _Jv_JNI_CallStaticMethodA<jint>, // CallStaticIntMethodA - _Jv_JNI_CallStaticMethod<jlong>, // CallStaticLongMethod - _Jv_JNI_CallStaticMethodV<jlong>, // CallStaticLongMethodV - _Jv_JNI_CallStaticMethodA<jlong>, // CallStaticLongMethodA - _Jv_JNI_CallStaticMethod<jfloat>, // CallStaticFloatMethod - _Jv_JNI_CallStaticMethodV<jfloat>, // CallStaticFloatMethodV - _Jv_JNI_CallStaticMethodA<jfloat>, // CallStaticFloatMethodA - _Jv_JNI_CallStaticMethod<jdouble>, // CallStaticDoubleMethod - _Jv_JNI_CallStaticMethodV<jdouble>, // CallStaticDoubleMethodV - _Jv_JNI_CallStaticMethodA<jdouble>, // CallStaticDoubleMethodA - _Jv_JNI_CallStaticVoidMethod, // CallStaticVoidMethod - _Jv_JNI_CallStaticVoidMethodV, // CallStaticVoidMethodV - _Jv_JNI_CallStaticVoidMethodA, // CallStaticVoidMethodA - - _Jv_JNI_GetAnyFieldID<true>, // GetStaticFieldID - _Jv_JNI_GetStaticField<jobject>, // GetStaticObjectField - _Jv_JNI_GetStaticField<jboolean>, // GetStaticBooleanField - _Jv_JNI_GetStaticField<jbyte>, // GetStaticByteField - _Jv_JNI_GetStaticField<jchar>, // GetStaticCharField - _Jv_JNI_GetStaticField<jshort>, // GetStaticShortField - _Jv_JNI_GetStaticField<jint>, // GetStaticIntField - _Jv_JNI_GetStaticField<jlong>, // GetStaticLongField - _Jv_JNI_GetStaticField<jfloat>, // GetStaticFloatField - _Jv_JNI_GetStaticField<jdouble>, // GetStaticDoubleField - _Jv_JNI_SetStaticField, // SetStaticObjectField - _Jv_JNI_SetStaticField, // SetStaticBooleanField - _Jv_JNI_SetStaticField, // SetStaticByteField - _Jv_JNI_SetStaticField, // SetStaticCharField - _Jv_JNI_SetStaticField, // SetStaticShortField - _Jv_JNI_SetStaticField, // SetStaticIntField - _Jv_JNI_SetStaticField, // SetStaticLongField - _Jv_JNI_SetStaticField, // SetStaticFloatField - _Jv_JNI_SetStaticField, // SetStaticDoubleField - _Jv_JNI_NewString, // NewString - _Jv_JNI_GetStringLength, // GetStringLength - _Jv_JNI_GetStringChars, // GetStringChars - _Jv_JNI_ReleaseStringChars, // ReleaseStringChars - _Jv_JNI_NewStringUTF, // NewStringUTF - _Jv_JNI_GetStringUTFLength, // GetStringUTFLength - _Jv_JNI_GetStringUTFChars, // GetStringUTFChars - _Jv_JNI_ReleaseStringUTFChars, // ReleaseStringUTFChars - _Jv_JNI_GetArrayLength, // GetArrayLength - _Jv_JNI_NewObjectArray, // NewObjectArray - _Jv_JNI_GetObjectArrayElement, // GetObjectArrayElement - _Jv_JNI_SetObjectArrayElement, // SetObjectArrayElement - _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>, - // NewBooleanArray - _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>, // NewByteArray - _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>, // NewCharArray - _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>, // NewShortArray - _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>, // NewIntArray - _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>, // NewLongArray - _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>, // NewFloatArray - _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>, // NewDoubleArray - _Jv_JNI_GetPrimitiveArrayElements<jboolean, JvPrimClass (boolean)>, - // GetBooleanArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jbyte, JvPrimClass (byte)>, - // GetByteArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jchar, JvPrimClass (char)>, - // GetCharArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jshort, JvPrimClass (short)>, - // GetShortArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jint, JvPrimClass (int)>, - // GetIntArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jlong, JvPrimClass (long)>, - // GetLongArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jfloat, JvPrimClass (float)>, - // GetFloatArrayElements - _Jv_JNI_GetPrimitiveArrayElements<jdouble, JvPrimClass (double)>, - // GetDoubleArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jboolean, JvPrimClass (boolean)>, - // ReleaseBooleanArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jbyte, JvPrimClass (byte)>, - // ReleaseByteArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jchar, JvPrimClass (char)>, - // ReleaseCharArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jshort, JvPrimClass (short)>, - // ReleaseShortArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jint, JvPrimClass (int)>, - // ReleaseIntArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jlong, JvPrimClass (long)>, - // ReleaseLongArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jfloat, JvPrimClass (float)>, - // ReleaseFloatArrayElements - _Jv_JNI_ReleasePrimitiveArrayElements<jdouble, JvPrimClass (double)>, - // ReleaseDoubleArrayElements - _Jv_JNI_GetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>, - // GetBooleanArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>, - // GetByteArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jchar, JvPrimClass (char)>, - // GetCharArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jshort, JvPrimClass (short)>, - // GetShortArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jint, JvPrimClass (int)>, - // GetIntArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jlong, JvPrimClass (long)>, - // GetLongArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>, - // GetFloatArrayRegion - _Jv_JNI_GetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>, - // GetDoubleArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>, - // SetBooleanArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>, - // SetByteArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jchar, JvPrimClass (char)>, - // SetCharArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jshort, JvPrimClass (short)>, - // SetShortArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jint, JvPrimClass (int)>, - // SetIntArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jlong, JvPrimClass (long)>, - // SetLongArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>, - // SetFloatArrayRegion - _Jv_JNI_SetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>, - // SetDoubleArrayRegion - _Jv_JNI_RegisterNatives, // RegisterNatives - _Jv_JNI_UnregisterNatives, // UnregisterNatives - _Jv_JNI_MonitorEnter, // MonitorEnter - _Jv_JNI_MonitorExit, // MonitorExit - _Jv_JNI_GetJavaVM, // GetJavaVM - - _Jv_JNI_GetStringRegion, // GetStringRegion - _Jv_JNI_GetStringUTFRegion, // GetStringUTFRegion - _Jv_JNI_GetPrimitiveArrayCritical, // GetPrimitiveArrayCritical - _Jv_JNI_ReleasePrimitiveArrayCritical, // ReleasePrimitiveArrayCritical - _Jv_JNI_GetStringCritical, // GetStringCritical - _Jv_JNI_ReleaseStringCritical, // ReleaseStringCritical - - _Jv_JNI_NewWeakGlobalRef, // NewWeakGlobalRef - _Jv_JNI_DeleteWeakGlobalRef, // DeleteWeakGlobalRef - - _Jv_JNI_ExceptionCheck, // ExceptionCheck - - _Jv_JNI_NewDirectByteBuffer, // NewDirectByteBuffer - _Jv_JNI_GetDirectBufferAddress, // GetDirectBufferAddress - _Jv_JNI_GetDirectBufferCapacity, // GetDirectBufferCapacity - - _Jv_JNI_GetObjectRefType // GetObjectRefType -}; - -struct JNIInvokeInterface_ _Jv_JNI_InvokeFunctions = -{ - RESERVED, - RESERVED, - RESERVED, - - _Jv_JNI_DestroyJavaVM, - _Jv_JNI_AttachCurrentThread, - _Jv_JNI_DetachCurrentThread, - _Jv_JNI_GetEnv, - _Jv_JNI_AttachCurrentThreadAsDaemon -}; |