1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jni_internal.h"
18
19 #include <cstdarg>
20 #include <log/log.h>
21 #include <memory>
22 #include <utility>
23
24 #include "art_field-inl.h"
25 #include "art_method-inl.h"
26 #include "base/allocator.h"
27 #include "base/atomic.h"
28 #include "base/casts.h"
29 #include "base/enums.h"
30 #include "base/file_utils.h"
31 #include "base/logging.h" // For VLOG.
32 #include "base/mutex.h"
33 #include "base/safe_map.h"
34 #include "base/stl_util.h"
35 #include "class_linker-inl.h"
36 #include "class_root-inl.h"
37 #include "dex/dex_file-inl.h"
38 #include "dex/utf-inl.h"
39 #include "fault_handler.h"
40 #include "hidden_api.h"
41 #include "gc/accounting/card_table-inl.h"
42 #include "gc_root.h"
43 #include "indirect_reference_table-inl.h"
44 #include "interpreter/interpreter.h"
45 #include "java_vm_ext.h"
46 #include "jni_env_ext.h"
47 #include "jvalue-inl.h"
48 #include "mirror/class-alloc-inl.h"
49 #include "mirror/class-inl.h"
50 #include "mirror/class_loader.h"
51 #include "mirror/dex_cache-inl.h"
52 #include "mirror/field.h"
53 #include "mirror/method.h"
54 #include "mirror/object-inl.h"
55 #include "mirror/object_array-alloc-inl.h"
56 #include "mirror/object_array-inl.h"
57 #include "mirror/string-alloc-inl.h"
58 #include "mirror/string-inl.h"
59 #include "mirror/throwable.h"
60 #include "nativehelper/scoped_local_ref.h"
61 #include "parsed_options.h"
62 #include "reflection.h"
63 #include "runtime.h"
64 #include "scoped_thread_state_change-inl.h"
65 #include "thread.h"
66 #include "well_known_classes.h"
67
68 namespace art {
69
70 namespace {
71
72 // Frees the given va_list upon destruction.
73 // This also guards the returns from inside of the CHECK_NON_NULL_ARGUMENTs.
74 struct ScopedVAArgs {
ScopedVAArgsart::__anon29e82fe90111::ScopedVAArgs75 explicit ScopedVAArgs(va_list* args): args(args) {}
76 ScopedVAArgs(const ScopedVAArgs&) = delete;
77 ScopedVAArgs(ScopedVAArgs&&) = delete;
~ScopedVAArgsart::__anon29e82fe90111::ScopedVAArgs78 ~ScopedVAArgs() { va_end(*args); }
79
80 private:
81 va_list* args;
82 };
83
84 constexpr char kBadUtf8ReplacementChar[] = "?";
85
86 // This is a modified version of CountModifiedUtf8Chars() from utf.cc
87 // with extra checks and different output options.
88 //
89 // The `good` functor can process valid characters.
90 // The `bad` functor is called when we find an invalid character and
91 // returns true to abort processing, or false to continue processing.
92 //
93 // When aborted, VisitModifiedUtf8Chars() returns 0, otherwise the
94 // number of UTF-16 chars.
95 template <typename GoodFunc, typename BadFunc>
VisitModifiedUtf8Chars(const char * utf8,size_t byte_count,GoodFunc good,BadFunc bad)96 size_t VisitModifiedUtf8Chars(const char* utf8, size_t byte_count, GoodFunc good, BadFunc bad) {
97 DCHECK_LE(byte_count, strlen(utf8));
98 size_t len = 0;
99 const char* end = utf8 + byte_count;
100 while (utf8 != end) {
101 int ic = *utf8;
102 if (LIKELY((ic & 0x80) == 0)) {
103 // One-byte encoding.
104 good(utf8, 1u);
105 utf8 += 1u;
106 len += 1u;
107 continue;
108 }
109 auto is_ascii = [utf8]() {
110 const char* ptr = utf8; // Make a copy that can be modified by GetUtf16FromUtf8().
111 return mirror::String::IsASCII(dchecked_integral_cast<uint16_t>(GetUtf16FromUtf8(&ptr)));
112 };
113 // Note: Neither CountModifiedUtf8Chars() nor GetUtf16FromUtf8() checks whether
114 // the bit 0x40 is correctly set in the leading byte of a multi-byte sequence.
115 if ((ic & 0x20) == 0) {
116 // Two-byte encoding.
117 if (static_cast<size_t>(end - utf8) < 2u) {
118 return bad() ? 0u : len + 1u; // Reached end of sequence
119 }
120 if (mirror::kUseStringCompression && is_ascii()) {
121 if (bad()) {
122 return 0u;
123 }
124 } else {
125 good(utf8, 2u);
126 }
127 utf8 += 2u;
128 len += 1u;
129 continue;
130 }
131 if ((ic & 0x10) == 0) {
132 // Three-byte encoding.
133 if (static_cast<size_t>(end - utf8) < 3u) {
134 return bad() ? 0u : len + 1u; // Reached end of sequence
135 }
136 if (mirror::kUseStringCompression && is_ascii()) {
137 if (bad()) {
138 return 0u;
139 }
140 } else {
141 good(utf8, 3u);
142 }
143 utf8 += 3u;
144 len += 1u;
145 continue;
146 }
147
148 // Four-byte encoding: needs to be converted into a surrogate pair.
149 // The decoded chars are never ASCII.
150 if (static_cast<size_t>(end - utf8) < 4u) {
151 return bad() ? 0u : len + 1u; // Reached end of sequence
152 }
153 good(utf8, 4u);
154 utf8 += 4u;
155 len += 2u;
156 }
157 return len;
158 }
159
160 } // namespace
161
162 // Consider turning this on when there is errors which could be related to JNI array copies such as
163 // things not rendering correctly. E.g. b/16858794
164 static constexpr bool kWarnJniAbort = false;
165
GetJniAccessContext(Thread * self)166 static hiddenapi::AccessContext GetJniAccessContext(Thread* self)
167 REQUIRES_SHARED(Locks::mutator_lock_) {
168 // Construct AccessContext from the first calling class on stack.
169 // If the calling class cannot be determined, e.g. unattached threads,
170 // we conservatively assume the caller is trusted.
171 ObjPtr<mirror::Class> caller = GetCallingClass(self, /* num_frames= */ 1);
172 return caller.IsNull() ? hiddenapi::AccessContext(/* is_trusted= */ true)
173 : hiddenapi::AccessContext(caller);
174 }
175
176 template<typename T>
ShouldDenyAccessToMember(T * member,Thread * self,hiddenapi::AccessMethod access_kind=hiddenapi::AccessMethod::kJNI)177 ALWAYS_INLINE static bool ShouldDenyAccessToMember(
178 T* member,
179 Thread* self,
180 hiddenapi::AccessMethod access_kind = hiddenapi::AccessMethod::kJNI)
181 REQUIRES_SHARED(Locks::mutator_lock_) {
182 return hiddenapi::ShouldDenyAccessToMember(
183 member,
184 [self]() REQUIRES_SHARED(Locks::mutator_lock_) { return GetJniAccessContext(self); },
185 access_kind);
186 }
187
188 // Helpers to call instrumentation functions for fields. These take jobjects so we don't need to set
189 // up handles for the rare case where these actually do something. Once these functions return it is
190 // possible there will be a pending exception if the instrumentation happens to throw one.
NotifySetObjectField(ArtField * field,jobject obj,jobject jval)191 static void NotifySetObjectField(ArtField* field, jobject obj, jobject jval)
192 REQUIRES_SHARED(Locks::mutator_lock_) {
193 DCHECK_EQ(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
194 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
195 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
196 Thread* self = Thread::Current();
197 ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc=*/ nullptr,
198 /*check_suspended=*/ true,
199 /*abort_on_error=*/ false);
200
201 if (cur_method == nullptr) {
202 // Set/Get Fields can be issued without a method during runtime startup/teardown. Ignore all
203 // of these changes.
204 return;
205 }
206 DCHECK(cur_method->IsNative());
207 JValue val;
208 val.SetL(self->DecodeJObject(jval));
209 instrumentation->FieldWriteEvent(self,
210 self->DecodeJObject(obj),
211 cur_method,
212 0, // dex_pc is always 0 since this is a native method.
213 field,
214 val);
215 }
216 }
217
NotifySetPrimitiveField(ArtField * field,jobject obj,JValue val)218 static void NotifySetPrimitiveField(ArtField* field, jobject obj, JValue val)
219 REQUIRES_SHARED(Locks::mutator_lock_) {
220 DCHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
221 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
222 if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
223 Thread* self = Thread::Current();
224 ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc=*/ nullptr,
225 /*check_suspended=*/ true,
226 /*abort_on_error=*/ false);
227
228 if (cur_method == nullptr) {
229 // Set/Get Fields can be issued without a method during runtime startup/teardown. Ignore all
230 // of these changes.
231 return;
232 }
233 DCHECK(cur_method->IsNative());
234 instrumentation->FieldWriteEvent(self,
235 self->DecodeJObject(obj),
236 cur_method,
237 0, // dex_pc is always 0 since this is a native method.
238 field,
239 val);
240 }
241 }
242
NotifyGetField(ArtField * field,jobject obj)243 static void NotifyGetField(ArtField* field, jobject obj)
244 REQUIRES_SHARED(Locks::mutator_lock_) {
245 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
246 if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
247 Thread* self = Thread::Current();
248 ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc=*/ nullptr,
249 /*check_suspended=*/ true,
250 /*abort_on_error=*/ false);
251
252 if (cur_method == nullptr) {
253 // Set/Get Fields can be issued without a method during runtime startup/teardown. Ignore all
254 // of these changes.
255 return;
256 }
257 DCHECK(cur_method->IsNative());
258 instrumentation->FieldReadEvent(self,
259 self->DecodeJObject(obj),
260 cur_method,
261 0, // dex_pc is always 0 since this is a native method.
262 field);
263 }
264 }
265
266 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
267 // separated with slashes but aren't wrapped with "L;" like regular descriptors
268 // (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
269 // exception; there the "L;" must be present ("[La/b/C;"). Historically we've
270 // supported names with dots too (such as "a.b.C").
NormalizeJniClassDescriptor(const char * name)271 static std::string NormalizeJniClassDescriptor(const char* name) {
272 std::string result;
273 // Add the missing "L;" if necessary.
274 if (name[0] == '[') {
275 result = name;
276 } else {
277 result += 'L';
278 result += name;
279 result += ';';
280 }
281 // Rewrite '.' as '/' for backwards compatibility.
282 if (result.find('.') != std::string::npos) {
283 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
284 << "\"" << name << "\"";
285 std::replace(result.begin(), result.end(), '.', '/');
286 }
287 return result;
288 }
289
ReportInvalidJNINativeMethod(const ScopedObjectAccess & soa,ObjPtr<mirror::Class> c,const char * kind,jint idx)290 static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa,
291 ObjPtr<mirror::Class> c,
292 const char* kind,
293 jint idx)
294 REQUIRES_SHARED(Locks::mutator_lock_) {
295 LOG(ERROR)
296 << "Failed to register native method in " << c->PrettyDescriptor()
297 << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
298 << ": " << kind << " is null at index " << idx;
299 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
300 "%s is null at index %d",
301 kind,
302 idx);
303 }
304
305 template<bool kEnableIndexIds>
FindMethodID(ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)306 static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
307 const char* name, const char* sig, bool is_static)
308 REQUIRES_SHARED(Locks::mutator_lock_) {
309 return jni::EncodeArtMethod<kEnableIndexIds>(FindMethodJNI(soa, jni_class, name, sig, is_static));
310 }
311
312 template<bool kEnableIndexIds>
GetClassLoader(const ScopedObjectAccess & soa)313 static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
314 REQUIRES_SHARED(Locks::mutator_lock_) {
315 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
316 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
317 if (method ==
318 jni::DecodeArtMethod<kEnableIndexIds>(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
319 return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
320 }
321 // If we have a method, use its ClassLoader for context.
322 if (method != nullptr) {
323 return method->GetDeclaringClass()->GetClassLoader();
324 }
325 // We don't have a method, so try to use the system ClassLoader.
326 ObjPtr<mirror::ClassLoader> class_loader =
327 soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader());
328 if (class_loader != nullptr) {
329 return class_loader;
330 }
331 // See if the override ClassLoader is set for gtests.
332 class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
333 if (class_loader != nullptr) {
334 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
335 // image.
336 CHECK(Runtime::Current()->IsAotCompiler());
337 CHECK(!Runtime::Current()->IsCompilingBootImage());
338 return class_loader;
339 }
340 // Use the BOOTCLASSPATH.
341 return nullptr;
342 }
343
344 template<bool kEnableIndexIds>
FindFieldID(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)345 static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
346 const char* sig, bool is_static)
347 REQUIRES_SHARED(Locks::mutator_lock_) {
348 return jni::EncodeArtField<kEnableIndexIds>(FindFieldJNI(soa, jni_class, name, sig, is_static));
349 }
350
ThrowAIOOBE(ScopedObjectAccess & soa,ObjPtr<mirror::Array> array,jsize start,jsize length,const char * identifier)351 static void ThrowAIOOBE(ScopedObjectAccess& soa,
352 ObjPtr<mirror::Array> array,
353 jsize start,
354 jsize length,
355 const char* identifier)
356 REQUIRES_SHARED(Locks::mutator_lock_) {
357 std::string type(array->PrettyTypeOf());
358 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
359 "%s offset=%d length=%d %s.length=%d",
360 type.c_str(), start, length, identifier, array->GetLength());
361 }
362
ThrowSIOOBE(ScopedObjectAccess & soa,jsize start,jsize length,jsize array_length)363 static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
364 jsize array_length)
365 REQUIRES_SHARED(Locks::mutator_lock_) {
366 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
367 "offset=%d length=%d string.length()=%d", start, length,
368 array_length);
369 }
370
ThrowNoSuchMethodError(const ScopedObjectAccess & soa,ObjPtr<mirror::Class> c,const char * name,const char * sig,const char * kind)371 static void ThrowNoSuchMethodError(const ScopedObjectAccess& soa,
372 ObjPtr<mirror::Class> c,
373 const char* name,
374 const char* sig,
375 const char* kind)
376 REQUIRES_SHARED(Locks::mutator_lock_) {
377 std::string temp;
378 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
379 "no %s method \"%s.%s%s\"",
380 kind,
381 c->GetDescriptor(&temp),
382 name,
383 sig);
384 }
385
EnsureInitialized(Thread * self,ObjPtr<mirror::Class> klass)386 static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
387 REQUIRES_SHARED(Locks::mutator_lock_) {
388 if (LIKELY(klass->IsInitialized())) {
389 return klass;
390 }
391 StackHandleScope<1> hs(self);
392 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
393 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
394 return nullptr;
395 }
396 return h_klass.Get();
397 }
398
FindMethodJNI(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)399 ArtMethod* FindMethodJNI(const ScopedObjectAccess& soa,
400 jclass jni_class,
401 const char* name,
402 const char* sig,
403 bool is_static) {
404 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class));
405 if (c == nullptr) {
406 return nullptr;
407 }
408 ArtMethod* method = nullptr;
409 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
410 if (c->IsInterface()) {
411 method = c->FindInterfaceMethod(name, sig, pointer_size);
412 } else {
413 method = c->FindClassMethod(name, sig, pointer_size);
414 }
415 if (method != nullptr &&
416 ShouldDenyAccessToMember(method, soa.Self(), hiddenapi::AccessMethod::kNone)) {
417 // The resolved method that we have found cannot be accessed due to
418 // hiddenapi (typically it is declared up the hierarchy and is not an SDK
419 // method). Try to find an interface method from the implemented interfaces which is
420 // accessible.
421 ArtMethod* itf_method = c->FindAccessibleInterfaceMethod(method, pointer_size);
422 if (itf_method == nullptr) {
423 // No interface method. Call ShouldDenyAccessToMember again but this time
424 // with AccessMethod::kJNI to ensure that an appropriate warning is
425 // logged.
426 ShouldDenyAccessToMember(method, soa.Self(), hiddenapi::AccessMethod::kJNI);
427 method = nullptr;
428 } else {
429 // We found an interface method that is accessible, continue with the resolved method.
430 }
431 }
432 if (method == nullptr || method->IsStatic() != is_static) {
433 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
434 return nullptr;
435 }
436 return method;
437 }
438
FindFieldJNI(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)439 ArtField* FindFieldJNI(const ScopedObjectAccess& soa,
440 jclass jni_class,
441 const char* name,
442 const char* sig,
443 bool is_static) {
444 StackHandleScope<2> hs(soa.Self());
445 Handle<mirror::Class> c(
446 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class))));
447 if (c == nullptr) {
448 return nullptr;
449 }
450 ArtField* field = nullptr;
451 ObjPtr<mirror::Class> field_type;
452 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
453 if (UNLIKELY(sig[0] == '\0')) {
454 DCHECK(field == nullptr);
455 } else if (sig[1] != '\0') {
456 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
457 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
458 } else {
459 field_type = class_linker->FindPrimitiveClass(*sig);
460 }
461 if (field_type == nullptr) {
462 // Failed to find type from the signature of the field.
463 DCHECK(sig[0] == '\0' || soa.Self()->IsExceptionPending());
464 StackHandleScope<1> hs2(soa.Self());
465 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
466 soa.Self()->ClearException();
467 std::string temp;
468 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
469 "no type \"%s\" found and so no field \"%s\" "
470 "could be found in class \"%s\" or its superclasses", sig, name,
471 c->GetDescriptor(&temp));
472 if (cause != nullptr) {
473 soa.Self()->GetException()->SetCause(cause.Get());
474 }
475 return nullptr;
476 }
477 std::string temp;
478 if (is_static) {
479 field = mirror::Class::FindStaticField(
480 soa.Self(), c.Get(), name, field_type->GetDescriptor(&temp));
481 } else {
482 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
483 }
484 if (field != nullptr && ShouldDenyAccessToMember(field, soa.Self())) {
485 field = nullptr;
486 }
487 if (field == nullptr) {
488 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
489 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
490 sig, name, c->GetDescriptor(&temp));
491 return nullptr;
492 }
493 return field;
494 }
495
ThrowNewException(JNIEnv * env,jclass exception_class,const char * msg,jobject cause)496 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
497 REQUIRES(!Locks::mutator_lock_) {
498 // Turn the const char* into a java.lang.String.
499 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
500 if (msg != nullptr && s.get() == nullptr) {
501 return JNI_ERR;
502 }
503
504 // Choose an appropriate constructor and set up the arguments.
505 jvalue args[2];
506 const char* signature;
507 if (msg == nullptr && cause == nullptr) {
508 signature = "()V";
509 } else if (msg != nullptr && cause == nullptr) {
510 signature = "(Ljava/lang/String;)V";
511 args[0].l = s.get();
512 } else if (msg == nullptr && cause != nullptr) {
513 signature = "(Ljava/lang/Throwable;)V";
514 args[0].l = cause;
515 } else {
516 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
517 args[0].l = s.get();
518 args[1].l = cause;
519 }
520 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
521 if (mid == nullptr) {
522 ScopedObjectAccess soa(env);
523 LOG(ERROR) << "No <init>" << signature << " in "
524 << mirror::Class::PrettyClass(soa.Decode<mirror::Class>(exception_class));
525 return JNI_ERR;
526 }
527
528 ScopedLocalRef<jthrowable> exception(
529 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
530 if (exception.get() == nullptr) {
531 return JNI_ERR;
532 }
533 ScopedObjectAccess soa(env);
534 soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()));
535 return JNI_OK;
536 }
537
JavaVmExtFromEnv(JNIEnv * env)538 static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
539 return reinterpret_cast<JNIEnvExt*>(env)->GetVm();
540 }
541
542 #define CHECK_NON_NULL_ARGUMENT(value) \
543 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
544
545 #define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
546 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
547
548 #define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
549 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
550
551 #define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
552 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
553
554 #define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
555 if (UNLIKELY((value) == nullptr)) { \
556 JavaVmExtFromEnv(env)->JniAbort(name, #value " == null"); \
557 return return_val; \
558 }
559
560 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
561 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
562 JavaVmExtFromEnv(env)->JniAbort(__FUNCTION__, #value " == null"); \
563 return; \
564 }
565
566 template <bool kNative>
FindMethod(ObjPtr<mirror::Class> c,std::string_view name,std::string_view sig)567 static ArtMethod* FindMethod(ObjPtr<mirror::Class> c,
568 std::string_view name,
569 std::string_view sig)
570 REQUIRES_SHARED(Locks::mutator_lock_) {
571 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
572 for (auto& method : c->GetMethods(pointer_size)) {
573 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
574 return &method;
575 }
576 }
577 return nullptr;
578 }
579
580 template <bool kEnableIndexIds>
581 class JNI {
582 public:
GetVersion(JNIEnv *)583 static jint GetVersion(JNIEnv*) {
584 return JNI_VERSION_1_6;
585 }
586
DefineClass(JNIEnv *,const char *,jobject,const jbyte *,jsize)587 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
588 LOG(WARNING) << "JNI DefineClass is not supported";
589 return nullptr;
590 }
591
FindClass(JNIEnv * env,const char * name)592 static jclass FindClass(JNIEnv* env, const char* name) {
593 CHECK_NON_NULL_ARGUMENT(name);
594 Runtime* runtime = Runtime::Current();
595 ClassLinker* class_linker = runtime->GetClassLinker();
596 std::string descriptor(NormalizeJniClassDescriptor(name));
597 ScopedObjectAccess soa(env);
598 ObjPtr<mirror::Class> c = nullptr;
599 if (runtime->IsStarted()) {
600 StackHandleScope<1> hs(soa.Self());
601 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader<kEnableIndexIds>(soa)));
602 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
603 } else {
604 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
605 }
606 return soa.AddLocalReference<jclass>(c);
607 }
608
FromReflectedMethod(JNIEnv * env,jobject jlr_method)609 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
610 CHECK_NON_NULL_ARGUMENT(jlr_method);
611 ScopedObjectAccess soa(env);
612 return jni::EncodeArtMethod<kEnableIndexIds>(ArtMethod::FromReflectedMethod(soa, jlr_method));
613 }
614
FromReflectedField(JNIEnv * env,jobject jlr_field)615 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
616 CHECK_NON_NULL_ARGUMENT(jlr_field);
617 ScopedObjectAccess soa(env);
618 ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
619 if (obj_field->GetClass() != GetClassRoot<mirror::Field>()) {
620 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
621 return nullptr;
622 }
623 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(obj_field);
624 return jni::EncodeArtField<kEnableIndexIds>(field->GetArtField());
625 }
626
ToReflectedMethod(JNIEnv * env,jclass,jmethodID mid,jboolean)627 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
628 CHECK_NON_NULL_ARGUMENT(mid);
629 ScopedObjectAccess soa(env);
630 ArtMethod* m = jni::DecodeArtMethod(mid);
631 ObjPtr<mirror::Executable> method;
632 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
633 if (m->IsConstructor()) {
634 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), m);
635 } else {
636 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), m);
637 }
638 return soa.AddLocalReference<jobject>(method);
639 }
640
ToReflectedField(JNIEnv * env,jclass,jfieldID fid,jboolean)641 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
642 CHECK_NON_NULL_ARGUMENT(fid);
643 ScopedObjectAccess soa(env);
644 ArtField* f = jni::DecodeArtField(fid);
645 return soa.AddLocalReference<jobject>(
646 mirror::Field::CreateFromArtField(soa.Self(), f, true));
647 }
648
GetObjectClass(JNIEnv * env,jobject java_object)649 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
650 CHECK_NON_NULL_ARGUMENT(java_object);
651 ScopedObjectAccess soa(env);
652 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
653 return soa.AddLocalReference<jclass>(o->GetClass());
654 }
655
GetSuperclass(JNIEnv * env,jclass java_class)656 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
657 CHECK_NON_NULL_ARGUMENT(java_class);
658 ScopedObjectAccess soa(env);
659 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
660 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
661 }
662
663 // Note: java_class1 should be safely castable to java_class2, and
664 // not the other way around.
IsAssignableFrom(JNIEnv * env,jclass java_class1,jclass java_class2)665 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
666 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
667 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
668 ScopedObjectAccess soa(env);
669 ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
670 ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
671 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
672 }
673
IsInstanceOf(JNIEnv * env,jobject jobj,jclass java_class)674 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
675 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
676 if (jobj == nullptr) {
677 // Note: JNI is different from regular Java instanceof in this respect
678 return JNI_TRUE;
679 } else {
680 ScopedObjectAccess soa(env);
681 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj);
682 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
683 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
684 }
685 }
686
Throw(JNIEnv * env,jthrowable java_exception)687 static jint Throw(JNIEnv* env, jthrowable java_exception) {
688 ScopedObjectAccess soa(env);
689 ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception);
690 if (exception == nullptr) {
691 return JNI_ERR;
692 }
693 soa.Self()->SetException(exception);
694 return JNI_OK;
695 }
696
ThrowNew(JNIEnv * env,jclass c,const char * msg)697 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
698 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
699 return ThrowNewException(env, c, msg, nullptr);
700 }
701
ExceptionCheck(JNIEnv * env)702 static jboolean ExceptionCheck(JNIEnv* env) {
703 return static_cast<JNIEnvExt*>(env)->self_->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
704 }
705
ExceptionClear(JNIEnv * env)706 static void ExceptionClear(JNIEnv* env) {
707 ScopedObjectAccess soa(env);
708 soa.Self()->ClearException();
709 }
710
ExceptionDescribe(JNIEnv * env)711 static void ExceptionDescribe(JNIEnv* env) {
712 ScopedObjectAccess soa(env);
713
714 // If we have no exception to describe, pass through.
715 if (!soa.Self()->GetException()) {
716 return;
717 }
718
719 StackHandleScope<1> hs(soa.Self());
720 Handle<mirror::Throwable> old_exception(
721 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
722 soa.Self()->ClearException();
723 ScopedLocalRef<jthrowable> exception(env,
724 soa.AddLocalReference<jthrowable>(old_exception.Get()));
725 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
726 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
727 if (mid == nullptr) {
728 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
729 << mirror::Object::PrettyTypeOf(old_exception.Get());
730 } else {
731 env->CallVoidMethod(exception.get(), mid);
732 if (soa.Self()->IsExceptionPending()) {
733 LOG(WARNING) << "JNI WARNING: " << mirror::Object::PrettyTypeOf(soa.Self()->GetException())
734 << " thrown while calling printStackTrace";
735 soa.Self()->ClearException();
736 }
737 }
738 soa.Self()->SetException(old_exception.Get());
739 }
740
ExceptionOccurred(JNIEnv * env)741 static jthrowable ExceptionOccurred(JNIEnv* env) {
742 ScopedObjectAccess soa(env);
743 ObjPtr<mirror::Object> exception = soa.Self()->GetException();
744 return soa.AddLocalReference<jthrowable>(exception);
745 }
746
FatalError(JNIEnv *,const char * msg)747 static void FatalError(JNIEnv*, const char* msg) {
748 LOG(FATAL) << "JNI FatalError called: " << msg;
749 }
750
PushLocalFrame(JNIEnv * env,jint capacity)751 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
752 // TODO: SOA may not be necessary but I do it to please lock annotations.
753 ScopedObjectAccess soa(env);
754 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
755 return JNI_ERR;
756 }
757 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
758 return JNI_OK;
759 }
760
PopLocalFrame(JNIEnv * env,jobject java_survivor)761 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
762 ScopedObjectAccess soa(env);
763 ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor);
764 soa.Env()->PopFrame();
765 return soa.AddLocalReference<jobject>(survivor);
766 }
767
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity)768 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
769 // TODO: SOA may not be necessary but I do it to please lock annotations.
770 ScopedObjectAccess soa(env);
771 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
772 }
773
NewGlobalRef(JNIEnv * env,jobject obj)774 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
775 ScopedObjectAccess soa(env);
776 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
777 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
778 }
779
DeleteGlobalRef(JNIEnv * env,jobject obj)780 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
781 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->GetVm();
782 Thread* self = down_cast<JNIEnvExt*>(env)->self_;
783 vm->DeleteGlobalRef(self, obj);
784 }
785
NewWeakGlobalRef(JNIEnv * env,jobject obj)786 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
787 ScopedObjectAccess soa(env);
788 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
789 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
790 }
791
DeleteWeakGlobalRef(JNIEnv * env,jweak obj)792 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
793 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->GetVm();
794 Thread* self = down_cast<JNIEnvExt*>(env)->self_;
795 vm->DeleteWeakGlobalRef(self, obj);
796 }
797
NewLocalRef(JNIEnv * env,jobject obj)798 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
799 ScopedObjectAccess soa(env);
800 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
801 // Check for null after decoding the object to handle cleared weak globals.
802 if (decoded_obj == nullptr) {
803 return nullptr;
804 }
805 return soa.AddLocalReference<jobject>(decoded_obj);
806 }
807
DeleteLocalRef(JNIEnv * env,jobject obj)808 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
809 if (obj == nullptr) {
810 return;
811 }
812 // SOA is only necessary to have exclusion between GC root marking and removing.
813 // We don't want to have the GC attempt to mark a null root if we just removed
814 // it. b/22119403
815 ScopedObjectAccess soa(env);
816 auto* ext_env = down_cast<JNIEnvExt*>(env);
817 if (!ext_env->locals_.Remove(ext_env->local_ref_cookie_, obj)) {
818 // Attempting to delete a local reference that is not in the
819 // topmost local reference frame is a no-op. DeleteLocalRef returns
820 // void and doesn't throw any exceptions, but we should probably
821 // complain about it so the user will notice that things aren't
822 // going quite the way they expect.
823 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
824 << "failed to find entry";
825 }
826 }
827
IsSameObject(JNIEnv * env,jobject obj1,jobject obj2)828 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
829 if (obj1 == obj2) {
830 return JNI_TRUE;
831 } else {
832 ScopedObjectAccess soa(env);
833 return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2))
834 ? JNI_TRUE : JNI_FALSE;
835 }
836 }
837
AllocObject(JNIEnv * env,jclass java_class)838 static jobject AllocObject(JNIEnv* env, jclass java_class) {
839 CHECK_NON_NULL_ARGUMENT(java_class);
840 ScopedObjectAccess soa(env);
841 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class));
842 if (c == nullptr) {
843 return nullptr;
844 }
845 if (c->IsStringClass()) {
846 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
847 return soa.AddLocalReference<jobject>(
848 mirror::String::AllocEmptyString(soa.Self(), allocator_type));
849 }
850 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
851 }
852
NewObject(JNIEnv * env,jclass java_class,jmethodID mid,...)853 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
854 va_list args;
855 va_start(args, mid);
856 ScopedVAArgs free_args_later(&args);
857 CHECK_NON_NULL_ARGUMENT(java_class);
858 CHECK_NON_NULL_ARGUMENT(mid);
859 jobject result = NewObjectV(env, java_class, mid, args);
860 return result;
861 }
862
NewObjectV(JNIEnv * env,jclass java_class,jmethodID mid,va_list args)863 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
864 CHECK_NON_NULL_ARGUMENT(java_class);
865 CHECK_NON_NULL_ARGUMENT(mid);
866 ScopedObjectAccess soa(env);
867 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
868 soa.Decode<mirror::Class>(java_class));
869 if (c == nullptr) {
870 return nullptr;
871 }
872 if (c->IsStringClass()) {
873 // Replace calls to String.<init> with equivalent StringFactory call.
874 jmethodID sf_mid = jni::EncodeArtMethod<kEnableIndexIds>(
875 WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
876 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
877 }
878 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
879 if (result == nullptr) {
880 return nullptr;
881 }
882 jobject local_result = soa.AddLocalReference<jobject>(result);
883 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
884 if (soa.Self()->IsExceptionPending()) {
885 return nullptr;
886 }
887 return local_result;
888 }
889
NewObjectA(JNIEnv * env,jclass java_class,jmethodID mid,const jvalue * args)890 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, const jvalue* args) {
891 CHECK_NON_NULL_ARGUMENT(java_class);
892 CHECK_NON_NULL_ARGUMENT(mid);
893 ScopedObjectAccess soa(env);
894 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
895 soa.Decode<mirror::Class>(java_class));
896 if (c == nullptr) {
897 return nullptr;
898 }
899 if (c->IsStringClass()) {
900 // Replace calls to String.<init> with equivalent StringFactory call.
901 jmethodID sf_mid = jni::EncodeArtMethod<kEnableIndexIds>(
902 WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
903 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
904 }
905 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
906 if (result == nullptr) {
907 return nullptr;
908 }
909 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
910 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
911 if (soa.Self()->IsExceptionPending()) {
912 return nullptr;
913 }
914 return local_result;
915 }
916
GetMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)917 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
918 CHECK_NON_NULL_ARGUMENT(java_class);
919 CHECK_NON_NULL_ARGUMENT(name);
920 CHECK_NON_NULL_ARGUMENT(sig);
921 ScopedObjectAccess soa(env);
922 return FindMethodID<kEnableIndexIds>(soa, java_class, name, sig, false);
923 }
924
GetStaticMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)925 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
926 const char* sig) {
927 CHECK_NON_NULL_ARGUMENT(java_class);
928 CHECK_NON_NULL_ARGUMENT(name);
929 CHECK_NON_NULL_ARGUMENT(sig);
930 ScopedObjectAccess soa(env);
931 return FindMethodID<kEnableIndexIds>(soa, java_class, name, sig, true);
932 }
933
CallObjectMethod(JNIEnv * env,jobject obj,jmethodID mid,...)934 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
935 va_list ap;
936 va_start(ap, mid);
937 ScopedVAArgs free_args_later(&ap);
938 CHECK_NON_NULL_ARGUMENT(obj);
939 CHECK_NON_NULL_ARGUMENT(mid);
940 ScopedObjectAccess soa(env);
941 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
942 return soa.AddLocalReference<jobject>(result.GetL());
943 }
944
CallObjectMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)945 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
946 CHECK_NON_NULL_ARGUMENT(obj);
947 CHECK_NON_NULL_ARGUMENT(mid);
948 ScopedObjectAccess soa(env);
949 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
950 return soa.AddLocalReference<jobject>(result.GetL());
951 }
952
CallObjectMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)953 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
954 CHECK_NON_NULL_ARGUMENT(obj);
955 CHECK_NON_NULL_ARGUMENT(mid);
956 ScopedObjectAccess soa(env);
957 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
958 return soa.AddLocalReference<jobject>(result.GetL());
959 }
960
CallBooleanMethod(JNIEnv * env,jobject obj,jmethodID mid,...)961 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
962 va_list ap;
963 va_start(ap, mid);
964 ScopedVAArgs free_args_later(&ap);
965 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
966 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
967 ScopedObjectAccess soa(env);
968 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
969 return result.GetZ();
970 }
971
CallBooleanMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)972 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
973 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
974 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
975 ScopedObjectAccess soa(env);
976 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
977 }
978
CallBooleanMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)979 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
980 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
981 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
982 ScopedObjectAccess soa(env);
983 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
984 }
985
CallByteMethod(JNIEnv * env,jobject obj,jmethodID mid,...)986 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
987 va_list ap;
988 va_start(ap, mid);
989 ScopedVAArgs free_args_later(&ap);
990 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
991 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
992 ScopedObjectAccess soa(env);
993 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
994 return result.GetB();
995 }
996
CallByteMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)997 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
998 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
999 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1000 ScopedObjectAccess soa(env);
1001 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
1002 }
1003
CallByteMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1004 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1005 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1006 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1007 ScopedObjectAccess soa(env);
1008 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
1009 }
1010
CallCharMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1011 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1012 va_list ap;
1013 va_start(ap, mid);
1014 ScopedVAArgs free_args_later(&ap);
1015 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1016 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1017 ScopedObjectAccess soa(env);
1018 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1019 return result.GetC();
1020 }
1021
CallCharMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1022 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1023 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1024 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1025 ScopedObjectAccess soa(env);
1026 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
1027 }
1028
CallCharMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1029 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1030 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1031 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1032 ScopedObjectAccess soa(env);
1033 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
1034 }
1035
CallDoubleMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1036 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1037 va_list ap;
1038 va_start(ap, mid);
1039 ScopedVAArgs free_args_later(&ap);
1040 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1041 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1042 ScopedObjectAccess soa(env);
1043 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1044 return result.GetD();
1045 }
1046
CallDoubleMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1047 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1048 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1049 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1050 ScopedObjectAccess soa(env);
1051 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
1052 }
1053
CallDoubleMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1054 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1055 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1056 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1057 ScopedObjectAccess soa(env);
1058 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
1059 }
1060
CallFloatMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1061 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1062 va_list ap;
1063 va_start(ap, mid);
1064 ScopedVAArgs free_args_later(&ap);
1065 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1066 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1067 ScopedObjectAccess soa(env);
1068 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1069 return result.GetF();
1070 }
1071
CallFloatMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1072 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1073 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1074 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1075 ScopedObjectAccess soa(env);
1076 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
1077 }
1078
CallFloatMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1079 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1080 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1081 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1082 ScopedObjectAccess soa(env);
1083 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
1084 }
1085
CallIntMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1086 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1087 va_list ap;
1088 va_start(ap, mid);
1089 ScopedVAArgs free_args_later(&ap);
1090 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1092 ScopedObjectAccess soa(env);
1093 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1094 return result.GetI();
1095 }
1096
CallIntMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1097 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1098 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1099 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1100 ScopedObjectAccess soa(env);
1101 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
1102 }
1103
CallIntMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1104 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1105 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1106 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1107 ScopedObjectAccess soa(env);
1108 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
1109 }
1110
CallLongMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1111 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1112 va_list ap;
1113 va_start(ap, mid);
1114 ScopedVAArgs free_args_later(&ap);
1115 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1116 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1117 ScopedObjectAccess soa(env);
1118 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1119 return result.GetJ();
1120 }
1121
CallLongMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1122 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1123 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1124 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1125 ScopedObjectAccess soa(env);
1126 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
1127 }
1128
CallLongMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1129 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1130 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1131 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1132 ScopedObjectAccess soa(env);
1133 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
1134 }
1135
CallShortMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1136 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1137 va_list ap;
1138 va_start(ap, mid);
1139 ScopedVAArgs free_args_later(&ap);
1140 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1141 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1142 ScopedObjectAccess soa(env);
1143 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1144 return result.GetS();
1145 }
1146
CallShortMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1147 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1148 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1149 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1150 ScopedObjectAccess soa(env);
1151 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
1152 }
1153
CallShortMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1154 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1155 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1156 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1157 ScopedObjectAccess soa(env);
1158 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
1159 }
1160
CallVoidMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1161 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1162 va_list ap;
1163 va_start(ap, mid);
1164 ScopedVAArgs free_args_later(&ap);
1165 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1166 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1167 ScopedObjectAccess soa(env);
1168 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
1169 }
1170
CallVoidMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1171 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1172 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1173 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1174 ScopedObjectAccess soa(env);
1175 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
1176 }
1177
CallVoidMethodA(JNIEnv * env,jobject obj,jmethodID mid,const jvalue * args)1178 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, const jvalue* args) {
1179 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1180 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1181 ScopedObjectAccess soa(env);
1182 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
1183 }
1184
CallNonvirtualObjectMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1185 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1186 va_list ap;
1187 va_start(ap, mid);
1188 ScopedVAArgs free_args_later(&ap);
1189 CHECK_NON_NULL_ARGUMENT(obj);
1190 CHECK_NON_NULL_ARGUMENT(mid);
1191 ScopedObjectAccess soa(env);
1192 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1193 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1194 return local_result;
1195 }
1196
CallNonvirtualObjectMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1197 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1198 va_list args) {
1199 CHECK_NON_NULL_ARGUMENT(obj);
1200 CHECK_NON_NULL_ARGUMENT(mid);
1201 ScopedObjectAccess soa(env);
1202 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1203 return soa.AddLocalReference<jobject>(result.GetL());
1204 }
1205
CallNonvirtualObjectMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1206 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1207 const jvalue* args) {
1208 CHECK_NON_NULL_ARGUMENT(obj);
1209 CHECK_NON_NULL_ARGUMENT(mid);
1210 ScopedObjectAccess soa(env);
1211 JValue result(InvokeWithJValues(soa, obj, mid, args));
1212 return soa.AddLocalReference<jobject>(result.GetL());
1213 }
1214
CallNonvirtualBooleanMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1215 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1216 ...) {
1217 va_list ap;
1218 va_start(ap, mid);
1219 ScopedVAArgs free_args_later(&ap);
1220 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1221 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1222 ScopedObjectAccess soa(env);
1223 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1224 return result.GetZ();
1225 }
1226
CallNonvirtualBooleanMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1227 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1228 va_list args) {
1229 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1230 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1231 ScopedObjectAccess soa(env);
1232 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
1233 }
1234
CallNonvirtualBooleanMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1235 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1236 const jvalue* args) {
1237 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1238 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1239 ScopedObjectAccess soa(env);
1240 return InvokeWithJValues(soa, obj, mid, args).GetZ();
1241 }
1242
CallNonvirtualByteMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1243 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1244 va_list ap;
1245 va_start(ap, mid);
1246 ScopedVAArgs free_args_later(&ap);
1247 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1248 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1249 ScopedObjectAccess soa(env);
1250 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1251 return result.GetB();
1252 }
1253
CallNonvirtualByteMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1254 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1255 va_list args) {
1256 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1257 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1258 ScopedObjectAccess soa(env);
1259 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1260 }
1261
CallNonvirtualByteMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1262 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1263 const jvalue* args) {
1264 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1265 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1266 ScopedObjectAccess soa(env);
1267 return InvokeWithJValues(soa, obj, mid, args).GetB();
1268 }
1269
CallNonvirtualCharMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1270 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1271 va_list ap;
1272 va_start(ap, mid);
1273 ScopedVAArgs free_args_later(&ap);
1274 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1275 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1276 ScopedObjectAccess soa(env);
1277 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1278 return result.GetC();
1279 }
1280
CallNonvirtualCharMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1281 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1282 va_list args) {
1283 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1284 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1285 ScopedObjectAccess soa(env);
1286 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1287 }
1288
CallNonvirtualCharMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1289 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1290 const jvalue* args) {
1291 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1292 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1293 ScopedObjectAccess soa(env);
1294 return InvokeWithJValues(soa, obj, mid, args).GetC();
1295 }
1296
CallNonvirtualShortMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1297 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1298 va_list ap;
1299 va_start(ap, mid);
1300 ScopedVAArgs free_args_later(&ap);
1301 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1302 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1303 ScopedObjectAccess soa(env);
1304 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1305 return result.GetS();
1306 }
1307
CallNonvirtualShortMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1308 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1309 va_list args) {
1310 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1311 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1312 ScopedObjectAccess soa(env);
1313 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1314 }
1315
CallNonvirtualShortMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1316 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1317 const jvalue* args) {
1318 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1319 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1320 ScopedObjectAccess soa(env);
1321 return InvokeWithJValues(soa, obj, mid, args).GetS();
1322 }
1323
CallNonvirtualIntMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1324 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1325 va_list ap;
1326 va_start(ap, mid);
1327 ScopedVAArgs free_args_later(&ap);
1328 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1329 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1330 ScopedObjectAccess soa(env);
1331 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1332 return result.GetI();
1333 }
1334
CallNonvirtualIntMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1335 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1336 va_list args) {
1337 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1338 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1339 ScopedObjectAccess soa(env);
1340 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1341 }
1342
CallNonvirtualIntMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1343 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1344 const jvalue* args) {
1345 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1346 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1347 ScopedObjectAccess soa(env);
1348 return InvokeWithJValues(soa, obj, mid, args).GetI();
1349 }
1350
CallNonvirtualLongMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1351 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1352 va_list ap;
1353 va_start(ap, mid);
1354 ScopedVAArgs free_args_later(&ap);
1355 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1356 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1357 ScopedObjectAccess soa(env);
1358 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1359 return result.GetJ();
1360 }
1361
CallNonvirtualLongMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1362 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1363 va_list args) {
1364 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1365 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1366 ScopedObjectAccess soa(env);
1367 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1368 }
1369
CallNonvirtualLongMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1370 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1371 const jvalue* args) {
1372 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1373 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1374 ScopedObjectAccess soa(env);
1375 return InvokeWithJValues(soa, obj, mid, args).GetJ();
1376 }
1377
CallNonvirtualFloatMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1378 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1379 va_list ap;
1380 va_start(ap, mid);
1381 ScopedVAArgs free_args_later(&ap);
1382 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1383 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1384 ScopedObjectAccess soa(env);
1385 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1386 return result.GetF();
1387 }
1388
CallNonvirtualFloatMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1389 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1390 va_list args) {
1391 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1392 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1393 ScopedObjectAccess soa(env);
1394 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1395 }
1396
CallNonvirtualFloatMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1397 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1398 const jvalue* args) {
1399 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1400 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1401 ScopedObjectAccess soa(env);
1402 return InvokeWithJValues(soa, obj, mid, args).GetF();
1403 }
1404
CallNonvirtualDoubleMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1405 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1406 va_list ap;
1407 va_start(ap, mid);
1408 ScopedVAArgs free_args_later(&ap);
1409 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1410 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1411 ScopedObjectAccess soa(env);
1412 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1413 return result.GetD();
1414 }
1415
CallNonvirtualDoubleMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1416 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1417 va_list args) {
1418 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1419 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1420 ScopedObjectAccess soa(env);
1421 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1422 }
1423
CallNonvirtualDoubleMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1424 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1425 const jvalue* args) {
1426 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1427 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1428 ScopedObjectAccess soa(env);
1429 return InvokeWithJValues(soa, obj, mid, args).GetD();
1430 }
1431
CallNonvirtualVoidMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1432 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1433 va_list ap;
1434 va_start(ap, mid);
1435 ScopedVAArgs free_args_later(&ap);
1436 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1437 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1438 ScopedObjectAccess soa(env);
1439 InvokeWithVarArgs(soa, obj, mid, ap);
1440 }
1441
CallNonvirtualVoidMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1442 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1443 va_list args) {
1444 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1445 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1446 ScopedObjectAccess soa(env);
1447 InvokeWithVarArgs(soa, obj, mid, args);
1448 }
1449
CallNonvirtualVoidMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,const jvalue * args)1450 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1451 const jvalue* args) {
1452 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1453 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1454 ScopedObjectAccess soa(env);
1455 InvokeWithJValues(soa, obj, mid, args);
1456 }
1457
GetFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1458 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1459 CHECK_NON_NULL_ARGUMENT(java_class);
1460 CHECK_NON_NULL_ARGUMENT(name);
1461 CHECK_NON_NULL_ARGUMENT(sig);
1462 ScopedObjectAccess soa(env);
1463 return FindFieldID<kEnableIndexIds>(soa, java_class, name, sig, false);
1464 }
1465
GetStaticFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1466 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1467 const char* sig) {
1468 CHECK_NON_NULL_ARGUMENT(java_class);
1469 CHECK_NON_NULL_ARGUMENT(name);
1470 CHECK_NON_NULL_ARGUMENT(sig);
1471 ScopedObjectAccess soa(env);
1472 return FindFieldID<kEnableIndexIds>(soa, java_class, name, sig, true);
1473 }
1474
GetObjectField(JNIEnv * env,jobject obj,jfieldID fid)1475 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1476 CHECK_NON_NULL_ARGUMENT(obj);
1477 CHECK_NON_NULL_ARGUMENT(fid);
1478 ScopedObjectAccess soa(env);
1479 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
1480 NotifyGetField(f, obj);
1481 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
1482 return soa.AddLocalReference<jobject>(f->GetObject(o));
1483 }
1484
GetStaticObjectField(JNIEnv * env,jclass,jfieldID fid)1485 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1486 CHECK_NON_NULL_ARGUMENT(fid);
1487 ScopedObjectAccess soa(env);
1488 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
1489 NotifyGetField(f, nullptr);
1490 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1491 }
1492
SetObjectField(JNIEnv * env,jobject java_object,jfieldID fid,jobject java_value)1493 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1494 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1495 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1496 ScopedObjectAccess soa(env);
1497 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
1498 NotifySetObjectField(f, java_object, java_value);
1499 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
1500 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
1501 f->SetObject<false>(o, v);
1502 }
1503
SetStaticObjectField(JNIEnv * env,jclass,jfieldID fid,jobject java_value)1504 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1505 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1506 ScopedObjectAccess soa(env);
1507 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
1508 NotifySetObjectField(f, nullptr, java_value);
1509 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
1510 f->SetObject<false>(f->GetDeclaringClass(), v);
1511 }
1512
1513 #define GET_PRIMITIVE_FIELD(fn, instance) \
1514 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1515 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1516 ScopedObjectAccess soa(env); \
1517 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
1518 NotifyGetField(f, instance); \
1519 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
1520 return f->Get ##fn (o)
1521
1522 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
1523 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1524 ScopedObjectAccess soa(env); \
1525 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
1526 NotifyGetField(f, nullptr); \
1527 return f->Get ##fn (f->GetDeclaringClass())
1528
1529 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
1530 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1531 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1532 ScopedObjectAccess soa(env); \
1533 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
1534 NotifySetPrimitiveField(f, instance, JValue::FromPrimitive<decltype(value)>(value)); \
1535 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
1536 f->Set ##fn <false>(o, value)
1537
1538 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1539 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1540 ScopedObjectAccess soa(env); \
1541 ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
1542 NotifySetPrimitiveField(f, nullptr, JValue::FromPrimitive<decltype(value)>(value)); \
1543 f->Set ##fn <false>(f->GetDeclaringClass(), value)
1544
GetBooleanField(JNIEnv * env,jobject obj,jfieldID fid)1545 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1546 GET_PRIMITIVE_FIELD(Boolean, obj);
1547 }
1548
GetByteField(JNIEnv * env,jobject obj,jfieldID fid)1549 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1550 GET_PRIMITIVE_FIELD(Byte, obj);
1551 }
1552
GetCharField(JNIEnv * env,jobject obj,jfieldID fid)1553 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1554 GET_PRIMITIVE_FIELD(Char, obj);
1555 }
1556
GetShortField(JNIEnv * env,jobject obj,jfieldID fid)1557 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1558 GET_PRIMITIVE_FIELD(Short, obj);
1559 }
1560
GetIntField(JNIEnv * env,jobject obj,jfieldID fid)1561 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1562 GET_PRIMITIVE_FIELD(Int, obj);
1563 }
1564
GetLongField(JNIEnv * env,jobject obj,jfieldID fid)1565 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1566 GET_PRIMITIVE_FIELD(Long, obj);
1567 }
1568
GetFloatField(JNIEnv * env,jobject obj,jfieldID fid)1569 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1570 GET_PRIMITIVE_FIELD(Float, obj);
1571 }
1572
GetDoubleField(JNIEnv * env,jobject obj,jfieldID fid)1573 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1574 GET_PRIMITIVE_FIELD(Double, obj);
1575 }
1576
GetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid)1577 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1578 GET_STATIC_PRIMITIVE_FIELD(Boolean);
1579 }
1580
GetStaticByteField(JNIEnv * env,jclass,jfieldID fid)1581 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1582 GET_STATIC_PRIMITIVE_FIELD(Byte);
1583 }
1584
GetStaticCharField(JNIEnv * env,jclass,jfieldID fid)1585 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1586 GET_STATIC_PRIMITIVE_FIELD(Char);
1587 }
1588
GetStaticShortField(JNIEnv * env,jclass,jfieldID fid)1589 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1590 GET_STATIC_PRIMITIVE_FIELD(Short);
1591 }
1592
GetStaticIntField(JNIEnv * env,jclass,jfieldID fid)1593 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1594 GET_STATIC_PRIMITIVE_FIELD(Int);
1595 }
1596
GetStaticLongField(JNIEnv * env,jclass,jfieldID fid)1597 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1598 GET_STATIC_PRIMITIVE_FIELD(Long);
1599 }
1600
GetStaticFloatField(JNIEnv * env,jclass,jfieldID fid)1601 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1602 GET_STATIC_PRIMITIVE_FIELD(Float);
1603 }
1604
GetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid)1605 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1606 GET_STATIC_PRIMITIVE_FIELD(Double);
1607 }
1608
SetBooleanField(JNIEnv * env,jobject obj,jfieldID fid,jboolean v)1609 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1610 SET_PRIMITIVE_FIELD(Boolean, obj, v);
1611 }
1612
SetByteField(JNIEnv * env,jobject obj,jfieldID fid,jbyte v)1613 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1614 SET_PRIMITIVE_FIELD(Byte, obj, v);
1615 }
1616
SetCharField(JNIEnv * env,jobject obj,jfieldID fid,jchar v)1617 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1618 SET_PRIMITIVE_FIELD(Char, obj, v);
1619 }
1620
SetFloatField(JNIEnv * env,jobject obj,jfieldID fid,jfloat v)1621 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1622 SET_PRIMITIVE_FIELD(Float, obj, v);
1623 }
1624
SetDoubleField(JNIEnv * env,jobject obj,jfieldID fid,jdouble v)1625 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1626 SET_PRIMITIVE_FIELD(Double, obj, v);
1627 }
1628
SetIntField(JNIEnv * env,jobject obj,jfieldID fid,jint v)1629 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1630 SET_PRIMITIVE_FIELD(Int, obj, v);
1631 }
1632
SetLongField(JNIEnv * env,jobject obj,jfieldID fid,jlong v)1633 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1634 SET_PRIMITIVE_FIELD(Long, obj, v);
1635 }
1636
SetShortField(JNIEnv * env,jobject obj,jfieldID fid,jshort v)1637 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1638 SET_PRIMITIVE_FIELD(Short, obj, v);
1639 }
1640
SetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid,jboolean v)1641 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1642 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1643 }
1644
SetStaticByteField(JNIEnv * env,jclass,jfieldID fid,jbyte v)1645 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1646 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1647 }
1648
SetStaticCharField(JNIEnv * env,jclass,jfieldID fid,jchar v)1649 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1650 SET_STATIC_PRIMITIVE_FIELD(Char, v);
1651 }
1652
SetStaticFloatField(JNIEnv * env,jclass,jfieldID fid,jfloat v)1653 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1654 SET_STATIC_PRIMITIVE_FIELD(Float, v);
1655 }
1656
SetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid,jdouble v)1657 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1658 SET_STATIC_PRIMITIVE_FIELD(Double, v);
1659 }
1660
SetStaticIntField(JNIEnv * env,jclass,jfieldID fid,jint v)1661 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1662 SET_STATIC_PRIMITIVE_FIELD(Int, v);
1663 }
1664
SetStaticLongField(JNIEnv * env,jclass,jfieldID fid,jlong v)1665 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1666 SET_STATIC_PRIMITIVE_FIELD(Long, v);
1667 }
1668
SetStaticShortField(JNIEnv * env,jclass,jfieldID fid,jshort v)1669 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1670 SET_STATIC_PRIMITIVE_FIELD(Short, v);
1671 }
1672
CallStaticObjectMethod(JNIEnv * env,jclass,jmethodID mid,...)1673 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1674 va_list ap;
1675 va_start(ap, mid);
1676 ScopedVAArgs free_args_later(&ap);
1677 CHECK_NON_NULL_ARGUMENT(mid);
1678 ScopedObjectAccess soa(env);
1679 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1680 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1681 return local_result;
1682 }
1683
CallStaticObjectMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1684 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1685 CHECK_NON_NULL_ARGUMENT(mid);
1686 ScopedObjectAccess soa(env);
1687 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
1688 return soa.AddLocalReference<jobject>(result.GetL());
1689 }
1690
CallStaticObjectMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1691 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1692 CHECK_NON_NULL_ARGUMENT(mid);
1693 ScopedObjectAccess soa(env);
1694 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
1695 return soa.AddLocalReference<jobject>(result.GetL());
1696 }
1697
CallStaticBooleanMethod(JNIEnv * env,jclass,jmethodID mid,...)1698 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1699 va_list ap;
1700 va_start(ap, mid);
1701 ScopedVAArgs free_args_later(&ap);
1702 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1703 ScopedObjectAccess soa(env);
1704 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1705 return result.GetZ();
1706 }
1707
CallStaticBooleanMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1708 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1709 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1710 ScopedObjectAccess soa(env);
1711 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1712 }
1713
CallStaticBooleanMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1714 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1715 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1716 ScopedObjectAccess soa(env);
1717 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1718 }
1719
CallStaticByteMethod(JNIEnv * env,jclass,jmethodID mid,...)1720 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1721 va_list ap;
1722 va_start(ap, mid);
1723 ScopedVAArgs free_args_later(&ap);
1724 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1725 ScopedObjectAccess soa(env);
1726 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1727 return result.GetB();
1728 }
1729
CallStaticByteMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1730 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1731 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1732 ScopedObjectAccess soa(env);
1733 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1734 }
1735
CallStaticByteMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1736 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1737 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1738 ScopedObjectAccess soa(env);
1739 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1740 }
1741
CallStaticCharMethod(JNIEnv * env,jclass,jmethodID mid,...)1742 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1743 va_list ap;
1744 va_start(ap, mid);
1745 ScopedVAArgs free_args_later(&ap);
1746 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1747 ScopedObjectAccess soa(env);
1748 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1749 return result.GetC();
1750 }
1751
CallStaticCharMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1752 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1753 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1754 ScopedObjectAccess soa(env);
1755 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1756 }
1757
CallStaticCharMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1758 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1760 ScopedObjectAccess soa(env);
1761 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1762 }
1763
CallStaticShortMethod(JNIEnv * env,jclass,jmethodID mid,...)1764 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1765 va_list ap;
1766 va_start(ap, mid);
1767 ScopedVAArgs free_args_later(&ap);
1768 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1769 ScopedObjectAccess soa(env);
1770 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1771 return result.GetS();
1772 }
1773
CallStaticShortMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1774 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1775 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1776 ScopedObjectAccess soa(env);
1777 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1778 }
1779
CallStaticShortMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1780 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1781 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1782 ScopedObjectAccess soa(env);
1783 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1784 }
1785
CallStaticIntMethod(JNIEnv * env,jclass,jmethodID mid,...)1786 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1787 va_list ap;
1788 va_start(ap, mid);
1789 ScopedVAArgs free_args_later(&ap);
1790 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1791 ScopedObjectAccess soa(env);
1792 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1793 return result.GetI();
1794 }
1795
CallStaticIntMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1796 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1797 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1798 ScopedObjectAccess soa(env);
1799 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1800 }
1801
CallStaticIntMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1802 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1803 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1804 ScopedObjectAccess soa(env);
1805 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1806 }
1807
CallStaticLongMethod(JNIEnv * env,jclass,jmethodID mid,...)1808 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1809 va_list ap;
1810 va_start(ap, mid);
1811 ScopedVAArgs free_args_later(&ap);
1812 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1813 ScopedObjectAccess soa(env);
1814 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1815 return result.GetJ();
1816 }
1817
CallStaticLongMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1818 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1819 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1820 ScopedObjectAccess soa(env);
1821 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1822 }
1823
CallStaticLongMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1824 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1826 ScopedObjectAccess soa(env);
1827 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1828 }
1829
CallStaticFloatMethod(JNIEnv * env,jclass,jmethodID mid,...)1830 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1831 va_list ap;
1832 va_start(ap, mid);
1833 ScopedVAArgs free_args_later(&ap);
1834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1835 ScopedObjectAccess soa(env);
1836 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1837 return result.GetF();
1838 }
1839
CallStaticFloatMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1840 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1841 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1842 ScopedObjectAccess soa(env);
1843 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1844 }
1845
CallStaticFloatMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1846 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1847 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1848 ScopedObjectAccess soa(env);
1849 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1850 }
1851
CallStaticDoubleMethod(JNIEnv * env,jclass,jmethodID mid,...)1852 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1853 va_list ap;
1854 va_start(ap, mid);
1855 ScopedVAArgs free_args_later(&ap);
1856 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1857 ScopedObjectAccess soa(env);
1858 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1859 return result.GetD();
1860 }
1861
CallStaticDoubleMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1862 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1863 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1864 ScopedObjectAccess soa(env);
1865 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1866 }
1867
CallStaticDoubleMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1868 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1869 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1870 ScopedObjectAccess soa(env);
1871 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1872 }
1873
CallStaticVoidMethod(JNIEnv * env,jclass,jmethodID mid,...)1874 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1875 va_list ap;
1876 va_start(ap, mid);
1877 ScopedVAArgs free_args_later(&ap);
1878 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1879 ScopedObjectAccess soa(env);
1880 InvokeWithVarArgs(soa, nullptr, mid, ap);
1881 }
1882
CallStaticVoidMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1883 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1884 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1885 ScopedObjectAccess soa(env);
1886 InvokeWithVarArgs(soa, nullptr, mid, args);
1887 }
1888
CallStaticVoidMethodA(JNIEnv * env,jclass,jmethodID mid,const jvalue * args)1889 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, const jvalue* args) {
1890 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1891 ScopedObjectAccess soa(env);
1892 InvokeWithJValues(soa, nullptr, mid, args);
1893 }
1894
NewString(JNIEnv * env,const jchar * chars,jsize char_count)1895 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1896 if (UNLIKELY(char_count < 0)) {
1897 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
1898 return nullptr;
1899 }
1900 if (UNLIKELY(chars == nullptr && char_count > 0)) {
1901 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
1902 return nullptr;
1903 }
1904 ScopedObjectAccess soa(env);
1905 ObjPtr<mirror::String> result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
1906 return soa.AddLocalReference<jstring>(result);
1907 }
1908
NewStringUTF(JNIEnv * env,const char * utf)1909 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1910 if (utf == nullptr) {
1911 return nullptr;
1912 }
1913
1914 // The input may come from an untrusted source, so we need to validate it.
1915 // We do not perform full validation, only as much as necessary to avoid reading
1916 // beyond the terminating null character or breaking string compression invariants.
1917 // CheckJNI performs stronger validation.
1918 size_t utf8_length = strlen(utf);
1919 if (UNLIKELY(utf8_length > static_cast<uint32_t>(std::numeric_limits<int32_t>::max()))) {
1920 // Converting the utf8_length to int32_t for String::AllocFromModifiedUtf8() would
1921 // overflow. Throw OOME eagerly to avoid 2GiB allocation when trying to replace
1922 // invalid sequences (even if such replacements could reduce the size below 2GiB).
1923 std::string error =
1924 android::base::StringPrintf("NewStringUTF input is 2 GiB or more: %zu", utf8_length);
1925 ScopedObjectAccess soa(env);
1926 soa.Self()->ThrowOutOfMemoryError(error.c_str());
1927 return nullptr;
1928 }
1929 std::optional<std::string> replacement_utf;
1930 size_t utf16_length = VisitModifiedUtf8Chars(
1931 utf,
1932 utf8_length,
1933 /*good=*/ [](const char* ptr ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) {},
1934 /*bad=*/ []() { return true; }); // Abort processing and return 0 for bad characters.
1935 if (UNLIKELY(utf8_length != 0u && utf16_length == 0u)) {
1936 // VisitModifiedUtf8Chars() aborted for a bad character.
1937 android_errorWriteLog(0x534e4554, "172655291"); // Report to SafetyNet.
1938 // Report the error to logcat but avoid too much spam.
1939 static const uint64_t kMinDelay = UINT64_C(10000000000); // 10s
1940 static std::atomic<uint64_t> prev_bad_input_time(UINT64_C(0));
1941 uint64_t prev_time = prev_bad_input_time.load(std::memory_order_relaxed);
1942 uint64_t now = NanoTime();
1943 if ((prev_time == 0u || now - prev_time >= kMinDelay) &&
1944 prev_bad_input_time.compare_exchange_strong(prev_time, now, std::memory_order_relaxed)) {
1945 LOG(ERROR) << "Invalid UTF-8 input to JNI::NewStringUTF()";
1946 }
1947 // Copy the input to the `replacement_utf` and replace bad characters.
1948 replacement_utf.emplace();
1949 replacement_utf->reserve(utf8_length);
1950 utf16_length = VisitModifiedUtf8Chars(
1951 utf,
1952 utf8_length,
1953 /*good=*/ [&](const char* ptr, size_t length) {
1954 replacement_utf->append(ptr, length);
1955 },
1956 /*bad=*/ [&]() {
1957 replacement_utf->append(kBadUtf8ReplacementChar, sizeof(kBadUtf8ReplacementChar) - 1u);
1958 return false; // Continue processing.
1959 });
1960 utf = replacement_utf->c_str();
1961 utf8_length = replacement_utf->length();
1962 }
1963 DCHECK_LE(utf16_length, utf8_length);
1964 DCHECK_LE(utf8_length, static_cast<uint32_t>(std::numeric_limits<int32_t>::max()));
1965
1966 ScopedObjectAccess soa(env);
1967 ObjPtr<mirror::String> result =
1968 mirror::String::AllocFromModifiedUtf8(soa.Self(), utf16_length, utf, utf8_length);
1969 return soa.AddLocalReference<jstring>(result);
1970 }
1971
GetStringLength(JNIEnv * env,jstring java_string)1972 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1973 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1974 ScopedObjectAccess soa(env);
1975 return soa.Decode<mirror::String>(java_string)->GetLength();
1976 }
1977
GetStringUTFLength(JNIEnv * env,jstring java_string)1978 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1979 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1980 ScopedObjectAccess soa(env);
1981 return soa.Decode<mirror::String>(java_string)->GetUtfLength();
1982 }
1983
GetStringRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,jchar * buf)1984 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1985 jchar* buf) {
1986 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1987 ScopedObjectAccess soa(env);
1988 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
1989 if (start < 0 || length < 0 || length > s->GetLength() - start) {
1990 ThrowSIOOBE(soa, start, length, s->GetLength());
1991 } else {
1992 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1993 if (s->IsCompressed()) {
1994 const uint8_t* src = s->GetValueCompressed() + start;
1995 for (int i = 0; i < length; ++i) {
1996 buf[i] = static_cast<jchar>(src[i]);
1997 }
1998 } else {
1999 const jchar* chars = static_cast<jchar*>(s->GetValue());
2000 memcpy(buf, chars + start, length * sizeof(jchar));
2001 }
2002 }
2003 }
2004
GetStringUTFRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,char * buf)2005 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
2006 char* buf) {
2007 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2008 ScopedObjectAccess soa(env);
2009 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2010 if (start < 0 || length < 0 || length > s->GetLength() - start) {
2011 ThrowSIOOBE(soa, start, length, s->GetLength());
2012 } else {
2013 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2014 if (length == 0 && buf == nullptr) {
2015 // Don't touch anything when length is 0 and null buffer.
2016 return;
2017 }
2018 if (s->IsCompressed()) {
2019 const uint8_t* src = s->GetValueCompressed() + start;
2020 for (int i = 0; i < length; ++i) {
2021 buf[i] = static_cast<jchar>(src[i]);
2022 }
2023 buf[length] = '\0';
2024 } else {
2025 const jchar* chars = s->GetValue();
2026 size_t bytes = CountUtf8Bytes(chars + start, length);
2027 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
2028 buf[bytes] = '\0';
2029 }
2030 }
2031 }
2032
GetStringChars(JNIEnv * env,jstring java_string,jboolean * is_copy)2033 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2034 CHECK_NON_NULL_ARGUMENT(java_string);
2035 ScopedObjectAccess soa(env);
2036 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2037 gc::Heap* heap = Runtime::Current()->GetHeap();
2038 if (heap->IsMovableObject(s) || s->IsCompressed()) {
2039 jchar* chars = new jchar[s->GetLength()];
2040 if (s->IsCompressed()) {
2041 int32_t length = s->GetLength();
2042 const uint8_t* src = s->GetValueCompressed();
2043 for (int i = 0; i < length; ++i) {
2044 chars[i] = static_cast<jchar>(src[i]);
2045 }
2046 } else {
2047 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
2048 }
2049 if (is_copy != nullptr) {
2050 *is_copy = JNI_TRUE;
2051 }
2052 return chars;
2053 }
2054 if (is_copy != nullptr) {
2055 *is_copy = JNI_FALSE;
2056 }
2057 return static_cast<jchar*>(s->GetValue());
2058 }
2059
ReleaseStringChars(JNIEnv * env,jstring java_string,const jchar * chars)2060 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
2061 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2062 ScopedObjectAccess soa(env);
2063 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2064 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
2065 delete[] chars;
2066 }
2067 }
2068
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * is_copy)2069 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2070 CHECK_NON_NULL_ARGUMENT(java_string);
2071 ScopedObjectAccess soa(env);
2072 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2073 gc::Heap* heap = Runtime::Current()->GetHeap();
2074 if (s->IsCompressed()) {
2075 if (is_copy != nullptr) {
2076 *is_copy = JNI_TRUE;
2077 }
2078 int32_t length = s->GetLength();
2079 const uint8_t* src = s->GetValueCompressed();
2080 jchar* chars = new jchar[length];
2081 for (int i = 0; i < length; ++i) {
2082 chars[i] = static_cast<jchar>(src[i]);
2083 }
2084 return chars;
2085 } else {
2086 if (heap->IsMovableObject(s)) {
2087 StackHandleScope<1> hs(soa.Self());
2088 HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
2089 if (!kUseReadBarrier) {
2090 heap->IncrementDisableMovingGC(soa.Self());
2091 } else {
2092 // For the CC collector, we only need to wait for the thread flip rather
2093 // than the whole GC to occur thanks to the to-space invariant.
2094 heap->IncrementDisableThreadFlip(soa.Self());
2095 }
2096 }
2097 if (is_copy != nullptr) {
2098 *is_copy = JNI_FALSE;
2099 }
2100 return static_cast<jchar*>(s->GetValue());
2101 }
2102 }
2103
ReleaseStringCritical(JNIEnv * env,jstring java_string,const jchar * chars)2104 static void ReleaseStringCritical(JNIEnv* env,
2105 jstring java_string,
2106 const jchar* chars) {
2107 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2108 ScopedObjectAccess soa(env);
2109 gc::Heap* heap = Runtime::Current()->GetHeap();
2110 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2111 if (!s->IsCompressed() && heap->IsMovableObject(s)) {
2112 if (!kUseReadBarrier) {
2113 heap->DecrementDisableMovingGC(soa.Self());
2114 } else {
2115 heap->DecrementDisableThreadFlip(soa.Self());
2116 }
2117 }
2118 // TODO: For uncompressed strings GetStringCritical() always returns `s->GetValue()`.
2119 // Should we report an error if the user passes a different `chars`?
2120 if (s->IsCompressed() || (!s->IsCompressed() && s->GetValue() != chars)) {
2121 delete[] chars;
2122 }
2123 }
2124
GetStringUTFChars(JNIEnv * env,jstring java_string,jboolean * is_copy)2125 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2126 if (java_string == nullptr) {
2127 return nullptr;
2128 }
2129 if (is_copy != nullptr) {
2130 *is_copy = JNI_TRUE;
2131 }
2132 ScopedObjectAccess soa(env);
2133 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
2134 size_t byte_count = s->GetUtfLength();
2135 char* bytes = new char[byte_count + 1];
2136 CHECK(bytes != nullptr); // bionic aborts anyway.
2137 if (s->IsCompressed()) {
2138 const uint8_t* src = s->GetValueCompressed();
2139 for (size_t i = 0; i < byte_count; ++i) {
2140 bytes[i] = src[i];
2141 }
2142 } else {
2143 const uint16_t* chars = s->GetValue();
2144 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
2145 }
2146 bytes[byte_count] = '\0';
2147 return bytes;
2148 }
2149
ReleaseStringUTFChars(JNIEnv *,jstring,const char * chars)2150 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
2151 delete[] chars;
2152 }
2153
GetArrayLength(JNIEnv * env,jarray java_array)2154 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
2155 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
2156 ScopedObjectAccess soa(env);
2157 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array);
2158 if (UNLIKELY(!obj->IsArrayInstance())) {
2159 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", obj->PrettyTypeOf().c_str());
2160 return 0;
2161 }
2162 ObjPtr<mirror::Array> array = obj->AsArray();
2163 return array->GetLength();
2164 }
2165
GetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index)2166 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
2167 CHECK_NON_NULL_ARGUMENT(java_array);
2168 ScopedObjectAccess soa(env);
2169 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
2170 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
2171 return soa.AddLocalReference<jobject>(array->Get(index));
2172 }
2173
SetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index,jobject java_value)2174 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2175 jobject java_value) {
2176 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2177 ScopedObjectAccess soa(env);
2178 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
2179 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
2180 ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value);
2181 array->Set<false>(index, value);
2182 }
2183
NewBooleanArray(JNIEnv * env,jsize length)2184 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
2185 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
2186 }
2187
NewByteArray(JNIEnv * env,jsize length)2188 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
2189 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
2190 }
2191
NewCharArray(JNIEnv * env,jsize length)2192 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
2193 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
2194 }
2195
NewDoubleArray(JNIEnv * env,jsize length)2196 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
2197 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
2198 }
2199
NewFloatArray(JNIEnv * env,jsize length)2200 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
2201 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
2202 }
2203
NewIntArray(JNIEnv * env,jsize length)2204 static jintArray NewIntArray(JNIEnv* env, jsize length) {
2205 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
2206 }
2207
NewLongArray(JNIEnv * env,jsize length)2208 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
2209 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
2210 }
2211
NewObjectArray(JNIEnv * env,jsize length,jclass element_jclass,jobject initial_element)2212 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
2213 jobject initial_element) {
2214 if (UNLIKELY(length < 0)) {
2215 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
2216 return nullptr;
2217 }
2218 CHECK_NON_NULL_ARGUMENT(element_jclass);
2219
2220 // Compute the array class corresponding to the given element class.
2221 ScopedObjectAccess soa(env);
2222 ObjPtr<mirror::Class> array_class;
2223 {
2224 ObjPtr<mirror::Class> element_class = soa.Decode<mirror::Class>(element_jclass);
2225 if (UNLIKELY(element_class->IsPrimitive())) {
2226 soa.Vm()->JniAbortF("NewObjectArray",
2227 "not an object type: %s",
2228 element_class->PrettyDescriptor().c_str());
2229 return nullptr;
2230 }
2231 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2232 array_class = class_linker->FindArrayClass(soa.Self(), element_class);
2233 if (UNLIKELY(array_class == nullptr)) {
2234 return nullptr;
2235 }
2236 }
2237
2238 // Allocate and initialize if necessary.
2239 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
2240 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
2241 if (result != nullptr && initial_element != nullptr) {
2242 ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element);
2243 if (initial_object != nullptr) {
2244 ObjPtr<mirror::Class> element_class = result->GetClass()->GetComponentType();
2245 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
2246 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
2247 "element type of '%s'",
2248 mirror::Class::PrettyDescriptor(initial_object->GetClass()).c_str(),
2249 element_class->PrettyDescriptor().c_str());
2250 return nullptr;
2251 } else {
2252 for (jsize i = 0; i < length; ++i) {
2253 result->SetWithoutChecks<false>(i, initial_object);
2254 }
2255 }
2256 }
2257 }
2258 return soa.AddLocalReference<jobjectArray>(result);
2259 }
2260
NewShortArray(JNIEnv * env,jsize length)2261 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
2262 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
2263 }
2264
GetPrimitiveArrayCritical(JNIEnv * env,jarray java_array,jboolean * is_copy)2265 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
2266 CHECK_NON_NULL_ARGUMENT(java_array);
2267 ScopedObjectAccess soa(env);
2268 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
2269 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2270 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
2271 array->GetClass()->PrettyDescriptor().c_str());
2272 return nullptr;
2273 }
2274 gc::Heap* heap = Runtime::Current()->GetHeap();
2275 if (heap->IsMovableObject(array)) {
2276 if (!kUseReadBarrier) {
2277 heap->IncrementDisableMovingGC(soa.Self());
2278 } else {
2279 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
2280 // to occur thanks to the to-space invariant.
2281 heap->IncrementDisableThreadFlip(soa.Self());
2282 }
2283 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
2284 array = soa.Decode<mirror::Array>(java_array);
2285 }
2286 if (is_copy != nullptr) {
2287 *is_copy = JNI_FALSE;
2288 }
2289 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
2290 }
2291
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray java_array,void * elements,jint mode)2292 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
2293 jint mode) {
2294 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2295 ScopedObjectAccess soa(env);
2296 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
2297 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2298 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
2299 array->GetClass()->PrettyDescriptor().c_str());
2300 return;
2301 }
2302 const size_t component_size = array->GetClass()->GetComponentSize();
2303 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
2304 }
2305
GetBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * is_copy)2306 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
2307 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
2308 }
2309
GetByteArrayElements(JNIEnv * env,jbyteArray array,jboolean * is_copy)2310 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
2311 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
2312 }
2313
GetCharArrayElements(JNIEnv * env,jcharArray array,jboolean * is_copy)2314 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
2315 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
2316 }
2317
GetDoubleArrayElements(JNIEnv * env,jdoubleArray array,jboolean * is_copy)2318 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
2319 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
2320 }
2321
GetFloatArrayElements(JNIEnv * env,jfloatArray array,jboolean * is_copy)2322 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
2323 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
2324 }
2325
GetIntArrayElements(JNIEnv * env,jintArray array,jboolean * is_copy)2326 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
2327 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
2328 }
2329
GetLongArrayElements(JNIEnv * env,jlongArray array,jboolean * is_copy)2330 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
2331 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
2332 }
2333
GetShortArrayElements(JNIEnv * env,jshortArray array,jboolean * is_copy)2334 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
2335 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
2336 }
2337
ReleaseBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * elements,jint mode)2338 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2339 jint mode) {
2340 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2341 mode);
2342 }
2343
ReleaseByteArrayElements(JNIEnv * env,jbyteArray array,jbyte * elements,jint mode)2344 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
2345 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
2346 }
2347
ReleaseCharArrayElements(JNIEnv * env,jcharArray array,jchar * elements,jint mode)2348 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
2349 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
2350 }
2351
ReleaseDoubleArrayElements(JNIEnv * env,jdoubleArray array,jdouble * elements,jint mode)2352 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2353 jint mode) {
2354 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
2355 }
2356
ReleaseFloatArrayElements(JNIEnv * env,jfloatArray array,jfloat * elements,jint mode)2357 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2358 jint mode) {
2359 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
2360 }
2361
ReleaseIntArrayElements(JNIEnv * env,jintArray array,jint * elements,jint mode)2362 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
2363 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
2364 }
2365
ReleaseLongArrayElements(JNIEnv * env,jlongArray array,jlong * elements,jint mode)2366 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
2367 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
2368 }
2369
ReleaseShortArrayElements(JNIEnv * env,jshortArray array,jshort * elements,jint mode)2370 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2371 jint mode) {
2372 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
2373 }
2374
GetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,jboolean * buf)2375 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2376 jboolean* buf) {
2377 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2378 length, buf);
2379 }
2380
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,jbyte * buf)2381 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2382 jbyte* buf) {
2383 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2384 }
2385
GetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,jchar * buf)2386 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2387 jchar* buf) {
2388 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2389 }
2390
GetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,jdouble * buf)2391 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2392 jdouble* buf) {
2393 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2394 buf);
2395 }
2396
GetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,jfloat * buf)2397 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2398 jfloat* buf) {
2399 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2400 buf);
2401 }
2402
GetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,jint * buf)2403 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2404 jint* buf) {
2405 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2406 }
2407
GetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,jlong * buf)2408 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2409 jlong* buf) {
2410 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2411 }
2412
GetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,jshort * buf)2413 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2414 jshort* buf) {
2415 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2416 buf);
2417 }
2418
SetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,const jboolean * buf)2419 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2420 const jboolean* buf) {
2421 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2422 length, buf);
2423 }
2424
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,const jbyte * buf)2425 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2426 const jbyte* buf) {
2427 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2428 }
2429
SetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,const jchar * buf)2430 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2431 const jchar* buf) {
2432 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2433 }
2434
SetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,const jdouble * buf)2435 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2436 const jdouble* buf) {
2437 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2438 buf);
2439 }
2440
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,const jfloat * buf)2441 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2442 const jfloat* buf) {
2443 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2444 buf);
2445 }
2446
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,const jint * buf)2447 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2448 const jint* buf) {
2449 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2450 }
2451
SetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,const jlong * buf)2452 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2453 const jlong* buf) {
2454 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2455 }
2456
SetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,const jshort * buf)2457 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2458 const jshort* buf) {
2459 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2460 buf);
2461 }
2462
RegisterNatives(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count)2463 static jint RegisterNatives(JNIEnv* env,
2464 jclass java_class,
2465 const JNINativeMethod* methods,
2466 jint method_count) {
2467 if (UNLIKELY(method_count < 0)) {
2468 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2469 method_count);
2470 return JNI_ERR; // Not reached except in unit tests.
2471 }
2472 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
2473 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2474 ScopedObjectAccess soa(env);
2475 StackHandleScope<1> hs(soa.Self());
2476 Handle<mirror::Class> c = hs.NewHandle(soa.Decode<mirror::Class>(java_class));
2477 if (UNLIKELY(method_count == 0)) {
2478 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2479 << c->PrettyDescriptor();
2480 return JNI_OK;
2481 }
2482 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2483 for (jint i = 0; i < method_count; ++i) {
2484 const char* name = methods[i].name;
2485 const char* sig = methods[i].signature;
2486 const void* fnPtr = methods[i].fnPtr;
2487 if (UNLIKELY(name == nullptr)) {
2488 ReportInvalidJNINativeMethod(soa, c.Get(), "method name", i);
2489 return JNI_ERR;
2490 } else if (UNLIKELY(sig == nullptr)) {
2491 ReportInvalidJNINativeMethod(soa, c.Get(), "method signature", i);
2492 return JNI_ERR;
2493 } else if (UNLIKELY(fnPtr == nullptr)) {
2494 ReportInvalidJNINativeMethod(soa, c.Get(), "native function", i);
2495 return JNI_ERR;
2496 }
2497 bool is_fast = false;
2498 // Notes about fast JNI calls:
2499 //
2500 // On a normal JNI call, the calling thread usually transitions
2501 // from the kRunnable state to the kNative state. But if the
2502 // called native function needs to access any Java object, it
2503 // will have to transition back to the kRunnable state.
2504 //
2505 // There is a cost to this double transition. For a JNI call
2506 // that should be quick, this cost may dominate the call cost.
2507 //
2508 // On a fast JNI call, the calling thread avoids this double
2509 // transition by not transitioning from kRunnable to kNative and
2510 // stays in the kRunnable state.
2511 //
2512 // There are risks to using a fast JNI call because it can delay
2513 // a response to a thread suspension request which is typically
2514 // used for a GC root scanning, etc. If a fast JNI call takes a
2515 // long time, it could cause longer thread suspension latency
2516 // and GC pauses.
2517 //
2518 // Thus, fast JNI should be used with care. It should be used
2519 // for a JNI call that takes a short amount of time (eg. no
2520 // long-running loop) and does not block (eg. no locks, I/O,
2521 // etc.)
2522 //
2523 // A '!' prefix in the signature in the JNINativeMethod
2524 // indicates that it's a fast JNI call and the runtime omits the
2525 // thread state transition from kRunnable to kNative at the
2526 // entry.
2527 if (*sig == '!') {
2528 is_fast = true;
2529 ++sig;
2530 }
2531
2532 // Note: the right order is to try to find the method locally
2533 // first, either as a direct or a virtual method. Then move to
2534 // the parent.
2535 ArtMethod* m = nullptr;
2536 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->GetVm()->IsCheckJniEnabled();
2537 for (ObjPtr<mirror::Class> current_class = c.Get();
2538 current_class != nullptr;
2539 current_class = current_class->GetSuperClass()) {
2540 // Search first only comparing methods which are native.
2541 m = FindMethod<true>(current_class, name, sig);
2542 if (m != nullptr) {
2543 break;
2544 }
2545
2546 // Search again comparing to all methods, to find non-native methods that match.
2547 m = FindMethod<false>(current_class, name, sig);
2548 if (m != nullptr) {
2549 break;
2550 }
2551
2552 if (warn_on_going_to_parent) {
2553 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2554 << "This is slow, consider changing your RegisterNatives calls.";
2555 warn_on_going_to_parent = false;
2556 }
2557 }
2558
2559 if (m == nullptr) {
2560 c->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
2561 LOG(ERROR)
2562 << "Failed to register native method "
2563 << c->PrettyDescriptor() << "." << name << sig << " in "
2564 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2565 ThrowNoSuchMethodError(soa, c.Get(), name, sig, "static or non-static");
2566 return JNI_ERR;
2567 } else if (!m->IsNative()) {
2568 LOG(ERROR)
2569 << "Failed to register non-native method "
2570 << c->PrettyDescriptor() << "." << name << sig
2571 << " as native";
2572 ThrowNoSuchMethodError(soa, c.Get(), name, sig, "native");
2573 return JNI_ERR;
2574 }
2575
2576 VLOG(jni) << "[Registering JNI native method " << m->PrettyMethod() << "]";
2577
2578 if (UNLIKELY(is_fast)) {
2579 // There are a few reasons to switch:
2580 // 1) We don't support !bang JNI anymore, it will turn to a hard error later.
2581 // 2) @FastNative is actually faster. At least 1.5x faster than !bang JNI.
2582 // and switching is super easy, remove ! in C code, add annotation in .java code.
2583 // 3) Good chance of hitting DCHECK failures in ScopedFastNativeObjectAccess
2584 // since that checks for presence of @FastNative and not for ! in the descriptor.
2585 LOG(WARNING) << "!bang JNI is deprecated. Switch to @FastNative for " << m->PrettyMethod();
2586 is_fast = false;
2587 // TODO: make this a hard register error in the future.
2588 }
2589
2590 const void* final_function_ptr = class_linker->RegisterNative(soa.Self(), m, fnPtr);
2591 UNUSED(final_function_ptr);
2592 }
2593 return JNI_OK;
2594 }
2595
UnregisterNatives(JNIEnv * env,jclass java_class)2596 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2597 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
2598 ScopedObjectAccess soa(env);
2599 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
2600
2601 VLOG(jni) << "[Unregistering JNI native methods for " << mirror::Class::PrettyClass(c) << "]";
2602
2603 size_t unregistered_count = 0;
2604 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2605 auto pointer_size = class_linker->GetImagePointerSize();
2606 for (auto& m : c->GetMethods(pointer_size)) {
2607 if (m.IsNative()) {
2608 class_linker->UnregisterNative(soa.Self(), &m);
2609 unregistered_count++;
2610 }
2611 }
2612
2613 if (unregistered_count == 0) {
2614 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2615 << mirror::Class::PrettyDescriptor(c) << "' that contains no native methods";
2616 }
2617 return JNI_OK;
2618 }
2619
MonitorEnter(JNIEnv * env,jobject java_object)2620 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2621 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2622 ScopedObjectAccess soa(env);
2623 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
2624 o = o->MonitorEnter(soa.Self());
2625 if (soa.Self()->HoldsLock(o)) {
2626 soa.Env()->monitors_.Add(o);
2627 }
2628 if (soa.Self()->IsExceptionPending()) {
2629 return JNI_ERR;
2630 }
2631 return JNI_OK;
2632 }
2633
MonitorExit(JNIEnv * env,jobject java_object)2634 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2635 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2636 ScopedObjectAccess soa(env);
2637 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
2638 bool remove_mon = soa.Self()->HoldsLock(o);
2639 o->MonitorExit(soa.Self());
2640 if (remove_mon) {
2641 soa.Env()->monitors_.Remove(o);
2642 }
2643 if (soa.Self()->IsExceptionPending()) {
2644 return JNI_ERR;
2645 }
2646 return JNI_OK;
2647 }
2648
GetJavaVM(JNIEnv * env,JavaVM ** vm)2649 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2650 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2651 Runtime* runtime = Runtime::Current();
2652 if (runtime != nullptr) {
2653 *vm = runtime->GetJavaVM();
2654 } else {
2655 *vm = nullptr;
2656 }
2657 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2658 }
2659
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)2660 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2661 if (capacity < 0) {
2662 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2663 capacity);
2664 return nullptr;
2665 }
2666 if (address == nullptr && capacity != 0) {
2667 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2668 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
2669 return nullptr;
2670 }
2671
2672 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
2673 if (capacity > INT_MAX) {
2674 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2675 "buffer capacity greater than maximum jint: %" PRId64,
2676 capacity);
2677 return nullptr;
2678 }
2679 jlong address_arg = reinterpret_cast<jlong>(address);
2680 jint capacity_arg = static_cast<jint>(capacity);
2681
2682 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2683 WellKnownClasses::java_nio_DirectByteBuffer_init,
2684 address_arg, capacity_arg);
2685 return static_cast<JNIEnvExt*>(env)->self_->IsExceptionPending() ? nullptr : result;
2686 }
2687
GetDirectBufferAddress(JNIEnv * env,jobject java_buffer)2688 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2689 // Return null if |java_buffer| is not defined.
2690 if (java_buffer == nullptr) {
2691 return nullptr;
2692 }
2693
2694 // Return null if |java_buffer| is not a java.nio.Buffer instance.
2695 if (!IsInstanceOf(env, java_buffer, WellKnownClasses::java_nio_Buffer)) {
2696 return nullptr;
2697 }
2698
2699 // Buffer.address is non-null when the |java_buffer| is direct.
2700 return reinterpret_cast<void*>(env->GetLongField(
2701 java_buffer, WellKnownClasses::java_nio_Buffer_address));
2702 }
2703
GetDirectBufferCapacity(JNIEnv * env,jobject java_buffer)2704 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2705 if (java_buffer == nullptr) {
2706 return -1;
2707 }
2708
2709 if (!IsInstanceOf(env, java_buffer, WellKnownClasses::java_nio_Buffer)) {
2710 return -1;
2711 }
2712
2713 // When checking the buffer capacity, it's important to note that a zero-sized direct buffer
2714 // may have a null address field which means we can't tell whether it is direct or not.
2715 // We therefore call Buffer.isDirect(). One path that creates such a buffer is
2716 // FileChannel.map() if the file size is zero.
2717 //
2718 // NB GetDirectBufferAddress() does not need to call Buffer.isDirect() since it is only
2719 // able return a valid address if the Buffer address field is not-null.
2720 jboolean direct = env->CallBooleanMethod(java_buffer,
2721 WellKnownClasses::java_nio_Buffer_isDirect);
2722 if (!direct) {
2723 return -1;
2724 }
2725
2726 return static_cast<jlong>(env->GetIntField(
2727 java_buffer, WellKnownClasses::java_nio_Buffer_capacity));
2728 }
2729
GetObjectRefType(JNIEnv * env ATTRIBUTE_UNUSED,jobject java_object)2730 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2731 if (java_object == nullptr) {
2732 return JNIInvalidRefType;
2733 }
2734
2735 // Do we definitely know what kind of reference this is?
2736 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2737 IndirectRefKind kind = IndirectReferenceTable::GetIndirectRefKind(ref);
2738 switch (kind) {
2739 case kLocal:
2740 return JNILocalRefType;
2741 case kGlobal:
2742 return JNIGlobalRefType;
2743 case kWeakGlobal:
2744 return JNIWeakGlobalRefType;
2745 case kJniTransitionOrInvalid:
2746 // Assume value is in a JNI transition frame.
2747 return JNILocalRefType;
2748 }
2749 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2750 UNREACHABLE();
2751 }
2752
2753 private:
EnsureLocalCapacityInternal(ScopedObjectAccess & soa,jint desired_capacity,const char * caller)2754 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2755 const char* caller)
2756 REQUIRES_SHARED(Locks::mutator_lock_) {
2757 if (desired_capacity < 0) {
2758 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2759 return JNI_ERR;
2760 }
2761
2762 std::string error_msg;
2763 if (!soa.Env()->locals_.EnsureFreeCapacity(static_cast<size_t>(desired_capacity), &error_msg)) {
2764 std::string caller_error = android::base::StringPrintf("%s: %s", caller, error_msg.c_str());
2765 soa.Self()->ThrowOutOfMemoryError(caller_error.c_str());
2766 return JNI_ERR;
2767 }
2768 return JNI_OK;
2769 }
2770
2771 template<typename JniT, typename ArtT>
NewPrimitiveArray(JNIEnv * env,jsize length)2772 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
2773 ScopedObjectAccess soa(env);
2774 if (UNLIKELY(length < 0)) {
2775 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2776 return nullptr;
2777 }
2778 ObjPtr<ArtT> result = ArtT::Alloc(soa.Self(), length);
2779 return soa.AddLocalReference<JniT>(result);
2780 }
2781
2782 template <typename JArrayT, typename ElementT, typename ArtArrayT>
DecodeAndCheckArrayType(ScopedObjectAccess & soa,JArrayT java_array,const char * fn_name,const char * operation)2783 static ObjPtr<ArtArrayT> DecodeAndCheckArrayType(ScopedObjectAccess& soa,
2784 JArrayT java_array,
2785 const char* fn_name,
2786 const char* operation)
2787 REQUIRES_SHARED(Locks::mutator_lock_) {
2788 ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array);
2789 ObjPtr<mirror::Class> expected_array_class = GetClassRoot<ArtArrayT>();
2790 if (UNLIKELY(expected_array_class != array->GetClass())) {
2791 soa.Vm()->JniAbortF(fn_name,
2792 "attempt to %s %s primitive array elements with an object of type %s",
2793 operation,
2794 mirror::Class::PrettyDescriptor(
2795 expected_array_class->GetComponentType()).c_str(),
2796 mirror::Class::PrettyDescriptor(array->GetClass()).c_str());
2797 return nullptr;
2798 }
2799 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2800 return array;
2801 }
2802
2803 template <typename ArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArray(JNIEnv * env,ArrayT java_array,jboolean * is_copy)2804 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2805 CHECK_NON_NULL_ARGUMENT(java_array);
2806 ScopedObjectAccess soa(env);
2807 ObjPtr<ArtArrayT> array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(
2808 soa, java_array, "GetArrayElements", "get");
2809 if (UNLIKELY(array == nullptr)) {
2810 return nullptr;
2811 }
2812 // Only make a copy if necessary.
2813 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2814 if (is_copy != nullptr) {
2815 *is_copy = JNI_TRUE;
2816 }
2817 const size_t component_size = sizeof(ElementT);
2818 size_t size = array->GetLength() * component_size;
2819 void* data = new uint64_t[RoundUp(size, 8) / 8];
2820 memcpy(data, array->GetData(), size);
2821 return reinterpret_cast<ElementT*>(data);
2822 } else {
2823 if (is_copy != nullptr) {
2824 *is_copy = JNI_FALSE;
2825 }
2826 return reinterpret_cast<ElementT*>(array->GetData());
2827 }
2828 }
2829
2830 template <typename ArrayT, typename ElementT, typename ArtArrayT>
ReleasePrimitiveArray(JNIEnv * env,ArrayT java_array,ElementT * elements,jint mode)2831 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
2832 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2833 ScopedObjectAccess soa(env);
2834 ObjPtr<ArtArrayT> array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(
2835 soa, java_array, "ReleaseArrayElements", "release");
2836 if (array == nullptr) {
2837 return;
2838 }
2839 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2840 }
2841
ReleasePrimitiveArray(ScopedObjectAccess & soa,ObjPtr<mirror::Array> array,size_t component_size,void * elements,jint mode)2842 static void ReleasePrimitiveArray(ScopedObjectAccess& soa,
2843 ObjPtr<mirror::Array> array,
2844 size_t component_size,
2845 void* elements,
2846 jint mode)
2847 REQUIRES_SHARED(Locks::mutator_lock_) {
2848 void* array_data = array->GetRawData(component_size, 0);
2849 gc::Heap* heap = Runtime::Current()->GetHeap();
2850 bool is_copy = array_data != elements;
2851 size_t bytes = array->GetLength() * component_size;
2852 if (is_copy) {
2853 // Integrity check: If elements is not the same as the java array's data, it better not be a
2854 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2855 // copies we make?
2856 if (heap->IsNonDiscontinuousSpaceHeapAddress(elements)) {
2857 soa.Vm()->JniAbortF("ReleaseArrayElements",
2858 "invalid element pointer %p, array elements are %p",
2859 reinterpret_cast<void*>(elements), array_data);
2860 return;
2861 }
2862 if (mode != JNI_ABORT) {
2863 memcpy(array_data, elements, bytes);
2864 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2865 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2866 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2867 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
2868 }
2869 }
2870 if (mode != JNI_COMMIT) {
2871 if (is_copy) {
2872 delete[] reinterpret_cast<uint64_t*>(elements);
2873 } else if (heap->IsMovableObject(array)) {
2874 // Non copy to a movable object must means that we had disabled the moving GC.
2875 if (!kUseReadBarrier) {
2876 heap->DecrementDisableMovingGC(soa.Self());
2877 } else {
2878 heap->DecrementDisableThreadFlip(soa.Self());
2879 }
2880 }
2881 }
2882 }
2883
2884 template <typename JArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,ElementT * buf)2885 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2886 jsize start, jsize length, ElementT* buf) {
2887 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2888 ScopedObjectAccess soa(env);
2889 ObjPtr<ArtArrayT> array = DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(
2890 soa, java_array, "GetPrimitiveArrayRegion", "get region of");
2891 if (array != nullptr) {
2892 if (start < 0 || length < 0 || length > array->GetLength() - start) {
2893 ThrowAIOOBE(soa, array, start, length, "src");
2894 } else {
2895 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2896 ElementT* data = array->GetData();
2897 memcpy(buf, data + start, length * sizeof(ElementT));
2898 }
2899 }
2900 }
2901
2902 template <typename JArrayT, typename ElementT, typename ArtArrayT>
SetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,const ElementT * buf)2903 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2904 jsize start, jsize length, const ElementT* buf) {
2905 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2906 ScopedObjectAccess soa(env);
2907 ObjPtr<ArtArrayT> array = DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(
2908 soa, java_array, "SetPrimitiveArrayRegion", "set region of");
2909 if (array != nullptr) {
2910 if (start < 0 || length < 0 || length > array->GetLength() - start) {
2911 ThrowAIOOBE(soa, array, start, length, "dst");
2912 } else {
2913 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2914 ElementT* data = array->GetData();
2915 memcpy(data + start, buf, length * sizeof(ElementT));
2916 }
2917 }
2918 }
2919 };
2920
2921 template<bool kEnableIndexIds>
2922 struct JniNativeInterfaceFunctions {
2923 using JNIImpl = JNI<kEnableIndexIds>;
2924 static constexpr JNINativeInterface gJniNativeInterface = {
2925 nullptr, // reserved0.
2926 nullptr, // reserved1.
2927 nullptr, // reserved2.
2928 nullptr, // reserved3.
2929 JNIImpl::GetVersion,
2930 JNIImpl::DefineClass,
2931 JNIImpl::FindClass,
2932 JNIImpl::FromReflectedMethod,
2933 JNIImpl::FromReflectedField,
2934 JNIImpl::ToReflectedMethod,
2935 JNIImpl::GetSuperclass,
2936 JNIImpl::IsAssignableFrom,
2937 JNIImpl::ToReflectedField,
2938 JNIImpl::Throw,
2939 JNIImpl::ThrowNew,
2940 JNIImpl::ExceptionOccurred,
2941 JNIImpl::ExceptionDescribe,
2942 JNIImpl::ExceptionClear,
2943 JNIImpl::FatalError,
2944 JNIImpl::PushLocalFrame,
2945 JNIImpl::PopLocalFrame,
2946 JNIImpl::NewGlobalRef,
2947 JNIImpl::DeleteGlobalRef,
2948 JNIImpl::DeleteLocalRef,
2949 JNIImpl::IsSameObject,
2950 JNIImpl::NewLocalRef,
2951 JNIImpl::EnsureLocalCapacity,
2952 JNIImpl::AllocObject,
2953 JNIImpl::NewObject,
2954 JNIImpl::NewObjectV,
2955 JNIImpl::NewObjectA,
2956 JNIImpl::GetObjectClass,
2957 JNIImpl::IsInstanceOf,
2958 JNIImpl::GetMethodID,
2959 JNIImpl::CallObjectMethod,
2960 JNIImpl::CallObjectMethodV,
2961 JNIImpl::CallObjectMethodA,
2962 JNIImpl::CallBooleanMethod,
2963 JNIImpl::CallBooleanMethodV,
2964 JNIImpl::CallBooleanMethodA,
2965 JNIImpl::CallByteMethod,
2966 JNIImpl::CallByteMethodV,
2967 JNIImpl::CallByteMethodA,
2968 JNIImpl::CallCharMethod,
2969 JNIImpl::CallCharMethodV,
2970 JNIImpl::CallCharMethodA,
2971 JNIImpl::CallShortMethod,
2972 JNIImpl::CallShortMethodV,
2973 JNIImpl::CallShortMethodA,
2974 JNIImpl::CallIntMethod,
2975 JNIImpl::CallIntMethodV,
2976 JNIImpl::CallIntMethodA,
2977 JNIImpl::CallLongMethod,
2978 JNIImpl::CallLongMethodV,
2979 JNIImpl::CallLongMethodA,
2980 JNIImpl::CallFloatMethod,
2981 JNIImpl::CallFloatMethodV,
2982 JNIImpl::CallFloatMethodA,
2983 JNIImpl::CallDoubleMethod,
2984 JNIImpl::CallDoubleMethodV,
2985 JNIImpl::CallDoubleMethodA,
2986 JNIImpl::CallVoidMethod,
2987 JNIImpl::CallVoidMethodV,
2988 JNIImpl::CallVoidMethodA,
2989 JNIImpl::CallNonvirtualObjectMethod,
2990 JNIImpl::CallNonvirtualObjectMethodV,
2991 JNIImpl::CallNonvirtualObjectMethodA,
2992 JNIImpl::CallNonvirtualBooleanMethod,
2993 JNIImpl::CallNonvirtualBooleanMethodV,
2994 JNIImpl::CallNonvirtualBooleanMethodA,
2995 JNIImpl::CallNonvirtualByteMethod,
2996 JNIImpl::CallNonvirtualByteMethodV,
2997 JNIImpl::CallNonvirtualByteMethodA,
2998 JNIImpl::CallNonvirtualCharMethod,
2999 JNIImpl::CallNonvirtualCharMethodV,
3000 JNIImpl::CallNonvirtualCharMethodA,
3001 JNIImpl::CallNonvirtualShortMethod,
3002 JNIImpl::CallNonvirtualShortMethodV,
3003 JNIImpl::CallNonvirtualShortMethodA,
3004 JNIImpl::CallNonvirtualIntMethod,
3005 JNIImpl::CallNonvirtualIntMethodV,
3006 JNIImpl::CallNonvirtualIntMethodA,
3007 JNIImpl::CallNonvirtualLongMethod,
3008 JNIImpl::CallNonvirtualLongMethodV,
3009 JNIImpl::CallNonvirtualLongMethodA,
3010 JNIImpl::CallNonvirtualFloatMethod,
3011 JNIImpl::CallNonvirtualFloatMethodV,
3012 JNIImpl::CallNonvirtualFloatMethodA,
3013 JNIImpl::CallNonvirtualDoubleMethod,
3014 JNIImpl::CallNonvirtualDoubleMethodV,
3015 JNIImpl::CallNonvirtualDoubleMethodA,
3016 JNIImpl::CallNonvirtualVoidMethod,
3017 JNIImpl::CallNonvirtualVoidMethodV,
3018 JNIImpl::CallNonvirtualVoidMethodA,
3019 JNIImpl::GetFieldID,
3020 JNIImpl::GetObjectField,
3021 JNIImpl::GetBooleanField,
3022 JNIImpl::GetByteField,
3023 JNIImpl::GetCharField,
3024 JNIImpl::GetShortField,
3025 JNIImpl::GetIntField,
3026 JNIImpl::GetLongField,
3027 JNIImpl::GetFloatField,
3028 JNIImpl::GetDoubleField,
3029 JNIImpl::SetObjectField,
3030 JNIImpl::SetBooleanField,
3031 JNIImpl::SetByteField,
3032 JNIImpl::SetCharField,
3033 JNIImpl::SetShortField,
3034 JNIImpl::SetIntField,
3035 JNIImpl::SetLongField,
3036 JNIImpl::SetFloatField,
3037 JNIImpl::SetDoubleField,
3038 JNIImpl::GetStaticMethodID,
3039 JNIImpl::CallStaticObjectMethod,
3040 JNIImpl::CallStaticObjectMethodV,
3041 JNIImpl::CallStaticObjectMethodA,
3042 JNIImpl::CallStaticBooleanMethod,
3043 JNIImpl::CallStaticBooleanMethodV,
3044 JNIImpl::CallStaticBooleanMethodA,
3045 JNIImpl::CallStaticByteMethod,
3046 JNIImpl::CallStaticByteMethodV,
3047 JNIImpl::CallStaticByteMethodA,
3048 JNIImpl::CallStaticCharMethod,
3049 JNIImpl::CallStaticCharMethodV,
3050 JNIImpl::CallStaticCharMethodA,
3051 JNIImpl::CallStaticShortMethod,
3052 JNIImpl::CallStaticShortMethodV,
3053 JNIImpl::CallStaticShortMethodA,
3054 JNIImpl::CallStaticIntMethod,
3055 JNIImpl::CallStaticIntMethodV,
3056 JNIImpl::CallStaticIntMethodA,
3057 JNIImpl::CallStaticLongMethod,
3058 JNIImpl::CallStaticLongMethodV,
3059 JNIImpl::CallStaticLongMethodA,
3060 JNIImpl::CallStaticFloatMethod,
3061 JNIImpl::CallStaticFloatMethodV,
3062 JNIImpl::CallStaticFloatMethodA,
3063 JNIImpl::CallStaticDoubleMethod,
3064 JNIImpl::CallStaticDoubleMethodV,
3065 JNIImpl::CallStaticDoubleMethodA,
3066 JNIImpl::CallStaticVoidMethod,
3067 JNIImpl::CallStaticVoidMethodV,
3068 JNIImpl::CallStaticVoidMethodA,
3069 JNIImpl::GetStaticFieldID,
3070 JNIImpl::GetStaticObjectField,
3071 JNIImpl::GetStaticBooleanField,
3072 JNIImpl::GetStaticByteField,
3073 JNIImpl::GetStaticCharField,
3074 JNIImpl::GetStaticShortField,
3075 JNIImpl::GetStaticIntField,
3076 JNIImpl::GetStaticLongField,
3077 JNIImpl::GetStaticFloatField,
3078 JNIImpl::GetStaticDoubleField,
3079 JNIImpl::SetStaticObjectField,
3080 JNIImpl::SetStaticBooleanField,
3081 JNIImpl::SetStaticByteField,
3082 JNIImpl::SetStaticCharField,
3083 JNIImpl::SetStaticShortField,
3084 JNIImpl::SetStaticIntField,
3085 JNIImpl::SetStaticLongField,
3086 JNIImpl::SetStaticFloatField,
3087 JNIImpl::SetStaticDoubleField,
3088 JNIImpl::NewString,
3089 JNIImpl::GetStringLength,
3090 JNIImpl::GetStringChars,
3091 JNIImpl::ReleaseStringChars,
3092 JNIImpl::NewStringUTF,
3093 JNIImpl::GetStringUTFLength,
3094 JNIImpl::GetStringUTFChars,
3095 JNIImpl::ReleaseStringUTFChars,
3096 JNIImpl::GetArrayLength,
3097 JNIImpl::NewObjectArray,
3098 JNIImpl::GetObjectArrayElement,
3099 JNIImpl::SetObjectArrayElement,
3100 JNIImpl::NewBooleanArray,
3101 JNIImpl::NewByteArray,
3102 JNIImpl::NewCharArray,
3103 JNIImpl::NewShortArray,
3104 JNIImpl::NewIntArray,
3105 JNIImpl::NewLongArray,
3106 JNIImpl::NewFloatArray,
3107 JNIImpl::NewDoubleArray,
3108 JNIImpl::GetBooleanArrayElements,
3109 JNIImpl::GetByteArrayElements,
3110 JNIImpl::GetCharArrayElements,
3111 JNIImpl::GetShortArrayElements,
3112 JNIImpl::GetIntArrayElements,
3113 JNIImpl::GetLongArrayElements,
3114 JNIImpl::GetFloatArrayElements,
3115 JNIImpl::GetDoubleArrayElements,
3116 JNIImpl::ReleaseBooleanArrayElements,
3117 JNIImpl::ReleaseByteArrayElements,
3118 JNIImpl::ReleaseCharArrayElements,
3119 JNIImpl::ReleaseShortArrayElements,
3120 JNIImpl::ReleaseIntArrayElements,
3121 JNIImpl::ReleaseLongArrayElements,
3122 JNIImpl::ReleaseFloatArrayElements,
3123 JNIImpl::ReleaseDoubleArrayElements,
3124 JNIImpl::GetBooleanArrayRegion,
3125 JNIImpl::GetByteArrayRegion,
3126 JNIImpl::GetCharArrayRegion,
3127 JNIImpl::GetShortArrayRegion,
3128 JNIImpl::GetIntArrayRegion,
3129 JNIImpl::GetLongArrayRegion,
3130 JNIImpl::GetFloatArrayRegion,
3131 JNIImpl::GetDoubleArrayRegion,
3132 JNIImpl::SetBooleanArrayRegion,
3133 JNIImpl::SetByteArrayRegion,
3134 JNIImpl::SetCharArrayRegion,
3135 JNIImpl::SetShortArrayRegion,
3136 JNIImpl::SetIntArrayRegion,
3137 JNIImpl::SetLongArrayRegion,
3138 JNIImpl::SetFloatArrayRegion,
3139 JNIImpl::SetDoubleArrayRegion,
3140 JNIImpl::RegisterNatives,
3141 JNIImpl::UnregisterNatives,
3142 JNIImpl::MonitorEnter,
3143 JNIImpl::MonitorExit,
3144 JNIImpl::GetJavaVM,
3145 JNIImpl::GetStringRegion,
3146 JNIImpl::GetStringUTFRegion,
3147 JNIImpl::GetPrimitiveArrayCritical,
3148 JNIImpl::ReleasePrimitiveArrayCritical,
3149 JNIImpl::GetStringCritical,
3150 JNIImpl::ReleaseStringCritical,
3151 JNIImpl::NewWeakGlobalRef,
3152 JNIImpl::DeleteWeakGlobalRef,
3153 JNIImpl::ExceptionCheck,
3154 JNIImpl::NewDirectByteBuffer,
3155 JNIImpl::GetDirectBufferAddress,
3156 JNIImpl::GetDirectBufferCapacity,
3157 JNIImpl::GetObjectRefType,
3158 };
3159 };
3160
GetJniNativeInterface()3161 const JNINativeInterface* GetJniNativeInterface() {
3162 // The template argument is passed down through the Encode/DecodeArtMethod/Field calls so if
3163 // JniIdType is kPointer the calls will be a simple cast with no branches. This ensures that
3164 // the normal case is still fast.
3165 return Runtime::Current()->GetJniIdType() == JniIdType::kPointer
3166 ? &JniNativeInterfaceFunctions<false>::gJniNativeInterface
3167 : &JniNativeInterfaceFunctions<true>::gJniNativeInterface;
3168 }
3169
3170 void (*gJniSleepForeverStub[])() = {
3171 nullptr, // reserved0.
3172 nullptr, // reserved1.
3173 nullptr, // reserved2.
3174 nullptr, // reserved3.
3175 SleepForever,
3176 SleepForever,
3177 SleepForever,
3178 SleepForever,
3179 SleepForever,
3180 SleepForever,
3181 SleepForever,
3182 SleepForever,
3183 SleepForever,
3184 SleepForever,
3185 SleepForever,
3186 SleepForever,
3187 SleepForever,
3188 SleepForever,
3189 SleepForever,
3190 SleepForever,
3191 SleepForever,
3192 SleepForever,
3193 SleepForever,
3194 SleepForever,
3195 SleepForever,
3196 SleepForever,
3197 SleepForever,
3198 SleepForever,
3199 SleepForever,
3200 SleepForever,
3201 SleepForever,
3202 SleepForever,
3203 SleepForever,
3204 SleepForever,
3205 SleepForever,
3206 SleepForever,
3207 SleepForever,
3208 SleepForever,
3209 SleepForever,
3210 SleepForever,
3211 SleepForever,
3212 SleepForever,
3213 SleepForever,
3214 SleepForever,
3215 SleepForever,
3216 SleepForever,
3217 SleepForever,
3218 SleepForever,
3219 SleepForever,
3220 SleepForever,
3221 SleepForever,
3222 SleepForever,
3223 SleepForever,
3224 SleepForever,
3225 SleepForever,
3226 SleepForever,
3227 SleepForever,
3228 SleepForever,
3229 SleepForever,
3230 SleepForever,
3231 SleepForever,
3232 SleepForever,
3233 SleepForever,
3234 SleepForever,
3235 SleepForever,
3236 SleepForever,
3237 SleepForever,
3238 SleepForever,
3239 SleepForever,
3240 SleepForever,
3241 SleepForever,
3242 SleepForever,
3243 SleepForever,
3244 SleepForever,
3245 SleepForever,
3246 SleepForever,
3247 SleepForever,
3248 SleepForever,
3249 SleepForever,
3250 SleepForever,
3251 SleepForever,
3252 SleepForever,
3253 SleepForever,
3254 SleepForever,
3255 SleepForever,
3256 SleepForever,
3257 SleepForever,
3258 SleepForever,
3259 SleepForever,
3260 SleepForever,
3261 SleepForever,
3262 SleepForever,
3263 SleepForever,
3264 SleepForever,
3265 SleepForever,
3266 SleepForever,
3267 SleepForever,
3268 SleepForever,
3269 SleepForever,
3270 SleepForever,
3271 SleepForever,
3272 SleepForever,
3273 SleepForever,
3274 SleepForever,
3275 SleepForever,
3276 SleepForever,
3277 SleepForever,
3278 SleepForever,
3279 SleepForever,
3280 SleepForever,
3281 SleepForever,
3282 SleepForever,
3283 SleepForever,
3284 SleepForever,
3285 SleepForever,
3286 SleepForever,
3287 SleepForever,
3288 SleepForever,
3289 SleepForever,
3290 SleepForever,
3291 SleepForever,
3292 SleepForever,
3293 SleepForever,
3294 SleepForever,
3295 SleepForever,
3296 SleepForever,
3297 SleepForever,
3298 SleepForever,
3299 SleepForever,
3300 SleepForever,
3301 SleepForever,
3302 SleepForever,
3303 SleepForever,
3304 SleepForever,
3305 SleepForever,
3306 SleepForever,
3307 SleepForever,
3308 SleepForever,
3309 SleepForever,
3310 SleepForever,
3311 SleepForever,
3312 SleepForever,
3313 SleepForever,
3314 SleepForever,
3315 SleepForever,
3316 SleepForever,
3317 SleepForever,
3318 SleepForever,
3319 SleepForever,
3320 SleepForever,
3321 SleepForever,
3322 SleepForever,
3323 SleepForever,
3324 SleepForever,
3325 SleepForever,
3326 SleepForever,
3327 SleepForever,
3328 SleepForever,
3329 SleepForever,
3330 SleepForever,
3331 SleepForever,
3332 SleepForever,
3333 SleepForever,
3334 SleepForever,
3335 SleepForever,
3336 SleepForever,
3337 SleepForever,
3338 SleepForever,
3339 SleepForever,
3340 SleepForever,
3341 SleepForever,
3342 SleepForever,
3343 SleepForever,
3344 SleepForever,
3345 SleepForever,
3346 SleepForever,
3347 SleepForever,
3348 SleepForever,
3349 SleepForever,
3350 SleepForever,
3351 SleepForever,
3352 SleepForever,
3353 SleepForever,
3354 SleepForever,
3355 SleepForever,
3356 SleepForever,
3357 SleepForever,
3358 SleepForever,
3359 SleepForever,
3360 SleepForever,
3361 SleepForever,
3362 SleepForever,
3363 SleepForever,
3364 SleepForever,
3365 SleepForever,
3366 SleepForever,
3367 SleepForever,
3368 SleepForever,
3369 SleepForever,
3370 SleepForever,
3371 SleepForever,
3372 SleepForever,
3373 SleepForever,
3374 SleepForever,
3375 SleepForever,
3376 SleepForever,
3377 SleepForever,
3378 SleepForever,
3379 SleepForever,
3380 SleepForever,
3381 SleepForever,
3382 SleepForever,
3383 SleepForever,
3384 SleepForever,
3385 SleepForever,
3386 SleepForever,
3387 SleepForever,
3388 SleepForever,
3389 SleepForever,
3390 SleepForever,
3391 SleepForever,
3392 SleepForever,
3393 SleepForever,
3394 SleepForever,
3395 SleepForever,
3396 SleepForever,
3397 SleepForever,
3398 SleepForever,
3399 SleepForever,
3400 SleepForever,
3401 SleepForever,
3402 SleepForever,
3403 SleepForever,
3404 };
3405
GetRuntimeShutdownNativeInterface()3406 const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3407 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3408 }
3409
3410 } // namespace art
3411
operator <<(std::ostream & os,const jobjectRefType & rhs)3412 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3413 switch (rhs) {
3414 case JNIInvalidRefType:
3415 os << "JNIInvalidRefType";
3416 return os;
3417 case JNILocalRefType:
3418 os << "JNILocalRefType";
3419 return os;
3420 case JNIGlobalRefType:
3421 os << "JNIGlobalRefType";
3422 return os;
3423 case JNIWeakGlobalRefType:
3424 os << "JNIWeakGlobalRefType";
3425 return os;
3426 default:
3427 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3428 UNREACHABLE();
3429 }
3430 }
3431