1 // jni.cc - JNI implementation, including the jump table.
3 /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 // Note: currently we take the approach of not checking most
12 // arguments. Instead we could do more checking conditionally (e.g.,
13 // if DEBUG is defined). That might be beneficial in some cases,
14 // though to me it seems that one could just as easily use the
22 // Define this before including jni.h.
23 #define __GCJ_JNI_IMPL__
27 #include <java-assert.h>
30 #include <java/lang/Class.h>
31 #include <java/lang/ClassLoader.h>
32 #include <java/lang/Throwable.h>
33 #include <java/lang/ArrayIndexOutOfBoundsException.h>
34 #include <java/lang/StringIndexOutOfBoundsException.h>
35 #include <java/lang/InstantiationException.h>
36 #include <java/lang/NoSuchFieldError.h>
37 #include <java/lang/NoSuchMethodError.h>
38 #include <java/lang/reflect/Constructor.h>
39 #include <java/lang/reflect/Method.h>
40 #include <java/lang/reflect/Modifier.h>
41 #include <java/lang/OutOfMemoryError.h>
42 #include <java/util/Hashtable.h>
43 #include <java/lang/Integer.h>
45 #include <gcj/method.h>
46 #include <gcj/field.h>
48 #include <java-interp.h>
50 #define ClassClass _CL_Q34java4lang5Class
51 extern java::lang::Class ClassClass;
52 #define ObjectClass _CL_Q34java4lang6Object
53 extern java::lang::Class ObjectClass;
55 #define MethodClass _CL_Q44java4lang7reflect6Method
56 extern java::lang::Class MethodClass;
58 // This enum is used to select different template instantiations in
59 // the invocation code.
68 // Forward declaration.
69 extern struct JNINativeInterface _Jv_JNIFunctions;
71 // Number of slots in the default frame. The VM must allow at least
75 // This structure is used to keep track of local references.
76 struct _Jv_JNI_LocalFrame
78 // This is true if this frame object represents a pushed frame (eg
79 // from PushLocalFrame).
82 // Number of elements in frame.
85 // Next frame in chain.
86 _Jv_JNI_LocalFrame *next;
88 // The elements. These are allocated using the C "struct hack".
92 // This holds a reference count for all local and global references.
93 static java::util::Hashtable *ref_table;
100 ref_table = new java::util::Hashtable;
103 // Tell the GC that a certain pointer is live.
105 mark_for_gc (jobject obj)
107 JvSynchronize sync (ref_table);
109 using namespace java::lang;
110 Integer *refcount = (Integer *) ref_table->get (obj);
111 jint val = (refcount == NULL) ? 0 : refcount->intValue ();
112 ref_table->put (obj, new Integer (val + 1));
117 unmark_for_gc (jobject obj)
119 JvSynchronize sync (ref_table);
121 using namespace java::lang;
122 Integer *refcount = (Integer *) ref_table->get (obj);
124 jint val = refcount->intValue () - 1;
126 ref_table->remove (obj);
128 ref_table->put (obj, new Integer (val));
134 _Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
141 _Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
147 _Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
149 _Jv_JNI_LocalFrame *frame;
151 for (frame = env->locals; frame != NULL; frame = frame->next)
153 for (int i = 0; i < FRAME_SIZE; ++i)
155 if (frame->vec[i] == obj)
157 frame->vec[i] = NULL;
163 // Don't go past a marked frame.
164 JvAssert (! frame->marker);
171 _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
173 // It is easier to just always allocate a new frame of the requested
174 // size. This isn't the most efficient thing, but for now we don't
175 // care. Note that _Jv_JNI_PushLocalFrame relies on this right now.
177 _Jv_JNI_LocalFrame *frame
178 = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
179 + size * sizeof (jobject));
182 // FIXME: exception processing.
183 env->ex = new java::lang::OutOfMemoryError;
187 frame->marker = true;
189 memset (&frame->vec[0], 0, size * sizeof (jobject));
190 frame->next = env->locals;
197 _Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
199 jint r = _Jv_JNI_EnsureLocalCapacity (env, size);
203 // The new frame is on top.
204 env->locals->marker = true;
210 _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
212 // Try to find an open slot somewhere in the topmost frame.
213 _Jv_JNI_LocalFrame *frame = env->locals;
214 bool done = false, set = false;
215 while (frame != NULL && ! done)
217 for (int i = 0; i < frame->size; ++i)
218 if (frame->vec[i] == NULL)
229 // No slots, so we allocate a new frame. According to the spec
230 // we could just die here. FIXME: return value.
231 _Jv_JNI_EnsureLocalCapacity (env, 16);
232 // We know the first element of the new frame will be ok.
233 env->locals->vec[0] = obj;
241 _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
243 _Jv_JNI_LocalFrame *rf = env->locals;
246 while (rf != NULL && ! done)
248 for (int i = 0; i < rf->size; ++i)
249 if (rf->vec[i] != NULL)
250 unmark_for_gc (rf->vec[i]);
252 // If the frame we just freed is the marker frame, we are done.
255 _Jv_JNI_LocalFrame *n = rf->next;
256 // When N==NULL, we've reached the stack-allocated frame, and we
257 // must not free it. However, we must be sure to clear all its
258 // elements, since we might conceivably reuse it.
261 memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
269 return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
272 // This function is used from other template functions. It wraps the
273 // return value appropriately; we specialize it so that object returns
274 // are turned into local references.
277 wrap_value (JNIEnv *, T value)
284 wrap_value (JNIEnv *env, jobject value)
286 return _Jv_JNI_NewLocalRef (env, value);
292 _Jv_JNI_GetVersion (JNIEnv *)
294 return JNI_VERSION_1_2;
298 _Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
299 const jbyte *buf, jsize bufLen)
301 jbyteArray bytes = JvNewByteArray (bufLen);
302 jbyte *elts = elements (bytes);
303 memcpy (elts, buf, bufLen * sizeof (jbyte));
305 java::lang::ClassLoader *l
306 = reinterpret_cast<java::lang::ClassLoader *> (loader);
308 // FIXME: exception processing.
309 jclass result = l->defineClass (bytes, 0, bufLen);
310 return (jclass) _Jv_JNI_NewLocalRef (env, result);
314 _Jv_JNI_FindClass (JNIEnv *env, const char *name)
316 // FIXME: assume that NAME isn't too long.
317 int len = strlen (name);
319 for (int i = 0; i <= len; ++i)
320 s[i] = (name[i] == '/') ? '.' : name[i];
321 jstring n = JvNewStringUTF (s);
323 java::lang::ClassLoader *loader;
324 if (env->klass == NULL)
326 // FIXME: should use getBaseClassLoader, but we don't have that
328 loader = java::lang::ClassLoader::getSystemClassLoader ();
331 loader = env->klass->getClassLoader ();
333 // FIXME: exception processing.
334 jclass r = loader->findClass (n);
336 return (jclass) _Jv_JNI_NewLocalRef (env, r);
340 _Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
342 return (jclass) _Jv_JNI_NewLocalRef (env, clazz->getSuperclass ());
346 _Jv_JNI_IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
348 return clazz1->isAssignableFrom (clazz2);
352 _Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
359 _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
361 using namespace java::lang::reflect;
363 JArray<jclass> *argtypes
364 = (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL);
366 jclass *elts = elements (argtypes);
367 elts[0] = &StringClass;
369 // FIXME: exception processing.
370 Constructor *cons = clazz->getConstructor (argtypes);
372 jobjectArray values = JvNewObjectArray (1, &StringClass, NULL);
373 jobject *velts = elements (values);
374 velts[0] = JvNewStringUTF (message);
376 // FIXME: exception processing.
377 jobject obj = cons->newInstance (values);
379 env->ex = reinterpret_cast<jthrowable> (obj);
384 _Jv_JNI_ExceptionOccurred (JNIEnv *env)
386 return (jthrowable) _Jv_JNI_NewLocalRef (env, env->ex);
390 _Jv_JNI_ExceptionDescribe (JNIEnv *env)
393 env->ex->printStackTrace();
397 _Jv_JNI_ExceptionClear (JNIEnv *env)
403 _Jv_JNI_ExceptionCheck (JNIEnv *env)
405 return env->ex != NULL;
409 _Jv_JNI_FatalError (JNIEnv *, const char *message)
417 _Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
423 _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
426 using namespace java::lang::reflect;
427 if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
428 env->ex = new java::lang::InstantiationException ();
431 // FIXME: exception processing.
432 // FIXME: will this work for String?
433 obj = JvAllocObject (clazz);
436 return _Jv_JNI_NewLocalRef (env, obj);
440 _Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
442 return (jclass) _Jv_JNI_NewLocalRef (env, obj->getClass());
446 _Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
448 return clazz->isInstance(obj);
454 // This section concerns method invocation.
457 template<jboolean is_static>
459 _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
460 const char *name, const char *sig)
462 // FIXME: exception processing.
463 _Jv_InitClass (clazz);
465 _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
466 _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
468 JvAssert (! clazz->isPrimitive());
470 using namespace java::lang::reflect;
472 while (clazz != NULL)
474 jint count = JvNumMethods (clazz);
475 jmethodID meth = JvGetFirstMethod (clazz);
477 for (jint i = 0; i < count; ++i)
479 if (((is_static && Modifier::isStatic (meth->accflags))
480 || (! is_static && ! Modifier::isStatic (meth->accflags)))
481 && _Jv_equalUtf8Consts (meth->name, name_u)
482 && _Jv_equalUtf8Consts (meth->signature, sig_u))
485 meth = meth->getNextMethod();
488 clazz = clazz->getSuperclass ();
491 env->ex = new java::lang::NoSuchMethodError ();
495 // This is a helper function which turns a va_list into an array of
496 // `jvalue's. It needs signature information in order to do its work.
497 // The array of values must already be allocated.
499 array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
501 jclass *arg_elts = elements (arg_types);
502 for (int i = 0; i < arg_types->length; ++i)
504 if (arg_elts[i] == JvPrimClass (byte))
505 values[i].b = va_arg (vargs, jbyte);
506 else if (arg_elts[i] == JvPrimClass (short))
507 values[i].s = va_arg (vargs, jshort);
508 else if (arg_elts[i] == JvPrimClass (int))
509 values[i].i = va_arg (vargs, jint);
510 else if (arg_elts[i] == JvPrimClass (long))
511 values[i].j = va_arg (vargs, jlong);
512 else if (arg_elts[i] == JvPrimClass (float))
513 values[i].f = va_arg (vargs, jfloat);
514 else if (arg_elts[i] == JvPrimClass (double))
515 values[i].d = va_arg (vargs, jdouble);
516 else if (arg_elts[i] == JvPrimClass (boolean))
517 values[i].z = va_arg (vargs, jboolean);
518 else if (arg_elts[i] == JvPrimClass (char))
519 values[i].c = va_arg (vargs, jchar);
523 values[i].l = va_arg (vargs, jobject);
528 // This can call any sort of method: virtual, "nonvirtual", static, or
530 template<typename T, invocation_type style>
532 _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
533 jmethodID id, va_list vargs)
536 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
538 jclass decl_class = klass ? klass : obj->getClass ();
539 JvAssert (decl_class != NULL);
542 JArray<jclass> *arg_types;
543 // FIXME: exception processing.
544 _Jv_GetTypesFromSignature (id, decl_class,
545 &arg_types, &return_type);
547 jvalue args[arg_types->length];
548 array_from_valist (args, arg_types, vargs);
551 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
552 style == constructor,
553 arg_types, args, &result);
558 // We cheat a little here. FIXME.
559 return wrap_value (env, * (T *) &result);
562 template<typename T, invocation_type style>
564 _Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass,
565 jmethodID method, ...)
570 va_start (args, method);
571 result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args);
577 template<typename T, invocation_type style>
579 _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
580 jmethodID id, jvalue *args)
583 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
585 jclass decl_class = klass ? klass : obj->getClass ();
586 JvAssert (decl_class != NULL);
589 JArray<jclass> *arg_types;
590 // FIXME: exception processing.
591 _Jv_GetTypesFromSignature (id, decl_class,
592 &arg_types, &return_type);
595 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
596 style == constructor,
597 arg_types, args, &result);
602 // We cheat a little here. FIXME.
603 return wrap_value (env, * (T *) &result);
606 template<invocation_type style>
608 _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
609 jmethodID id, va_list vargs)
612 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
614 jclass decl_class = klass ? klass : obj->getClass ();
615 JvAssert (decl_class != NULL);
618 JArray<jclass> *arg_types;
619 // FIXME: exception processing.
620 _Jv_GetTypesFromSignature (id, decl_class,
621 &arg_types, &return_type);
623 jvalue args[arg_types->length];
624 array_from_valist (args, arg_types, vargs);
626 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
627 style == constructor,
628 arg_types, args, NULL);
634 template<invocation_type style>
636 _Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass,
637 jmethodID method, ...)
641 va_start (args, method);
642 _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args);
646 template<invocation_type style>
648 _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
649 jmethodID id, jvalue *args)
652 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
654 jclass decl_class = klass ? klass : obj->getClass ();
655 JvAssert (decl_class != NULL);
658 JArray<jclass> *arg_types;
659 // FIXME: exception processing.
660 _Jv_GetTypesFromSignature (id, decl_class,
661 &arg_types, &return_type);
663 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
664 style == constructor,
665 arg_types, args, NULL);
671 // Functions with this signature are used to implement functions in
672 // the CallMethod family.
675 _Jv_JNI_CallMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args)
677 return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
680 // Functions with this signature are used to implement functions in
681 // the CallMethod family.
684 _Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
690 result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
696 // Functions with this signature are used to implement functions in
697 // the CallMethod family.
700 _Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
702 return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args);
706 _Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args)
708 _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
712 _Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
717 _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
722 _Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
724 _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args);
727 // Functions with this signature are used to implement functions in
728 // the CallStaticMethod family.
731 _Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
732 jmethodID id, va_list args)
734 return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args);
737 // Functions with this signature are used to implement functions in
738 // the CallStaticMethod family.
741 _Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
747 result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass,
754 // Functions with this signature are used to implement functions in
755 // the CallStaticMethod family.
758 _Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
761 return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
765 _Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, jmethodID id,
768 _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
772 _Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
777 _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
782 _Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, jmethodID id,
785 _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args);
789 _Jv_JNI_NewObjectV (JNIEnv *env, jclass klass,
790 jmethodID id, va_list args)
792 return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
797 _Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...)
803 result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
811 _Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
814 return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass,
822 _Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field)
824 T *ptr = (T *) ((char *) obj + field->getOffset ());
825 return wrap_value (env, *ptr);
830 _Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
832 T *ptr = (T *) ((char *) obj + field->getOffset ());
836 template<jboolean is_static>
838 _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
839 const char *name, const char *sig)
841 // FIXME: exception processing.
842 _Jv_InitClass (clazz);
844 _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
846 jclass field_class = NULL;
848 field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
851 _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
852 field_class = _Jv_FindClass (sig_u, NULL);
855 // FIXME: what if field_class == NULL?
857 while (clazz != NULL)
859 jint count = (is_static
860 ? JvNumStaticFields (clazz)
861 : JvNumInstanceFields (clazz));
862 jfieldID field = (is_static
863 ? JvGetFirstStaticField (clazz)
864 : JvGetFirstInstanceField (clazz));
865 for (jint i = 0; i < count; ++i)
867 // The field is resolved as a side effect of class
869 JvAssert (field->isResolved ());
871 _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);
873 if (_Jv_equalUtf8Consts (f_name, a_name)
874 && field->getClass() == field_class)
877 field = field->getNextField ();
880 clazz = clazz->getSuperclass ();
883 env->ex = new java::lang::NoSuchFieldError ();
889 _Jv_JNI_GetStaticField (JNIEnv *env, jclass, jfieldID field)
891 T *ptr = (T *) field->u.addr;
892 return wrap_value (env, *ptr);
897 _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
899 T *ptr = (T *) field->u.addr;
904 _Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
906 // FIXME: exception processing.
907 jstring r = _Jv_NewString (unichars, len);
908 return (jstring) _Jv_JNI_NewLocalRef (env, r);
912 _Jv_JNI_GetStringLength (JNIEnv *, jstring string)
914 return string->length();
918 _Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
920 jchar *result = _Jv_GetStringChars (string);
921 mark_for_gc (string);
924 return (const jchar *) result;
928 _Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
930 unmark_for_gc (string);
934 _Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
936 // FIXME: exception processing.
937 jstring result = JvNewStringUTF (bytes);
938 return (jstring) _Jv_JNI_NewLocalRef (env, result);
942 _Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
944 return JvGetStringUTFLength (string);
948 _Jv_JNI_GetStringUTFChars (JNIEnv *, jstring string, jboolean *isCopy)
950 jsize len = JvGetStringUTFLength (string);
951 // FIXME: exception processing.
952 char *r = (char *) _Jv_Malloc (len + 1);
953 JvGetStringUTFRegion (string, 0, len, r);
959 return (const char *) r;
963 _Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
965 _Jv_Free ((void *) utf);
969 _Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, jsize len,
972 jchar *result = _Jv_GetStringChars (string);
973 if (start < 0 || start > string->length ()
974 || len < 0 || start + len > string->length ())
975 env->ex = new java::lang::StringIndexOutOfBoundsException ();
977 memcpy (buf, &result[start], len * sizeof (jchar));
981 _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
982 jsize len, char *buf)
984 if (start < 0 || start > str->length ()
985 || len < 0 || start + len > str->length ())
986 env->ex = new java::lang::StringIndexOutOfBoundsException ();
988 _Jv_GetStringUTFRegion (str, start, len, buf);
992 _Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
994 jchar *result = _Jv_GetStringChars (str);
1001 _Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
1007 _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
1009 return array->length;
1013 _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
1016 // FIXME: exception processing.
1017 jarray result = JvNewObjectArray (length, elementClass, init);
1018 return (jarray) _Jv_JNI_NewLocalRef (env, result);
1022 _Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
1024 jobject *elts = elements (array);
1025 return _Jv_JNI_NewLocalRef (env, elts[index]);
1029 _Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index,
1032 // FIXME: exception processing.
1033 _Jv_CheckArrayStore (array, value);
1034 jobject *elts = elements (array);
1035 elts[index] = value;
1038 template<typename T, jclass K>
1040 _Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
1042 // FIXME: exception processing.
1043 return (JArray<T> *) _Jv_JNI_NewLocalRef (env,
1044 _Jv_NewPrimArray (K, length));
1047 template<typename T>
1049 _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
1052 T *elts = elements (array);
1055 // We elect never to copy.
1058 mark_for_gc (array);
1062 template<typename T>
1064 _Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *array,
1065 T *, jint /* mode */)
1067 // Note that we ignore MODE. We can do this because we never copy
1068 // the array elements. My reading of the JNI documentation is that
1069 // this is an option for the implementor.
1070 unmark_for_gc (array);
1073 template<typename T>
1075 _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
1076 jsize start, jsize len,
1079 if (start < 0 || len >= array->length || start + len >= array->length)
1082 env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
1086 T *elts = elements (array) + start;
1087 memcpy (buf, elts, len * sizeof (T));
1091 template<typename T>
1093 _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
1094 jsize start, jsize len, T *buf)
1096 if (start < 0 || len >= array->length || start + len >= array->length)
1099 env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
1103 T *elts = elements (array) + start;
1104 memcpy (elts, buf, len * sizeof (T));
1109 _Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
1112 // FIXME: does this work?
1113 jclass klass = array->getClass()->getComponentType();
1114 JvAssert (klass->isPrimitive ());
1115 char *r = _Jv_GetArrayElementFromElementType (array, klass);
1122 _Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
1128 _Jv_JNI_MonitorEnter (JNIEnv *, jobject obj)
1130 // FIXME: exception processing.
1131 jint r = _Jv_MonitorEnter (obj);
1136 _Jv_JNI_MonitorExit (JNIEnv *, jobject obj)
1138 // FIXME: exception processing.
1139 jint r = _Jv_MonitorExit (obj);
1145 _Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
1148 // FIXME: exception processing.
1149 java::lang::reflect::Field *field = new java::lang::reflect::Field();
1150 field->declaringClass = cls;
1151 field->offset = (char*) fieldID - (char *) cls->fields;
1152 field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
1153 return _Jv_JNI_NewLocalRef (env, field);
1158 _Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
1160 using namespace java::lang::reflect;
1162 Field *field = reinterpret_cast<Field *> (f);
1163 return _Jv_FromReflectedField (field);
1167 _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
1170 using namespace java::lang::reflect;
1173 static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
1176 if (_Jv_equalUtf8Consts (id->name, init_name))
1179 Constructor *cons = new Constructor ();
1180 cons->offset = (char *) id - (char *) &klass->methods;
1181 cons->declaringClass = klass;
1186 Method *meth = new Method ();
1187 meth->offset = (char *) id - (char *) &klass->methods;
1188 meth->declaringClass = klass;
1192 return _Jv_JNI_NewLocalRef (env, result);
1196 _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
1198 using namespace java::lang::reflect;
1199 if ((&MethodClass)->isInstance (method))
1200 return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
1202 _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
1207 // This function is the stub which is used to turn an ordinary (CNI)
1208 // method call into a JNI call.
1210 _Jv_JNI_conversion_call (ffi_cif *cif,
1215 _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
1218 _Jv_JNI_LocalFrame *frame
1219 = (_Jv_JNI_LocalFrame *) alloca (sizeof (_Jv_JNI_LocalFrame)
1220 + FRAME_SIZE * sizeof (jobject));
1222 env.p = &_Jv_JNIFunctions;
1224 env.klass = _this->defining_class;
1227 frame->marker = true;
1229 frame->size = FRAME_SIZE;
1230 for (int i = 0; i < frame->size; ++i)
1231 frame->vec[i] = NULL;
1233 // FIXME: we should mark every reference parameter as a local. For
1234 // now we assume a conservative GC, and we assume that the
1235 // references are on the stack somewhere.
1238 NULL, // FIXME: function pointer.
1244 _Jv_JNI_PopLocalFrame (&env, NULL);
1246 while (env.locals != frame);
1254 #define NOT_IMPL NULL
1255 #define RESERVED NULL
1257 struct JNINativeInterface _Jv_JNIFunctions =
1264 _Jv_JNI_DefineClass,
1266 _Jv_JNI_FromReflectedMethod,
1267 _Jv_JNI_FromReflectedField,
1268 _Jv_JNI_ToReflectedMethod,
1269 _Jv_JNI_GetSuperclass,
1270 _Jv_JNI_IsAssignableFrom,
1271 _Jv_JNI_ToReflectedField,
1274 _Jv_JNI_ExceptionOccurred,
1275 _Jv_JNI_ExceptionDescribe,
1276 _Jv_JNI_ExceptionClear,
1279 _Jv_JNI_PushLocalFrame,
1280 _Jv_JNI_PopLocalFrame,
1281 _Jv_JNI_NewGlobalRef,
1282 _Jv_JNI_DeleteGlobalRef,
1283 _Jv_JNI_DeleteLocalRef,
1285 _Jv_JNI_IsSameObject,
1287 _Jv_JNI_NewLocalRef,
1288 _Jv_JNI_EnsureLocalCapacity,
1290 _Jv_JNI_AllocObject,
1294 _Jv_JNI_GetObjectClass,
1295 _Jv_JNI_IsInstanceOf,
1296 _Jv_JNI_GetAnyMethodID<false>,
1298 _Jv_JNI_CallMethod<jobject>,
1299 _Jv_JNI_CallMethodV<jobject>,
1300 _Jv_JNI_CallMethodA<jobject>,
1301 _Jv_JNI_CallMethod<jboolean>,
1302 _Jv_JNI_CallMethodV<jboolean>,
1303 _Jv_JNI_CallMethodA<jboolean>,
1304 _Jv_JNI_CallMethod<jbyte>,
1305 _Jv_JNI_CallMethodV<jbyte>,
1306 _Jv_JNI_CallMethodA<jbyte>,
1307 _Jv_JNI_CallMethod<jchar>,
1308 _Jv_JNI_CallMethodV<jchar>,
1309 _Jv_JNI_CallMethodA<jchar>,
1310 _Jv_JNI_CallMethod<jshort>,
1311 _Jv_JNI_CallMethodV<jshort>,
1312 _Jv_JNI_CallMethodA<jshort>,
1313 _Jv_JNI_CallMethod<jint>,
1314 _Jv_JNI_CallMethodV<jint>,
1315 _Jv_JNI_CallMethodA<jint>,
1316 _Jv_JNI_CallMethod<jlong>,
1317 _Jv_JNI_CallMethodV<jlong>,
1318 _Jv_JNI_CallMethodA<jlong>,
1319 _Jv_JNI_CallMethod<jfloat>,
1320 _Jv_JNI_CallMethodV<jfloat>,
1321 _Jv_JNI_CallMethodA<jfloat>,
1322 _Jv_JNI_CallMethod<jdouble>,
1323 _Jv_JNI_CallMethodV<jdouble>,
1324 _Jv_JNI_CallMethodA<jdouble>,
1325 _Jv_JNI_CallVoidMethod,
1326 _Jv_JNI_CallVoidMethodV,
1327 _Jv_JNI_CallVoidMethodA,
1329 // Nonvirtual method invocation functions follow.
1330 _Jv_JNI_CallAnyMethod<jobject, nonvirtual>,
1331 _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>,
1332 _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>,
1333 _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>,
1334 _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>,
1335 _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>,
1336 _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>,
1337 _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>,
1338 _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>,
1339 _Jv_JNI_CallAnyMethod<jchar, nonvirtual>,
1340 _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>,
1341 _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>,
1342 _Jv_JNI_CallAnyMethod<jshort, nonvirtual>,
1343 _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>,
1344 _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>,
1345 _Jv_JNI_CallAnyMethod<jint, nonvirtual>,
1346 _Jv_JNI_CallAnyMethodV<jint, nonvirtual>,
1347 _Jv_JNI_CallAnyMethodA<jint, nonvirtual>,
1348 _Jv_JNI_CallAnyMethod<jlong, nonvirtual>,
1349 _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>,
1350 _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>,
1351 _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>,
1352 _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>,
1353 _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>,
1354 _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>,
1355 _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>,
1356 _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>,
1357 _Jv_JNI_CallAnyVoidMethod<nonvirtual>,
1358 _Jv_JNI_CallAnyVoidMethodV<nonvirtual>,
1359 _Jv_JNI_CallAnyVoidMethodA<nonvirtual>,
1361 _Jv_JNI_GetAnyFieldID<false>,
1362 _Jv_JNI_GetField<jobject>,
1363 _Jv_JNI_GetField<jboolean>,
1364 _Jv_JNI_GetField<jbyte>,
1365 _Jv_JNI_GetField<jchar>,
1366 _Jv_JNI_GetField<jshort>,
1367 _Jv_JNI_GetField<jint>,
1368 _Jv_JNI_GetField<jlong>,
1369 _Jv_JNI_GetField<jfloat>,
1370 _Jv_JNI_GetField<jdouble>,
1380 _Jv_JNI_GetAnyMethodID<true>,
1382 _Jv_JNI_CallStaticMethod<jobject>,
1383 _Jv_JNI_CallStaticMethodV<jobject>,
1384 _Jv_JNI_CallStaticMethodA<jobject>,
1385 _Jv_JNI_CallStaticMethod<jboolean>,
1386 _Jv_JNI_CallStaticMethodV<jboolean>,
1387 _Jv_JNI_CallStaticMethodA<jboolean>,
1388 _Jv_JNI_CallStaticMethod<jbyte>,
1389 _Jv_JNI_CallStaticMethodV<jbyte>,
1390 _Jv_JNI_CallStaticMethodA<jbyte>,
1391 _Jv_JNI_CallStaticMethod<jchar>,
1392 _Jv_JNI_CallStaticMethodV<jchar>,
1393 _Jv_JNI_CallStaticMethodA<jchar>,
1394 _Jv_JNI_CallStaticMethod<jshort>,
1395 _Jv_JNI_CallStaticMethodV<jshort>,
1396 _Jv_JNI_CallStaticMethodA<jshort>,
1397 _Jv_JNI_CallStaticMethod<jint>,
1398 _Jv_JNI_CallStaticMethodV<jint>,
1399 _Jv_JNI_CallStaticMethodA<jint>,
1400 _Jv_JNI_CallStaticMethod<jlong>,
1401 _Jv_JNI_CallStaticMethodV<jlong>,
1402 _Jv_JNI_CallStaticMethodA<jlong>,
1403 _Jv_JNI_CallStaticMethod<jfloat>,
1404 _Jv_JNI_CallStaticMethodV<jfloat>,
1405 _Jv_JNI_CallStaticMethodA<jfloat>,
1406 _Jv_JNI_CallStaticMethod<jdouble>,
1407 _Jv_JNI_CallStaticMethodV<jdouble>,
1408 _Jv_JNI_CallStaticMethodA<jdouble>,
1409 _Jv_JNI_CallStaticVoidMethod,
1410 _Jv_JNI_CallStaticVoidMethodV,
1411 _Jv_JNI_CallStaticVoidMethodA,
1413 _Jv_JNI_GetAnyFieldID<true>,
1414 _Jv_JNI_GetStaticField<jobject>,
1415 _Jv_JNI_GetStaticField<jboolean>,
1416 _Jv_JNI_GetStaticField<jbyte>,
1417 _Jv_JNI_GetStaticField<jchar>,
1418 _Jv_JNI_GetStaticField<jshort>,
1419 _Jv_JNI_GetStaticField<jint>,
1420 _Jv_JNI_GetStaticField<jlong>,
1421 _Jv_JNI_GetStaticField<jfloat>,
1422 _Jv_JNI_GetStaticField<jdouble>,
1423 _Jv_JNI_SetStaticField,
1424 _Jv_JNI_SetStaticField,
1425 _Jv_JNI_SetStaticField,
1426 _Jv_JNI_SetStaticField,
1427 _Jv_JNI_SetStaticField,
1428 _Jv_JNI_SetStaticField,
1429 _Jv_JNI_SetStaticField,
1430 _Jv_JNI_SetStaticField,
1431 _Jv_JNI_SetStaticField,
1433 _Jv_JNI_GetStringLength,
1434 _Jv_JNI_GetStringChars,
1435 _Jv_JNI_ReleaseStringChars,
1436 _Jv_JNI_NewStringUTF,
1437 _Jv_JNI_GetStringUTFLength,
1438 _Jv_JNI_GetStringUTFChars,
1439 _Jv_JNI_ReleaseStringUTFChars,
1440 _Jv_JNI_GetArrayLength,
1441 _Jv_JNI_NewObjectArray,
1442 _Jv_JNI_GetObjectArrayElement,
1443 _Jv_JNI_SetObjectArrayElement,
1444 _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>,
1445 _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>,
1446 _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>,
1447 _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>,
1448 _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>,
1449 _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>,
1450 _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>,
1451 _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>,
1452 _Jv_JNI_GetPrimitiveArrayElements,
1453 _Jv_JNI_GetPrimitiveArrayElements,
1454 _Jv_JNI_GetPrimitiveArrayElements,
1455 _Jv_JNI_GetPrimitiveArrayElements,
1456 _Jv_JNI_GetPrimitiveArrayElements,
1457 _Jv_JNI_GetPrimitiveArrayElements,
1458 _Jv_JNI_GetPrimitiveArrayElements,
1459 _Jv_JNI_GetPrimitiveArrayElements,
1460 _Jv_JNI_ReleasePrimitiveArrayElements,
1461 _Jv_JNI_ReleasePrimitiveArrayElements,
1462 _Jv_JNI_ReleasePrimitiveArrayElements,
1463 _Jv_JNI_ReleasePrimitiveArrayElements,
1464 _Jv_JNI_ReleasePrimitiveArrayElements,
1465 _Jv_JNI_ReleasePrimitiveArrayElements,
1466 _Jv_JNI_ReleasePrimitiveArrayElements,
1467 _Jv_JNI_ReleasePrimitiveArrayElements,
1468 _Jv_JNI_GetPrimitiveArrayRegion,
1469 _Jv_JNI_GetPrimitiveArrayRegion,
1470 _Jv_JNI_GetPrimitiveArrayRegion,
1471 _Jv_JNI_GetPrimitiveArrayRegion,
1472 _Jv_JNI_GetPrimitiveArrayRegion,
1473 _Jv_JNI_GetPrimitiveArrayRegion,
1474 _Jv_JNI_GetPrimitiveArrayRegion,
1475 _Jv_JNI_GetPrimitiveArrayRegion,
1476 _Jv_JNI_SetPrimitiveArrayRegion,
1477 _Jv_JNI_SetPrimitiveArrayRegion,
1478 _Jv_JNI_SetPrimitiveArrayRegion,
1479 _Jv_JNI_SetPrimitiveArrayRegion,
1480 _Jv_JNI_SetPrimitiveArrayRegion,
1481 _Jv_JNI_SetPrimitiveArrayRegion,
1482 _Jv_JNI_SetPrimitiveArrayRegion,
1483 _Jv_JNI_SetPrimitiveArrayRegion,
1484 NOT_IMPL /* RegisterNatives */,
1485 NOT_IMPL /* UnregisterNatives */,
1486 _Jv_JNI_MonitorEnter,
1487 _Jv_JNI_MonitorExit,
1488 NOT_IMPL /* GetJavaVM */,
1490 _Jv_JNI_GetStringRegion,
1491 _Jv_JNI_GetStringUTFRegion,
1492 _Jv_JNI_GetPrimitiveArrayCritical,
1493 _Jv_JNI_ReleasePrimitiveArrayCritical,
1494 _Jv_JNI_GetStringCritical,
1495 _Jv_JNI_ReleaseStringCritical,
1497 NOT_IMPL /* newweakglobalref */,
1498 NOT_IMPL /* deleteweakglobalref */,
1500 _Jv_JNI_ExceptionCheck