duke@435: /* coleenp@4037: * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "classfile/systemDictionary.hpp" stefank@2314: #include "classfile/vmSymbols.hpp" stefank@2314: #include "oops/instanceKlass.hpp" stefank@2314: #include "oops/oop.inline.hpp" coleenp@2497: #include "oops/symbol.hpp" stefank@2314: #include "prims/jni.h" stefank@2314: #include "prims/jniCheck.hpp" stefank@2314: #include "prims/jvm_misc.hpp" stefank@2314: #include "runtime/fieldDescriptor.hpp" stefank@2314: #include "runtime/handles.hpp" stefank@2314: #include "runtime/interfaceSupport.hpp" stefank@2314: #include "runtime/jfieldIDWorkaround.hpp" stefank@2314: #include "runtime/thread.hpp" stefank@2314: #ifdef TARGET_ARCH_x86 stefank@2314: # include "jniTypes_x86.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_sparc stefank@2314: # include "jniTypes_sparc.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_ARCH_zero stefank@2314: # include "jniTypes_zero.hpp" stefank@2314: #endif bobv@2508: #ifdef TARGET_ARCH_arm bobv@2508: # include "jniTypes_arm.hpp" bobv@2508: #endif bobv@2508: #ifdef TARGET_ARCH_ppc bobv@2508: # include "jniTypes_ppc.hpp" bobv@2508: #endif duke@435: duke@435: duke@435: // Heap objects are allowed to be directly referenced only in VM code, duke@435: // not in native code. duke@435: duke@435: #define ASSERT_OOPS_ALLOWED \ duke@435: assert(JavaThread::current()->thread_state() == _thread_in_vm, \ duke@435: "jniCheck examining oops in bad state.") duke@435: duke@435: duke@435: // Execute the given block of source code with the thread in VM state. duke@435: // To do this, transition from the NATIVE state to the VM state, execute duke@435: // the code, and transtition back. The ThreadInVMfromNative constructor duke@435: // performs the transition to VM state, its destructor restores the duke@435: // NATIVE state. duke@435: duke@435: #define IN_VM(source_code) { \ duke@435: { \ duke@435: ThreadInVMfromNative __tiv(thr); \ duke@435: source_code \ duke@435: } \ duke@435: } duke@435: duke@435: duke@435: /* duke@435: * DECLARATIONS duke@435: */ duke@435: duke@435: static struct JNINativeInterface_ * unchecked_jni_NativeInterface; duke@435: duke@435: duke@435: /* duke@435: * MACRO DEFINITIONS duke@435: */ duke@435: duke@435: // All JNI checked functions here use JNI_ENTRY_CHECKED() instead of the duke@435: // QUICK_ENTRY or LEAF variants found in jni.cpp. This allows handles duke@435: // to be created if a fatal error should occur. duke@435: duke@435: // Check for thread not attached to VM; need to catch this before duke@435: // assertions in the wrapper routines might fire duke@435: duke@435: // Check for env being the one value appropriate for this thread. duke@435: duke@435: #define JNI_ENTRY_CHECKED(result_type, header) \ duke@435: extern "C" { \ duke@435: result_type JNICALL header { \ duke@435: JavaThread* thr = (JavaThread*)ThreadLocalStorage::get_thread_slow();\ duke@435: if (thr == NULL || !thr->is_Java_thread()) { \ duke@435: tty->print_cr(fatal_using_jnienv_in_nonjava); \ duke@435: os::abort(true); \ duke@435: } \ duke@435: JNIEnv* xenv = thr->jni_environment(); \ duke@435: if (env != xenv) { \ duke@435: NativeReportJNIFatalError(thr, warn_wrong_jnienv); \ duke@435: } \ never@3241: VM_ENTRY_BASE(result_type, header, thr) duke@435: duke@435: duke@435: #define UNCHECKED() (unchecked_jni_NativeInterface) duke@435: duke@435: static const char * warn_wrong_jnienv = "Using JNIEnv in the wrong thread"; duke@435: static const char * warn_bad_class_descriptor = "JNI FindClass received a bad class descriptor \"%s\". A correct class descriptor " \ duke@435: "has no leading \"L\" or trailing \";\". Incorrect descriptors will not be accepted in future releases."; duke@435: static const char * fatal_using_jnienv_in_nonjava = "FATAL ERROR in native method: Using JNIEnv in non-Java thread"; duke@435: static const char * warn_other_function_in_critical = "Warning: Calling other JNI functions in the scope of " \ duke@435: "Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical"; duke@435: static const char * fatal_bad_ref_to_jni = "Bad global or local ref passed to JNI"; duke@435: static const char * fatal_received_null_class = "JNI received a null class"; duke@435: static const char * fatal_class_not_a_class = "JNI received a class argument that is not a class"; duke@435: static const char * fatal_class_not_a_throwable_class = "JNI Throw or ThrowNew received a class argument that is not a Throwable or Throwable subclass"; duke@435: static const char * fatal_wrong_class_or_method = "Wrong object class or methodID passed to JNI call"; dcubed@1352: static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call"; duke@435: static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations"; duke@435: static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation"; mgerdin@5418: static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation"; duke@435: static const char * fatal_non_array = "Non-array passed to JNI array operations"; duke@435: static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI"; duke@435: static const char * fatal_should_be_static = "Non-static field ID passed to JNI"; duke@435: static const char * fatal_wrong_static_field = "Wrong static field ID passed to JNI"; duke@435: static const char * fatal_static_field_not_found = "Static field not found in JNI get/set field operations"; duke@435: static const char * fatal_static_field_mismatch = "Field type (static) mismatch in JNI get/set field operations"; duke@435: static const char * fatal_should_be_nonstatic = "Static field ID passed to JNI"; duke@435: static const char * fatal_null_object = "Null object passed to JNI"; duke@435: static const char * fatal_wrong_field = "Wrong field ID passed to JNI"; duke@435: static const char * fatal_instance_field_not_found = "Instance field not found in JNI get/set field operations"; duke@435: static const char * fatal_instance_field_mismatch = "Field type (instance) mismatch in JNI get/set field operations"; duke@435: static const char * fatal_non_string = "JNI string operation received a non-string"; duke@435: duke@435: duke@435: // When in VM state: duke@435: static void ReportJNIWarning(JavaThread* thr, const char *msg) { duke@435: tty->print_cr("WARNING in native method: %s", msg); duke@435: thr->print_stack(); duke@435: } duke@435: duke@435: // When in NATIVE state: duke@435: static void NativeReportJNIFatalError(JavaThread* thr, const char *msg) { duke@435: IN_VM( duke@435: ReportJNIFatalError(thr, msg); duke@435: ) duke@435: } duke@435: duke@435: static void NativeReportJNIWarning(JavaThread* thr, const char *msg) { duke@435: IN_VM( duke@435: ReportJNIWarning(thr, msg); duke@435: ) duke@435: } duke@435: duke@435: duke@435: duke@435: duke@435: /* duke@435: * SUPPORT FUNCTIONS duke@435: */ duke@435: duke@435: static inline void duke@435: functionEnterCritical(JavaThread* thr) duke@435: { duke@435: if (thr->has_pending_exception()) { duke@435: NativeReportJNIWarning(thr, "JNI call made with exception pending"); duke@435: } duke@435: } duke@435: duke@435: static inline void duke@435: functionEnterCriticalExceptionAllowed(JavaThread* thr) duke@435: { duke@435: } duke@435: duke@435: static inline void duke@435: functionEnter(JavaThread* thr) duke@435: { duke@435: if (thr->in_critical()) { duke@435: tty->print_cr(warn_other_function_in_critical); duke@435: } duke@435: if (thr->has_pending_exception()) { duke@435: NativeReportJNIWarning(thr, "JNI call made with exception pending"); duke@435: } duke@435: } duke@435: duke@435: static inline void duke@435: functionEnterExceptionAllowed(JavaThread* thr) duke@435: { duke@435: if (thr->in_critical()) { duke@435: tty->print_cr(warn_other_function_in_critical); duke@435: } duke@435: } duke@435: duke@435: static inline void duke@435: functionExit(JNIEnv *env) duke@435: { duke@435: /* nothing to do at this time */ duke@435: } duke@435: duke@435: static inline void duke@435: checkStaticFieldID(JavaThread* thr, jfieldID fid, jclass cls, int ftype) duke@435: { duke@435: fieldDescriptor fd; duke@435: duke@435: /* make sure it is a static field */ duke@435: if (!jfieldIDWorkaround::is_static_jfieldID(fid)) duke@435: ReportJNIFatalError(thr, fatal_should_be_static); duke@435: duke@435: /* validate the class being passed */ duke@435: ASSERT_OOPS_ALLOWED; coleenp@4037: Klass* k_oop = jniCheck::validate_class(thr, cls, false); duke@435: duke@435: /* check for proper subclass hierarchy */ duke@435: JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid); coleenp@4037: Klass* f_oop = id->holder(); coleenp@4037: if (!InstanceKlass::cast(k_oop)->is_subtype_of(f_oop)) duke@435: ReportJNIFatalError(thr, fatal_wrong_static_field); duke@435: duke@435: /* check for proper field type */ never@2658: if (!id->find_local_field(&fd)) duke@435: ReportJNIFatalError(thr, fatal_static_field_not_found); duke@435: if ((fd.field_type() != ftype) && duke@435: !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) { duke@435: ReportJNIFatalError(thr, fatal_static_field_mismatch); duke@435: } duke@435: } duke@435: duke@435: static inline void duke@435: checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype) duke@435: { duke@435: fieldDescriptor fd; duke@435: duke@435: /* make sure it is an instance field */ duke@435: if (jfieldIDWorkaround::is_static_jfieldID(fid)) duke@435: ReportJNIFatalError(thr, fatal_should_be_nonstatic); duke@435: duke@435: /* validate the object being passed and then get its class */ duke@435: ASSERT_OOPS_ALLOWED; duke@435: oop oopObj = jniCheck::validate_object(thr, obj); duke@435: if (!oopObj) { duke@435: ReportJNIFatalError(thr, fatal_null_object); duke@435: } coleenp@4037: Klass* k_oop = oopObj->klass(); duke@435: duke@435: if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) { duke@435: ReportJNIFatalError(thr, fatal_wrong_field); duke@435: } duke@435: duke@435: /* make sure the field exists */ duke@435: int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid); coleenp@4037: if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset)) duke@435: ReportJNIFatalError(thr, fatal_wrong_field); duke@435: duke@435: /* check for proper field type */ coleenp@4037: if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset, duke@435: false, &fd)) duke@435: ReportJNIFatalError(thr, fatal_instance_field_not_found); duke@435: duke@435: if ((fd.field_type() != ftype) && duke@435: !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) { duke@435: ReportJNIFatalError(thr, fatal_instance_field_mismatch); duke@435: } duke@435: } duke@435: duke@435: static inline void duke@435: checkString(JavaThread* thr, jstring js) duke@435: { duke@435: ASSERT_OOPS_ALLOWED; duke@435: oop s = jniCheck::validate_object(thr, js); duke@435: if (!s || !java_lang_String::is_instance(s)) duke@435: ReportJNIFatalError(thr, fatal_non_string); duke@435: } duke@435: mgerdin@5418: static inline arrayOop mgerdin@5418: check_is_array(JavaThread* thr, jarray jArray) duke@435: { duke@435: ASSERT_OOPS_ALLOWED; duke@435: arrayOop aOop; duke@435: duke@435: aOop = (arrayOop)jniCheck::validate_object(thr, jArray); mgerdin@5418: if (aOop == NULL || !aOop->is_array()) { duke@435: ReportJNIFatalError(thr, fatal_non_array); mgerdin@5418: } mgerdin@5418: return aOop; mgerdin@5418: } duke@435: mgerdin@5418: static inline arrayOop mgerdin@5418: check_is_primitive_array(JavaThread* thr, jarray jArray) { mgerdin@5418: arrayOop aOop = check_is_array(thr, jArray); mgerdin@5418: mgerdin@5418: if (!aOop->is_typeArray()) { mgerdin@5418: ReportJNIFatalError(thr, fatal_prim_type_array_expected); mgerdin@5418: } mgerdin@5418: return aOop; mgerdin@5418: } mgerdin@5418: mgerdin@5418: static inline void mgerdin@5418: check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType) mgerdin@5418: { mgerdin@5418: BasicType array_type; mgerdin@5418: arrayOop aOop; mgerdin@5418: mgerdin@5418: aOop = check_is_primitive_array(thr, jArray); mgerdin@5418: array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); mgerdin@5418: if (array_type != elementType) { mgerdin@5418: ReportJNIFatalError(thr, fatal_element_type_mismatch); duke@435: } duke@435: } duke@435: mgerdin@5418: static inline void mgerdin@5418: check_is_obj_array(JavaThread* thr, jarray jArray) { dholmes@5423: arrayOop aOop = check_is_array(thr, jArray); dholmes@5423: if (!aOop->is_objArray()) { mgerdin@5418: ReportJNIFatalError(thr, fatal_object_array_expected); mgerdin@5418: } mgerdin@5418: } duke@435: duke@435: oop jniCheck::validate_handle(JavaThread* thr, jobject obj) { duke@435: if (JNIHandles::is_frame_handle(thr, obj) || duke@435: JNIHandles::is_local_handle(thr, obj) || duke@435: JNIHandles::is_global_handle(obj) || duke@435: JNIHandles::is_weak_global_handle(obj)) { duke@435: ASSERT_OOPS_ALLOWED; duke@435: return JNIHandles::resolve_external_guard(obj); duke@435: } duke@435: ReportJNIFatalError(thr, fatal_bad_ref_to_jni); duke@435: return NULL; duke@435: } duke@435: duke@435: coleenp@4037: Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) { duke@435: ASSERT_OOPS_ALLOWED; dcubed@1352: // do the fast jmethodID check first coleenp@4037: Method* moop = Method::checked_resolve_jmethod_id(method_id); duke@435: if (moop == NULL) { duke@435: ReportJNIFatalError(thr, fatal_wrong_class_or_method); duke@435: } coleenp@4037: // jmethodIDs are supposed to be weak handles in the class loader data, coleenp@4037: // but that can be expensive so check it last coleenp@4037: else if (!Method::is_method_id(method_id)) { dcubed@1352: ReportJNIFatalError(thr, fatal_non_weak_method); dcubed@1352: } duke@435: return moop; duke@435: } duke@435: duke@435: duke@435: oop jniCheck::validate_object(JavaThread* thr, jobject obj) { duke@435: if (!obj) duke@435: return NULL; duke@435: ASSERT_OOPS_ALLOWED; duke@435: oop oopObj = jniCheck::validate_handle(thr, obj); duke@435: if (!oopObj) { duke@435: ReportJNIFatalError(thr, fatal_bad_ref_to_jni); duke@435: } duke@435: return oopObj; duke@435: } duke@435: duke@435: // Warn if a class descriptor is in decorated form; class descriptors duke@435: // passed to JNI findClass should not be decorated unless they are duke@435: // array descriptors. duke@435: void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) { duke@435: if (name == NULL) return; // implementation accepts NULL so just return duke@435: duke@435: size_t len = strlen(name); duke@435: duke@435: if (len >= 2 && duke@435: name[0] == JVM_SIGNATURE_CLASS && // 'L' duke@435: name[len-1] == JVM_SIGNATURE_ENDCLASS ) { // ';' duke@435: char msg[JVM_MAXPATHLEN]; duke@435: jio_snprintf(msg, JVM_MAXPATHLEN, warn_bad_class_descriptor, name); duke@435: ReportJNIWarning(thr, msg); duke@435: } duke@435: } duke@435: coleenp@4037: Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) { duke@435: ASSERT_OOPS_ALLOWED; duke@435: oop mirror = jniCheck::validate_handle(thr, clazz); duke@435: if (!mirror) { duke@435: ReportJNIFatalError(thr, fatal_received_null_class); duke@435: } duke@435: never@1577: if (mirror->klass() != SystemDictionary::Class_klass()) { duke@435: ReportJNIFatalError(thr, fatal_class_not_a_class); duke@435: } duke@435: coleenp@4037: Klass* k = java_lang_Class::as_Klass(mirror); duke@435: // Make allowances for primitive classes ... duke@435: if (!(k != NULL || allow_primitive && java_lang_Class::is_primitive(mirror))) { duke@435: ReportJNIFatalError(thr, fatal_class_not_a_class); duke@435: } duke@435: return k; duke@435: } duke@435: coleenp@4037: void jniCheck::validate_throwable_klass(JavaThread* thr, Klass* klass) { duke@435: ASSERT_OOPS_ALLOWED; duke@435: assert(klass != NULL, "klass argument must have a value"); duke@435: hseigel@4278: if (!klass->oop_is_instance() || coleenp@4037: !InstanceKlass::cast(klass)->is_subclass_of(SystemDictionary::Throwable_klass())) { duke@435: ReportJNIFatalError(thr, fatal_class_not_a_throwable_class); duke@435: } duke@435: } duke@435: duke@435: void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) { duke@435: /* validate the object being passed */ duke@435: ASSERT_OOPS_ALLOWED; duke@435: jniCheck::validate_jmethod_id(thr, method_id); duke@435: jniCheck::validate_object(thr, obj); duke@435: } duke@435: duke@435: void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) { duke@435: /* validate the class being passed */ duke@435: ASSERT_OOPS_ALLOWED; duke@435: jniCheck::validate_jmethod_id(thr, method_id); duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: } duke@435: duke@435: duke@435: /* duke@435: * IMPLEMENTATION OF FUNCTIONS IN CHECKED TABLE duke@435: */ duke@435: duke@435: JNI_ENTRY_CHECKED(jclass, duke@435: checked_jni_DefineClass(JNIEnv *env, duke@435: const char *name, duke@435: jobject loader, duke@435: const jbyte *buf, duke@435: jsize len)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, loader); duke@435: ) duke@435: jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jclass, duke@435: checked_jni_FindClass(JNIEnv *env, duke@435: const char *name)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class_descriptor(thr, name); duke@435: ) duke@435: jclass result = UNCHECKED()->FindClass(env, name); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jmethodID, duke@435: checked_jni_FromReflectedMethod(JNIEnv *env, duke@435: jobject method)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, method); duke@435: ) duke@435: jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jfieldID, duke@435: checked_jni_FromReflectedField(JNIEnv *env, duke@435: jobject field)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, field); duke@435: ) duke@435: jfieldID result = UNCHECKED()->FromReflectedField(env, field); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_ToReflectedMethod(JNIEnv *env, duke@435: jclass cls, duke@435: jmethodID methodID, duke@435: jboolean isStatic)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, cls, false); duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: ) duke@435: jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, duke@435: isStatic); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jclass, duke@435: checked_jni_GetSuperclass(JNIEnv *env, duke@435: jclass sub)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, sub, true); duke@435: ) duke@435: jclass result = UNCHECKED()->GetSuperclass(env, sub); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jboolean, duke@435: checked_jni_IsAssignableFrom(JNIEnv *env, duke@435: jclass sub, duke@435: jclass sup)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, sub, true); duke@435: jniCheck::validate_class(thr, sup, true); duke@435: ) duke@435: jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_ToReflectedField(JNIEnv *env, duke@435: jclass cls, duke@435: jfieldID fieldID, duke@435: jboolean isStatic)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, cls, false); duke@435: ) duke@435: jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, duke@435: isStatic); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_Throw(JNIEnv *env, duke@435: jthrowable obj)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: oop oopObj = jniCheck::validate_object(thr, obj); duke@435: if (oopObj == NULL) { duke@435: // Unchecked Throw tolerates a NULL obj, so just warn duke@435: ReportJNIWarning(thr, "JNI Throw called with NULL throwable"); duke@435: } else { duke@435: jniCheck::validate_throwable_klass(thr, oopObj->klass()); duke@435: } duke@435: ) duke@435: jint result = UNCHECKED()->Throw(env, obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_ThrowNew(JNIEnv *env, duke@435: jclass clazz, duke@435: const char *msg)) duke@435: functionEnter(thr); duke@435: IN_VM( coleenp@4037: Klass* k = jniCheck::validate_class(thr, clazz, false); coleenp@4037: assert(k != NULL, "validate_class shouldn't return NULL Klass*"); duke@435: jniCheck::validate_throwable_klass(thr, k); duke@435: ) duke@435: jint result = UNCHECKED()->ThrowNew(env, clazz, msg); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jthrowable, duke@435: checked_jni_ExceptionOccurred(JNIEnv *env)) duke@435: functionEnterExceptionAllowed(thr); duke@435: jthrowable result = UNCHECKED()->ExceptionOccurred(env); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ExceptionDescribe(JNIEnv *env)) duke@435: functionEnterExceptionAllowed(thr); duke@435: UNCHECKED()->ExceptionDescribe(env); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ExceptionClear(JNIEnv *env)) duke@435: functionEnterExceptionAllowed(thr); duke@435: UNCHECKED()->ExceptionClear(env); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_FatalError(JNIEnv *env, duke@435: const char *msg)) duke@435: functionEnter(thr); duke@435: UNCHECKED()->FatalError(env, msg); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_PushLocalFrame(JNIEnv *env, duke@435: jint capacity)) duke@435: functionEnterExceptionAllowed(thr); duke@435: if (capacity < 0) duke@435: NativeReportJNIFatalError(thr, "negative capacity"); duke@435: jint result = UNCHECKED()->PushLocalFrame(env, capacity); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_PopLocalFrame(JNIEnv *env, duke@435: jobject result)) duke@435: functionEnterExceptionAllowed(thr); duke@435: jobject res = UNCHECKED()->PopLocalFrame(env, result); duke@435: functionExit(env); duke@435: return res; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewGlobalRef(JNIEnv *env, duke@435: jobject lobj)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: if (lobj != NULL) { duke@435: jniCheck::validate_handle(thr, lobj); duke@435: } duke@435: ) duke@435: jobject result = UNCHECKED()->NewGlobalRef(env,lobj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_DeleteGlobalRef(JNIEnv *env, duke@435: jobject gref)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, gref); duke@435: if (gref && !JNIHandles::is_global_handle(gref)) { duke@435: ReportJNIFatalError(thr, duke@435: "Invalid global JNI handle passed to DeleteGlobalRef"); duke@435: } duke@435: ) duke@435: UNCHECKED()->DeleteGlobalRef(env,gref); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_DeleteLocalRef(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: if (obj && !(JNIHandles::is_local_handle(thr, obj) || duke@435: JNIHandles::is_frame_handle(thr, obj))) duke@435: ReportJNIFatalError(thr, duke@435: "Invalid local JNI handle passed to DeleteLocalRef"); duke@435: ) duke@435: UNCHECKED()->DeleteLocalRef(env, obj); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jboolean, duke@435: checked_jni_IsSameObject(JNIEnv *env, duke@435: jobject obj1, duke@435: jobject obj2)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: /* This JNI function can be used to compare weak global references duke@435: * to NULL objects. If the handles are valid, but contain NULL, duke@435: * then don't attempt to validate the object. duke@435: */ duke@435: if (obj1 != NULL && jniCheck::validate_handle(thr, obj1) != NULL) { duke@435: jniCheck::validate_object(thr, obj1); duke@435: } duke@435: if (obj2 != NULL && jniCheck::validate_handle(thr, obj2) != NULL) { duke@435: jniCheck::validate_object(thr, obj2); duke@435: } duke@435: ) duke@435: jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewLocalRef(JNIEnv *env, duke@435: jobject ref)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: if (ref != NULL) { duke@435: jniCheck::validate_handle(thr, ref); duke@435: } duke@435: ) duke@435: jobject result = UNCHECKED()->NewLocalRef(env, ref); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_EnsureLocalCapacity(JNIEnv *env, duke@435: jint capacity)) duke@435: functionEnter(thr); duke@435: if (capacity < 0) { duke@435: NativeReportJNIFatalError(thr, "negative capacity"); duke@435: } duke@435: jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_AllocObject(JNIEnv *env, duke@435: jclass clazz)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: ) duke@435: jobject result = UNCHECKED()->AllocObject(env,clazz); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewObject(JNIEnv *env, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: ...)) duke@435: functionEnter(thr); duke@435: va_list args; duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: ) duke@435: va_start(args, methodID); duke@435: jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); duke@435: va_end(args); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewObjectV(JNIEnv *env, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: va_list args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: ) duke@435: jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewObjectA(JNIEnv *env, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: const jvalue *args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: ) duke@435: jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jclass, duke@435: checked_jni_GetObjectClass(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: ) duke@435: jclass result = UNCHECKED()->GetObjectClass(env,obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jboolean, duke@435: checked_jni_IsInstanceOf(JNIEnv *env, duke@435: jobject obj, duke@435: jclass clazz)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: jniCheck::validate_class(thr, clazz, true); duke@435: ) duke@435: jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jmethodID, duke@435: checked_jni_GetMethodID(JNIEnv *env, duke@435: jclass clazz, duke@435: const char *name, duke@435: const char *sig)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: ) duke@435: jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: #define WRAPPER_CallMethod(ResultType, Result) \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_Call##Result##Method(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jmethodID methodID, \ duke@435: ...)) \ duke@435: functionEnter(thr); \ duke@435: va_list args; \ duke@435: IN_VM( \ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: ) \ duke@435: va_start(args,methodID); \ duke@435: ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \ duke@435: args); \ duke@435: va_end(args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_Call##Result##MethodV(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jmethodID methodID, \ duke@435: va_list args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM(\ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: ) \ duke@435: ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_Call##Result##MethodA(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jmethodID methodID, \ duke@435: const jvalue * args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: ) \ duke@435: ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_CallMethod(jobject,Object) duke@435: WRAPPER_CallMethod(jboolean,Boolean) duke@435: WRAPPER_CallMethod(jbyte,Byte) duke@435: WRAPPER_CallMethod(jshort,Short) duke@435: WRAPPER_CallMethod(jchar,Char) duke@435: WRAPPER_CallMethod(jint,Int) duke@435: WRAPPER_CallMethod(jlong,Long) duke@435: WRAPPER_CallMethod(jfloat,Float) duke@435: WRAPPER_CallMethod(jdouble,Double) duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallVoidMethod(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jmethodID methodID, \ duke@435: ...)) duke@435: functionEnter(thr); duke@435: va_list args; duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: ) duke@435: va_start(args,methodID); duke@435: UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); duke@435: va_end(args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallVoidMethodV(JNIEnv *env, duke@435: jobject obj, duke@435: jmethodID methodID, duke@435: va_list args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: ) duke@435: UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallVoidMethodA(JNIEnv *env, duke@435: jobject obj, duke@435: jmethodID methodID, duke@435: const jvalue * args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: ) duke@435: UNCHECKED()->CallVoidMethodA(env,obj,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: #define WRAPPER_CallNonvirtualMethod(ResultType, Result) \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_CallNonvirtual##Result##Method(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID, \ duke@435: ...)) \ duke@435: functionEnter(thr); \ duke@435: va_list args; \ duke@435: IN_VM( \ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: jniCheck::validate_call_class(thr, clazz, methodID); \ duke@435: ) \ duke@435: va_start(args,methodID); \ duke@435: ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ duke@435: obj, \ duke@435: clazz, \ duke@435: methodID,\ duke@435: args); \ duke@435: va_end(args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_CallNonvirtual##Result##MethodV(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID, \ duke@435: va_list args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: jniCheck::validate_call_class(thr, clazz, methodID); \ duke@435: ) \ duke@435: ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ duke@435: obj, \ duke@435: clazz, \ duke@435: methodID,\ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ResultType, \ duke@435: checked_jni_CallNonvirtual##Result##MethodA(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID, \ duke@435: const jvalue * args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_call_object(thr, obj, methodID); \ duke@435: jniCheck::validate_call_class(thr, clazz, methodID); \ duke@435: ) \ duke@435: ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \ duke@435: obj, \ duke@435: clazz, \ duke@435: methodID,\ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_CallNonvirtualMethod(jobject,Object) duke@435: WRAPPER_CallNonvirtualMethod(jboolean,Boolean) duke@435: WRAPPER_CallNonvirtualMethod(jbyte,Byte) duke@435: WRAPPER_CallNonvirtualMethod(jshort,Short) duke@435: WRAPPER_CallNonvirtualMethod(jchar,Char) duke@435: WRAPPER_CallNonvirtualMethod(jint,Int) duke@435: WRAPPER_CallNonvirtualMethod(jlong,Long) duke@435: WRAPPER_CallNonvirtualMethod(jfloat,Float) duke@435: WRAPPER_CallNonvirtualMethod(jdouble,Double) duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallNonvirtualVoidMethod(JNIEnv *env, duke@435: jobject obj, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: ...)) duke@435: functionEnter(thr); duke@435: va_list args; duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: jniCheck::validate_call_class(thr, clazz, methodID); duke@435: ) duke@435: va_start(args,methodID); duke@435: UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); duke@435: va_end(args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallNonvirtualVoidMethodV(JNIEnv *env, duke@435: jobject obj, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: va_list args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: jniCheck::validate_call_class(thr, clazz, methodID); duke@435: ) duke@435: UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallNonvirtualVoidMethodA(JNIEnv *env, duke@435: jobject obj, duke@435: jclass clazz, duke@435: jmethodID methodID, duke@435: const jvalue * args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_call_object(thr, obj, methodID); duke@435: jniCheck::validate_call_class(thr, clazz, methodID); duke@435: ) duke@435: UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jfieldID, duke@435: checked_jni_GetFieldID(JNIEnv *env, duke@435: jclass clazz, duke@435: const char *name, duke@435: const char *sig)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: ) duke@435: jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: #define WRAPPER_GetField(ReturnType,Result,FieldType) \ duke@435: JNI_ENTRY_CHECKED(ReturnType, \ duke@435: checked_jni_Get##Result##Field(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jfieldID fieldID)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: checkInstanceFieldID(thr, fieldID, obj, FieldType); \ duke@435: ) \ duke@435: ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_GetField(jobject, Object, T_OBJECT) duke@435: WRAPPER_GetField(jboolean, Boolean, T_BOOLEAN) duke@435: WRAPPER_GetField(jbyte, Byte, T_BYTE) duke@435: WRAPPER_GetField(jshort, Short, T_SHORT) duke@435: WRAPPER_GetField(jchar, Char, T_CHAR) duke@435: WRAPPER_GetField(jint, Int, T_INT) duke@435: WRAPPER_GetField(jlong, Long, T_LONG) duke@435: WRAPPER_GetField(jfloat, Float, T_FLOAT) duke@435: WRAPPER_GetField(jdouble, Double, T_DOUBLE) duke@435: duke@435: #define WRAPPER_SetField(ValueType,Result,FieldType) \ duke@435: JNI_ENTRY_CHECKED(void, \ duke@435: checked_jni_Set##Result##Field(JNIEnv *env, \ duke@435: jobject obj, \ duke@435: jfieldID fieldID, \ duke@435: ValueType val)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: checkInstanceFieldID(thr, fieldID, obj, FieldType); \ duke@435: ) \ duke@435: UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \ duke@435: functionExit(env); \ duke@435: JNI_END duke@435: duke@435: WRAPPER_SetField(jobject, Object, T_OBJECT) duke@435: WRAPPER_SetField(jboolean, Boolean, T_BOOLEAN) duke@435: WRAPPER_SetField(jbyte, Byte, T_BYTE) duke@435: WRAPPER_SetField(jshort, Short, T_SHORT) duke@435: WRAPPER_SetField(jchar, Char, T_CHAR) duke@435: WRAPPER_SetField(jint, Int, T_INT) duke@435: WRAPPER_SetField(jlong, Long, T_LONG) duke@435: WRAPPER_SetField(jfloat, Float, T_FLOAT) duke@435: WRAPPER_SetField(jdouble, Double, T_DOUBLE) duke@435: duke@435: duke@435: JNI_ENTRY_CHECKED(jmethodID, duke@435: checked_jni_GetStaticMethodID(JNIEnv *env, duke@435: jclass clazz, duke@435: const char *name, duke@435: const char *sig)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: ) duke@435: jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: #define WRAPPER_CallStaticMethod(ReturnType,Result) \ duke@435: JNI_ENTRY_CHECKED(ReturnType, \ duke@435: checked_jni_CallStatic##Result##Method(JNIEnv *env, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID, \ duke@435: ...)) \ duke@435: functionEnter(thr); \ duke@435: va_list args; \ duke@435: IN_VM( \ duke@435: jniCheck::validate_jmethod_id(thr, methodID); \ duke@435: jniCheck::validate_class(thr, clazz, false); \ duke@435: ) \ duke@435: va_start(args,methodID); \ duke@435: ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ duke@435: clazz, \ duke@435: methodID, \ duke@435: args); \ duke@435: va_end(args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ReturnType, \ duke@435: checked_jni_CallStatic##Result##MethodV(JNIEnv *env, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID,\ duke@435: va_list args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_jmethod_id(thr, methodID); \ duke@435: jniCheck::validate_class(thr, clazz, false); \ duke@435: ) \ duke@435: ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ duke@435: clazz, \ duke@435: methodID, \ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END \ duke@435: \ duke@435: JNI_ENTRY_CHECKED(ReturnType, \ duke@435: checked_jni_CallStatic##Result##MethodA(JNIEnv *env, \ duke@435: jclass clazz, \ duke@435: jmethodID methodID, \ duke@435: const jvalue *args)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_jmethod_id(thr, methodID); \ duke@435: jniCheck::validate_class(thr, clazz, false); \ duke@435: ) \ duke@435: ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \ duke@435: clazz, \ duke@435: methodID, \ duke@435: args); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_CallStaticMethod(jobject,Object) duke@435: WRAPPER_CallStaticMethod(jboolean,Boolean) duke@435: WRAPPER_CallStaticMethod(jbyte,Byte) duke@435: WRAPPER_CallStaticMethod(jshort,Short) duke@435: WRAPPER_CallStaticMethod(jchar,Char) duke@435: WRAPPER_CallStaticMethod(jint,Int) duke@435: WRAPPER_CallStaticMethod(jlong,Long) duke@435: WRAPPER_CallStaticMethod(jfloat,Float) duke@435: WRAPPER_CallStaticMethod(jdouble,Double) duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallStaticVoidMethod(JNIEnv *env, duke@435: jclass cls, duke@435: jmethodID methodID, duke@435: ...)) duke@435: functionEnter(thr); duke@435: va_list args; duke@435: IN_VM( duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: jniCheck::validate_class(thr, cls, false); duke@435: ) duke@435: va_start(args,methodID); duke@435: UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); duke@435: va_end(args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallStaticVoidMethodV(JNIEnv *env, duke@435: jclass cls, duke@435: jmethodID methodID, duke@435: va_list args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: jniCheck::validate_class(thr, cls, false); duke@435: ) duke@435: UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_CallStaticVoidMethodA(JNIEnv *env, duke@435: jclass cls, duke@435: jmethodID methodID, duke@435: const jvalue * args)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_jmethod_id(thr, methodID); duke@435: jniCheck::validate_class(thr, cls, false); duke@435: ) duke@435: UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jfieldID, duke@435: checked_jni_GetStaticFieldID(JNIEnv *env, duke@435: jclass clazz, duke@435: const char *name, duke@435: const char *sig)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_class(thr, clazz, false); duke@435: ) duke@435: jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: #define WRAPPER_GetStaticField(ReturnType,Result,FieldType) \ duke@435: JNI_ENTRY_CHECKED(ReturnType, \ duke@435: checked_jni_GetStatic##Result##Field(JNIEnv *env, \ duke@435: jclass clazz, \ duke@435: jfieldID fieldID)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_class(thr, clazz, false); \ duke@435: checkStaticFieldID(thr, fieldID, clazz, FieldType); \ duke@435: ) \ duke@435: ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ duke@435: clazz, \ duke@435: fieldID); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_GetStaticField(jobject, Object, T_OBJECT) duke@435: WRAPPER_GetStaticField(jboolean, Boolean, T_BOOLEAN) duke@435: WRAPPER_GetStaticField(jbyte, Byte, T_BYTE) duke@435: WRAPPER_GetStaticField(jshort, Short, T_SHORT) duke@435: WRAPPER_GetStaticField(jchar, Char, T_CHAR) duke@435: WRAPPER_GetStaticField(jint, Int, T_INT) duke@435: WRAPPER_GetStaticField(jlong, Long, T_LONG) duke@435: WRAPPER_GetStaticField(jfloat, Float, T_FLOAT) duke@435: WRAPPER_GetStaticField(jdouble, Double, T_DOUBLE) duke@435: duke@435: #define WRAPPER_SetStaticField(ValueType,Result,FieldType) \ duke@435: JNI_ENTRY_CHECKED(void, \ duke@435: checked_jni_SetStatic##Result##Field(JNIEnv *env, \ duke@435: jclass clazz, \ duke@435: jfieldID fieldID, \ duke@435: ValueType value)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ duke@435: jniCheck::validate_class(thr, clazz, false); \ duke@435: checkStaticFieldID(thr, fieldID, clazz, FieldType); \ duke@435: ) \ duke@435: UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \ duke@435: functionExit(env); \ duke@435: JNI_END duke@435: duke@435: WRAPPER_SetStaticField(jobject, Object, T_OBJECT) duke@435: WRAPPER_SetStaticField(jboolean, Boolean, T_BOOLEAN) duke@435: WRAPPER_SetStaticField(jbyte, Byte, T_BYTE) duke@435: WRAPPER_SetStaticField(jshort, Short, T_SHORT) duke@435: WRAPPER_SetStaticField(jchar, Char, T_CHAR) duke@435: WRAPPER_SetStaticField(jint, Int, T_INT) duke@435: WRAPPER_SetStaticField(jlong, Long, T_LONG) duke@435: WRAPPER_SetStaticField(jfloat, Float, T_FLOAT) duke@435: WRAPPER_SetStaticField(jdouble, Double, T_DOUBLE) duke@435: duke@435: duke@435: JNI_ENTRY_CHECKED(jstring, duke@435: checked_jni_NewString(JNIEnv *env, duke@435: const jchar *unicode, duke@435: jsize len)) duke@435: functionEnter(thr); duke@435: jstring result = UNCHECKED()->NewString(env,unicode,len); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jsize, duke@435: checked_jni_GetStringLength(JNIEnv *env, duke@435: jstring str)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: jsize result = UNCHECKED()->GetStringLength(env,str); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: sla@2331: // Arbitrary (but well-known) tag sla@2331: const jint STRING_TAG = 0x47114711; sla@2331: duke@435: JNI_ENTRY_CHECKED(const jchar *, duke@435: checked_jni_GetStringChars(JNIEnv *env, duke@435: jstring str, duke@435: jboolean *isCopy)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy); sla@2331: assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected"); sla@2331: sla@2331: size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination zgu@3900: jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal); sla@2331: *tagLocation = STRING_TAG; sla@2331: jchar* newResult = (jchar*) (tagLocation + 1); sla@2331: memcpy(newResult, result, len * sizeof(jchar)); sla@2331: // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes sla@2331: // Note that the dtrace arguments for the allocated memory will not match up with this solution. sla@2331: FreeHeap((char*)result); sla@2331: duke@435: functionExit(env); sla@2331: return newResult; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ReleaseStringChars(JNIEnv *env, duke@435: jstring str, duke@435: const jchar *chars)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) sla@2331: if (chars == NULL) { sla@2331: // still do the unchecked call to allow dtrace probes sla@2331: UNCHECKED()->ReleaseStringChars(env,str,chars); sla@2331: } sla@2331: else { sla@2331: jint* tagLocation = ((jint*) chars) - 1; sla@2331: if (*tagLocation != STRING_TAG) { sla@2331: NativeReportJNIFatalError(thr, "ReleaseStringChars called on something not allocated by GetStringChars"); sla@2331: } sla@2331: UNCHECKED()->ReleaseStringChars(env,str,(const jchar*)tagLocation); sla@2331: } duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jstring, duke@435: checked_jni_NewStringUTF(JNIEnv *env, duke@435: const char *utf)) duke@435: functionEnter(thr); duke@435: jstring result = UNCHECKED()->NewStringUTF(env,utf); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jsize, duke@435: checked_jni_GetStringUTFLength(JNIEnv *env, duke@435: jstring str)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: jsize result = UNCHECKED()->GetStringUTFLength(env,str); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: sla@2331: // Arbitrary (but well-known) tag - different than GetStringChars sla@2331: const jint STRING_UTF_TAG = 0x48124812; sla@2331: duke@435: JNI_ENTRY_CHECKED(const char *, duke@435: checked_jni_GetStringUTFChars(JNIEnv *env, duke@435: jstring str, duke@435: jboolean *isCopy)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy); sla@2331: assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected"); sla@2331: sla@2331: size_t len = strlen(result) + 1; // + 1 for NULL termination zgu@3900: jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal); sla@2331: *tagLocation = STRING_UTF_TAG; sla@2331: char* newResult = (char*) (tagLocation + 1); sla@2331: strcpy(newResult, result); sla@2331: // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes sla@2331: // Note that the dtrace arguments for the allocated memory will not match up with this solution. zgu@3900: FreeHeap((char*)result, mtInternal); sla@2331: duke@435: functionExit(env); sla@2331: return newResult; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ReleaseStringUTFChars(JNIEnv *env, duke@435: jstring str, duke@435: const char* chars)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) sla@2331: if (chars == NULL) { sla@2331: // still do the unchecked call to allow dtrace probes sla@2331: UNCHECKED()->ReleaseStringUTFChars(env,str,chars); sla@2331: } sla@2331: else { sla@2331: jint* tagLocation = ((jint*) chars) - 1; sla@2331: if (*tagLocation != STRING_UTF_TAG) { sla@2331: NativeReportJNIFatalError(thr, "ReleaseStringUTFChars called on something not allocated by GetStringUTFChars"); sla@2331: } sla@2331: UNCHECKED()->ReleaseStringUTFChars(env,str,(const char*)tagLocation); sla@2331: } duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jsize, duke@435: checked_jni_GetArrayLength(JNIEnv *env, duke@435: jarray array)) duke@435: functionEnter(thr); duke@435: IN_VM( mgerdin@5418: check_is_array(thr, array); duke@435: ) duke@435: jsize result = UNCHECKED()->GetArrayLength(env,array); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobjectArray, duke@435: checked_jni_NewObjectArray(JNIEnv *env, duke@435: jsize len, duke@435: jclass clazz, duke@435: jobject init)) duke@435: functionEnter(thr); duke@435: jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_GetObjectArrayElement(JNIEnv *env, duke@435: jobjectArray array, duke@435: jsize index)) duke@435: functionEnter(thr); duke@435: IN_VM( mgerdin@5418: check_is_obj_array(thr, array); duke@435: ) duke@435: jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_SetObjectArrayElement(JNIEnv *env, duke@435: jobjectArray array, duke@435: jsize index, duke@435: jobject val)) duke@435: functionEnter(thr); duke@435: IN_VM( mgerdin@5418: check_is_obj_array(thr, array); duke@435: ) duke@435: UNCHECKED()->SetObjectArrayElement(env,array,index,val); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: #define WRAPPER_NewScalarArray(Return, Result) \ duke@435: JNI_ENTRY_CHECKED(Return, \ duke@435: checked_jni_New##Result##Array(JNIEnv *env, \ duke@435: jsize len)) \ duke@435: functionEnter(thr); \ duke@435: Return result = UNCHECKED()->New##Result##Array(env,len); \ duke@435: functionExit(env); \ duke@435: return (Return) result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_NewScalarArray(jbooleanArray, Boolean) duke@435: WRAPPER_NewScalarArray(jbyteArray, Byte) duke@435: WRAPPER_NewScalarArray(jshortArray, Short) duke@435: WRAPPER_NewScalarArray(jcharArray, Char) duke@435: WRAPPER_NewScalarArray(jintArray, Int) duke@435: WRAPPER_NewScalarArray(jlongArray, Long) duke@435: WRAPPER_NewScalarArray(jfloatArray, Float) duke@435: WRAPPER_NewScalarArray(jdoubleArray, Double) duke@435: duke@435: #define WRAPPER_GetScalarArrayElements(ElementTag,ElementType,Result) \ duke@435: JNI_ENTRY_CHECKED(ElementType *, \ duke@435: checked_jni_Get##Result##ArrayElements(JNIEnv *env, \ duke@435: ElementType##Array array, \ duke@435: jboolean *isCopy)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ mgerdin@5418: check_primitive_array_type(thr, array, ElementTag); \ duke@435: ) \ duke@435: ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \ duke@435: array, \ duke@435: isCopy); \ duke@435: functionExit(env); \ duke@435: return result; \ duke@435: JNI_END duke@435: duke@435: WRAPPER_GetScalarArrayElements(T_BOOLEAN, jboolean, Boolean) duke@435: WRAPPER_GetScalarArrayElements(T_BYTE, jbyte, Byte) duke@435: WRAPPER_GetScalarArrayElements(T_SHORT, jshort, Short) duke@435: WRAPPER_GetScalarArrayElements(T_CHAR, jchar, Char) duke@435: WRAPPER_GetScalarArrayElements(T_INT, jint, Int) duke@435: WRAPPER_GetScalarArrayElements(T_LONG, jlong, Long) duke@435: WRAPPER_GetScalarArrayElements(T_FLOAT, jfloat, Float) duke@435: WRAPPER_GetScalarArrayElements(T_DOUBLE, jdouble, Double) duke@435: duke@435: #define WRAPPER_ReleaseScalarArrayElements(ElementTag,ElementType,Result,Tag) \ duke@435: JNI_ENTRY_CHECKED(void, \ duke@435: checked_jni_Release##Result##ArrayElements(JNIEnv *env, \ duke@435: ElementType##Array array, \ duke@435: ElementType *elems, \ duke@435: jint mode)) \ duke@435: functionEnterExceptionAllowed(thr); \ duke@435: IN_VM( \ mgerdin@5418: check_primitive_array_type(thr, array, ElementTag); \ duke@435: ASSERT_OOPS_ALLOWED; \ duke@435: typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ duke@435: /* cannot check validity of copy, unless every request is logged by duke@435: * checking code. Implementation of this check is deferred until a duke@435: * subsequent release. duke@435: */ \ duke@435: ) \ duke@435: UNCHECKED()->Release##Result##ArrayElements(env,array,elems,mode); \ duke@435: functionExit(env); \ duke@435: JNI_END duke@435: duke@435: WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool) duke@435: WRAPPER_ReleaseScalarArrayElements(T_BYTE, jbyte, Byte, byte) duke@435: WRAPPER_ReleaseScalarArrayElements(T_SHORT, jshort, Short, short) duke@435: WRAPPER_ReleaseScalarArrayElements(T_CHAR, jchar, Char, char) duke@435: WRAPPER_ReleaseScalarArrayElements(T_INT, jint, Int, int) duke@435: WRAPPER_ReleaseScalarArrayElements(T_LONG, jlong, Long, long) duke@435: WRAPPER_ReleaseScalarArrayElements(T_FLOAT, jfloat, Float, float) duke@435: WRAPPER_ReleaseScalarArrayElements(T_DOUBLE, jdouble, Double, double) duke@435: duke@435: #define WRAPPER_GetScalarArrayRegion(ElementTag,ElementType,Result) \ duke@435: JNI_ENTRY_CHECKED(void, \ duke@435: checked_jni_Get##Result##ArrayRegion(JNIEnv *env, \ duke@435: ElementType##Array array, \ duke@435: jsize start, \ duke@435: jsize len, \ duke@435: ElementType *buf)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ mgerdin@5418: check_primitive_array_type(thr, array, ElementTag); \ duke@435: ) \ duke@435: UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ duke@435: functionExit(env); \ duke@435: JNI_END duke@435: duke@435: WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) duke@435: WRAPPER_GetScalarArrayRegion(T_BYTE, jbyte, Byte) duke@435: WRAPPER_GetScalarArrayRegion(T_SHORT, jshort, Short) duke@435: WRAPPER_GetScalarArrayRegion(T_CHAR, jchar, Char) duke@435: WRAPPER_GetScalarArrayRegion(T_INT, jint, Int) duke@435: WRAPPER_GetScalarArrayRegion(T_LONG, jlong, Long) duke@435: WRAPPER_GetScalarArrayRegion(T_FLOAT, jfloat, Float) duke@435: WRAPPER_GetScalarArrayRegion(T_DOUBLE, jdouble, Double) duke@435: duke@435: #define WRAPPER_SetScalarArrayRegion(ElementTag,ElementType,Result) \ duke@435: JNI_ENTRY_CHECKED(void, \ duke@435: checked_jni_Set##Result##ArrayRegion(JNIEnv *env, \ duke@435: ElementType##Array array, \ duke@435: jsize start, \ duke@435: jsize len, \ duke@435: const ElementType *buf)) \ duke@435: functionEnter(thr); \ duke@435: IN_VM( \ mgerdin@5418: check_primitive_array_type(thr, array, ElementTag); \ duke@435: ) \ duke@435: UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ duke@435: functionExit(env); \ duke@435: JNI_END duke@435: duke@435: WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) duke@435: WRAPPER_SetScalarArrayRegion(T_BYTE, jbyte, Byte) duke@435: WRAPPER_SetScalarArrayRegion(T_SHORT, jshort, Short) duke@435: WRAPPER_SetScalarArrayRegion(T_CHAR, jchar, Char) duke@435: WRAPPER_SetScalarArrayRegion(T_INT, jint, Int) duke@435: WRAPPER_SetScalarArrayRegion(T_LONG, jlong, Long) duke@435: WRAPPER_SetScalarArrayRegion(T_FLOAT, jfloat, Float) duke@435: WRAPPER_SetScalarArrayRegion(T_DOUBLE, jdouble, Double) duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_RegisterNatives(JNIEnv *env, duke@435: jclass clazz, duke@435: const JNINativeMethod *methods, duke@435: jint nMethods)) duke@435: functionEnter(thr); duke@435: jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_UnregisterNatives(JNIEnv *env, duke@435: jclass clazz)) duke@435: functionEnter(thr); duke@435: jint result = UNCHECKED()->UnregisterNatives(env,clazz); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_MonitorEnter(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: ) duke@435: jint result = UNCHECKED()->MonitorEnter(env,obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_MonitorExit(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnterExceptionAllowed(thr); duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: ) duke@435: jint result = UNCHECKED()->MonitorExit(env,obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_GetJavaVM(JNIEnv *env, duke@435: JavaVM **vm)) duke@435: functionEnter(thr); duke@435: jint result = UNCHECKED()->GetJavaVM(env,vm); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_GetStringRegion(JNIEnv *env, duke@435: jstring str, duke@435: jsize start, duke@435: jsize len, duke@435: jchar *buf)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: UNCHECKED()->GetStringRegion(env, str, start, len, buf); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_GetStringUTFRegion(JNIEnv *env, duke@435: jstring str, duke@435: jsize start, duke@435: jsize len, duke@435: char *buf)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void *, duke@435: checked_jni_GetPrimitiveArrayCritical(JNIEnv *env, duke@435: jarray array, duke@435: jboolean *isCopy)) duke@435: functionEnterCritical(thr); duke@435: IN_VM( mgerdin@5418: check_is_primitive_array(thr, array); duke@435: ) duke@435: void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ReleasePrimitiveArrayCritical(JNIEnv *env, duke@435: jarray array, duke@435: void *carray, duke@435: jint mode)) duke@435: functionEnterCriticalExceptionAllowed(thr); duke@435: IN_VM( mgerdin@5418: check_is_primitive_array(thr, array); duke@435: ) duke@435: /* The Hotspot JNI code does not use the parameters, so just check the duke@435: * array parameter as a minor sanity check duke@435: */ duke@435: UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, carray, mode); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(const jchar*, duke@435: checked_jni_GetStringCritical(JNIEnv *env, duke@435: jstring string, duke@435: jboolean *isCopy)) duke@435: functionEnterCritical(thr); duke@435: IN_VM( duke@435: checkString(thr, string); duke@435: ) duke@435: const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_ReleaseStringCritical(JNIEnv *env, duke@435: jstring str, duke@435: const jchar *chars)) duke@435: functionEnterCriticalExceptionAllowed(thr); duke@435: IN_VM( duke@435: checkString(thr, str); duke@435: ) duke@435: /* The Hotspot JNI code does not use the parameters, so just check the duke@435: * string parameter as a minor sanity check duke@435: */ duke@435: UNCHECKED()->ReleaseStringCritical(env, str, chars); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jweak, duke@435: checked_jni_NewWeakGlobalRef(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnter(thr); duke@435: IN_VM( duke@435: if (obj != NULL) { duke@435: jniCheck::validate_handle(thr, obj); duke@435: } duke@435: ) duke@435: jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void, duke@435: checked_jni_DeleteWeakGlobalRef(JNIEnv *env, duke@435: jweak ref)) duke@435: functionEnterExceptionAllowed(thr); duke@435: UNCHECKED()->DeleteWeakGlobalRef(env, ref); duke@435: functionExit(env); duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jboolean, duke@435: checked_jni_ExceptionCheck(JNIEnv *env)) duke@435: functionEnterExceptionAllowed(thr); duke@435: jboolean result = UNCHECKED()->ExceptionCheck(env); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobject, duke@435: checked_jni_NewDirectByteBuffer(JNIEnv *env, duke@435: void *address, duke@435: jlong capacity)) duke@435: functionEnter(thr); duke@435: jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(void *, duke@435: checked_jni_GetDirectBufferAddress(JNIEnv *env, duke@435: jobject buf)) duke@435: functionEnter(thr); duke@435: void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jlong, duke@435: checked_jni_GetDirectBufferCapacity(JNIEnv *env, duke@435: jobject buf)) duke@435: functionEnter(thr); duke@435: jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: JNI_ENTRY_CHECKED(jobjectRefType, duke@435: checked_jni_GetObjectRefType(JNIEnv *env, duke@435: jobject obj)) duke@435: functionEnter(thr); duke@435: /* validate the object being passed */ duke@435: IN_VM( duke@435: jniCheck::validate_object(thr, obj); duke@435: ) duke@435: jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: duke@435: JNI_ENTRY_CHECKED(jint, duke@435: checked_jni_GetVersion(JNIEnv *env)) duke@435: functionEnter(thr); duke@435: jint result = UNCHECKED()->GetVersion(env); duke@435: functionExit(env); duke@435: return result; duke@435: JNI_END duke@435: duke@435: duke@435: duke@435: /* duke@435: * Structure containing all checked jni functions duke@435: */ duke@435: struct JNINativeInterface_ checked_jni_NativeInterface = { duke@435: NULL, duke@435: NULL, duke@435: NULL, duke@435: duke@435: NULL, duke@435: duke@435: checked_jni_GetVersion, duke@435: duke@435: checked_jni_DefineClass, duke@435: checked_jni_FindClass, duke@435: duke@435: checked_jni_FromReflectedMethod, duke@435: checked_jni_FromReflectedField, duke@435: duke@435: checked_jni_ToReflectedMethod, duke@435: duke@435: checked_jni_GetSuperclass, duke@435: checked_jni_IsAssignableFrom, duke@435: duke@435: checked_jni_ToReflectedField, duke@435: duke@435: checked_jni_Throw, duke@435: checked_jni_ThrowNew, duke@435: checked_jni_ExceptionOccurred, duke@435: checked_jni_ExceptionDescribe, duke@435: checked_jni_ExceptionClear, duke@435: checked_jni_FatalError, duke@435: duke@435: checked_jni_PushLocalFrame, duke@435: checked_jni_PopLocalFrame, duke@435: duke@435: checked_jni_NewGlobalRef, duke@435: checked_jni_DeleteGlobalRef, duke@435: checked_jni_DeleteLocalRef, duke@435: checked_jni_IsSameObject, duke@435: duke@435: checked_jni_NewLocalRef, duke@435: checked_jni_EnsureLocalCapacity, duke@435: duke@435: checked_jni_AllocObject, duke@435: checked_jni_NewObject, duke@435: checked_jni_NewObjectV, duke@435: checked_jni_NewObjectA, duke@435: duke@435: checked_jni_GetObjectClass, duke@435: checked_jni_IsInstanceOf, duke@435: duke@435: checked_jni_GetMethodID, duke@435: duke@435: checked_jni_CallObjectMethod, duke@435: checked_jni_CallObjectMethodV, duke@435: checked_jni_CallObjectMethodA, duke@435: checked_jni_CallBooleanMethod, duke@435: checked_jni_CallBooleanMethodV, duke@435: checked_jni_CallBooleanMethodA, duke@435: checked_jni_CallByteMethod, duke@435: checked_jni_CallByteMethodV, duke@435: checked_jni_CallByteMethodA, duke@435: checked_jni_CallCharMethod, duke@435: checked_jni_CallCharMethodV, duke@435: checked_jni_CallCharMethodA, duke@435: checked_jni_CallShortMethod, duke@435: checked_jni_CallShortMethodV, duke@435: checked_jni_CallShortMethodA, duke@435: checked_jni_CallIntMethod, duke@435: checked_jni_CallIntMethodV, duke@435: checked_jni_CallIntMethodA, duke@435: checked_jni_CallLongMethod, duke@435: checked_jni_CallLongMethodV, duke@435: checked_jni_CallLongMethodA, duke@435: checked_jni_CallFloatMethod, duke@435: checked_jni_CallFloatMethodV, duke@435: checked_jni_CallFloatMethodA, duke@435: checked_jni_CallDoubleMethod, duke@435: checked_jni_CallDoubleMethodV, duke@435: checked_jni_CallDoubleMethodA, duke@435: checked_jni_CallVoidMethod, duke@435: checked_jni_CallVoidMethodV, duke@435: checked_jni_CallVoidMethodA, duke@435: duke@435: checked_jni_CallNonvirtualObjectMethod, duke@435: checked_jni_CallNonvirtualObjectMethodV, duke@435: checked_jni_CallNonvirtualObjectMethodA, duke@435: checked_jni_CallNonvirtualBooleanMethod, duke@435: checked_jni_CallNonvirtualBooleanMethodV, duke@435: checked_jni_CallNonvirtualBooleanMethodA, duke@435: checked_jni_CallNonvirtualByteMethod, duke@435: checked_jni_CallNonvirtualByteMethodV, duke@435: checked_jni_CallNonvirtualByteMethodA, duke@435: checked_jni_CallNonvirtualCharMethod, duke@435: checked_jni_CallNonvirtualCharMethodV, duke@435: checked_jni_CallNonvirtualCharMethodA, duke@435: checked_jni_CallNonvirtualShortMethod, duke@435: checked_jni_CallNonvirtualShortMethodV, duke@435: checked_jni_CallNonvirtualShortMethodA, duke@435: checked_jni_CallNonvirtualIntMethod, duke@435: checked_jni_CallNonvirtualIntMethodV, duke@435: checked_jni_CallNonvirtualIntMethodA, duke@435: checked_jni_CallNonvirtualLongMethod, duke@435: checked_jni_CallNonvirtualLongMethodV, duke@435: checked_jni_CallNonvirtualLongMethodA, duke@435: checked_jni_CallNonvirtualFloatMethod, duke@435: checked_jni_CallNonvirtualFloatMethodV, duke@435: checked_jni_CallNonvirtualFloatMethodA, duke@435: checked_jni_CallNonvirtualDoubleMethod, duke@435: checked_jni_CallNonvirtualDoubleMethodV, duke@435: checked_jni_CallNonvirtualDoubleMethodA, duke@435: checked_jni_CallNonvirtualVoidMethod, duke@435: checked_jni_CallNonvirtualVoidMethodV, duke@435: checked_jni_CallNonvirtualVoidMethodA, duke@435: duke@435: checked_jni_GetFieldID, duke@435: duke@435: checked_jni_GetObjectField, duke@435: checked_jni_GetBooleanField, duke@435: checked_jni_GetByteField, duke@435: checked_jni_GetCharField, duke@435: checked_jni_GetShortField, duke@435: checked_jni_GetIntField, duke@435: checked_jni_GetLongField, duke@435: checked_jni_GetFloatField, duke@435: checked_jni_GetDoubleField, duke@435: duke@435: checked_jni_SetObjectField, duke@435: checked_jni_SetBooleanField, duke@435: checked_jni_SetByteField, duke@435: checked_jni_SetCharField, duke@435: checked_jni_SetShortField, duke@435: checked_jni_SetIntField, duke@435: checked_jni_SetLongField, duke@435: checked_jni_SetFloatField, duke@435: checked_jni_SetDoubleField, duke@435: duke@435: checked_jni_GetStaticMethodID, duke@435: duke@435: checked_jni_CallStaticObjectMethod, duke@435: checked_jni_CallStaticObjectMethodV, duke@435: checked_jni_CallStaticObjectMethodA, duke@435: checked_jni_CallStaticBooleanMethod, duke@435: checked_jni_CallStaticBooleanMethodV, duke@435: checked_jni_CallStaticBooleanMethodA, duke@435: checked_jni_CallStaticByteMethod, duke@435: checked_jni_CallStaticByteMethodV, duke@435: checked_jni_CallStaticByteMethodA, duke@435: checked_jni_CallStaticCharMethod, duke@435: checked_jni_CallStaticCharMethodV, duke@435: checked_jni_CallStaticCharMethodA, duke@435: checked_jni_CallStaticShortMethod, duke@435: checked_jni_CallStaticShortMethodV, duke@435: checked_jni_CallStaticShortMethodA, duke@435: checked_jni_CallStaticIntMethod, duke@435: checked_jni_CallStaticIntMethodV, duke@435: checked_jni_CallStaticIntMethodA, duke@435: checked_jni_CallStaticLongMethod, duke@435: checked_jni_CallStaticLongMethodV, duke@435: checked_jni_CallStaticLongMethodA, duke@435: checked_jni_CallStaticFloatMethod, duke@435: checked_jni_CallStaticFloatMethodV, duke@435: checked_jni_CallStaticFloatMethodA, duke@435: checked_jni_CallStaticDoubleMethod, duke@435: checked_jni_CallStaticDoubleMethodV, duke@435: checked_jni_CallStaticDoubleMethodA, duke@435: checked_jni_CallStaticVoidMethod, duke@435: checked_jni_CallStaticVoidMethodV, duke@435: checked_jni_CallStaticVoidMethodA, duke@435: duke@435: checked_jni_GetStaticFieldID, duke@435: duke@435: checked_jni_GetStaticObjectField, duke@435: checked_jni_GetStaticBooleanField, duke@435: checked_jni_GetStaticByteField, duke@435: checked_jni_GetStaticCharField, duke@435: checked_jni_GetStaticShortField, duke@435: checked_jni_GetStaticIntField, duke@435: checked_jni_GetStaticLongField, duke@435: checked_jni_GetStaticFloatField, duke@435: checked_jni_GetStaticDoubleField, duke@435: duke@435: checked_jni_SetStaticObjectField, duke@435: checked_jni_SetStaticBooleanField, duke@435: checked_jni_SetStaticByteField, duke@435: checked_jni_SetStaticCharField, duke@435: checked_jni_SetStaticShortField, duke@435: checked_jni_SetStaticIntField, duke@435: checked_jni_SetStaticLongField, duke@435: checked_jni_SetStaticFloatField, duke@435: checked_jni_SetStaticDoubleField, duke@435: duke@435: checked_jni_NewString, duke@435: checked_jni_GetStringLength, duke@435: checked_jni_GetStringChars, duke@435: checked_jni_ReleaseStringChars, duke@435: duke@435: checked_jni_NewStringUTF, duke@435: checked_jni_GetStringUTFLength, duke@435: checked_jni_GetStringUTFChars, duke@435: checked_jni_ReleaseStringUTFChars, duke@435: duke@435: checked_jni_GetArrayLength, duke@435: duke@435: checked_jni_NewObjectArray, duke@435: checked_jni_GetObjectArrayElement, duke@435: checked_jni_SetObjectArrayElement, duke@435: duke@435: checked_jni_NewBooleanArray, duke@435: checked_jni_NewByteArray, duke@435: checked_jni_NewCharArray, duke@435: checked_jni_NewShortArray, duke@435: checked_jni_NewIntArray, duke@435: checked_jni_NewLongArray, duke@435: checked_jni_NewFloatArray, duke@435: checked_jni_NewDoubleArray, duke@435: duke@435: checked_jni_GetBooleanArrayElements, duke@435: checked_jni_GetByteArrayElements, duke@435: checked_jni_GetCharArrayElements, duke@435: checked_jni_GetShortArrayElements, duke@435: checked_jni_GetIntArrayElements, duke@435: checked_jni_GetLongArrayElements, duke@435: checked_jni_GetFloatArrayElements, duke@435: checked_jni_GetDoubleArrayElements, duke@435: duke@435: checked_jni_ReleaseBooleanArrayElements, duke@435: checked_jni_ReleaseByteArrayElements, duke@435: checked_jni_ReleaseCharArrayElements, duke@435: checked_jni_ReleaseShortArrayElements, duke@435: checked_jni_ReleaseIntArrayElements, duke@435: checked_jni_ReleaseLongArrayElements, duke@435: checked_jni_ReleaseFloatArrayElements, duke@435: checked_jni_ReleaseDoubleArrayElements, duke@435: duke@435: checked_jni_GetBooleanArrayRegion, duke@435: checked_jni_GetByteArrayRegion, duke@435: checked_jni_GetCharArrayRegion, duke@435: checked_jni_GetShortArrayRegion, duke@435: checked_jni_GetIntArrayRegion, duke@435: checked_jni_GetLongArrayRegion, duke@435: checked_jni_GetFloatArrayRegion, duke@435: checked_jni_GetDoubleArrayRegion, duke@435: duke@435: checked_jni_SetBooleanArrayRegion, duke@435: checked_jni_SetByteArrayRegion, duke@435: checked_jni_SetCharArrayRegion, duke@435: checked_jni_SetShortArrayRegion, duke@435: checked_jni_SetIntArrayRegion, duke@435: checked_jni_SetLongArrayRegion, duke@435: checked_jni_SetFloatArrayRegion, duke@435: checked_jni_SetDoubleArrayRegion, duke@435: duke@435: checked_jni_RegisterNatives, duke@435: checked_jni_UnregisterNatives, duke@435: duke@435: checked_jni_MonitorEnter, duke@435: checked_jni_MonitorExit, duke@435: duke@435: checked_jni_GetJavaVM, duke@435: duke@435: checked_jni_GetStringRegion, duke@435: checked_jni_GetStringUTFRegion, duke@435: duke@435: checked_jni_GetPrimitiveArrayCritical, duke@435: checked_jni_ReleasePrimitiveArrayCritical, duke@435: duke@435: checked_jni_GetStringCritical, duke@435: checked_jni_ReleaseStringCritical, duke@435: duke@435: checked_jni_NewWeakGlobalRef, duke@435: checked_jni_DeleteWeakGlobalRef, duke@435: duke@435: checked_jni_ExceptionCheck, duke@435: duke@435: checked_jni_NewDirectByteBuffer, duke@435: checked_jni_GetDirectBufferAddress, duke@435: checked_jni_GetDirectBufferCapacity, duke@435: duke@435: // New 1.6 Features duke@435: duke@435: checked_jni_GetObjectRefType duke@435: }; duke@435: duke@435: duke@435: // Returns the function structure duke@435: struct JNINativeInterface_* jni_functions_check() { duke@435: duke@435: unchecked_jni_NativeInterface = jni_functions_nocheck(); duke@435: duke@435: // make sure the last pointer in the checked table is not null, indicating duke@435: // an addition to the JNINativeInterface_ structure without initializing duke@435: // it in the checked table. duke@435: debug_only(int *lastPtr = (int *)((char *)&checked_jni_NativeInterface + \ duke@435: sizeof(*unchecked_jni_NativeInterface) - sizeof(char *));) duke@435: assert(*lastPtr != 0, duke@435: "Mismatched JNINativeInterface tables, check for new entries"); duke@435: duke@435: // with -verbose:jni this message will print duke@435: if (PrintJNIResolving) { duke@435: tty->print_cr("Checked JNI functions are being used to " \ duke@435: "validate JNI usage"); duke@435: } duke@435: duke@435: return &checked_jni_NativeInterface; duke@435: }