1 | /* |
2 | * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "jni.h" |
27 | #include "jvm.h" |
28 | #include "classfile/javaClasses.inline.hpp" |
29 | #include "classfile/systemDictionary.hpp" |
30 | #include "classfile/vmSymbols.hpp" |
31 | #include "memory/allocation.inline.hpp" |
32 | #include "memory/guardedMemory.hpp" |
33 | #include "oops/instanceKlass.hpp" |
34 | #include "oops/oop.inline.hpp" |
35 | #include "oops/symbol.hpp" |
36 | #include "prims/jniCheck.hpp" |
37 | #include "prims/jvm_misc.hpp" |
38 | #include "runtime/fieldDescriptor.inline.hpp" |
39 | #include "runtime/handles.inline.hpp" |
40 | #include "runtime/interfaceSupport.inline.hpp" |
41 | #include "runtime/jfieldIDWorkaround.hpp" |
42 | #include "runtime/jniHandles.inline.hpp" |
43 | #include "runtime/thread.inline.hpp" |
44 | |
45 | // Complain every extra number of unplanned local refs |
46 | #define CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD 32 |
47 | |
48 | // Heap objects are allowed to be directly referenced only in VM code, |
49 | // not in native code. |
50 | |
51 | #define ASSERT_OOPS_ALLOWED \ |
52 | assert(JavaThread::current()->thread_state() == _thread_in_vm, \ |
53 | "jniCheck examining oops in bad state.") |
54 | |
55 | |
56 | // Execute the given block of source code with the thread in VM state. |
57 | // To do this, transition from the NATIVE state to the VM state, execute |
58 | // the code, and transtition back. The ThreadInVMfromNative constructor |
59 | // performs the transition to VM state, its destructor restores the |
60 | // NATIVE state. |
61 | |
62 | #define IN_VM(source_code) { \ |
63 | { \ |
64 | ThreadInVMfromNative __tiv(thr); \ |
65 | source_code \ |
66 | } \ |
67 | } |
68 | |
69 | |
70 | /* |
71 | * DECLARATIONS |
72 | */ |
73 | |
74 | static struct JNINativeInterface_ * unchecked_jni_NativeInterface; |
75 | |
76 | |
77 | /* |
78 | * MACRO DEFINITIONS |
79 | */ |
80 | |
81 | // All JNI checked functions here use JNI_ENTRY_CHECKED() instead of the |
82 | // QUICK_ENTRY or LEAF variants found in jni.cpp. This allows handles |
83 | // to be created if a fatal error should occur. |
84 | |
85 | // Check for thread not attached to VM; need to catch this before |
86 | // assertions in the wrapper routines might fire |
87 | |
88 | // Check for env being the one value appropriate for this thread. |
89 | |
90 | #define JNI_ENTRY_CHECKED(result_type, header) \ |
91 | extern "C" { \ |
92 | result_type JNICALL header { \ |
93 | JavaThread* thr = (JavaThread*) Thread::current_or_null(); \ |
94 | if (thr == NULL || !thr->is_Java_thread()) { \ |
95 | tty->print_cr("%s", fatal_using_jnienv_in_nonjava); \ |
96 | os::abort(true); \ |
97 | } \ |
98 | JNIEnv* xenv = thr->jni_environment(); \ |
99 | if (env != xenv) { \ |
100 | NativeReportJNIFatalError(thr, warn_wrong_jnienv); \ |
101 | } \ |
102 | VM_ENTRY_BASE(result_type, header, thr) |
103 | |
104 | |
105 | #define UNCHECKED() (unchecked_jni_NativeInterface) |
106 | |
107 | static const char * warn_wrong_jnienv = "Using JNIEnv in the wrong thread" ; |
108 | static const char * warn_bad_class_descriptor1 = "JNI FindClass received a bad class descriptor \"" ; |
109 | static const char * warn_bad_class_descriptor2 = "\". A correct class descriptor " \ |
110 | "has no leading \"L\" or trailing \";\". Incorrect descriptors will not be accepted in future releases." ; |
111 | static const char * fatal_using_jnienv_in_nonjava = "FATAL ERROR in native method: Using JNIEnv in non-Java thread" ; |
112 | static const char * warn_other_function_in_critical = "Warning: Calling other JNI functions in the scope of " \ |
113 | "Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical" ; |
114 | static const char * fatal_bad_ref_to_jni = "Bad global or local ref passed to JNI" ; |
115 | static const char * fatal_received_null_class = "JNI received a null class" ; |
116 | static const char * fatal_class_not_a_class = "JNI received a class argument that is not a class" ; |
117 | 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" ; |
118 | static const char * fatal_wrong_class_or_method = "Wrong object class or methodID passed to JNI call" ; |
119 | static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call" ; |
120 | static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations" ; |
121 | static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation" ; |
122 | static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation" ; |
123 | static const char * fatal_non_array = "Non-array passed to JNI array operations" ; |
124 | static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI" ; |
125 | static const char * fatal_should_be_static = "Non-static field ID passed to JNI" ; |
126 | static const char * fatal_wrong_static_field = "Wrong static field ID passed to JNI" ; |
127 | static const char * fatal_static_field_not_found = "Static field not found in JNI get/set field operations" ; |
128 | static const char * fatal_static_field_mismatch = "Field type (static) mismatch in JNI get/set field operations" ; |
129 | static const char * fatal_should_be_nonstatic = "Static field ID passed to JNI" ; |
130 | static const char * fatal_null_object = "Null object passed to JNI" ; |
131 | static const char * fatal_wrong_field = "Wrong field ID passed to JNI" ; |
132 | static const char * fatal_instance_field_not_found = "Instance field not found in JNI get/set field operations" ; |
133 | static const char * fatal_instance_field_mismatch = "Field type (instance) mismatch in JNI get/set field operations" ; |
134 | static const char * fatal_non_string = "JNI string operation received a non-string" ; |
135 | |
136 | |
137 | // When in VM state: |
138 | static void ReportJNIWarning(JavaThread* thr, const char *msg) { |
139 | tty->print_cr("WARNING in native method: %s" , msg); |
140 | thr->print_stack(); |
141 | } |
142 | |
143 | // When in NATIVE state: |
144 | static void NativeReportJNIFatalError(JavaThread* thr, const char *msg) { |
145 | IN_VM( |
146 | ReportJNIFatalError(thr, msg); |
147 | ) |
148 | } |
149 | |
150 | static void NativeReportJNIWarning(JavaThread* thr, const char *msg) { |
151 | IN_VM( |
152 | ReportJNIWarning(thr, msg); |
153 | ) |
154 | } |
155 | |
156 | |
157 | |
158 | |
159 | /* |
160 | * SUPPORT FUNCTIONS |
161 | */ |
162 | |
163 | /** |
164 | * Check whether or not a programmer has actually checked for exceptions. According |
165 | * to the JNI Specification ("jni/spec/design.html#java_exceptions"): |
166 | * |
167 | * There are two cases where the programmer needs to check for exceptions without |
168 | * being able to first check an error code: |
169 | * |
170 | * - The JNI functions that invoke a Java method return the result of the Java method. |
171 | * The programmer must call ExceptionOccurred() to check for possible exceptions |
172 | * that occurred during the execution of the Java method. |
173 | * |
174 | * - Some of the JNI array access functions do not return an error code, but may |
175 | * throw an ArrayIndexOutOfBoundsException or ArrayStoreException. |
176 | * |
177 | * In all other cases, a non-error return value guarantees that no exceptions have been thrown. |
178 | * |
179 | * Programmers often defend against ArrayIndexOutOfBoundsException, so warning |
180 | * for these functions would be pedantic. |
181 | */ |
182 | static inline void |
183 | check_pending_exception(JavaThread* thr) { |
184 | if (thr->has_pending_exception()) { |
185 | NativeReportJNIWarning(thr, "JNI call made with exception pending" ); |
186 | } |
187 | if (thr->is_pending_jni_exception_check()) { |
188 | IN_VM( |
189 | tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s" , |
190 | thr->get_pending_jni_exception_check()); |
191 | thr->print_stack(); |
192 | ) |
193 | thr->clear_pending_jni_exception_check(); // Just complain once |
194 | } |
195 | } |
196 | |
197 | /** |
198 | * Add to the planned number of handles. I.e. plus current live & warning threshold |
199 | */ |
200 | static inline void |
201 | add_planned_handle_capacity(JNIHandleBlock* handles, size_t capacity) { |
202 | handles->set_planned_capacity(capacity + |
203 | handles->get_number_of_live_handles() + |
204 | CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD); |
205 | } |
206 | |
207 | |
208 | static inline void |
209 | functionEnterCritical(JavaThread* thr) |
210 | { |
211 | check_pending_exception(thr); |
212 | } |
213 | |
214 | static inline void |
215 | functionEnterCriticalExceptionAllowed(JavaThread* thr) |
216 | { |
217 | } |
218 | |
219 | static inline void |
220 | functionEnter(JavaThread* thr) |
221 | { |
222 | if (thr->in_critical()) { |
223 | tty->print_cr("%s" , warn_other_function_in_critical); |
224 | } |
225 | check_pending_exception(thr); |
226 | } |
227 | |
228 | static inline void |
229 | functionEnterExceptionAllowed(JavaThread* thr) |
230 | { |
231 | if (thr->in_critical()) { |
232 | tty->print_cr("%s" , warn_other_function_in_critical); |
233 | } |
234 | } |
235 | |
236 | static inline void |
237 | functionExit(JavaThread* thr) |
238 | { |
239 | JNIHandleBlock* handles = thr->active_handles(); |
240 | size_t planned_capacity = handles->get_planned_capacity(); |
241 | size_t live_handles = handles->get_number_of_live_handles(); |
242 | if (live_handles > planned_capacity) { |
243 | IN_VM( |
244 | tty->print_cr("WARNING: JNI local refs: " SIZE_FORMAT ", exceeds capacity: " SIZE_FORMAT, |
245 | live_handles, planned_capacity); |
246 | thr->print_stack(); |
247 | ) |
248 | // Complain just the once, reset to current + warn threshold |
249 | add_planned_handle_capacity(handles, 0); |
250 | } |
251 | } |
252 | |
253 | static inline void |
254 | checkStaticFieldID(JavaThread* thr, jfieldID fid, jclass cls, int ftype) |
255 | { |
256 | fieldDescriptor fd; |
257 | |
258 | /* make sure it is a static field */ |
259 | if (!jfieldIDWorkaround::is_static_jfieldID(fid)) |
260 | ReportJNIFatalError(thr, fatal_should_be_static); |
261 | |
262 | /* validate the class being passed */ |
263 | ASSERT_OOPS_ALLOWED; |
264 | Klass* k_oop = jniCheck::validate_class(thr, cls, false); |
265 | |
266 | /* check for proper subclass hierarchy */ |
267 | JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid); |
268 | Klass* f_oop = id->holder(); |
269 | if (!InstanceKlass::cast(k_oop)->is_subtype_of(f_oop)) |
270 | ReportJNIFatalError(thr, fatal_wrong_static_field); |
271 | |
272 | /* check for proper field type */ |
273 | if (!id->find_local_field(&fd)) |
274 | ReportJNIFatalError(thr, fatal_static_field_not_found); |
275 | if ((fd.field_type() != ftype) && |
276 | !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) { |
277 | ReportJNIFatalError(thr, fatal_static_field_mismatch); |
278 | } |
279 | } |
280 | |
281 | static inline void |
282 | checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype) |
283 | { |
284 | fieldDescriptor fd; |
285 | |
286 | /* make sure it is an instance field */ |
287 | if (jfieldIDWorkaround::is_static_jfieldID(fid)) |
288 | ReportJNIFatalError(thr, fatal_should_be_nonstatic); |
289 | |
290 | /* validate the object being passed and then get its class */ |
291 | ASSERT_OOPS_ALLOWED; |
292 | oop oopObj = jniCheck::validate_object(thr, obj); |
293 | if (oopObj == NULL) { |
294 | ReportJNIFatalError(thr, fatal_null_object); |
295 | } |
296 | Klass* k_oop = oopObj->klass(); |
297 | |
298 | if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) { |
299 | ReportJNIFatalError(thr, fatal_wrong_field); |
300 | } |
301 | |
302 | /* make sure the field exists */ |
303 | int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid); |
304 | if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset)) |
305 | ReportJNIFatalError(thr, fatal_wrong_field); |
306 | |
307 | /* check for proper field type */ |
308 | if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset, |
309 | false, &fd)) |
310 | ReportJNIFatalError(thr, fatal_instance_field_not_found); |
311 | |
312 | if ((fd.field_type() != ftype) && |
313 | !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) { |
314 | ReportJNIFatalError(thr, fatal_instance_field_mismatch); |
315 | } |
316 | } |
317 | |
318 | static inline void |
319 | checkString(JavaThread* thr, jstring js) |
320 | { |
321 | ASSERT_OOPS_ALLOWED; |
322 | oop s = jniCheck::validate_object(thr, js); |
323 | if ((s == NULL) || !java_lang_String::is_instance(s)) |
324 | ReportJNIFatalError(thr, fatal_non_string); |
325 | } |
326 | |
327 | static inline arrayOop |
328 | check_is_array(JavaThread* thr, jarray jArray) |
329 | { |
330 | ASSERT_OOPS_ALLOWED; |
331 | arrayOop aOop; |
332 | |
333 | aOop = (arrayOop)jniCheck::validate_object(thr, jArray); |
334 | if (aOop == NULL || !aOop->is_array()) { |
335 | ReportJNIFatalError(thr, fatal_non_array); |
336 | } |
337 | return aOop; |
338 | } |
339 | |
340 | static inline arrayOop |
341 | check_is_primitive_array(JavaThread* thr, jarray jArray) { |
342 | arrayOop aOop = check_is_array(thr, jArray); |
343 | |
344 | if (!aOop->is_typeArray()) { |
345 | ReportJNIFatalError(thr, fatal_prim_type_array_expected); |
346 | } |
347 | return aOop; |
348 | } |
349 | |
350 | static inline void |
351 | check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType) |
352 | { |
353 | BasicType array_type; |
354 | arrayOop aOop; |
355 | |
356 | aOop = check_is_primitive_array(thr, jArray); |
357 | array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); |
358 | if (array_type != elementType) { |
359 | ReportJNIFatalError(thr, fatal_element_type_mismatch); |
360 | } |
361 | } |
362 | |
363 | static inline void |
364 | check_is_obj_array(JavaThread* thr, jarray jArray) { |
365 | arrayOop aOop = check_is_array(thr, jArray); |
366 | if (!aOop->is_objArray()) { |
367 | ReportJNIFatalError(thr, fatal_object_array_expected); |
368 | } |
369 | } |
370 | |
371 | /* |
372 | * Copy and wrap array elements for bounds checking. |
373 | * Remember the original elements (GuardedMemory::get_tag()) |
374 | */ |
375 | static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array, |
376 | void* orig_elements) { |
377 | void* result; |
378 | IN_VM( |
379 | oop a = JNIHandles::resolve_non_null(array); |
380 | size_t len = arrayOop(a)->length() << |
381 | TypeArrayKlass::cast(a->klass())->log2_element_size(); |
382 | result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements); |
383 | ) |
384 | return result; |
385 | } |
386 | |
387 | static void* check_wrapped_array(JavaThread* thr, const char* fn_name, |
388 | void* obj, void* carray, size_t* rsz) { |
389 | if (carray == NULL) { |
390 | tty->print_cr("%s: elements vector NULL" PTR_FORMAT, fn_name, p2i(obj)); |
391 | NativeReportJNIFatalError(thr, "Elements vector NULL" ); |
392 | } |
393 | GuardedMemory guarded(carray); |
394 | void* orig_result = guarded.get_tag(); |
395 | if (!guarded.verify_guards()) { |
396 | tty->print_cr("ReleasePrimitiveArrayCritical: release array failed bounds " |
397 | "check, incorrect pointer returned ? array: " PTR_FORMAT " carray: " |
398 | PTR_FORMAT, p2i(obj), p2i(carray)); |
399 | guarded.print_on(tty); |
400 | NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: " |
401 | "failed bounds check" ); |
402 | } |
403 | if (orig_result == NULL) { |
404 | tty->print_cr("ReleasePrimitiveArrayCritical: unrecognized elements. array: " |
405 | PTR_FORMAT " carray: " PTR_FORMAT, p2i(obj), p2i(carray)); |
406 | guarded.print_on(tty); |
407 | NativeReportJNIFatalError(thr, "ReleasePrimitiveArrayCritical: " |
408 | "unrecognized elements" ); |
409 | } |
410 | if (rsz != NULL) { |
411 | *rsz = guarded.get_user_size(); |
412 | } |
413 | return orig_result; |
414 | } |
415 | |
416 | static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name, |
417 | void* obj, void* carray, jint mode) { |
418 | size_t sz; |
419 | void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz); |
420 | switch (mode) { |
421 | // As we never make copies, mode 0 and JNI_COMMIT are the same. |
422 | case 0: |
423 | case JNI_COMMIT: |
424 | memcpy(orig_result, carray, sz); |
425 | break; |
426 | case JNI_ABORT: |
427 | break; |
428 | default: |
429 | tty->print_cr("%s: Unrecognized mode %i releasing array " |
430 | PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray)); |
431 | NativeReportJNIFatalError(thr, "Unrecognized array release mode" ); |
432 | } |
433 | // We always need to release the copy we made with GuardedMemory |
434 | GuardedMemory::free_copy(carray); |
435 | return orig_result; |
436 | } |
437 | |
438 | oop jniCheck::validate_handle(JavaThread* thr, jobject obj) { |
439 | if ((obj != NULL) && (JNIHandles::handle_type(thr, obj) != JNIInvalidRefType)) { |
440 | ASSERT_OOPS_ALLOWED; |
441 | return JNIHandles::resolve_external_guard(obj); |
442 | } |
443 | ReportJNIFatalError(thr, fatal_bad_ref_to_jni); |
444 | return NULL; |
445 | } |
446 | |
447 | |
448 | Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) { |
449 | ASSERT_OOPS_ALLOWED; |
450 | // do the fast jmethodID check first |
451 | Method* moop = Method::checked_resolve_jmethod_id(method_id); |
452 | if (moop == NULL) { |
453 | ReportJNIFatalError(thr, fatal_wrong_class_or_method); |
454 | } |
455 | // jmethodIDs are supposed to be weak handles in the class loader data, |
456 | // but that can be expensive so check it last |
457 | else if (!Method::is_method_id(method_id)) { |
458 | ReportJNIFatalError(thr, fatal_non_weak_method); |
459 | } |
460 | return moop; |
461 | } |
462 | |
463 | |
464 | oop jniCheck::validate_object(JavaThread* thr, jobject obj) { |
465 | if (obj == NULL) return NULL; |
466 | ASSERT_OOPS_ALLOWED; |
467 | oop oopObj = jniCheck::validate_handle(thr, obj); |
468 | if (oopObj == NULL) { |
469 | ReportJNIFatalError(thr, fatal_bad_ref_to_jni); |
470 | } |
471 | return oopObj; |
472 | } |
473 | |
474 | // Warn if a class descriptor is in decorated form; class descriptors |
475 | // passed to JNI findClass should not be decorated unless they are |
476 | // array descriptors. |
477 | void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) { |
478 | if (name == NULL) return; // implementation accepts NULL so just return |
479 | |
480 | size_t len = strlen(name); |
481 | |
482 | if (len >= 2 && |
483 | name[0] == JVM_SIGNATURE_CLASS && // 'L' |
484 | name[len-1] == JVM_SIGNATURE_ENDCLASS ) { // ';' |
485 | char msg[JVM_MAXPATHLEN]; |
486 | jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s" , |
487 | warn_bad_class_descriptor1, name, warn_bad_class_descriptor2); |
488 | ReportJNIWarning(thr, msg); |
489 | } |
490 | } |
491 | |
492 | Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) { |
493 | ASSERT_OOPS_ALLOWED; |
494 | oop mirror = jniCheck::validate_handle(thr, clazz); |
495 | if (mirror == NULL) { |
496 | ReportJNIFatalError(thr, fatal_received_null_class); |
497 | } |
498 | |
499 | if (mirror->klass() != SystemDictionary::Class_klass()) { |
500 | ReportJNIFatalError(thr, fatal_class_not_a_class); |
501 | } |
502 | |
503 | Klass* k = java_lang_Class::as_Klass(mirror); |
504 | // Make allowances for primitive classes ... |
505 | if (!(k != NULL || (allow_primitive && java_lang_Class::is_primitive(mirror)))) { |
506 | ReportJNIFatalError(thr, fatal_class_not_a_class); |
507 | } |
508 | return k; |
509 | } |
510 | |
511 | void jniCheck::validate_throwable_klass(JavaThread* thr, Klass* klass) { |
512 | ASSERT_OOPS_ALLOWED; |
513 | assert(klass != NULL, "klass argument must have a value" ); |
514 | |
515 | if (!klass->is_instance_klass() || |
516 | !InstanceKlass::cast(klass)->is_subclass_of(SystemDictionary::Throwable_klass())) { |
517 | ReportJNIFatalError(thr, fatal_class_not_a_throwable_class); |
518 | } |
519 | } |
520 | |
521 | void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) { |
522 | /* validate the object being passed */ |
523 | ASSERT_OOPS_ALLOWED; |
524 | jniCheck::validate_jmethod_id(thr, method_id); |
525 | jniCheck::validate_object(thr, obj); |
526 | } |
527 | |
528 | void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) { |
529 | /* validate the class being passed */ |
530 | ASSERT_OOPS_ALLOWED; |
531 | jniCheck::validate_jmethod_id(thr, method_id); |
532 | jniCheck::validate_class(thr, clazz, false); |
533 | } |
534 | |
535 | |
536 | /* |
537 | * IMPLEMENTATION OF FUNCTIONS IN CHECKED TABLE |
538 | */ |
539 | |
540 | JNI_ENTRY_CHECKED(jclass, |
541 | checked_jni_DefineClass(JNIEnv *env, |
542 | const char *name, |
543 | jobject loader, |
544 | const jbyte *buf, |
545 | jsize len)) |
546 | functionEnter(thr); |
547 | IN_VM( |
548 | jniCheck::validate_object(thr, loader); |
549 | ) |
550 | jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len); |
551 | functionExit(thr); |
552 | return result; |
553 | JNI_END |
554 | |
555 | JNI_ENTRY_CHECKED(jclass, |
556 | checked_jni_FindClass(JNIEnv *env, |
557 | const char *name)) |
558 | functionEnter(thr); |
559 | IN_VM( |
560 | jniCheck::validate_class_descriptor(thr, name); |
561 | ) |
562 | jclass result = UNCHECKED()->FindClass(env, name); |
563 | functionExit(thr); |
564 | return result; |
565 | JNI_END |
566 | |
567 | JNI_ENTRY_CHECKED(jmethodID, |
568 | checked_jni_FromReflectedMethod(JNIEnv *env, |
569 | jobject method)) |
570 | functionEnter(thr); |
571 | IN_VM( |
572 | jniCheck::validate_object(thr, method); |
573 | ) |
574 | jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); |
575 | functionExit(thr); |
576 | return result; |
577 | JNI_END |
578 | |
579 | JNI_ENTRY_CHECKED(jfieldID, |
580 | checked_jni_FromReflectedField(JNIEnv *env, |
581 | jobject field)) |
582 | functionEnter(thr); |
583 | IN_VM( |
584 | jniCheck::validate_object(thr, field); |
585 | ) |
586 | jfieldID result = UNCHECKED()->FromReflectedField(env, field); |
587 | functionExit(thr); |
588 | return result; |
589 | JNI_END |
590 | |
591 | JNI_ENTRY_CHECKED(jobject, |
592 | checked_jni_ToReflectedMethod(JNIEnv *env, |
593 | jclass cls, |
594 | jmethodID methodID, |
595 | jboolean isStatic)) |
596 | functionEnter(thr); |
597 | IN_VM( |
598 | jniCheck::validate_class(thr, cls, false); |
599 | jniCheck::validate_jmethod_id(thr, methodID); |
600 | ) |
601 | jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, |
602 | isStatic); |
603 | functionExit(thr); |
604 | return result; |
605 | JNI_END |
606 | |
607 | JNI_ENTRY_CHECKED(jclass, |
608 | checked_jni_GetSuperclass(JNIEnv *env, |
609 | jclass sub)) |
610 | functionEnter(thr); |
611 | IN_VM( |
612 | jniCheck::validate_class(thr, sub, true); |
613 | ) |
614 | jclass result = UNCHECKED()->GetSuperclass(env, sub); |
615 | functionExit(thr); |
616 | return result; |
617 | JNI_END |
618 | |
619 | JNI_ENTRY_CHECKED(jboolean, |
620 | checked_jni_IsAssignableFrom(JNIEnv *env, |
621 | jclass sub, |
622 | jclass sup)) |
623 | functionEnter(thr); |
624 | IN_VM( |
625 | jniCheck::validate_class(thr, sub, true); |
626 | jniCheck::validate_class(thr, sup, true); |
627 | ) |
628 | jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); |
629 | functionExit(thr); |
630 | return result; |
631 | JNI_END |
632 | |
633 | JNI_ENTRY_CHECKED(jobject, |
634 | checked_jni_ToReflectedField(JNIEnv *env, |
635 | jclass cls, |
636 | jfieldID fieldID, |
637 | jboolean isStatic)) |
638 | functionEnter(thr); |
639 | IN_VM( |
640 | jniCheck::validate_class(thr, cls, false); |
641 | ) |
642 | jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, |
643 | isStatic); |
644 | functionExit(thr); |
645 | return result; |
646 | JNI_END |
647 | |
648 | JNI_ENTRY_CHECKED(jint, |
649 | checked_jni_Throw(JNIEnv *env, |
650 | jthrowable obj)) |
651 | functionEnter(thr); |
652 | IN_VM( |
653 | oop oopObj = jniCheck::validate_object(thr, obj); |
654 | if (oopObj == NULL) { |
655 | // Unchecked Throw tolerates a NULL obj, so just warn |
656 | ReportJNIWarning(thr, "JNI Throw called with NULL throwable" ); |
657 | } else { |
658 | jniCheck::validate_throwable_klass(thr, oopObj->klass()); |
659 | } |
660 | ) |
661 | jint result = UNCHECKED()->Throw(env, obj); |
662 | functionExit(thr); |
663 | return result; |
664 | JNI_END |
665 | |
666 | JNI_ENTRY_CHECKED(jint, |
667 | checked_jni_ThrowNew(JNIEnv *env, |
668 | jclass clazz, |
669 | const char *msg)) |
670 | functionEnter(thr); |
671 | IN_VM( |
672 | Klass* k = jniCheck::validate_class(thr, clazz, false); |
673 | assert(k != NULL, "validate_class shouldn't return NULL Klass*" ); |
674 | jniCheck::validate_throwable_klass(thr, k); |
675 | ) |
676 | jint result = UNCHECKED()->ThrowNew(env, clazz, msg); |
677 | functionExit(thr); |
678 | return result; |
679 | JNI_END |
680 | |
681 | JNI_ENTRY_CHECKED(jthrowable, |
682 | checked_jni_ExceptionOccurred(JNIEnv *env)) |
683 | thr->clear_pending_jni_exception_check(); |
684 | functionEnterExceptionAllowed(thr); |
685 | jthrowable result = UNCHECKED()->ExceptionOccurred(env); |
686 | functionExit(thr); |
687 | return result; |
688 | JNI_END |
689 | |
690 | JNI_ENTRY_CHECKED(void, |
691 | checked_jni_ExceptionDescribe(JNIEnv *env)) |
692 | functionEnterExceptionAllowed(thr); |
693 | UNCHECKED()->ExceptionDescribe(env); |
694 | functionExit(thr); |
695 | JNI_END |
696 | |
697 | JNI_ENTRY_CHECKED(void, |
698 | checked_jni_ExceptionClear(JNIEnv *env)) |
699 | thr->clear_pending_jni_exception_check(); |
700 | functionEnterExceptionAllowed(thr); |
701 | UNCHECKED()->ExceptionClear(env); |
702 | functionExit(thr); |
703 | JNI_END |
704 | |
705 | JNI_ENTRY_CHECKED(void, |
706 | checked_jni_FatalError(JNIEnv *env, |
707 | const char *msg)) |
708 | thr->clear_pending_jni_exception_check(); |
709 | functionEnter(thr); |
710 | UNCHECKED()->FatalError(env, msg); |
711 | functionExit(thr); |
712 | JNI_END |
713 | |
714 | JNI_ENTRY_CHECKED(jint, |
715 | checked_jni_PushLocalFrame(JNIEnv *env, |
716 | jint capacity)) |
717 | functionEnterExceptionAllowed(thr); |
718 | if (capacity < 0) |
719 | NativeReportJNIFatalError(thr, "negative capacity" ); |
720 | jint result = UNCHECKED()->PushLocalFrame(env, capacity); |
721 | if (result == JNI_OK) { |
722 | add_planned_handle_capacity(thr->active_handles(), capacity); |
723 | } |
724 | functionExit(thr); |
725 | return result; |
726 | JNI_END |
727 | |
728 | JNI_ENTRY_CHECKED(jobject, |
729 | checked_jni_PopLocalFrame(JNIEnv *env, |
730 | jobject result)) |
731 | functionEnterExceptionAllowed(thr); |
732 | jobject res = UNCHECKED()->PopLocalFrame(env, result); |
733 | functionExit(thr); |
734 | return res; |
735 | JNI_END |
736 | |
737 | JNI_ENTRY_CHECKED(jobject, |
738 | checked_jni_NewGlobalRef(JNIEnv *env, |
739 | jobject lobj)) |
740 | functionEnter(thr); |
741 | IN_VM( |
742 | if (lobj != NULL) { |
743 | jniCheck::validate_handle(thr, lobj); |
744 | } |
745 | ) |
746 | jobject result = UNCHECKED()->NewGlobalRef(env,lobj); |
747 | functionExit(thr); |
748 | return result; |
749 | JNI_END |
750 | |
751 | JNI_ENTRY_CHECKED(void, |
752 | checked_jni_DeleteGlobalRef(JNIEnv *env, |
753 | jobject gref)) |
754 | functionEnterExceptionAllowed(thr); |
755 | IN_VM( |
756 | jniCheck::validate_object(thr, gref); |
757 | if (gref && !JNIHandles::is_global_handle(gref)) { |
758 | ReportJNIFatalError(thr, |
759 | "Invalid global JNI handle passed to DeleteGlobalRef" ); |
760 | } |
761 | ) |
762 | UNCHECKED()->DeleteGlobalRef(env,gref); |
763 | functionExit(thr); |
764 | JNI_END |
765 | |
766 | JNI_ENTRY_CHECKED(void, |
767 | checked_jni_DeleteLocalRef(JNIEnv *env, |
768 | jobject obj)) |
769 | functionEnterExceptionAllowed(thr); |
770 | IN_VM( |
771 | jniCheck::validate_object(thr, obj); |
772 | if (obj && !(JNIHandles::is_local_handle(thr, obj) || |
773 | JNIHandles::is_frame_handle(thr, obj))) |
774 | ReportJNIFatalError(thr, |
775 | "Invalid local JNI handle passed to DeleteLocalRef" ); |
776 | ) |
777 | UNCHECKED()->DeleteLocalRef(env, obj); |
778 | functionExit(thr); |
779 | JNI_END |
780 | |
781 | JNI_ENTRY_CHECKED(jboolean, |
782 | checked_jni_IsSameObject(JNIEnv *env, |
783 | jobject obj1, |
784 | jobject obj2)) |
785 | functionEnterExceptionAllowed(thr); |
786 | IN_VM( |
787 | /* This JNI function can be used to compare weak global references |
788 | * to NULL objects. If the handles are valid, but contain NULL, |
789 | * then don't attempt to validate the object. |
790 | */ |
791 | if (obj1 != NULL && jniCheck::validate_handle(thr, obj1) != NULL) { |
792 | jniCheck::validate_object(thr, obj1); |
793 | } |
794 | if (obj2 != NULL && jniCheck::validate_handle(thr, obj2) != NULL) { |
795 | jniCheck::validate_object(thr, obj2); |
796 | } |
797 | ) |
798 | jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); |
799 | functionExit(thr); |
800 | return result; |
801 | JNI_END |
802 | |
803 | JNI_ENTRY_CHECKED(jobject, |
804 | checked_jni_NewLocalRef(JNIEnv *env, |
805 | jobject ref)) |
806 | functionEnter(thr); |
807 | IN_VM( |
808 | if (ref != NULL) { |
809 | jniCheck::validate_handle(thr, ref); |
810 | } |
811 | ) |
812 | jobject result = UNCHECKED()->NewLocalRef(env, ref); |
813 | functionExit(thr); |
814 | return result; |
815 | JNI_END |
816 | |
817 | JNI_ENTRY_CHECKED(jint, |
818 | checked_jni_EnsureLocalCapacity(JNIEnv *env, |
819 | jint capacity)) |
820 | functionEnter(thr); |
821 | if (capacity < 0) { |
822 | NativeReportJNIFatalError(thr, "negative capacity" ); |
823 | } |
824 | jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); |
825 | if (result == JNI_OK) { |
826 | // increase local ref capacity if needed |
827 | if ((size_t)capacity > thr->active_handles()->get_planned_capacity()) { |
828 | add_planned_handle_capacity(thr->active_handles(), capacity); |
829 | } |
830 | } |
831 | functionExit(thr); |
832 | return result; |
833 | JNI_END |
834 | |
835 | JNI_ENTRY_CHECKED(jobject, |
836 | checked_jni_AllocObject(JNIEnv *env, |
837 | jclass clazz)) |
838 | functionEnter(thr); |
839 | IN_VM( |
840 | jniCheck::validate_class(thr, clazz, false); |
841 | ) |
842 | jobject result = UNCHECKED()->AllocObject(env,clazz); |
843 | functionExit(thr); |
844 | return result; |
845 | JNI_END |
846 | |
847 | JNI_ENTRY_CHECKED(jobject, |
848 | checked_jni_NewObject(JNIEnv *env, |
849 | jclass clazz, |
850 | jmethodID methodID, |
851 | ...)) |
852 | functionEnter(thr); |
853 | va_list args; |
854 | IN_VM( |
855 | jniCheck::validate_class(thr, clazz, false); |
856 | jniCheck::validate_jmethod_id(thr, methodID); |
857 | ) |
858 | va_start(args, methodID); |
859 | jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); |
860 | va_end(args); |
861 | functionExit(thr); |
862 | return result; |
863 | JNI_END |
864 | |
865 | JNI_ENTRY_CHECKED(jobject, |
866 | checked_jni_NewObjectV(JNIEnv *env, |
867 | jclass clazz, |
868 | jmethodID methodID, |
869 | va_list args)) |
870 | functionEnter(thr); |
871 | IN_VM( |
872 | jniCheck::validate_class(thr, clazz, false); |
873 | jniCheck::validate_jmethod_id(thr, methodID); |
874 | ) |
875 | jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); |
876 | functionExit(thr); |
877 | return result; |
878 | JNI_END |
879 | |
880 | JNI_ENTRY_CHECKED(jobject, |
881 | checked_jni_NewObjectA(JNIEnv *env, |
882 | jclass clazz, |
883 | jmethodID methodID, |
884 | const jvalue *args)) |
885 | functionEnter(thr); |
886 | IN_VM( |
887 | jniCheck::validate_class(thr, clazz, false); |
888 | jniCheck::validate_jmethod_id(thr, methodID); |
889 | ) |
890 | jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); |
891 | functionExit(thr); |
892 | return result; |
893 | JNI_END |
894 | |
895 | JNI_ENTRY_CHECKED(jclass, |
896 | checked_jni_GetObjectClass(JNIEnv *env, |
897 | jobject obj)) |
898 | functionEnter(thr); |
899 | IN_VM( |
900 | jniCheck::validate_object(thr, obj); |
901 | ) |
902 | jclass result = UNCHECKED()->GetObjectClass(env,obj); |
903 | functionExit(thr); |
904 | return result; |
905 | JNI_END |
906 | |
907 | JNI_ENTRY_CHECKED(jboolean, |
908 | checked_jni_IsInstanceOf(JNIEnv *env, |
909 | jobject obj, |
910 | jclass clazz)) |
911 | functionEnter(thr); |
912 | IN_VM( |
913 | jniCheck::validate_object(thr, obj); |
914 | jniCheck::validate_class(thr, clazz, true); |
915 | ) |
916 | jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); |
917 | functionExit(thr); |
918 | return result; |
919 | JNI_END |
920 | |
921 | JNI_ENTRY_CHECKED(jmethodID, |
922 | checked_jni_GetMethodID(JNIEnv *env, |
923 | jclass clazz, |
924 | const char *name, |
925 | const char *sig)) |
926 | functionEnter(thr); |
927 | IN_VM( |
928 | jniCheck::validate_class(thr, clazz, false); |
929 | ) |
930 | jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig); |
931 | functionExit(thr); |
932 | return result; |
933 | JNI_END |
934 | |
935 | #define WRAPPER_CallMethod(ResultType, Result) \ |
936 | JNI_ENTRY_CHECKED(ResultType, \ |
937 | checked_jni_Call##Result##Method(JNIEnv *env, \ |
938 | jobject obj, \ |
939 | jmethodID methodID, \ |
940 | ...)) \ |
941 | functionEnter(thr); \ |
942 | va_list args; \ |
943 | IN_VM( \ |
944 | jniCheck::validate_call_object(thr, obj, methodID); \ |
945 | ) \ |
946 | va_start(args,methodID); \ |
947 | ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \ |
948 | args); \ |
949 | va_end(args); \ |
950 | thr->set_pending_jni_exception_check("Call"#Result"Method"); \ |
951 | functionExit(thr); \ |
952 | return result; \ |
953 | JNI_END \ |
954 | \ |
955 | JNI_ENTRY_CHECKED(ResultType, \ |
956 | checked_jni_Call##Result##MethodV(JNIEnv *env, \ |
957 | jobject obj, \ |
958 | jmethodID methodID, \ |
959 | va_list args)) \ |
960 | functionEnter(thr); \ |
961 | IN_VM(\ |
962 | jniCheck::validate_call_object(thr, obj, methodID); \ |
963 | ) \ |
964 | ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\ |
965 | args); \ |
966 | thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \ |
967 | functionExit(thr); \ |
968 | return result; \ |
969 | JNI_END \ |
970 | \ |
971 | JNI_ENTRY_CHECKED(ResultType, \ |
972 | checked_jni_Call##Result##MethodA(JNIEnv *env, \ |
973 | jobject obj, \ |
974 | jmethodID methodID, \ |
975 | const jvalue * args)) \ |
976 | functionEnter(thr); \ |
977 | IN_VM( \ |
978 | jniCheck::validate_call_object(thr, obj, methodID); \ |
979 | ) \ |
980 | ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\ |
981 | args); \ |
982 | thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \ |
983 | functionExit(thr); \ |
984 | return result; \ |
985 | JNI_END |
986 | |
987 | WRAPPER_CallMethod(jobject,Object) |
988 | WRAPPER_CallMethod(jboolean,Boolean) |
989 | WRAPPER_CallMethod(jbyte,Byte) |
990 | WRAPPER_CallMethod(jshort,Short) |
991 | WRAPPER_CallMethod(jchar,Char) |
992 | WRAPPER_CallMethod(jint,Int) |
993 | WRAPPER_CallMethod(jlong,Long) |
994 | WRAPPER_CallMethod(jfloat,Float) |
995 | WRAPPER_CallMethod(jdouble,Double) |
996 | |
997 | JNI_ENTRY_CHECKED(void, |
998 | checked_jni_CallVoidMethod(JNIEnv *env, \ |
999 | jobject obj, \ |
1000 | jmethodID methodID, \ |
1001 | ...)) |
1002 | functionEnter(thr); |
1003 | va_list args; |
1004 | IN_VM( |
1005 | jniCheck::validate_call_object(thr, obj, methodID); |
1006 | ) |
1007 | va_start(args,methodID); |
1008 | UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); |
1009 | va_end(args); |
1010 | thr->set_pending_jni_exception_check("CallVoidMethod" ); |
1011 | functionExit(thr); |
1012 | JNI_END |
1013 | |
1014 | JNI_ENTRY_CHECKED(void, |
1015 | checked_jni_CallVoidMethodV(JNIEnv *env, |
1016 | jobject obj, |
1017 | jmethodID methodID, |
1018 | va_list args)) |
1019 | functionEnter(thr); |
1020 | IN_VM( |
1021 | jniCheck::validate_call_object(thr, obj, methodID); |
1022 | ) |
1023 | UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); |
1024 | thr->set_pending_jni_exception_check("CallVoidMethodV" ); |
1025 | functionExit(thr); |
1026 | JNI_END |
1027 | |
1028 | JNI_ENTRY_CHECKED(void, |
1029 | checked_jni_CallVoidMethodA(JNIEnv *env, |
1030 | jobject obj, |
1031 | jmethodID methodID, |
1032 | const jvalue * args)) |
1033 | functionEnter(thr); |
1034 | IN_VM( |
1035 | jniCheck::validate_call_object(thr, obj, methodID); |
1036 | ) |
1037 | UNCHECKED()->CallVoidMethodA(env,obj,methodID,args); |
1038 | thr->set_pending_jni_exception_check("CallVoidMethodA" ); |
1039 | functionExit(thr); |
1040 | JNI_END |
1041 | |
1042 | #define WRAPPER_CallNonvirtualMethod(ResultType, Result) \ |
1043 | JNI_ENTRY_CHECKED(ResultType, \ |
1044 | checked_jni_CallNonvirtual##Result##Method(JNIEnv *env, \ |
1045 | jobject obj, \ |
1046 | jclass clazz, \ |
1047 | jmethodID methodID, \ |
1048 | ...)) \ |
1049 | functionEnter(thr); \ |
1050 | va_list args; \ |
1051 | IN_VM( \ |
1052 | jniCheck::validate_call_object(thr, obj, methodID); \ |
1053 | jniCheck::validate_call_class(thr, clazz, methodID); \ |
1054 | ) \ |
1055 | va_start(args,methodID); \ |
1056 | ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ |
1057 | obj, \ |
1058 | clazz, \ |
1059 | methodID,\ |
1060 | args); \ |
1061 | va_end(args); \ |
1062 | thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \ |
1063 | functionExit(thr); \ |
1064 | return result; \ |
1065 | JNI_END \ |
1066 | \ |
1067 | JNI_ENTRY_CHECKED(ResultType, \ |
1068 | checked_jni_CallNonvirtual##Result##MethodV(JNIEnv *env, \ |
1069 | jobject obj, \ |
1070 | jclass clazz, \ |
1071 | jmethodID methodID, \ |
1072 | va_list args)) \ |
1073 | functionEnter(thr); \ |
1074 | IN_VM( \ |
1075 | jniCheck::validate_call_object(thr, obj, methodID); \ |
1076 | jniCheck::validate_call_class(thr, clazz, methodID); \ |
1077 | ) \ |
1078 | ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ |
1079 | obj, \ |
1080 | clazz, \ |
1081 | methodID,\ |
1082 | args); \ |
1083 | thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \ |
1084 | functionExit(thr); \ |
1085 | return result; \ |
1086 | JNI_END \ |
1087 | \ |
1088 | JNI_ENTRY_CHECKED(ResultType, \ |
1089 | checked_jni_CallNonvirtual##Result##MethodA(JNIEnv *env, \ |
1090 | jobject obj, \ |
1091 | jclass clazz, \ |
1092 | jmethodID methodID, \ |
1093 | const jvalue * args)) \ |
1094 | functionEnter(thr); \ |
1095 | IN_VM( \ |
1096 | jniCheck::validate_call_object(thr, obj, methodID); \ |
1097 | jniCheck::validate_call_class(thr, clazz, methodID); \ |
1098 | ) \ |
1099 | ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \ |
1100 | obj, \ |
1101 | clazz, \ |
1102 | methodID,\ |
1103 | args); \ |
1104 | thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \ |
1105 | functionExit(thr); \ |
1106 | return result; \ |
1107 | JNI_END |
1108 | |
1109 | WRAPPER_CallNonvirtualMethod(jobject,Object) |
1110 | WRAPPER_CallNonvirtualMethod(jboolean,Boolean) |
1111 | WRAPPER_CallNonvirtualMethod(jbyte,Byte) |
1112 | WRAPPER_CallNonvirtualMethod(jshort,Short) |
1113 | WRAPPER_CallNonvirtualMethod(jchar,Char) |
1114 | WRAPPER_CallNonvirtualMethod(jint,Int) |
1115 | WRAPPER_CallNonvirtualMethod(jlong,Long) |
1116 | WRAPPER_CallNonvirtualMethod(jfloat,Float) |
1117 | WRAPPER_CallNonvirtualMethod(jdouble,Double) |
1118 | |
1119 | JNI_ENTRY_CHECKED(void, |
1120 | checked_jni_CallNonvirtualVoidMethod(JNIEnv *env, |
1121 | jobject obj, |
1122 | jclass clazz, |
1123 | jmethodID methodID, |
1124 | ...)) |
1125 | functionEnter(thr); |
1126 | va_list args; |
1127 | IN_VM( |
1128 | jniCheck::validate_call_object(thr, obj, methodID); |
1129 | jniCheck::validate_call_class(thr, clazz, methodID); |
1130 | ) |
1131 | va_start(args,methodID); |
1132 | UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); |
1133 | va_end(args); |
1134 | thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod" ); |
1135 | functionExit(thr); |
1136 | JNI_END |
1137 | |
1138 | JNI_ENTRY_CHECKED(void, |
1139 | checked_jni_CallNonvirtualVoidMethodV(JNIEnv *env, |
1140 | jobject obj, |
1141 | jclass clazz, |
1142 | jmethodID methodID, |
1143 | va_list args)) |
1144 | functionEnter(thr); |
1145 | IN_VM( |
1146 | jniCheck::validate_call_object(thr, obj, methodID); |
1147 | jniCheck::validate_call_class(thr, clazz, methodID); |
1148 | ) |
1149 | UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); |
1150 | thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV" ); |
1151 | functionExit(thr); |
1152 | JNI_END |
1153 | |
1154 | JNI_ENTRY_CHECKED(void, |
1155 | checked_jni_CallNonvirtualVoidMethodA(JNIEnv *env, |
1156 | jobject obj, |
1157 | jclass clazz, |
1158 | jmethodID methodID, |
1159 | const jvalue * args)) |
1160 | functionEnter(thr); |
1161 | IN_VM( |
1162 | jniCheck::validate_call_object(thr, obj, methodID); |
1163 | jniCheck::validate_call_class(thr, clazz, methodID); |
1164 | ) |
1165 | UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); |
1166 | thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA" ); |
1167 | functionExit(thr); |
1168 | JNI_END |
1169 | |
1170 | JNI_ENTRY_CHECKED(jfieldID, |
1171 | checked_jni_GetFieldID(JNIEnv *env, |
1172 | jclass clazz, |
1173 | const char *name, |
1174 | const char *sig)) |
1175 | functionEnter(thr); |
1176 | IN_VM( |
1177 | jniCheck::validate_class(thr, clazz, false); |
1178 | ) |
1179 | jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig); |
1180 | functionExit(thr); |
1181 | return result; |
1182 | JNI_END |
1183 | |
1184 | #define WRAPPER_GetField(ReturnType,Result,FieldType) \ |
1185 | JNI_ENTRY_CHECKED(ReturnType, \ |
1186 | checked_jni_Get##Result##Field(JNIEnv *env, \ |
1187 | jobject obj, \ |
1188 | jfieldID fieldID)) \ |
1189 | functionEnter(thr); \ |
1190 | IN_VM( \ |
1191 | checkInstanceFieldID(thr, fieldID, obj, FieldType); \ |
1192 | ) \ |
1193 | ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \ |
1194 | functionExit(thr); \ |
1195 | return result; \ |
1196 | JNI_END |
1197 | |
1198 | WRAPPER_GetField(jobject, Object, T_OBJECT) |
1199 | WRAPPER_GetField(jboolean, Boolean, T_BOOLEAN) |
1200 | WRAPPER_GetField(jbyte, Byte, T_BYTE) |
1201 | WRAPPER_GetField(jshort, Short, T_SHORT) |
1202 | WRAPPER_GetField(jchar, Char, T_CHAR) |
1203 | WRAPPER_GetField(jint, Int, T_INT) |
1204 | WRAPPER_GetField(jlong, Long, T_LONG) |
1205 | WRAPPER_GetField(jfloat, Float, T_FLOAT) |
1206 | WRAPPER_GetField(jdouble, Double, T_DOUBLE) |
1207 | |
1208 | #define WRAPPER_SetField(ValueType,Result,FieldType) \ |
1209 | JNI_ENTRY_CHECKED(void, \ |
1210 | checked_jni_Set##Result##Field(JNIEnv *env, \ |
1211 | jobject obj, \ |
1212 | jfieldID fieldID, \ |
1213 | ValueType val)) \ |
1214 | functionEnter(thr); \ |
1215 | IN_VM( \ |
1216 | checkInstanceFieldID(thr, fieldID, obj, FieldType); \ |
1217 | ) \ |
1218 | UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \ |
1219 | functionExit(thr); \ |
1220 | JNI_END |
1221 | |
1222 | WRAPPER_SetField(jobject, Object, T_OBJECT) |
1223 | WRAPPER_SetField(jboolean, Boolean, T_BOOLEAN) |
1224 | WRAPPER_SetField(jbyte, Byte, T_BYTE) |
1225 | WRAPPER_SetField(jshort, Short, T_SHORT) |
1226 | WRAPPER_SetField(jchar, Char, T_CHAR) |
1227 | WRAPPER_SetField(jint, Int, T_INT) |
1228 | WRAPPER_SetField(jlong, Long, T_LONG) |
1229 | WRAPPER_SetField(jfloat, Float, T_FLOAT) |
1230 | WRAPPER_SetField(jdouble, Double, T_DOUBLE) |
1231 | |
1232 | |
1233 | JNI_ENTRY_CHECKED(jmethodID, |
1234 | checked_jni_GetStaticMethodID(JNIEnv *env, |
1235 | jclass clazz, |
1236 | const char *name, |
1237 | const char *sig)) |
1238 | functionEnter(thr); |
1239 | IN_VM( |
1240 | jniCheck::validate_class(thr, clazz, false); |
1241 | ) |
1242 | jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig); |
1243 | functionExit(thr); |
1244 | return result; |
1245 | JNI_END |
1246 | |
1247 | #define WRAPPER_CallStaticMethod(ReturnType,Result) \ |
1248 | JNI_ENTRY_CHECKED(ReturnType, \ |
1249 | checked_jni_CallStatic##Result##Method(JNIEnv *env, \ |
1250 | jclass clazz, \ |
1251 | jmethodID methodID, \ |
1252 | ...)) \ |
1253 | functionEnter(thr); \ |
1254 | va_list args; \ |
1255 | IN_VM( \ |
1256 | jniCheck::validate_jmethod_id(thr, methodID); \ |
1257 | jniCheck::validate_class(thr, clazz, false); \ |
1258 | ) \ |
1259 | va_start(args,methodID); \ |
1260 | ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ |
1261 | clazz, \ |
1262 | methodID, \ |
1263 | args); \ |
1264 | va_end(args); \ |
1265 | thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \ |
1266 | functionExit(thr); \ |
1267 | return result; \ |
1268 | JNI_END \ |
1269 | \ |
1270 | JNI_ENTRY_CHECKED(ReturnType, \ |
1271 | checked_jni_CallStatic##Result##MethodV(JNIEnv *env, \ |
1272 | jclass clazz, \ |
1273 | jmethodID methodID,\ |
1274 | va_list args)) \ |
1275 | functionEnter(thr); \ |
1276 | IN_VM( \ |
1277 | jniCheck::validate_jmethod_id(thr, methodID); \ |
1278 | jniCheck::validate_class(thr, clazz, false); \ |
1279 | ) \ |
1280 | ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ |
1281 | clazz, \ |
1282 | methodID, \ |
1283 | args); \ |
1284 | thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \ |
1285 | functionExit(thr); \ |
1286 | return result; \ |
1287 | JNI_END \ |
1288 | \ |
1289 | JNI_ENTRY_CHECKED(ReturnType, \ |
1290 | checked_jni_CallStatic##Result##MethodA(JNIEnv *env, \ |
1291 | jclass clazz, \ |
1292 | jmethodID methodID, \ |
1293 | const jvalue *args)) \ |
1294 | functionEnter(thr); \ |
1295 | IN_VM( \ |
1296 | jniCheck::validate_jmethod_id(thr, methodID); \ |
1297 | jniCheck::validate_class(thr, clazz, false); \ |
1298 | ) \ |
1299 | ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \ |
1300 | clazz, \ |
1301 | methodID, \ |
1302 | args); \ |
1303 | thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \ |
1304 | functionExit(thr); \ |
1305 | return result; \ |
1306 | JNI_END |
1307 | |
1308 | WRAPPER_CallStaticMethod(jobject,Object) |
1309 | WRAPPER_CallStaticMethod(jboolean,Boolean) |
1310 | WRAPPER_CallStaticMethod(jbyte,Byte) |
1311 | WRAPPER_CallStaticMethod(jshort,Short) |
1312 | WRAPPER_CallStaticMethod(jchar,Char) |
1313 | WRAPPER_CallStaticMethod(jint,Int) |
1314 | WRAPPER_CallStaticMethod(jlong,Long) |
1315 | WRAPPER_CallStaticMethod(jfloat,Float) |
1316 | WRAPPER_CallStaticMethod(jdouble,Double) |
1317 | |
1318 | JNI_ENTRY_CHECKED(void, |
1319 | checked_jni_CallStaticVoidMethod(JNIEnv *env, |
1320 | jclass cls, |
1321 | jmethodID methodID, |
1322 | ...)) |
1323 | functionEnter(thr); |
1324 | va_list args; |
1325 | IN_VM( |
1326 | jniCheck::validate_jmethod_id(thr, methodID); |
1327 | jniCheck::validate_class(thr, cls, false); |
1328 | ) |
1329 | va_start(args,methodID); |
1330 | UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); |
1331 | va_end(args); |
1332 | thr->set_pending_jni_exception_check("CallStaticVoidMethod" ); |
1333 | functionExit(thr); |
1334 | JNI_END |
1335 | |
1336 | JNI_ENTRY_CHECKED(void, |
1337 | checked_jni_CallStaticVoidMethodV(JNIEnv *env, |
1338 | jclass cls, |
1339 | jmethodID methodID, |
1340 | va_list args)) |
1341 | functionEnter(thr); |
1342 | IN_VM( |
1343 | jniCheck::validate_jmethod_id(thr, methodID); |
1344 | jniCheck::validate_class(thr, cls, false); |
1345 | ) |
1346 | UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); |
1347 | thr->set_pending_jni_exception_check("CallStaticVoidMethodV" ); |
1348 | functionExit(thr); |
1349 | JNI_END |
1350 | |
1351 | JNI_ENTRY_CHECKED(void, |
1352 | checked_jni_CallStaticVoidMethodA(JNIEnv *env, |
1353 | jclass cls, |
1354 | jmethodID methodID, |
1355 | const jvalue * args)) |
1356 | functionEnter(thr); |
1357 | IN_VM( |
1358 | jniCheck::validate_jmethod_id(thr, methodID); |
1359 | jniCheck::validate_class(thr, cls, false); |
1360 | ) |
1361 | UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); |
1362 | thr->set_pending_jni_exception_check("CallStaticVoidMethodA" ); |
1363 | functionExit(thr); |
1364 | JNI_END |
1365 | |
1366 | JNI_ENTRY_CHECKED(jfieldID, |
1367 | checked_jni_GetStaticFieldID(JNIEnv *env, |
1368 | jclass clazz, |
1369 | const char *name, |
1370 | const char *sig)) |
1371 | functionEnter(thr); |
1372 | IN_VM( |
1373 | jniCheck::validate_class(thr, clazz, false); |
1374 | ) |
1375 | jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig); |
1376 | functionExit(thr); |
1377 | return result; |
1378 | JNI_END |
1379 | |
1380 | #define WRAPPER_GetStaticField(ReturnType,Result,FieldType) \ |
1381 | JNI_ENTRY_CHECKED(ReturnType, \ |
1382 | checked_jni_GetStatic##Result##Field(JNIEnv *env, \ |
1383 | jclass clazz, \ |
1384 | jfieldID fieldID)) \ |
1385 | functionEnter(thr); \ |
1386 | IN_VM( \ |
1387 | jniCheck::validate_class(thr, clazz, false); \ |
1388 | checkStaticFieldID(thr, fieldID, clazz, FieldType); \ |
1389 | ) \ |
1390 | ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ |
1391 | clazz, \ |
1392 | fieldID); \ |
1393 | functionExit(thr); \ |
1394 | return result; \ |
1395 | JNI_END |
1396 | |
1397 | WRAPPER_GetStaticField(jobject, Object, T_OBJECT) |
1398 | WRAPPER_GetStaticField(jboolean, Boolean, T_BOOLEAN) |
1399 | WRAPPER_GetStaticField(jbyte, Byte, T_BYTE) |
1400 | WRAPPER_GetStaticField(jshort, Short, T_SHORT) |
1401 | WRAPPER_GetStaticField(jchar, Char, T_CHAR) |
1402 | WRAPPER_GetStaticField(jint, Int, T_INT) |
1403 | WRAPPER_GetStaticField(jlong, Long, T_LONG) |
1404 | WRAPPER_GetStaticField(jfloat, Float, T_FLOAT) |
1405 | WRAPPER_GetStaticField(jdouble, Double, T_DOUBLE) |
1406 | |
1407 | #define WRAPPER_SetStaticField(ValueType,Result,FieldType) \ |
1408 | JNI_ENTRY_CHECKED(void, \ |
1409 | checked_jni_SetStatic##Result##Field(JNIEnv *env, \ |
1410 | jclass clazz, \ |
1411 | jfieldID fieldID, \ |
1412 | ValueType value)) \ |
1413 | functionEnter(thr); \ |
1414 | IN_VM( \ |
1415 | jniCheck::validate_class(thr, clazz, false); \ |
1416 | checkStaticFieldID(thr, fieldID, clazz, FieldType); \ |
1417 | ) \ |
1418 | UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \ |
1419 | functionExit(thr); \ |
1420 | JNI_END |
1421 | |
1422 | WRAPPER_SetStaticField(jobject, Object, T_OBJECT) |
1423 | WRAPPER_SetStaticField(jboolean, Boolean, T_BOOLEAN) |
1424 | WRAPPER_SetStaticField(jbyte, Byte, T_BYTE) |
1425 | WRAPPER_SetStaticField(jshort, Short, T_SHORT) |
1426 | WRAPPER_SetStaticField(jchar, Char, T_CHAR) |
1427 | WRAPPER_SetStaticField(jint, Int, T_INT) |
1428 | WRAPPER_SetStaticField(jlong, Long, T_LONG) |
1429 | WRAPPER_SetStaticField(jfloat, Float, T_FLOAT) |
1430 | WRAPPER_SetStaticField(jdouble, Double, T_DOUBLE) |
1431 | |
1432 | |
1433 | JNI_ENTRY_CHECKED(jstring, |
1434 | checked_jni_NewString(JNIEnv *env, |
1435 | const jchar *unicode, |
1436 | jsize len)) |
1437 | functionEnter(thr); |
1438 | jstring result = UNCHECKED()->NewString(env,unicode,len); |
1439 | functionExit(thr); |
1440 | return result; |
1441 | JNI_END |
1442 | |
1443 | JNI_ENTRY_CHECKED(jsize, |
1444 | checked_jni_GetStringLength(JNIEnv *env, |
1445 | jstring str)) |
1446 | functionEnter(thr); |
1447 | IN_VM( |
1448 | checkString(thr, str); |
1449 | ) |
1450 | jsize result = UNCHECKED()->GetStringLength(env,str); |
1451 | functionExit(thr); |
1452 | return result; |
1453 | JNI_END |
1454 | |
1455 | // Arbitrary (but well-known) tag |
1456 | const void* STRING_TAG = (void*)0x47114711; |
1457 | |
1458 | JNI_ENTRY_CHECKED(const jchar *, |
1459 | checked_jni_GetStringChars(JNIEnv *env, |
1460 | jstring str, |
1461 | jboolean *isCopy)) |
1462 | functionEnter(thr); |
1463 | IN_VM( |
1464 | checkString(thr, str); |
1465 | ) |
1466 | jchar* new_result = NULL; |
1467 | const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy); |
1468 | assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected" ); |
1469 | if (result != NULL) { |
1470 | size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination |
1471 | len *= sizeof(jchar); |
1472 | new_result = (jchar*) GuardedMemory::wrap_copy(result, len, STRING_TAG); |
1473 | if (new_result == NULL) { |
1474 | vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringChars" ); |
1475 | } |
1476 | // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes |
1477 | // Note that the dtrace arguments for the allocated memory will not match up with this solution. |
1478 | FreeHeap((char*)result); |
1479 | } |
1480 | functionExit(thr); |
1481 | return new_result; |
1482 | JNI_END |
1483 | |
1484 | JNI_ENTRY_CHECKED(void, |
1485 | checked_jni_ReleaseStringChars(JNIEnv *env, |
1486 | jstring str, |
1487 | const jchar *chars)) |
1488 | functionEnterExceptionAllowed(thr); |
1489 | IN_VM( |
1490 | checkString(thr, str); |
1491 | ) |
1492 | if (chars == NULL) { |
1493 | // still do the unchecked call to allow dtrace probes |
1494 | UNCHECKED()->ReleaseStringChars(env,str,chars); |
1495 | } |
1496 | else { |
1497 | GuardedMemory guarded((void*)chars); |
1498 | if (!guarded.verify_guards()) { |
1499 | tty->print_cr("ReleaseStringChars: release chars failed bounds check. " |
1500 | "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars)); |
1501 | guarded.print_on(tty); |
1502 | NativeReportJNIFatalError(thr, "ReleaseStringChars: " |
1503 | "release chars failed bounds check." ); |
1504 | } |
1505 | if (guarded.get_tag() != STRING_TAG) { |
1506 | tty->print_cr("ReleaseStringChars: called on something not allocated " |
1507 | "by GetStringChars. string: " PTR_FORMAT " chars: " PTR_FORMAT, |
1508 | p2i(str), p2i(chars)); |
1509 | NativeReportJNIFatalError(thr, "ReleaseStringChars called on something " |
1510 | "not allocated by GetStringChars" ); |
1511 | } |
1512 | UNCHECKED()->ReleaseStringChars(env, str, |
1513 | (const jchar*) guarded.release_for_freeing()); |
1514 | } |
1515 | functionExit(thr); |
1516 | JNI_END |
1517 | |
1518 | JNI_ENTRY_CHECKED(jstring, |
1519 | checked_jni_NewStringUTF(JNIEnv *env, |
1520 | const char *utf)) |
1521 | functionEnter(thr); |
1522 | jstring result = UNCHECKED()->NewStringUTF(env,utf); |
1523 | functionExit(thr); |
1524 | return result; |
1525 | JNI_END |
1526 | |
1527 | JNI_ENTRY_CHECKED(jsize, |
1528 | checked_jni_GetStringUTFLength(JNIEnv *env, |
1529 | jstring str)) |
1530 | functionEnter(thr); |
1531 | IN_VM( |
1532 | checkString(thr, str); |
1533 | ) |
1534 | jsize result = UNCHECKED()->GetStringUTFLength(env,str); |
1535 | functionExit(thr); |
1536 | return result; |
1537 | JNI_END |
1538 | |
1539 | // Arbitrary (but well-known) tag - different than GetStringChars |
1540 | const void* STRING_UTF_TAG = (void*) 0x48124812; |
1541 | |
1542 | JNI_ENTRY_CHECKED(const char *, |
1543 | checked_jni_GetStringUTFChars(JNIEnv *env, |
1544 | jstring str, |
1545 | jboolean *isCopy)) |
1546 | functionEnter(thr); |
1547 | IN_VM( |
1548 | checkString(thr, str); |
1549 | ) |
1550 | char* new_result = NULL; |
1551 | const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy); |
1552 | assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected" ); |
1553 | if (result != NULL) { |
1554 | size_t len = strlen(result) + 1; // + 1 for NULL termination |
1555 | new_result = (char*) GuardedMemory::wrap_copy(result, len, STRING_UTF_TAG); |
1556 | if (new_result == NULL) { |
1557 | vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringUTFChars" ); |
1558 | } |
1559 | // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes |
1560 | // Note that the dtrace arguments for the allocated memory will not match up with this solution. |
1561 | FreeHeap((char*)result); |
1562 | } |
1563 | functionExit(thr); |
1564 | return new_result; |
1565 | JNI_END |
1566 | |
1567 | JNI_ENTRY_CHECKED(void, |
1568 | checked_jni_ReleaseStringUTFChars(JNIEnv *env, |
1569 | jstring str, |
1570 | const char* chars)) |
1571 | functionEnterExceptionAllowed(thr); |
1572 | IN_VM( |
1573 | checkString(thr, str); |
1574 | ) |
1575 | if (chars == NULL) { |
1576 | // still do the unchecked call to allow dtrace probes |
1577 | UNCHECKED()->ReleaseStringUTFChars(env,str,chars); |
1578 | } |
1579 | else { |
1580 | GuardedMemory guarded((void*)chars); |
1581 | if (!guarded.verify_guards()) { |
1582 | tty->print_cr("ReleaseStringUTFChars: release chars failed bounds check. " |
1583 | "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars)); |
1584 | guarded.print_on(tty); |
1585 | NativeReportJNIFatalError(thr, "ReleaseStringUTFChars: " |
1586 | "release chars failed bounds check." ); |
1587 | } |
1588 | if (guarded.get_tag() != STRING_UTF_TAG) { |
1589 | tty->print_cr("ReleaseStringUTFChars: called on something not " |
1590 | "allocated by GetStringUTFChars. string: " PTR_FORMAT " chars: " |
1591 | PTR_FORMAT, p2i(str), p2i(chars)); |
1592 | NativeReportJNIFatalError(thr, "ReleaseStringUTFChars " |
1593 | "called on something not allocated by GetStringUTFChars" ); |
1594 | } |
1595 | UNCHECKED()->ReleaseStringUTFChars(env, str, |
1596 | (const char*) guarded.release_for_freeing()); |
1597 | } |
1598 | functionExit(thr); |
1599 | JNI_END |
1600 | |
1601 | JNI_ENTRY_CHECKED(jsize, |
1602 | checked_jni_GetArrayLength(JNIEnv *env, |
1603 | jarray array)) |
1604 | functionEnter(thr); |
1605 | IN_VM( |
1606 | check_is_array(thr, array); |
1607 | ) |
1608 | jsize result = UNCHECKED()->GetArrayLength(env,array); |
1609 | functionExit(thr); |
1610 | return result; |
1611 | JNI_END |
1612 | |
1613 | JNI_ENTRY_CHECKED(jobjectArray, |
1614 | checked_jni_NewObjectArray(JNIEnv *env, |
1615 | jsize len, |
1616 | jclass clazz, |
1617 | jobject init)) |
1618 | functionEnter(thr); |
1619 | jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); |
1620 | functionExit(thr); |
1621 | return result; |
1622 | JNI_END |
1623 | |
1624 | JNI_ENTRY_CHECKED(jobject, |
1625 | checked_jni_GetObjectArrayElement(JNIEnv *env, |
1626 | jobjectArray array, |
1627 | jsize index)) |
1628 | functionEnter(thr); |
1629 | IN_VM( |
1630 | check_is_obj_array(thr, array); |
1631 | ) |
1632 | jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); |
1633 | functionExit(thr); |
1634 | return result; |
1635 | JNI_END |
1636 | |
1637 | JNI_ENTRY_CHECKED(void, |
1638 | checked_jni_SetObjectArrayElement(JNIEnv *env, |
1639 | jobjectArray array, |
1640 | jsize index, |
1641 | jobject val)) |
1642 | functionEnter(thr); |
1643 | IN_VM( |
1644 | check_is_obj_array(thr, array); |
1645 | ) |
1646 | UNCHECKED()->SetObjectArrayElement(env,array,index,val); |
1647 | functionExit(thr); |
1648 | JNI_END |
1649 | |
1650 | #define WRAPPER_NewScalarArray(Return, Result) \ |
1651 | JNI_ENTRY_CHECKED(Return, \ |
1652 | checked_jni_New##Result##Array(JNIEnv *env, \ |
1653 | jsize len)) \ |
1654 | functionEnter(thr); \ |
1655 | Return result = UNCHECKED()->New##Result##Array(env,len); \ |
1656 | functionExit(thr); \ |
1657 | return (Return) result; \ |
1658 | JNI_END |
1659 | |
1660 | WRAPPER_NewScalarArray(jbooleanArray, Boolean) |
1661 | WRAPPER_NewScalarArray(jbyteArray, Byte) |
1662 | WRAPPER_NewScalarArray(jshortArray, Short) |
1663 | WRAPPER_NewScalarArray(jcharArray, Char) |
1664 | WRAPPER_NewScalarArray(jintArray, Int) |
1665 | WRAPPER_NewScalarArray(jlongArray, Long) |
1666 | WRAPPER_NewScalarArray(jfloatArray, Float) |
1667 | WRAPPER_NewScalarArray(jdoubleArray, Double) |
1668 | |
1669 | #define WRAPPER_GetScalarArrayElements(ElementTag,ElementType,Result) \ |
1670 | JNI_ENTRY_CHECKED(ElementType *, \ |
1671 | checked_jni_Get##Result##ArrayElements(JNIEnv *env, \ |
1672 | ElementType##Array array, \ |
1673 | jboolean *isCopy)) \ |
1674 | functionEnter(thr); \ |
1675 | IN_VM( \ |
1676 | check_primitive_array_type(thr, array, ElementTag); \ |
1677 | ) \ |
1678 | ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \ |
1679 | array, \ |
1680 | isCopy); \ |
1681 | if (result != NULL) { \ |
1682 | result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \ |
1683 | } \ |
1684 | functionExit(thr); \ |
1685 | return result; \ |
1686 | JNI_END |
1687 | |
1688 | WRAPPER_GetScalarArrayElements(T_BOOLEAN, jboolean, Boolean) |
1689 | WRAPPER_GetScalarArrayElements(T_BYTE, jbyte, Byte) |
1690 | WRAPPER_GetScalarArrayElements(T_SHORT, jshort, Short) |
1691 | WRAPPER_GetScalarArrayElements(T_CHAR, jchar, Char) |
1692 | WRAPPER_GetScalarArrayElements(T_INT, jint, Int) |
1693 | WRAPPER_GetScalarArrayElements(T_LONG, jlong, Long) |
1694 | WRAPPER_GetScalarArrayElements(T_FLOAT, jfloat, Float) |
1695 | WRAPPER_GetScalarArrayElements(T_DOUBLE, jdouble, Double) |
1696 | |
1697 | #define WRAPPER_ReleaseScalarArrayElements(ElementTag,ElementType,Result,Tag) \ |
1698 | JNI_ENTRY_CHECKED(void, \ |
1699 | checked_jni_Release##Result##ArrayElements(JNIEnv *env, \ |
1700 | ElementType##Array array, \ |
1701 | ElementType *elems, \ |
1702 | jint mode)) \ |
1703 | functionEnterExceptionAllowed(thr); \ |
1704 | IN_VM( \ |
1705 | check_primitive_array_type(thr, array, ElementTag); \ |
1706 | ASSERT_OOPS_ALLOWED; \ |
1707 | typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ |
1708 | ) \ |
1709 | ElementType* orig_result = (ElementType *) check_wrapped_array_release( \ |
1710 | thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode); \ |
1711 | UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \ |
1712 | functionExit(thr); \ |
1713 | JNI_END |
1714 | |
1715 | WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool) |
1716 | WRAPPER_ReleaseScalarArrayElements(T_BYTE, jbyte, Byte, byte) |
1717 | WRAPPER_ReleaseScalarArrayElements(T_SHORT, jshort, Short, short) |
1718 | WRAPPER_ReleaseScalarArrayElements(T_CHAR, jchar, Char, char) |
1719 | WRAPPER_ReleaseScalarArrayElements(T_INT, jint, Int, int) |
1720 | WRAPPER_ReleaseScalarArrayElements(T_LONG, jlong, Long, long) |
1721 | WRAPPER_ReleaseScalarArrayElements(T_FLOAT, jfloat, Float, float) |
1722 | WRAPPER_ReleaseScalarArrayElements(T_DOUBLE, jdouble, Double, double) |
1723 | |
1724 | #define WRAPPER_GetScalarArrayRegion(ElementTag,ElementType,Result) \ |
1725 | JNI_ENTRY_CHECKED(void, \ |
1726 | checked_jni_Get##Result##ArrayRegion(JNIEnv *env, \ |
1727 | ElementType##Array array, \ |
1728 | jsize start, \ |
1729 | jsize len, \ |
1730 | ElementType *buf)) \ |
1731 | functionEnter(thr); \ |
1732 | IN_VM( \ |
1733 | check_primitive_array_type(thr, array, ElementTag); \ |
1734 | ) \ |
1735 | UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ |
1736 | functionExit(thr); \ |
1737 | JNI_END |
1738 | |
1739 | WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) |
1740 | WRAPPER_GetScalarArrayRegion(T_BYTE, jbyte, Byte) |
1741 | WRAPPER_GetScalarArrayRegion(T_SHORT, jshort, Short) |
1742 | WRAPPER_GetScalarArrayRegion(T_CHAR, jchar, Char) |
1743 | WRAPPER_GetScalarArrayRegion(T_INT, jint, Int) |
1744 | WRAPPER_GetScalarArrayRegion(T_LONG, jlong, Long) |
1745 | WRAPPER_GetScalarArrayRegion(T_FLOAT, jfloat, Float) |
1746 | WRAPPER_GetScalarArrayRegion(T_DOUBLE, jdouble, Double) |
1747 | |
1748 | #define WRAPPER_SetScalarArrayRegion(ElementTag,ElementType,Result) \ |
1749 | JNI_ENTRY_CHECKED(void, \ |
1750 | checked_jni_Set##Result##ArrayRegion(JNIEnv *env, \ |
1751 | ElementType##Array array, \ |
1752 | jsize start, \ |
1753 | jsize len, \ |
1754 | const ElementType *buf)) \ |
1755 | functionEnter(thr); \ |
1756 | IN_VM( \ |
1757 | check_primitive_array_type(thr, array, ElementTag); \ |
1758 | ) \ |
1759 | UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ |
1760 | functionExit(thr); \ |
1761 | JNI_END |
1762 | |
1763 | WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) |
1764 | WRAPPER_SetScalarArrayRegion(T_BYTE, jbyte, Byte) |
1765 | WRAPPER_SetScalarArrayRegion(T_SHORT, jshort, Short) |
1766 | WRAPPER_SetScalarArrayRegion(T_CHAR, jchar, Char) |
1767 | WRAPPER_SetScalarArrayRegion(T_INT, jint, Int) |
1768 | WRAPPER_SetScalarArrayRegion(T_LONG, jlong, Long) |
1769 | WRAPPER_SetScalarArrayRegion(T_FLOAT, jfloat, Float) |
1770 | WRAPPER_SetScalarArrayRegion(T_DOUBLE, jdouble, Double) |
1771 | |
1772 | JNI_ENTRY_CHECKED(jint, |
1773 | checked_jni_RegisterNatives(JNIEnv *env, |
1774 | jclass clazz, |
1775 | const JNINativeMethod *methods, |
1776 | jint nMethods)) |
1777 | functionEnter(thr); |
1778 | jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); |
1779 | functionExit(thr); |
1780 | return result; |
1781 | JNI_END |
1782 | |
1783 | JNI_ENTRY_CHECKED(jint, |
1784 | checked_jni_UnregisterNatives(JNIEnv *env, |
1785 | jclass clazz)) |
1786 | functionEnter(thr); |
1787 | jint result = UNCHECKED()->UnregisterNatives(env,clazz); |
1788 | functionExit(thr); |
1789 | return result; |
1790 | JNI_END |
1791 | |
1792 | JNI_ENTRY_CHECKED(jint, |
1793 | checked_jni_MonitorEnter(JNIEnv *env, |
1794 | jobject obj)) |
1795 | functionEnter(thr); |
1796 | IN_VM( |
1797 | jniCheck::validate_object(thr, obj); |
1798 | ) |
1799 | jint result = UNCHECKED()->MonitorEnter(env,obj); |
1800 | functionExit(thr); |
1801 | return result; |
1802 | JNI_END |
1803 | |
1804 | JNI_ENTRY_CHECKED(jint, |
1805 | checked_jni_MonitorExit(JNIEnv *env, |
1806 | jobject obj)) |
1807 | functionEnterExceptionAllowed(thr); |
1808 | IN_VM( |
1809 | jniCheck::validate_object(thr, obj); |
1810 | ) |
1811 | jint result = UNCHECKED()->MonitorExit(env,obj); |
1812 | functionExit(thr); |
1813 | return result; |
1814 | JNI_END |
1815 | |
1816 | JNI_ENTRY_CHECKED(jint, |
1817 | checked_jni_GetJavaVM(JNIEnv *env, |
1818 | JavaVM **vm)) |
1819 | functionEnter(thr); |
1820 | jint result = UNCHECKED()->GetJavaVM(env,vm); |
1821 | functionExit(thr); |
1822 | return result; |
1823 | JNI_END |
1824 | |
1825 | JNI_ENTRY_CHECKED(void, |
1826 | checked_jni_GetStringRegion(JNIEnv *env, |
1827 | jstring str, |
1828 | jsize start, |
1829 | jsize len, |
1830 | jchar *buf)) |
1831 | functionEnter(thr); |
1832 | IN_VM( |
1833 | checkString(thr, str); |
1834 | ) |
1835 | UNCHECKED()->GetStringRegion(env, str, start, len, buf); |
1836 | functionExit(thr); |
1837 | JNI_END |
1838 | |
1839 | JNI_ENTRY_CHECKED(void, |
1840 | checked_jni_GetStringUTFRegion(JNIEnv *env, |
1841 | jstring str, |
1842 | jsize start, |
1843 | jsize len, |
1844 | char *buf)) |
1845 | functionEnter(thr); |
1846 | IN_VM( |
1847 | checkString(thr, str); |
1848 | ) |
1849 | UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); |
1850 | functionExit(thr); |
1851 | JNI_END |
1852 | |
1853 | JNI_ENTRY_CHECKED(void *, |
1854 | checked_jni_GetPrimitiveArrayCritical(JNIEnv *env, |
1855 | jarray array, |
1856 | jboolean *isCopy)) |
1857 | functionEnterCritical(thr); |
1858 | IN_VM( |
1859 | check_is_primitive_array(thr, array); |
1860 | ) |
1861 | void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy); |
1862 | if (result != NULL) { |
1863 | result = check_jni_wrap_copy_array(thr, array, result); |
1864 | } |
1865 | functionExit(thr); |
1866 | return result; |
1867 | JNI_END |
1868 | |
1869 | JNI_ENTRY_CHECKED(void, |
1870 | checked_jni_ReleasePrimitiveArrayCritical(JNIEnv *env, |
1871 | jarray array, |
1872 | void *carray, |
1873 | jint mode)) |
1874 | functionEnterCriticalExceptionAllowed(thr); |
1875 | IN_VM( |
1876 | check_is_primitive_array(thr, array); |
1877 | ) |
1878 | // Check the element array... |
1879 | void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical" , array, carray, mode); |
1880 | UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode); |
1881 | functionExit(thr); |
1882 | JNI_END |
1883 | |
1884 | JNI_ENTRY_CHECKED(const jchar*, |
1885 | checked_jni_GetStringCritical(JNIEnv *env, |
1886 | jstring string, |
1887 | jboolean *isCopy)) |
1888 | functionEnterCritical(thr); |
1889 | IN_VM( |
1890 | checkString(thr, string); |
1891 | ) |
1892 | const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); |
1893 | functionExit(thr); |
1894 | return result; |
1895 | JNI_END |
1896 | |
1897 | JNI_ENTRY_CHECKED(void, |
1898 | checked_jni_ReleaseStringCritical(JNIEnv *env, |
1899 | jstring str, |
1900 | const jchar *chars)) |
1901 | functionEnterCriticalExceptionAllowed(thr); |
1902 | IN_VM( |
1903 | checkString(thr, str); |
1904 | ) |
1905 | /* The Hotspot JNI code does not use the parameters, so just check the |
1906 | * string parameter as a minor sanity check |
1907 | */ |
1908 | UNCHECKED()->ReleaseStringCritical(env, str, chars); |
1909 | functionExit(thr); |
1910 | JNI_END |
1911 | |
1912 | JNI_ENTRY_CHECKED(jweak, |
1913 | checked_jni_NewWeakGlobalRef(JNIEnv *env, |
1914 | jobject obj)) |
1915 | functionEnter(thr); |
1916 | IN_VM( |
1917 | if (obj != NULL) { |
1918 | jniCheck::validate_handle(thr, obj); |
1919 | } |
1920 | ) |
1921 | jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); |
1922 | functionExit(thr); |
1923 | return result; |
1924 | JNI_END |
1925 | |
1926 | JNI_ENTRY_CHECKED(void, |
1927 | checked_jni_DeleteWeakGlobalRef(JNIEnv *env, |
1928 | jweak ref)) |
1929 | functionEnterExceptionAllowed(thr); |
1930 | UNCHECKED()->DeleteWeakGlobalRef(env, ref); |
1931 | functionExit(thr); |
1932 | JNI_END |
1933 | |
1934 | JNI_ENTRY_CHECKED(jboolean, |
1935 | checked_jni_ExceptionCheck(JNIEnv *env)) |
1936 | thr->clear_pending_jni_exception_check(); |
1937 | functionEnterExceptionAllowed(thr); |
1938 | jboolean result = UNCHECKED()->ExceptionCheck(env); |
1939 | functionExit(thr); |
1940 | return result; |
1941 | JNI_END |
1942 | |
1943 | JNI_ENTRY_CHECKED(jobject, |
1944 | checked_jni_NewDirectByteBuffer(JNIEnv *env, |
1945 | void *address, |
1946 | jlong capacity)) |
1947 | functionEnter(thr); |
1948 | jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); |
1949 | functionExit(thr); |
1950 | return result; |
1951 | JNI_END |
1952 | |
1953 | JNI_ENTRY_CHECKED(void *, |
1954 | checked_jni_GetDirectBufferAddress(JNIEnv *env, |
1955 | jobject buf)) |
1956 | functionEnter(thr); |
1957 | void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); |
1958 | functionExit(thr); |
1959 | return result; |
1960 | JNI_END |
1961 | |
1962 | JNI_ENTRY_CHECKED(jlong, |
1963 | checked_jni_GetDirectBufferCapacity(JNIEnv *env, |
1964 | jobject buf)) |
1965 | functionEnter(thr); |
1966 | jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); |
1967 | functionExit(thr); |
1968 | return result; |
1969 | JNI_END |
1970 | |
1971 | JNI_ENTRY_CHECKED(jobjectRefType, |
1972 | checked_jni_GetObjectRefType(JNIEnv *env, |
1973 | jobject obj)) |
1974 | functionEnter(thr); |
1975 | /* validate the object being passed */ |
1976 | IN_VM( |
1977 | jniCheck::validate_object(thr, obj); |
1978 | ) |
1979 | jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); |
1980 | functionExit(thr); |
1981 | return result; |
1982 | JNI_END |
1983 | |
1984 | |
1985 | JNI_ENTRY_CHECKED(jint, |
1986 | checked_jni_GetVersion(JNIEnv *env)) |
1987 | functionEnter(thr); |
1988 | jint result = UNCHECKED()->GetVersion(env); |
1989 | functionExit(thr); |
1990 | return result; |
1991 | JNI_END |
1992 | |
1993 | JNI_ENTRY_CHECKED(jobject, |
1994 | checked_jni_GetModule(JNIEnv *env, |
1995 | jclass clazz)) |
1996 | functionEnter(thr); |
1997 | jobject result = UNCHECKED()->GetModule(env,clazz); |
1998 | functionExit(thr); |
1999 | return result; |
2000 | JNI_END |
2001 | |
2002 | /* |
2003 | * Structure containing all checked jni functions |
2004 | */ |
2005 | struct JNINativeInterface_ checked_jni_NativeInterface = { |
2006 | NULL, |
2007 | NULL, |
2008 | NULL, |
2009 | |
2010 | NULL, |
2011 | |
2012 | checked_jni_GetVersion, |
2013 | |
2014 | checked_jni_DefineClass, |
2015 | checked_jni_FindClass, |
2016 | |
2017 | checked_jni_FromReflectedMethod, |
2018 | checked_jni_FromReflectedField, |
2019 | |
2020 | checked_jni_ToReflectedMethod, |
2021 | |
2022 | checked_jni_GetSuperclass, |
2023 | checked_jni_IsAssignableFrom, |
2024 | |
2025 | checked_jni_ToReflectedField, |
2026 | |
2027 | checked_jni_Throw, |
2028 | checked_jni_ThrowNew, |
2029 | checked_jni_ExceptionOccurred, |
2030 | checked_jni_ExceptionDescribe, |
2031 | checked_jni_ExceptionClear, |
2032 | checked_jni_FatalError, |
2033 | |
2034 | checked_jni_PushLocalFrame, |
2035 | checked_jni_PopLocalFrame, |
2036 | |
2037 | checked_jni_NewGlobalRef, |
2038 | checked_jni_DeleteGlobalRef, |
2039 | checked_jni_DeleteLocalRef, |
2040 | checked_jni_IsSameObject, |
2041 | |
2042 | checked_jni_NewLocalRef, |
2043 | checked_jni_EnsureLocalCapacity, |
2044 | |
2045 | checked_jni_AllocObject, |
2046 | checked_jni_NewObject, |
2047 | checked_jni_NewObjectV, |
2048 | checked_jni_NewObjectA, |
2049 | |
2050 | checked_jni_GetObjectClass, |
2051 | checked_jni_IsInstanceOf, |
2052 | |
2053 | checked_jni_GetMethodID, |
2054 | |
2055 | checked_jni_CallObjectMethod, |
2056 | checked_jni_CallObjectMethodV, |
2057 | checked_jni_CallObjectMethodA, |
2058 | checked_jni_CallBooleanMethod, |
2059 | checked_jni_CallBooleanMethodV, |
2060 | checked_jni_CallBooleanMethodA, |
2061 | checked_jni_CallByteMethod, |
2062 | checked_jni_CallByteMethodV, |
2063 | checked_jni_CallByteMethodA, |
2064 | checked_jni_CallCharMethod, |
2065 | checked_jni_CallCharMethodV, |
2066 | checked_jni_CallCharMethodA, |
2067 | checked_jni_CallShortMethod, |
2068 | checked_jni_CallShortMethodV, |
2069 | checked_jni_CallShortMethodA, |
2070 | checked_jni_CallIntMethod, |
2071 | checked_jni_CallIntMethodV, |
2072 | checked_jni_CallIntMethodA, |
2073 | checked_jni_CallLongMethod, |
2074 | checked_jni_CallLongMethodV, |
2075 | checked_jni_CallLongMethodA, |
2076 | checked_jni_CallFloatMethod, |
2077 | checked_jni_CallFloatMethodV, |
2078 | checked_jni_CallFloatMethodA, |
2079 | checked_jni_CallDoubleMethod, |
2080 | checked_jni_CallDoubleMethodV, |
2081 | checked_jni_CallDoubleMethodA, |
2082 | checked_jni_CallVoidMethod, |
2083 | checked_jni_CallVoidMethodV, |
2084 | checked_jni_CallVoidMethodA, |
2085 | |
2086 | checked_jni_CallNonvirtualObjectMethod, |
2087 | checked_jni_CallNonvirtualObjectMethodV, |
2088 | checked_jni_CallNonvirtualObjectMethodA, |
2089 | checked_jni_CallNonvirtualBooleanMethod, |
2090 | checked_jni_CallNonvirtualBooleanMethodV, |
2091 | checked_jni_CallNonvirtualBooleanMethodA, |
2092 | checked_jni_CallNonvirtualByteMethod, |
2093 | checked_jni_CallNonvirtualByteMethodV, |
2094 | checked_jni_CallNonvirtualByteMethodA, |
2095 | checked_jni_CallNonvirtualCharMethod, |
2096 | checked_jni_CallNonvirtualCharMethodV, |
2097 | checked_jni_CallNonvirtualCharMethodA, |
2098 | checked_jni_CallNonvirtualShortMethod, |
2099 | checked_jni_CallNonvirtualShortMethodV, |
2100 | checked_jni_CallNonvirtualShortMethodA, |
2101 | checked_jni_CallNonvirtualIntMethod, |
2102 | checked_jni_CallNonvirtualIntMethodV, |
2103 | checked_jni_CallNonvirtualIntMethodA, |
2104 | checked_jni_CallNonvirtualLongMethod, |
2105 | checked_jni_CallNonvirtualLongMethodV, |
2106 | checked_jni_CallNonvirtualLongMethodA, |
2107 | checked_jni_CallNonvirtualFloatMethod, |
2108 | checked_jni_CallNonvirtualFloatMethodV, |
2109 | checked_jni_CallNonvirtualFloatMethodA, |
2110 | checked_jni_CallNonvirtualDoubleMethod, |
2111 | checked_jni_CallNonvirtualDoubleMethodV, |
2112 | checked_jni_CallNonvirtualDoubleMethodA, |
2113 | checked_jni_CallNonvirtualVoidMethod, |
2114 | checked_jni_CallNonvirtualVoidMethodV, |
2115 | checked_jni_CallNonvirtualVoidMethodA, |
2116 | |
2117 | checked_jni_GetFieldID, |
2118 | |
2119 | checked_jni_GetObjectField, |
2120 | checked_jni_GetBooleanField, |
2121 | checked_jni_GetByteField, |
2122 | checked_jni_GetCharField, |
2123 | checked_jni_GetShortField, |
2124 | checked_jni_GetIntField, |
2125 | checked_jni_GetLongField, |
2126 | checked_jni_GetFloatField, |
2127 | checked_jni_GetDoubleField, |
2128 | |
2129 | checked_jni_SetObjectField, |
2130 | checked_jni_SetBooleanField, |
2131 | checked_jni_SetByteField, |
2132 | checked_jni_SetCharField, |
2133 | checked_jni_SetShortField, |
2134 | checked_jni_SetIntField, |
2135 | checked_jni_SetLongField, |
2136 | checked_jni_SetFloatField, |
2137 | checked_jni_SetDoubleField, |
2138 | |
2139 | checked_jni_GetStaticMethodID, |
2140 | |
2141 | checked_jni_CallStaticObjectMethod, |
2142 | checked_jni_CallStaticObjectMethodV, |
2143 | checked_jni_CallStaticObjectMethodA, |
2144 | checked_jni_CallStaticBooleanMethod, |
2145 | checked_jni_CallStaticBooleanMethodV, |
2146 | checked_jni_CallStaticBooleanMethodA, |
2147 | checked_jni_CallStaticByteMethod, |
2148 | checked_jni_CallStaticByteMethodV, |
2149 | checked_jni_CallStaticByteMethodA, |
2150 | checked_jni_CallStaticCharMethod, |
2151 | checked_jni_CallStaticCharMethodV, |
2152 | checked_jni_CallStaticCharMethodA, |
2153 | checked_jni_CallStaticShortMethod, |
2154 | checked_jni_CallStaticShortMethodV, |
2155 | checked_jni_CallStaticShortMethodA, |
2156 | checked_jni_CallStaticIntMethod, |
2157 | checked_jni_CallStaticIntMethodV, |
2158 | checked_jni_CallStaticIntMethodA, |
2159 | checked_jni_CallStaticLongMethod, |
2160 | checked_jni_CallStaticLongMethodV, |
2161 | checked_jni_CallStaticLongMethodA, |
2162 | checked_jni_CallStaticFloatMethod, |
2163 | checked_jni_CallStaticFloatMethodV, |
2164 | checked_jni_CallStaticFloatMethodA, |
2165 | checked_jni_CallStaticDoubleMethod, |
2166 | checked_jni_CallStaticDoubleMethodV, |
2167 | checked_jni_CallStaticDoubleMethodA, |
2168 | checked_jni_CallStaticVoidMethod, |
2169 | checked_jni_CallStaticVoidMethodV, |
2170 | checked_jni_CallStaticVoidMethodA, |
2171 | |
2172 | checked_jni_GetStaticFieldID, |
2173 | |
2174 | checked_jni_GetStaticObjectField, |
2175 | checked_jni_GetStaticBooleanField, |
2176 | checked_jni_GetStaticByteField, |
2177 | checked_jni_GetStaticCharField, |
2178 | checked_jni_GetStaticShortField, |
2179 | checked_jni_GetStaticIntField, |
2180 | checked_jni_GetStaticLongField, |
2181 | checked_jni_GetStaticFloatField, |
2182 | checked_jni_GetStaticDoubleField, |
2183 | |
2184 | checked_jni_SetStaticObjectField, |
2185 | checked_jni_SetStaticBooleanField, |
2186 | checked_jni_SetStaticByteField, |
2187 | checked_jni_SetStaticCharField, |
2188 | checked_jni_SetStaticShortField, |
2189 | checked_jni_SetStaticIntField, |
2190 | checked_jni_SetStaticLongField, |
2191 | checked_jni_SetStaticFloatField, |
2192 | checked_jni_SetStaticDoubleField, |
2193 | |
2194 | checked_jni_NewString, |
2195 | checked_jni_GetStringLength, |
2196 | checked_jni_GetStringChars, |
2197 | checked_jni_ReleaseStringChars, |
2198 | |
2199 | checked_jni_NewStringUTF, |
2200 | checked_jni_GetStringUTFLength, |
2201 | checked_jni_GetStringUTFChars, |
2202 | checked_jni_ReleaseStringUTFChars, |
2203 | |
2204 | checked_jni_GetArrayLength, |
2205 | |
2206 | checked_jni_NewObjectArray, |
2207 | checked_jni_GetObjectArrayElement, |
2208 | checked_jni_SetObjectArrayElement, |
2209 | |
2210 | checked_jni_NewBooleanArray, |
2211 | checked_jni_NewByteArray, |
2212 | checked_jni_NewCharArray, |
2213 | checked_jni_NewShortArray, |
2214 | checked_jni_NewIntArray, |
2215 | checked_jni_NewLongArray, |
2216 | checked_jni_NewFloatArray, |
2217 | checked_jni_NewDoubleArray, |
2218 | |
2219 | checked_jni_GetBooleanArrayElements, |
2220 | checked_jni_GetByteArrayElements, |
2221 | checked_jni_GetCharArrayElements, |
2222 | checked_jni_GetShortArrayElements, |
2223 | checked_jni_GetIntArrayElements, |
2224 | checked_jni_GetLongArrayElements, |
2225 | checked_jni_GetFloatArrayElements, |
2226 | checked_jni_GetDoubleArrayElements, |
2227 | |
2228 | checked_jni_ReleaseBooleanArrayElements, |
2229 | checked_jni_ReleaseByteArrayElements, |
2230 | checked_jni_ReleaseCharArrayElements, |
2231 | checked_jni_ReleaseShortArrayElements, |
2232 | checked_jni_ReleaseIntArrayElements, |
2233 | checked_jni_ReleaseLongArrayElements, |
2234 | checked_jni_ReleaseFloatArrayElements, |
2235 | checked_jni_ReleaseDoubleArrayElements, |
2236 | |
2237 | checked_jni_GetBooleanArrayRegion, |
2238 | checked_jni_GetByteArrayRegion, |
2239 | checked_jni_GetCharArrayRegion, |
2240 | checked_jni_GetShortArrayRegion, |
2241 | checked_jni_GetIntArrayRegion, |
2242 | checked_jni_GetLongArrayRegion, |
2243 | checked_jni_GetFloatArrayRegion, |
2244 | checked_jni_GetDoubleArrayRegion, |
2245 | |
2246 | checked_jni_SetBooleanArrayRegion, |
2247 | checked_jni_SetByteArrayRegion, |
2248 | checked_jni_SetCharArrayRegion, |
2249 | checked_jni_SetShortArrayRegion, |
2250 | checked_jni_SetIntArrayRegion, |
2251 | checked_jni_SetLongArrayRegion, |
2252 | checked_jni_SetFloatArrayRegion, |
2253 | checked_jni_SetDoubleArrayRegion, |
2254 | |
2255 | checked_jni_RegisterNatives, |
2256 | checked_jni_UnregisterNatives, |
2257 | |
2258 | checked_jni_MonitorEnter, |
2259 | checked_jni_MonitorExit, |
2260 | |
2261 | checked_jni_GetJavaVM, |
2262 | |
2263 | checked_jni_GetStringRegion, |
2264 | checked_jni_GetStringUTFRegion, |
2265 | |
2266 | checked_jni_GetPrimitiveArrayCritical, |
2267 | checked_jni_ReleasePrimitiveArrayCritical, |
2268 | |
2269 | checked_jni_GetStringCritical, |
2270 | checked_jni_ReleaseStringCritical, |
2271 | |
2272 | checked_jni_NewWeakGlobalRef, |
2273 | checked_jni_DeleteWeakGlobalRef, |
2274 | |
2275 | checked_jni_ExceptionCheck, |
2276 | |
2277 | checked_jni_NewDirectByteBuffer, |
2278 | checked_jni_GetDirectBufferAddress, |
2279 | checked_jni_GetDirectBufferCapacity, |
2280 | |
2281 | // New 1.6 Features |
2282 | |
2283 | checked_jni_GetObjectRefType, |
2284 | |
2285 | // Module Features |
2286 | |
2287 | checked_jni_GetModule |
2288 | }; |
2289 | |
2290 | |
2291 | // Returns the function structure |
2292 | struct JNINativeInterface_* jni_functions_check() { |
2293 | |
2294 | unchecked_jni_NativeInterface = jni_functions_nocheck(); |
2295 | |
2296 | // make sure the last pointer in the checked table is not null, indicating |
2297 | // an addition to the JNINativeInterface_ structure without initializing |
2298 | // it in the checked table. |
2299 | debug_only(int *lastPtr = (int *)((char *)&checked_jni_NativeInterface + \ |
2300 | sizeof(*unchecked_jni_NativeInterface) - sizeof(char *));) |
2301 | assert(*lastPtr != 0, |
2302 | "Mismatched JNINativeInterface tables, check for new entries" ); |
2303 | |
2304 | // with -verbose:jni this message will print |
2305 | if (PrintJNIResolving) { |
2306 | tty->print_cr("Checked JNI functions are being used to " \ |
2307 | "validate JNI usage" ); |
2308 | } |
2309 | |
2310 | return &checked_jni_NativeInterface; |
2311 | } |
2312 | |