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 #define ClassClass _CL_Q34java4lang5Class
49 extern java::lang::Class ClassClass;
50 #define ObjectClass _CL_Q34java4lang6Object
51 extern java::lang::Class ObjectClass;
53 #define MethodClass _CL_Q44java4lang7reflect6Method
54 extern java::lang::Class MethodClass;
56 // This enum is used to select different template instantiations in
57 // the invocation code.
66 // Forward declaration.
67 extern struct JNINativeInterface _Jv_JNIFunctions;
69 // Number of slots in the default frame. The VM must allow at least
73 // This structure is used to keep track of local references.
74 struct _Jv_JNI_LocalFrame
76 // This is true if this frame object represents a pushed frame (eg
77 // from PushLocalFrame).
80 // Number of elements in frame.
83 // Next frame in chain.
84 _Jv_JNI_LocalFrame *next;
86 // The elements. These are allocated using the C "struct hack".
90 // This holds a reference count for all local and global references.
91 static java::util::Hashtable *ref_table;
98 ref_table = new java::util::Hashtable;
101 // Tell the GC that a certain pointer is live.
103 mark_for_gc (jobject obj)
105 JvSynchronize sync (ref_table);
107 using namespace java::lang;
108 Integer *refcount = (Integer *) ref_table->get (obj);
109 jint val = (refcount == NULL) ? 0 : refcount->intValue ();
110 ref_table->put (obj, new Integer (val + 1));
115 unmark_for_gc (jobject obj)
117 JvSynchronize sync (ref_table);
119 using namespace java::lang;
120 Integer *refcount = (Integer *) ref_table->get (obj);
122 jint val = refcount->intValue () - 1;
124 ref_table->remove (obj);
126 ref_table->put (obj, new Integer (val));
132 _Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
139 _Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
145 _Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
147 _Jv_JNI_LocalFrame *frame;
149 for (frame = env->locals; frame != NULL; frame = frame->next)
151 for (int i = 0; i < FRAME_SIZE; ++i)
153 if (frame->vec[i] == obj)
155 frame->vec[i] = NULL;
161 // Don't go past a marked frame.
162 JvAssert (! frame->marker);
169 _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
171 // It is easier to just always allocate a new frame of the requested
172 // size. This isn't the most efficient thing, but for now we don't
173 // care. Note that _Jv_JNI_PushLocalFrame relies on this right now.
175 _Jv_JNI_LocalFrame *frame
176 = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
177 + size * sizeof (jobject));
180 // FIXME: exception processing.
181 env->ex = new java::lang::OutOfMemoryError;
185 frame->marker = true;
187 memset (&frame->vec[0], 0, size * sizeof (jobject));
188 frame->next = env->locals;
195 _Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
197 jint r = _Jv_JNI_EnsureLocalCapacity (env, size);
201 // The new frame is on top.
202 env->locals->marker = true;
208 _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
210 // Try to find an open slot somewhere in the topmost frame.
211 _Jv_JNI_LocalFrame *frame = env->locals;
212 bool done = false, set = false;
213 while (frame != NULL && ! done)
215 for (int i = 0; i < frame->size; ++i)
216 if (frame->vec[i] == NULL)
227 // No slots, so we allocate a new frame. According to the spec
228 // we could just die here. FIXME: return value.
229 _Jv_JNI_EnsureLocalCapacity (env, 16);
230 // We know the first element of the new frame will be ok.
231 env->locals->vec[0] = obj;
239 _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
241 _Jv_JNI_LocalFrame *rf = env->locals;
244 while (rf != NULL && ! done)
246 for (int i = 0; i < rf->size; ++i)
247 if (rf->vec[i] != NULL)
248 unmark_for_gc (rf->vec[i]);
250 // If the frame we just freed is the marker frame, we are done.
253 _Jv_JNI_LocalFrame *n = rf->next;
254 // When N==NULL, we've reached the stack-allocated frame, and we
255 // must not free it. However, we must be sure to clear all its
256 // elements, since we might conceivably reuse it.
259 memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
267 return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
270 // This function is used from other template functions. It wraps the
271 // return value appropriately; we specialize it so that object returns
272 // are turned into local references.
275 wrap_value (JNIEnv *, T value)
282 wrap_value (JNIEnv *env, jobject value)
284 return _Jv_JNI_NewLocalRef (env, value);
290 _Jv_JNI_GetVersion (JNIEnv *)
292 return JNI_VERSION_1_2;
296 _Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
297 const jbyte *buf, jsize bufLen)
299 jbyteArray bytes = JvNewByteArray (bufLen);
300 jbyte *elts = elements (bytes);
301 memcpy (elts, buf, bufLen * sizeof (jbyte));
303 java::lang::ClassLoader *l
304 = reinterpret_cast<java::lang::ClassLoader *> (loader);
306 // FIXME: exception processing.
307 jclass result = l->defineClass (bytes, 0, bufLen);
308 return (jclass) _Jv_JNI_NewLocalRef (env, result);
312 _Jv_JNI_FindClass (JNIEnv *env, const char *name)
314 // FIXME: assume that NAME isn't too long.
315 int len = strlen (name);
317 for (int i = 0; i <= len; ++i)
318 s[i] = (name[i] == '/') ? '.' : name[i];
319 jstring n = JvNewStringUTF (s);
321 java::lang::ClassLoader *loader;
322 if (env->klass == NULL)
324 // FIXME: should use getBaseClassLoader, but we don't have that
326 loader = java::lang::ClassLoader::getSystemClassLoader ();
329 loader = env->klass->getClassLoader ();
331 // FIXME: exception processing.
332 jclass r = loader->findClass (n);
334 return (jclass) _Jv_JNI_NewLocalRef (env, r);
338 _Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
340 return (jclass) _Jv_JNI_NewLocalRef (env, clazz->getSuperclass ());
344 _Jv_JNI_IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
346 return clazz1->isAssignableFrom (clazz2);
350 _Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
357 _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
359 using namespace java::lang::reflect;
361 JArray<jclass> *argtypes
362 = (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL);
364 jclass *elts = elements (argtypes);
365 elts[0] = &StringClass;
367 // FIXME: exception processing.
368 Constructor *cons = clazz->getConstructor (argtypes);
370 jobjectArray values = JvNewObjectArray (1, &StringClass, NULL);
371 jobject *velts = elements (values);
372 velts[0] = JvNewStringUTF (message);
374 // FIXME: exception processing.
375 jobject obj = cons->newInstance (values);
377 env->ex = reinterpret_cast<jthrowable> (obj);
382 _Jv_JNI_ExceptionOccurred (JNIEnv *env)
384 return (jthrowable) _Jv_JNI_NewLocalRef (env, env->ex);
388 _Jv_JNI_ExceptionDescribe (JNIEnv *env)
391 env->ex->printStackTrace();
395 _Jv_JNI_ExceptionClear (JNIEnv *env)
401 _Jv_JNI_ExceptionCheck (JNIEnv *env)
403 return env->ex != NULL;
407 _Jv_JNI_FatalError (JNIEnv *, const char *message)
415 _Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
421 _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
424 using namespace java::lang::reflect;
425 if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
426 env->ex = new java::lang::InstantiationException ();
429 // FIXME: exception processing.
430 // FIXME: will this work for String?
431 obj = JvAllocObject (clazz);
434 return _Jv_JNI_NewLocalRef (env, obj);
438 _Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
440 return (jclass) _Jv_JNI_NewLocalRef (env, obj->getClass());
444 _Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
446 return clazz->isInstance(obj);
452 // This section concerns method invocation.
455 template<jboolean is_static>
457 _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
458 const char *name, const char *sig)
460 // FIXME: exception processing.
461 _Jv_InitClass (clazz);
463 _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
464 _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
466 JvAssert (! clazz->isPrimitive());
468 using namespace java::lang::reflect;
470 while (clazz != NULL)
472 jint count = JvNumMethods (clazz);
473 jmethodID meth = JvGetFirstMethod (clazz);
475 for (jint i = 0; i < count; ++i)
477 if (((is_static && Modifier::isStatic (meth->accflags))
478 || (! is_static && ! Modifier::isStatic (meth->accflags)))
479 && _Jv_equalUtf8Consts (meth->name, name_u)
480 && _Jv_equalUtf8Consts (meth->signature, sig_u))
483 meth = meth->getNextMethod();
486 clazz = clazz->getSuperclass ();
489 env->ex = new java::lang::NoSuchMethodError ();
493 // This is a helper function which turns a va_list into an array of
494 // `jvalue's. It needs signature information in order to do its work.
495 // The array of values must already be allocated.
497 array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
499 jclass *arg_elts = elements (arg_types);
500 for (int i = 0; i < arg_types->length; ++i)
502 if (arg_elts[i] == JvPrimClass (byte))
503 values[i].b = va_arg (vargs, jbyte);
504 else if (arg_elts[i] == JvPrimClass (short))
505 values[i].s = va_arg (vargs, jshort);
506 else if (arg_elts[i] == JvPrimClass (int))
507 values[i].i = va_arg (vargs, jint);
508 else if (arg_elts[i] == JvPrimClass (long))
509 values[i].j = va_arg (vargs, jlong);
510 else if (arg_elts[i] == JvPrimClass (float))
511 values[i].f = va_arg (vargs, jfloat);
512 else if (arg_elts[i] == JvPrimClass (double))
513 values[i].d = va_arg (vargs, jdouble);
514 else if (arg_elts[i] == JvPrimClass (boolean))
515 values[i].z = va_arg (vargs, jboolean);
516 else if (arg_elts[i] == JvPrimClass (char))
517 values[i].c = va_arg (vargs, jchar);
521 values[i].l = va_arg (vargs, jobject);
526 // This can call any sort of method: virtual, "nonvirtual", static, or
528 template<typename T, invocation_type style>
530 _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
531 jmethodID id, va_list vargs)
534 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
536 jclass decl_class = klass ? klass : obj->getClass ();
537 JvAssert (decl_class != NULL);
540 JArray<jclass> *arg_types;
541 // FIXME: exception processing.
542 _Jv_GetTypesFromSignature (id, decl_class,
543 &arg_types, &return_type);
545 jvalue args[arg_types->length];
546 array_from_valist (args, arg_types, vargs);
549 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
550 style == constructor,
551 arg_types, args, &result);
556 // We cheat a little here. FIXME.
557 return wrap_value (env, * (T *) &result);
560 template<typename T, invocation_type style>
562 _Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass,
563 jmethodID method, ...)
568 va_start (args, method);
569 result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args);
575 template<typename T, invocation_type style>
577 _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
578 jmethodID id, jvalue *args)
581 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
583 jclass decl_class = klass ? klass : obj->getClass ();
584 JvAssert (decl_class != NULL);
587 JArray<jclass> *arg_types;
588 // FIXME: exception processing.
589 _Jv_GetTypesFromSignature (id, decl_class,
590 &arg_types, &return_type);
593 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
594 style == constructor,
595 arg_types, args, &result);
600 // We cheat a little here. FIXME.
601 return wrap_value (env, * (T *) &result);
604 template<invocation_type style>
606 _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
607 jmethodID id, va_list vargs)
610 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
612 jclass decl_class = klass ? klass : obj->getClass ();
613 JvAssert (decl_class != NULL);
616 JArray<jclass> *arg_types;
617 // FIXME: exception processing.
618 _Jv_GetTypesFromSignature (id, decl_class,
619 &arg_types, &return_type);
621 jvalue args[arg_types->length];
622 array_from_valist (args, arg_types, vargs);
624 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
625 style == constructor,
626 arg_types, args, NULL);
632 template<invocation_type style>
634 _Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass,
635 jmethodID method, ...)
639 va_start (args, method);
640 _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args);
644 template<invocation_type style>
646 _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
647 jmethodID id, jvalue *args)
650 id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
652 jclass decl_class = klass ? klass : obj->getClass ();
653 JvAssert (decl_class != NULL);
656 JArray<jclass> *arg_types;
657 // FIXME: exception processing.
658 _Jv_GetTypesFromSignature (id, decl_class,
659 &arg_types, &return_type);
661 jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
662 style == constructor,
663 arg_types, args, NULL);
669 // Functions with this signature are used to implement functions in
670 // the CallMethod family.
673 _Jv_JNI_CallMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args)
675 return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
678 // Functions with this signature are used to implement functions in
679 // the CallMethod family.
682 _Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
688 result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
694 // Functions with this signature are used to implement functions in
695 // the CallMethod family.
698 _Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
700 return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args);
704 _Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args)
706 _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
710 _Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
715 _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
720 _Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
722 _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args);
725 // Functions with this signature are used to implement functions in
726 // the CallStaticMethod family.
729 _Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
730 jmethodID id, va_list args)
732 return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args);
735 // Functions with this signature are used to implement functions in
736 // the CallStaticMethod family.
739 _Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
745 result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass,
752 // Functions with this signature are used to implement functions in
753 // the CallStaticMethod family.
756 _Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
759 return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
763 _Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, jmethodID id,
766 _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
770 _Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
775 _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
780 _Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, jmethodID id,
783 _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args);
787 _Jv_JNI_NewObjectV (JNIEnv *env, jclass klass,
788 jmethodID id, va_list args)
790 return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
795 _Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...)
801 result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
809 _Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
812 return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass,
820 _Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field)
822 T *ptr = (T *) ((char *) obj + field->getOffset ());
823 return wrap_value (env, *ptr);
828 _Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
830 T *ptr = (T *) ((char *) obj + field->getOffset ());
834 template<jboolean is_static>
836 _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
837 const char *name, const char *sig)
839 // FIXME: exception processing.
840 _Jv_InitClass (clazz);
842 _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
844 jclass field_class = NULL;
846 field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
849 _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
850 field_class = _Jv_FindClass (sig_u, NULL);
853 // FIXME: what if field_class == NULL?
855 while (clazz != NULL)
857 jint count = (is_static
858 ? JvNumStaticFields (clazz)
859 : JvNumInstanceFields (clazz));
860 jfieldID field = (is_static
861 ? JvGetFirstStaticField (clazz)
862 : JvGetFirstInstanceField (clazz));
863 for (jint i = 0; i < count; ++i)
865 // The field is resolved as a side effect of class
867 JvAssert (field->isResolved ());
869 _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);
871 if (_Jv_equalUtf8Consts (f_name, a_name)
872 && field->getClass() == field_class)
875 field = field->getNextField ();
878 clazz = clazz->getSuperclass ();
881 env->ex = new java::lang::NoSuchFieldError ();
887 _Jv_JNI_GetStaticField (JNIEnv *env, jclass, jfieldID field)
889 T *ptr = (T *) field->u.addr;
890 return wrap_value (env, *ptr);
895 _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
897 T *ptr = (T *) field->u.addr;
902 _Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
904 // FIXME: exception processing.
905 jstring r = _Jv_NewString (unichars, len);
906 return (jstring) _Jv_JNI_NewLocalRef (env, r);
910 _Jv_JNI_GetStringLength (JNIEnv *, jstring string)
912 return string->length();
916 _Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
918 jchar *result = _Jv_GetStringChars (string);
919 mark_for_gc (string);
922 return (const jchar *) result;
926 _Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
928 unmark_for_gc (string);
932 _Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
934 // FIXME: exception processing.
935 jstring result = JvNewStringUTF (bytes);
936 return (jstring) _Jv_JNI_NewLocalRef (env, result);
940 _Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
942 return JvGetStringUTFLength (string);
946 _Jv_JNI_GetStringUTFChars (JNIEnv *, jstring string, jboolean *isCopy)
948 jsize len = JvGetStringUTFLength (string);
949 // FIXME: exception processing.
950 char *r = (char *) _Jv_Malloc (len + 1);
951 JvGetStringUTFRegion (string, 0, len, r);
957 return (const char *) r;
961 _Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
963 _Jv_Free ((void *) utf);
967 _Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, jsize len,
970 jchar *result = _Jv_GetStringChars (string);
971 if (start < 0 || start > string->length ()
972 || len < 0 || start + len > string->length ())
973 env->ex = new java::lang::StringIndexOutOfBoundsException ();
975 memcpy (buf, &result[start], len * sizeof (jchar));
979 _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
980 jsize len, char *buf)
982 if (start < 0 || start > str->length ()
983 || len < 0 || start + len > str->length ())
984 env->ex = new java::lang::StringIndexOutOfBoundsException ();
986 _Jv_GetStringUTFRegion (str, start, len, buf);
990 _Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
992 jchar *result = _Jv_GetStringChars (str);
999 _Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
1005 _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
1007 return array->length;
1011 _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
1014 // FIXME: exception processing.
1015 jarray result = JvNewObjectArray (length, elementClass, init);
1016 return (jarray) _Jv_JNI_NewLocalRef (env, result);
1020 _Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
1022 jobject *elts = elements (array);
1023 return _Jv_JNI_NewLocalRef (env, elts[index]);
1027 _Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index,
1030 // FIXME: exception processing.
1031 _Jv_CheckArrayStore (array, value);
1032 jobject *elts = elements (array);
1033 elts[index] = value;
1036 template<typename T, jclass K>
1038 _Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
1040 // FIXME: exception processing.
1041 return (JArray<T> *) _Jv_JNI_NewLocalRef (env,
1042 _Jv_NewPrimArray (K, length));
1045 template<typename T>
1047 _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
1050 T *elts = elements (array);
1053 // We elect never to copy.
1056 mark_for_gc (array);
1060 template<typename T>
1062 _Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *array,
1063 T *, jint /* mode */)
1065 // Note that we ignore MODE. We can do this because we never copy
1066 // the array elements. My reading of the JNI documentation is that
1067 // this is an option for the implementor.
1068 unmark_for_gc (array);
1071 template<typename T>
1073 _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
1074 jsize start, jsize len,
1077 if (start < 0 || len >= array->length || start + len >= array->length)
1080 env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
1084 T *elts = elements (array) + start;
1085 memcpy (buf, elts, len * sizeof (T));
1089 template<typename T>
1091 _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
1092 jsize start, jsize len, T *buf)
1094 if (start < 0 || len >= array->length || start + len >= array->length)
1097 env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
1101 T *elts = elements (array) + start;
1102 memcpy (elts, buf, len * sizeof (T));
1107 _Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
1110 // FIXME: does this work?
1111 jclass klass = array->getClass()->getComponentType();
1112 JvAssert (klass->isPrimitive ());
1113 char *r = _Jv_GetArrayElementFromElementType (array, klass);
1120 _Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
1126 _Jv_JNI_MonitorEnter (JNIEnv *, jobject obj)
1128 // FIXME: exception processing.
1129 jint r = _Jv_MonitorEnter (obj);
1134 _Jv_JNI_MonitorExit (JNIEnv *, jobject obj)
1136 // FIXME: exception processing.
1137 jint r = _Jv_MonitorExit (obj);
1143 _Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
1146 // FIXME: exception processing.
1147 java::lang::reflect::Field *field = new java::lang::reflect::Field();
1148 field->declaringClass = cls;
1149 field->offset = (char*) fieldID - (char *) cls->fields;
1150 field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
1151 return _Jv_JNI_NewLocalRef (env, field);
1156 _Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
1158 using namespace java::lang::reflect;
1160 Field *field = reinterpret_cast<Field *> (f);
1161 return _Jv_FromReflectedField (field);
1165 _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
1168 using namespace java::lang::reflect;
1171 static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
1174 if (_Jv_equalUtf8Consts (id->name, init_name))
1177 Constructor *cons = new Constructor ();
1178 cons->offset = (char *) id - (char *) &klass->methods;
1179 cons->declaringClass = klass;
1184 Method *meth = new Method ();
1185 meth->offset = (char *) id - (char *) &klass->methods;
1186 meth->declaringClass = klass;
1190 return _Jv_JNI_NewLocalRef (env, result);
1194 _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
1196 using namespace java::lang::reflect;
1197 if ((&MethodClass)->isInstance (method))
1198 return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
1200 _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
1205 // This function is the stub which is used to turn an ordinary (CNI)
1206 // method call into a JNI call.
1208 template<typename T>
1210 _Jv_JNI_conversion_call (fixme)
1213 _Jv_JNI_LocalFrame *frame
1214 = (_Jv_JNI_LocalFrame *) alloca (sizeof (_Jv_JNI_LocalFrame)
1215 + FRAME_SIZE * sizeof (jobject));
1217 env.p = &_Jv_JNIFunctions;
1222 frame->marker = true;
1224 frame->size = FRAME_SIZE;
1225 for (int i = 0; i < frame->size; ++i)
1226 frame->vec[i] = NULL;
1228 T result = FIXME_ffi_call (args);
1232 _Jv_JNI_PopLocalFrame (&env, result);
1234 while (env.locals != frame);
1245 #define NOT_IMPL NULL
1246 #define RESERVED NULL
1248 struct JNINativeInterface _Jv_JNIFunctions =
1255 _Jv_JNI_DefineClass,
1257 _Jv_JNI_FromReflectedMethod,
1258 _Jv_JNI_FromReflectedField,
1259 _Jv_JNI_ToReflectedMethod,
1260 _Jv_JNI_GetSuperclass,
1261 _Jv_JNI_IsAssignableFrom,
1262 _Jv_JNI_ToReflectedField,
1265 _Jv_JNI_ExceptionOccurred,
1266 _Jv_JNI_ExceptionDescribe,
1267 _Jv_JNI_ExceptionClear,
1270 _Jv_JNI_PushLocalFrame,
1271 _Jv_JNI_PopLocalFrame,
1272 _Jv_JNI_NewGlobalRef,
1273 _Jv_JNI_DeleteGlobalRef,
1274 _Jv_JNI_DeleteLocalRef,
1276 _Jv_JNI_IsSameObject,
1278 _Jv_JNI_NewLocalRef,
1279 _Jv_JNI_EnsureLocalCapacity,
1281 _Jv_JNI_AllocObject,
1285 _Jv_JNI_GetObjectClass,
1286 _Jv_JNI_IsInstanceOf,
1287 _Jv_JNI_GetAnyMethodID<false>,
1289 _Jv_JNI_CallMethod<jobject>,
1290 _Jv_JNI_CallMethodV<jobject>,
1291 _Jv_JNI_CallMethodA<jobject>,
1292 _Jv_JNI_CallMethod<jboolean>,
1293 _Jv_JNI_CallMethodV<jboolean>,
1294 _Jv_JNI_CallMethodA<jboolean>,
1295 _Jv_JNI_CallMethod<jbyte>,
1296 _Jv_JNI_CallMethodV<jbyte>,
1297 _Jv_JNI_CallMethodA<jbyte>,
1298 _Jv_JNI_CallMethod<jchar>,
1299 _Jv_JNI_CallMethodV<jchar>,
1300 _Jv_JNI_CallMethodA<jchar>,
1301 _Jv_JNI_CallMethod<jshort>,
1302 _Jv_JNI_CallMethodV<jshort>,
1303 _Jv_JNI_CallMethodA<jshort>,
1304 _Jv_JNI_CallMethod<jint>,
1305 _Jv_JNI_CallMethodV<jint>,
1306 _Jv_JNI_CallMethodA<jint>,
1307 _Jv_JNI_CallMethod<jlong>,
1308 _Jv_JNI_CallMethodV<jlong>,
1309 _Jv_JNI_CallMethodA<jlong>,
1310 _Jv_JNI_CallMethod<jfloat>,
1311 _Jv_JNI_CallMethodV<jfloat>,
1312 _Jv_JNI_CallMethodA<jfloat>,
1313 _Jv_JNI_CallMethod<jdouble>,
1314 _Jv_JNI_CallMethodV<jdouble>,
1315 _Jv_JNI_CallMethodA<jdouble>,
1316 _Jv_JNI_CallVoidMethod,
1317 _Jv_JNI_CallVoidMethodV,
1318 _Jv_JNI_CallVoidMethodA,
1320 // Nonvirtual method invocation functions follow.
1321 _Jv_JNI_CallAnyMethod<jobject, nonvirtual>,
1322 _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>,
1323 _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>,
1324 _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>,
1325 _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>,
1326 _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>,
1327 _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>,
1328 _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>,
1329 _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>,
1330 _Jv_JNI_CallAnyMethod<jchar, nonvirtual>,
1331 _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>,
1332 _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>,
1333 _Jv_JNI_CallAnyMethod<jshort, nonvirtual>,
1334 _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>,
1335 _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>,
1336 _Jv_JNI_CallAnyMethod<jint, nonvirtual>,
1337 _Jv_JNI_CallAnyMethodV<jint, nonvirtual>,
1338 _Jv_JNI_CallAnyMethodA<jint, nonvirtual>,
1339 _Jv_JNI_CallAnyMethod<jlong, nonvirtual>,
1340 _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>,
1341 _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>,
1342 _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>,
1343 _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>,
1344 _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>,
1345 _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>,
1346 _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>,
1347 _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>,
1348 _Jv_JNI_CallAnyVoidMethod<nonvirtual>,
1349 _Jv_JNI_CallAnyVoidMethodV<nonvirtual>,
1350 _Jv_JNI_CallAnyVoidMethodA<nonvirtual>,
1352 _Jv_JNI_GetAnyFieldID<false>,
1353 _Jv_JNI_GetField<jobject>,
1354 _Jv_JNI_GetField<jboolean>,
1355 _Jv_JNI_GetField<jbyte>,
1356 _Jv_JNI_GetField<jchar>,
1357 _Jv_JNI_GetField<jshort>,
1358 _Jv_JNI_GetField<jint>,
1359 _Jv_JNI_GetField<jlong>,
1360 _Jv_JNI_GetField<jfloat>,
1361 _Jv_JNI_GetField<jdouble>,
1371 _Jv_JNI_GetAnyMethodID<true>,
1373 _Jv_JNI_CallStaticMethod<jobject>,
1374 _Jv_JNI_CallStaticMethodV<jobject>,
1375 _Jv_JNI_CallStaticMethodA<jobject>,
1376 _Jv_JNI_CallStaticMethod<jboolean>,
1377 _Jv_JNI_CallStaticMethodV<jboolean>,
1378 _Jv_JNI_CallStaticMethodA<jboolean>,
1379 _Jv_JNI_CallStaticMethod<jbyte>,
1380 _Jv_JNI_CallStaticMethodV<jbyte>,
1381 _Jv_JNI_CallStaticMethodA<jbyte>,
1382 _Jv_JNI_CallStaticMethod<jchar>,
1383 _Jv_JNI_CallStaticMethodV<jchar>,
1384 _Jv_JNI_CallStaticMethodA<jchar>,
1385 _Jv_JNI_CallStaticMethod<jshort>,
1386 _Jv_JNI_CallStaticMethodV<jshort>,
1387 _Jv_JNI_CallStaticMethodA<jshort>,
1388 _Jv_JNI_CallStaticMethod<jint>,
1389 _Jv_JNI_CallStaticMethodV<jint>,
1390 _Jv_JNI_CallStaticMethodA<jint>,
1391 _Jv_JNI_CallStaticMethod<jlong>,
1392 _Jv_JNI_CallStaticMethodV<jlong>,
1393 _Jv_JNI_CallStaticMethodA<jlong>,
1394 _Jv_JNI_CallStaticMethod<jfloat>,
1395 _Jv_JNI_CallStaticMethodV<jfloat>,
1396 _Jv_JNI_CallStaticMethodA<jfloat>,
1397 _Jv_JNI_CallStaticMethod<jdouble>,
1398 _Jv_JNI_CallStaticMethodV<jdouble>,
1399 _Jv_JNI_CallStaticMethodA<jdouble>,
1400 _Jv_JNI_CallStaticVoidMethod,
1401 _Jv_JNI_CallStaticVoidMethodV,
1402 _Jv_JNI_CallStaticVoidMethodA,
1404 _Jv_JNI_GetAnyFieldID<true>,
1405 _Jv_JNI_GetStaticField<jobject>,
1406 _Jv_JNI_GetStaticField<jboolean>,
1407 _Jv_JNI_GetStaticField<jbyte>,
1408 _Jv_JNI_GetStaticField<jchar>,
1409 _Jv_JNI_GetStaticField<jshort>,
1410 _Jv_JNI_GetStaticField<jint>,
1411 _Jv_JNI_GetStaticField<jlong>,
1412 _Jv_JNI_GetStaticField<jfloat>,
1413 _Jv_JNI_GetStaticField<jdouble>,
1414 _Jv_JNI_SetStaticField,
1415 _Jv_JNI_SetStaticField,
1416 _Jv_JNI_SetStaticField,
1417 _Jv_JNI_SetStaticField,
1418 _Jv_JNI_SetStaticField,
1419 _Jv_JNI_SetStaticField,
1420 _Jv_JNI_SetStaticField,
1421 _Jv_JNI_SetStaticField,
1422 _Jv_JNI_SetStaticField,
1424 _Jv_JNI_GetStringLength,
1425 _Jv_JNI_GetStringChars,
1426 _Jv_JNI_ReleaseStringChars,
1427 _Jv_JNI_NewStringUTF,
1428 _Jv_JNI_GetStringUTFLength,
1429 _Jv_JNI_GetStringUTFChars,
1430 _Jv_JNI_ReleaseStringUTFChars,
1431 _Jv_JNI_GetArrayLength,
1432 _Jv_JNI_NewObjectArray,
1433 _Jv_JNI_GetObjectArrayElement,
1434 _Jv_JNI_SetObjectArrayElement,
1435 _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>,
1436 _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>,
1437 _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>,
1438 _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>,
1439 _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>,
1440 _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>,
1441 _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>,
1442 _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>,
1443 _Jv_JNI_GetPrimitiveArrayElements,
1444 _Jv_JNI_GetPrimitiveArrayElements,
1445 _Jv_JNI_GetPrimitiveArrayElements,
1446 _Jv_JNI_GetPrimitiveArrayElements,
1447 _Jv_JNI_GetPrimitiveArrayElements,
1448 _Jv_JNI_GetPrimitiveArrayElements,
1449 _Jv_JNI_GetPrimitiveArrayElements,
1450 _Jv_JNI_GetPrimitiveArrayElements,
1451 _Jv_JNI_ReleasePrimitiveArrayElements,
1452 _Jv_JNI_ReleasePrimitiveArrayElements,
1453 _Jv_JNI_ReleasePrimitiveArrayElements,
1454 _Jv_JNI_ReleasePrimitiveArrayElements,
1455 _Jv_JNI_ReleasePrimitiveArrayElements,
1456 _Jv_JNI_ReleasePrimitiveArrayElements,
1457 _Jv_JNI_ReleasePrimitiveArrayElements,
1458 _Jv_JNI_ReleasePrimitiveArrayElements,
1459 _Jv_JNI_GetPrimitiveArrayRegion,
1460 _Jv_JNI_GetPrimitiveArrayRegion,
1461 _Jv_JNI_GetPrimitiveArrayRegion,
1462 _Jv_JNI_GetPrimitiveArrayRegion,
1463 _Jv_JNI_GetPrimitiveArrayRegion,
1464 _Jv_JNI_GetPrimitiveArrayRegion,
1465 _Jv_JNI_GetPrimitiveArrayRegion,
1466 _Jv_JNI_GetPrimitiveArrayRegion,
1467 _Jv_JNI_SetPrimitiveArrayRegion,
1468 _Jv_JNI_SetPrimitiveArrayRegion,
1469 _Jv_JNI_SetPrimitiveArrayRegion,
1470 _Jv_JNI_SetPrimitiveArrayRegion,
1471 _Jv_JNI_SetPrimitiveArrayRegion,
1472 _Jv_JNI_SetPrimitiveArrayRegion,
1473 _Jv_JNI_SetPrimitiveArrayRegion,
1474 _Jv_JNI_SetPrimitiveArrayRegion,
1475 NOT_IMPL /* RegisterNatives */,
1476 NOT_IMPL /* UnregisterNatives */,
1477 _Jv_JNI_MonitorEnter,
1478 _Jv_JNI_MonitorExit,
1479 NOT_IMPL /* GetJavaVM */,
1481 _Jv_JNI_GetStringRegion,
1482 _Jv_JNI_GetStringUTFRegion,
1483 _Jv_JNI_GetPrimitiveArrayCritical,
1484 _Jv_JNI_ReleasePrimitiveArrayCritical,
1485 _Jv_JNI_GetStringCritical,
1486 _Jv_JNI_ReleaseStringCritical,
1488 NOT_IMPL /* newweakglobalref */,
1489 NOT_IMPL /* deleteweakglobalref */,
1491 _Jv_JNI_ExceptionCheck