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 <dlfcn.h>
20
21 #include <cstdarg>
22 #include <memory>
23 #include <utility>
24 #include <vector>
25
26 #include "art_field-inl.h"
27 #include "art_method-inl.h"
28 #include "atomic.h"
29 #include "base/allocator.h"
30 #include "base/logging.h"
31 #include "base/mutex.h"
32 #include "base/stl_util.h"
33 #include "class_linker-inl.h"
34 #include "dex_file-inl.h"
35 #include "fault_handler.h"
36 #include "gc_root.h"
37 #include "gc/accounting/card_table-inl.h"
38 #include "indirect_reference_table-inl.h"
39 #include "interpreter/interpreter.h"
40 #include "jni_env_ext.h"
41 #include "java_vm_ext.h"
42 #include "mirror/class-inl.h"
43 #include "mirror/class_loader.h"
44 #include "mirror/field-inl.h"
45 #include "mirror/method.h"
46 #include "mirror/object-inl.h"
47 #include "mirror/object_array-inl.h"
48 #include "mirror/string-inl.h"
49 #include "mirror/throwable.h"
50 #include "parsed_options.h"
51 #include "reflection.h"
52 #include "runtime.h"
53 #include "safe_map.h"
54 #include "scoped_thread_state_change.h"
55 #include "ScopedLocalRef.h"
56 #include "thread.h"
57 #include "utf.h"
58 #include "well_known_classes.h"
59
60 namespace art {
61
62 // Consider turning this on when there is errors which could be related to JNI array copies such as
63 // things not rendering correctly. E.g. b/16858794
64 static constexpr bool kWarnJniAbort = false;
65
66 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
67 // separated with slashes but aren't wrapped with "L;" like regular descriptors
68 // (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
69 // exception; there the "L;" must be present ("[La/b/C;"). Historically we've
70 // supported names with dots too (such as "a.b.C").
NormalizeJniClassDescriptor(const char * name)71 static std::string NormalizeJniClassDescriptor(const char* name) {
72 std::string result;
73 // Add the missing "L;" if necessary.
74 if (name[0] == '[') {
75 result = name;
76 } else {
77 result += 'L';
78 result += name;
79 result += ';';
80 }
81 // Rewrite '.' as '/' for backwards compatibility.
82 if (result.find('.') != std::string::npos) {
83 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
84 << "\"" << name << "\"";
85 std::replace(result.begin(), result.end(), '.', '/');
86 }
87 return result;
88 }
89
ThrowNoSuchMethodError(ScopedObjectAccess & soa,mirror::Class * c,const char * name,const char * sig,const char * kind)90 static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
91 const char* name, const char* sig, const char* kind)
92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93 std::string temp;
94 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
95 "no %s method \"%s.%s%s\"",
96 kind, c->GetDescriptor(&temp), name, sig);
97 }
98
ReportInvalidJNINativeMethod(const ScopedObjectAccess & soa,mirror::Class * c,const char * kind,jint idx,bool return_errors)99 static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
100 const char* kind, jint idx, bool return_errors)
101 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
102 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
103 << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
104 << ": " << kind << " is null at index " << idx;
105 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
106 "%s is null at index %d", kind, idx);
107 }
108
EnsureInitialized(Thread * self,mirror::Class * klass)109 static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
110 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
111 if (LIKELY(klass->IsInitialized())) {
112 return klass;
113 }
114 StackHandleScope<1> hs(self);
115 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
116 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
117 return nullptr;
118 }
119 return h_klass.Get();
120 }
121
FindMethodID(ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)122 static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
123 const char* name, const char* sig, bool is_static)
124 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
126 if (c == nullptr) {
127 return nullptr;
128 }
129 ArtMethod* method = nullptr;
130 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
131 if (is_static) {
132 method = c->FindDirectMethod(name, sig, pointer_size);
133 } else if (c->IsInterface()) {
134 method = c->FindInterfaceMethod(name, sig, pointer_size);
135 } else {
136 method = c->FindVirtualMethod(name, sig, pointer_size);
137 if (method == nullptr) {
138 // No virtual method matching the signature. Search declared
139 // private methods and constructors.
140 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
141 }
142 }
143 if (method == nullptr || method->IsStatic() != is_static) {
144 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
145 return nullptr;
146 }
147 return soa.EncodeMethod(method);
148 }
149
GetClassLoader(const ScopedObjectAccess & soa)150 static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
151 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
152 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
153 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
154 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
155 return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
156 }
157 // If we have a method, use its ClassLoader for context.
158 if (method != nullptr) {
159 return method->GetDeclaringClass()->GetClassLoader();
160 }
161 // We don't have a method, so try to use the system ClassLoader.
162 mirror::ClassLoader* class_loader =
163 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
164 if (class_loader != nullptr) {
165 return class_loader;
166 }
167 // See if the override ClassLoader is set for gtests.
168 class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
169 if (class_loader != nullptr) {
170 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
171 // image.
172 CHECK(Runtime::Current()->IsAotCompiler());
173 CHECK(!Runtime::Current()->IsCompilingBootImage());
174 return class_loader;
175 }
176 // Use the BOOTCLASSPATH.
177 return nullptr;
178 }
179
FindFieldID(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)180 static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
181 const char* sig, bool is_static)
182 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
183 StackHandleScope<2> hs(soa.Self());
184 Handle<mirror::Class> c(
185 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
186 if (c.Get() == nullptr) {
187 return nullptr;
188 }
189 ArtField* field = nullptr;
190 mirror::Class* field_type;
191 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
192 if (sig[1] != '\0') {
193 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
194 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
195 } else {
196 field_type = class_linker->FindPrimitiveClass(*sig);
197 }
198 if (field_type == nullptr) {
199 // Failed to find type from the signature of the field.
200 DCHECK(soa.Self()->IsExceptionPending());
201 StackHandleScope<1> hs2(soa.Self());
202 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
203 soa.Self()->ClearException();
204 std::string temp;
205 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
206 "no type \"%s\" found and so no field \"%s\" "
207 "could be found in class \"%s\" or its superclasses", sig, name,
208 c->GetDescriptor(&temp));
209 soa.Self()->GetException()->SetCause(cause.Get());
210 return nullptr;
211 }
212 std::string temp;
213 if (is_static) {
214 field = mirror::Class::FindStaticField(soa.Self(), c, name,
215 field_type->GetDescriptor(&temp));
216 } else {
217 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
218 }
219 if (field == nullptr) {
220 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
221 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
222 sig, name, c->GetDescriptor(&temp));
223 return nullptr;
224 }
225 return soa.EncodeField(field);
226 }
227
ThrowAIOOBE(ScopedObjectAccess & soa,mirror::Array * array,jsize start,jsize length,const char * identifier)228 static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
229 jsize length, const char* identifier)
230 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
231 std::string type(PrettyTypeOf(array));
232 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
233 "%s offset=%d length=%d %s.length=%d",
234 type.c_str(), start, length, identifier, array->GetLength());
235 }
236
ThrowSIOOBE(ScopedObjectAccess & soa,jsize start,jsize length,jsize array_length)237 static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
238 jsize array_length)
239 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
240 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
241 "offset=%d length=%d string.length()=%d", start, length,
242 array_length);
243 }
244
ThrowNewException(JNIEnv * env,jclass exception_class,const char * msg,jobject cause)245 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
246 LOCKS_EXCLUDED(Locks::mutator_lock_) {
247 // Turn the const char* into a java.lang.String.
248 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
249 if (msg != nullptr && s.get() == nullptr) {
250 return JNI_ERR;
251 }
252
253 // Choose an appropriate constructor and set up the arguments.
254 jvalue args[2];
255 const char* signature;
256 if (msg == nullptr && cause == nullptr) {
257 signature = "()V";
258 } else if (msg != nullptr && cause == nullptr) {
259 signature = "(Ljava/lang/String;)V";
260 args[0].l = s.get();
261 } else if (msg == nullptr && cause != nullptr) {
262 signature = "(Ljava/lang/Throwable;)V";
263 args[0].l = cause;
264 } else {
265 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
266 args[0].l = s.get();
267 args[1].l = cause;
268 }
269 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
270 if (mid == nullptr) {
271 ScopedObjectAccess soa(env);
272 LOG(ERROR) << "No <init>" << signature << " in "
273 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
274 return JNI_ERR;
275 }
276
277 ScopedLocalRef<jthrowable> exception(
278 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
279 if (exception.get() == nullptr) {
280 return JNI_ERR;
281 }
282 ScopedObjectAccess soa(env);
283 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
284 return JNI_OK;
285 }
286
JavaVmExtFromEnv(JNIEnv * env)287 static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
288 return reinterpret_cast<JNIEnvExt*>(env)->vm;
289 }
290
291 #define CHECK_NON_NULL_ARGUMENT(value) \
292 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
293
294 #define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
295 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
296
297 #define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
298 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
299
300 #define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
301 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
302
303 #define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
304 if (UNLIKELY(value == nullptr)) { \
305 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
306 return return_val; \
307 }
308
309 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
310 if (UNLIKELY(length != 0 && value == nullptr)) { \
311 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
312 return; \
313 }
314
315 template <bool kNative>
FindMethod(mirror::Class * c,const StringPiece & name,const StringPiece & sig)316 static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
317 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
318 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
319 for (auto& method : c->GetDirectMethods(pointer_size)) {
320 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
321 return &method;
322 }
323 }
324 for (auto& method : c->GetVirtualMethods(pointer_size)) {
325 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
326 return &method;
327 }
328 }
329 return nullptr;
330 }
331
332 class JNI {
333 public:
GetVersion(JNIEnv *)334 static jint GetVersion(JNIEnv*) {
335 return JNI_VERSION_1_6;
336 }
337
DefineClass(JNIEnv *,const char *,jobject,const jbyte *,jsize)338 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
339 LOG(WARNING) << "JNI DefineClass is not supported";
340 return nullptr;
341 }
342
FindClass(JNIEnv * env,const char * name)343 static jclass FindClass(JNIEnv* env, const char* name) {
344 CHECK_NON_NULL_ARGUMENT(name);
345 Runtime* runtime = Runtime::Current();
346 ClassLinker* class_linker = runtime->GetClassLinker();
347 std::string descriptor(NormalizeJniClassDescriptor(name));
348 ScopedObjectAccess soa(env);
349 mirror::Class* c = nullptr;
350 if (runtime->IsStarted()) {
351 StackHandleScope<1> hs(soa.Self());
352 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
353 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
354 } else {
355 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
356 }
357 return soa.AddLocalReference<jclass>(c);
358 }
359
FromReflectedMethod(JNIEnv * env,jobject jlr_method)360 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
361 CHECK_NON_NULL_ARGUMENT(jlr_method);
362 ScopedObjectAccess soa(env);
363 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
364 }
365
FromReflectedField(JNIEnv * env,jobject jlr_field)366 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
367 CHECK_NON_NULL_ARGUMENT(jlr_field);
368 ScopedObjectAccess soa(env);
369 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
370 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
371 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
372 return nullptr;
373 }
374 auto* field = static_cast<mirror::Field*>(obj_field);
375 return soa.EncodeField(field->GetArtField());
376 }
377
ToReflectedMethod(JNIEnv * env,jclass,jmethodID mid,jboolean)378 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
379 CHECK_NON_NULL_ARGUMENT(mid);
380 ScopedObjectAccess soa(env);
381 ArtMethod* m = soa.DecodeMethod(mid);
382 mirror::AbstractMethod* method;
383 if (m->IsConstructor()) {
384 method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m);
385 } else {
386 method = mirror::Method::CreateFromArtMethod(soa.Self(), m);
387 }
388 return soa.AddLocalReference<jobject>(method);
389 }
390
ToReflectedField(JNIEnv * env,jclass,jfieldID fid,jboolean)391 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
392 CHECK_NON_NULL_ARGUMENT(fid);
393 ScopedObjectAccess soa(env);
394 ArtField* f = soa.DecodeField(fid);
395 return soa.AddLocalReference<jobject>(mirror::Field::CreateFromArtField(soa.Self(), f, true));
396 }
397
GetObjectClass(JNIEnv * env,jobject java_object)398 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
399 CHECK_NON_NULL_ARGUMENT(java_object);
400 ScopedObjectAccess soa(env);
401 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
402 return soa.AddLocalReference<jclass>(o->GetClass());
403 }
404
GetSuperclass(JNIEnv * env,jclass java_class)405 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
406 CHECK_NON_NULL_ARGUMENT(java_class);
407 ScopedObjectAccess soa(env);
408 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
409 return soa.AddLocalReference<jclass>(c->GetSuperClass());
410 }
411
412 // Note: java_class1 should be safely castable to java_class2, and
413 // not the other way around.
IsAssignableFrom(JNIEnv * env,jclass java_class1,jclass java_class2)414 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
415 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
416 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
417 ScopedObjectAccess soa(env);
418 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
419 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
420 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
421 }
422
IsInstanceOf(JNIEnv * env,jobject jobj,jclass java_class)423 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
424 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
425 if (jobj == nullptr) {
426 // Note: JNI is different from regular Java instanceof in this respect
427 return JNI_TRUE;
428 } else {
429 ScopedObjectAccess soa(env);
430 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
431 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
432 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
433 }
434 }
435
Throw(JNIEnv * env,jthrowable java_exception)436 static jint Throw(JNIEnv* env, jthrowable java_exception) {
437 ScopedObjectAccess soa(env);
438 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
439 if (exception == nullptr) {
440 return JNI_ERR;
441 }
442 soa.Self()->SetException(exception);
443 return JNI_OK;
444 }
445
ThrowNew(JNIEnv * env,jclass c,const char * msg)446 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
447 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
448 return ThrowNewException(env, c, msg, nullptr);
449 }
450
ExceptionCheck(JNIEnv * env)451 static jboolean ExceptionCheck(JNIEnv* env) {
452 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
453 }
454
ExceptionClear(JNIEnv * env)455 static void ExceptionClear(JNIEnv* env) {
456 ScopedObjectAccess soa(env);
457 soa.Self()->ClearException();
458 }
459
ExceptionDescribe(JNIEnv * env)460 static void ExceptionDescribe(JNIEnv* env) {
461 ScopedObjectAccess soa(env);
462
463 // If we have no exception to describe, pass through.
464 if (!soa.Self()->GetException()) {
465 return;
466 }
467
468 StackHandleScope<1> hs(soa.Self());
469 Handle<mirror::Throwable> old_exception(
470 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
471 soa.Self()->ClearException();
472 ScopedLocalRef<jthrowable> exception(env,
473 soa.AddLocalReference<jthrowable>(old_exception.Get()));
474 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
475 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
476 if (mid == nullptr) {
477 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
478 << PrettyTypeOf(old_exception.Get());
479 } else {
480 env->CallVoidMethod(exception.get(), mid);
481 if (soa.Self()->IsExceptionPending()) {
482 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
483 << " thrown while calling printStackTrace";
484 soa.Self()->ClearException();
485 }
486 }
487 soa.Self()->SetException(old_exception.Get());
488 }
489
ExceptionOccurred(JNIEnv * env)490 static jthrowable ExceptionOccurred(JNIEnv* env) {
491 ScopedObjectAccess soa(env);
492 mirror::Object* exception = soa.Self()->GetException();
493 return soa.AddLocalReference<jthrowable>(exception);
494 }
495
FatalError(JNIEnv *,const char * msg)496 static void FatalError(JNIEnv*, const char* msg) {
497 LOG(FATAL) << "JNI FatalError called: " << msg;
498 }
499
PushLocalFrame(JNIEnv * env,jint capacity)500 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
501 // TODO: SOA may not be necessary but I do it to please lock annotations.
502 ScopedObjectAccess soa(env);
503 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
504 return JNI_ERR;
505 }
506 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
507 return JNI_OK;
508 }
509
PopLocalFrame(JNIEnv * env,jobject java_survivor)510 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
511 ScopedObjectAccess soa(env);
512 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
513 soa.Env()->PopFrame();
514 return soa.AddLocalReference<jobject>(survivor);
515 }
516
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity)517 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
518 // TODO: SOA may not be necessary but I do it to please lock annotations.
519 ScopedObjectAccess soa(env);
520 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
521 }
522
NewGlobalRef(JNIEnv * env,jobject obj)523 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
524 ScopedObjectAccess soa(env);
525 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
526 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
527 }
528
DeleteGlobalRef(JNIEnv * env,jobject obj)529 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
530 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
531 Thread* self = down_cast<JNIEnvExt*>(env)->self;
532 vm->DeleteGlobalRef(self, obj);
533 }
534
NewWeakGlobalRef(JNIEnv * env,jobject obj)535 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
536 ScopedObjectAccess soa(env);
537 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
538 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
539 }
540
DeleteWeakGlobalRef(JNIEnv * env,jweak obj)541 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
542 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
543 Thread* self = down_cast<JNIEnvExt*>(env)->self;
544 vm->DeleteWeakGlobalRef(self, obj);
545 }
546
NewLocalRef(JNIEnv * env,jobject obj)547 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
548 ScopedObjectAccess soa(env);
549 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
550 // Check for null after decoding the object to handle cleared weak globals.
551 if (decoded_obj == nullptr) {
552 return nullptr;
553 }
554 return soa.AddLocalReference<jobject>(decoded_obj);
555 }
556
DeleteLocalRef(JNIEnv * env,jobject obj)557 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
558 if (obj == nullptr) {
559 return;
560 }
561 // SOA is only necessary to have exclusion between GC root marking and removing.
562 // We don't want to have the GC attempt to mark a null root if we just removed
563 // it. b/22119403
564 ScopedObjectAccess soa(env);
565 auto* ext_env = down_cast<JNIEnvExt*>(env);
566 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
567 // Attempting to delete a local reference that is not in the
568 // topmost local reference frame is a no-op. DeleteLocalRef returns
569 // void and doesn't throw any exceptions, but we should probably
570 // complain about it so the user will notice that things aren't
571 // going quite the way they expect.
572 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
573 << "failed to find entry";
574 }
575 }
576
IsSameObject(JNIEnv * env,jobject obj1,jobject obj2)577 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
578 if (obj1 == obj2) {
579 return JNI_TRUE;
580 } else {
581 ScopedObjectAccess soa(env);
582 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
583 ? JNI_TRUE : JNI_FALSE;
584 }
585 }
586
AllocObject(JNIEnv * env,jclass java_class)587 static jobject AllocObject(JNIEnv* env, jclass java_class) {
588 CHECK_NON_NULL_ARGUMENT(java_class);
589 ScopedObjectAccess soa(env);
590 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
591 if (c == nullptr) {
592 return nullptr;
593 }
594 if (c->IsStringClass()) {
595 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
596 mirror::SetStringCountVisitor visitor(0);
597 return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
598 allocator_type, visitor));
599 }
600 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
601 }
602
NewObject(JNIEnv * env,jclass java_class,jmethodID mid,...)603 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
604 va_list args;
605 va_start(args, mid);
606 CHECK_NON_NULL_ARGUMENT(java_class);
607 CHECK_NON_NULL_ARGUMENT(mid);
608 jobject result = NewObjectV(env, java_class, mid, args);
609 va_end(args);
610 return result;
611 }
612
NewObjectV(JNIEnv * env,jclass java_class,jmethodID mid,va_list args)613 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
614 CHECK_NON_NULL_ARGUMENT(java_class);
615 CHECK_NON_NULL_ARGUMENT(mid);
616 ScopedObjectAccess soa(env);
617 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
618 if (c == nullptr) {
619 return nullptr;
620 }
621 if (c->IsStringClass()) {
622 // Replace calls to String.<init> with equivalent StringFactory call.
623 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
624 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
625 }
626 mirror::Object* result = c->AllocObject(soa.Self());
627 if (result == nullptr) {
628 return nullptr;
629 }
630 jobject local_result = soa.AddLocalReference<jobject>(result);
631 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
632 if (soa.Self()->IsExceptionPending()) {
633 return nullptr;
634 }
635 return local_result;
636 }
637
NewObjectA(JNIEnv * env,jclass java_class,jmethodID mid,jvalue * args)638 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
639 CHECK_NON_NULL_ARGUMENT(java_class);
640 CHECK_NON_NULL_ARGUMENT(mid);
641 ScopedObjectAccess soa(env);
642 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
643 if (c == nullptr) {
644 return nullptr;
645 }
646 if (c->IsStringClass()) {
647 // Replace calls to String.<init> with equivalent StringFactory call.
648 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
649 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
650 }
651 mirror::Object* result = c->AllocObject(soa.Self());
652 if (result == nullptr) {
653 return nullptr;
654 }
655 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
656 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
657 if (soa.Self()->IsExceptionPending()) {
658 return nullptr;
659 }
660 return local_result;
661 }
662
GetMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)663 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
664 CHECK_NON_NULL_ARGUMENT(java_class);
665 CHECK_NON_NULL_ARGUMENT(name);
666 CHECK_NON_NULL_ARGUMENT(sig);
667 ScopedObjectAccess soa(env);
668 return FindMethodID(soa, java_class, name, sig, false);
669 }
670
GetStaticMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)671 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
672 const char* sig) {
673 CHECK_NON_NULL_ARGUMENT(java_class);
674 CHECK_NON_NULL_ARGUMENT(name);
675 CHECK_NON_NULL_ARGUMENT(sig);
676 ScopedObjectAccess soa(env);
677 return FindMethodID(soa, java_class, name, sig, true);
678 }
679
CallObjectMethod(JNIEnv * env,jobject obj,jmethodID mid,...)680 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
681 va_list ap;
682 va_start(ap, mid);
683 CHECK_NON_NULL_ARGUMENT(obj);
684 CHECK_NON_NULL_ARGUMENT(mid);
685 ScopedObjectAccess soa(env);
686 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
687 va_end(ap);
688 return soa.AddLocalReference<jobject>(result.GetL());
689 }
690
CallObjectMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)691 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
692 CHECK_NON_NULL_ARGUMENT(obj);
693 CHECK_NON_NULL_ARGUMENT(mid);
694 ScopedObjectAccess soa(env);
695 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
696 return soa.AddLocalReference<jobject>(result.GetL());
697 }
698
CallObjectMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)699 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
700 CHECK_NON_NULL_ARGUMENT(obj);
701 CHECK_NON_NULL_ARGUMENT(mid);
702 ScopedObjectAccess soa(env);
703 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
704 return soa.AddLocalReference<jobject>(result.GetL());
705 }
706
CallBooleanMethod(JNIEnv * env,jobject obj,jmethodID mid,...)707 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
708 va_list ap;
709 va_start(ap, mid);
710 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
711 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
712 ScopedObjectAccess soa(env);
713 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
714 va_end(ap);
715 return result.GetZ();
716 }
717
CallBooleanMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)718 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
719 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
720 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
721 ScopedObjectAccess soa(env);
722 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
723 }
724
CallBooleanMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)725 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
726 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
727 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
728 ScopedObjectAccess soa(env);
729 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
730 }
731
CallByteMethod(JNIEnv * env,jobject obj,jmethodID mid,...)732 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
733 va_list ap;
734 va_start(ap, mid);
735 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
736 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
737 ScopedObjectAccess soa(env);
738 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
739 va_end(ap);
740 return result.GetB();
741 }
742
CallByteMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)743 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
744 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
745 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
746 ScopedObjectAccess soa(env);
747 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
748 }
749
CallByteMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)750 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
751 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
752 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
753 ScopedObjectAccess soa(env);
754 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
755 }
756
CallCharMethod(JNIEnv * env,jobject obj,jmethodID mid,...)757 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
758 va_list ap;
759 va_start(ap, mid);
760 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
761 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
762 ScopedObjectAccess soa(env);
763 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
764 va_end(ap);
765 return result.GetC();
766 }
767
CallCharMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)768 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
769 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
770 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
771 ScopedObjectAccess soa(env);
772 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
773 }
774
CallCharMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)775 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
776 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
777 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
778 ScopedObjectAccess soa(env);
779 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
780 }
781
CallDoubleMethod(JNIEnv * env,jobject obj,jmethodID mid,...)782 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
783 va_list ap;
784 va_start(ap, mid);
785 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
786 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
787 ScopedObjectAccess soa(env);
788 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
789 va_end(ap);
790 return result.GetD();
791 }
792
CallDoubleMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)793 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
794 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
795 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
796 ScopedObjectAccess soa(env);
797 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
798 }
799
CallDoubleMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)800 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
801 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
802 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
803 ScopedObjectAccess soa(env);
804 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
805 }
806
CallFloatMethod(JNIEnv * env,jobject obj,jmethodID mid,...)807 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
808 va_list ap;
809 va_start(ap, mid);
810 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
811 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
812 ScopedObjectAccess soa(env);
813 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
814 va_end(ap);
815 return result.GetF();
816 }
817
CallFloatMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)818 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
819 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
820 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
821 ScopedObjectAccess soa(env);
822 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
823 }
824
CallFloatMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)825 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
826 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
827 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
828 ScopedObjectAccess soa(env);
829 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
830 }
831
CallIntMethod(JNIEnv * env,jobject obj,jmethodID mid,...)832 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
833 va_list ap;
834 va_start(ap, mid);
835 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
836 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
837 ScopedObjectAccess soa(env);
838 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
839 va_end(ap);
840 return result.GetI();
841 }
842
CallIntMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)843 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
844 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
845 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
846 ScopedObjectAccess soa(env);
847 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
848 }
849
CallIntMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)850 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
851 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
852 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
853 ScopedObjectAccess soa(env);
854 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
855 }
856
CallLongMethod(JNIEnv * env,jobject obj,jmethodID mid,...)857 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
858 va_list ap;
859 va_start(ap, mid);
860 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
861 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
862 ScopedObjectAccess soa(env);
863 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
864 va_end(ap);
865 return result.GetJ();
866 }
867
CallLongMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)868 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
869 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
870 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
871 ScopedObjectAccess soa(env);
872 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
873 }
874
CallLongMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)875 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
876 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
877 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
878 ScopedObjectAccess soa(env);
879 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
880 }
881
CallShortMethod(JNIEnv * env,jobject obj,jmethodID mid,...)882 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
883 va_list ap;
884 va_start(ap, mid);
885 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
886 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
887 ScopedObjectAccess soa(env);
888 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
889 va_end(ap);
890 return result.GetS();
891 }
892
CallShortMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)893 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
894 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
895 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
896 ScopedObjectAccess soa(env);
897 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
898 }
899
CallShortMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)900 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
901 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
902 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
903 ScopedObjectAccess soa(env);
904 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
905 }
906
CallVoidMethod(JNIEnv * env,jobject obj,jmethodID mid,...)907 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
908 va_list ap;
909 va_start(ap, mid);
910 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
911 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
912 ScopedObjectAccess soa(env);
913 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
914 va_end(ap);
915 }
916
CallVoidMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)917 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
918 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
919 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
920 ScopedObjectAccess soa(env);
921 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
922 }
923
CallVoidMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)924 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
925 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
926 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
927 ScopedObjectAccess soa(env);
928 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
929 }
930
CallNonvirtualObjectMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)931 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
932 va_list ap;
933 va_start(ap, mid);
934 CHECK_NON_NULL_ARGUMENT(obj);
935 CHECK_NON_NULL_ARGUMENT(mid);
936 ScopedObjectAccess soa(env);
937 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
938 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
939 va_end(ap);
940 return local_result;
941 }
942
CallNonvirtualObjectMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)943 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
944 va_list args) {
945 CHECK_NON_NULL_ARGUMENT(obj);
946 CHECK_NON_NULL_ARGUMENT(mid);
947 ScopedObjectAccess soa(env);
948 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
949 return soa.AddLocalReference<jobject>(result.GetL());
950 }
951
CallNonvirtualObjectMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)952 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
953 jvalue* args) {
954 CHECK_NON_NULL_ARGUMENT(obj);
955 CHECK_NON_NULL_ARGUMENT(mid);
956 ScopedObjectAccess soa(env);
957 JValue result(InvokeWithJValues(soa, obj, mid, args));
958 return soa.AddLocalReference<jobject>(result.GetL());
959 }
960
CallNonvirtualBooleanMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)961 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
962 ...) {
963 va_list ap;
964 va_start(ap, mid);
965 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
966 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
967 ScopedObjectAccess soa(env);
968 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
969 va_end(ap);
970 return result.GetZ();
971 }
972
CallNonvirtualBooleanMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)973 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
974 va_list args) {
975 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
976 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
977 ScopedObjectAccess soa(env);
978 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
979 }
980
CallNonvirtualBooleanMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)981 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
982 jvalue* args) {
983 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
984 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
985 ScopedObjectAccess soa(env);
986 return InvokeWithJValues(soa, obj, mid, args).GetZ();
987 }
988
CallNonvirtualByteMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)989 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
990 va_list ap;
991 va_start(ap, mid);
992 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
993 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
994 ScopedObjectAccess soa(env);
995 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
996 va_end(ap);
997 return result.GetB();
998 }
999
CallNonvirtualByteMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1000 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1001 va_list args) {
1002 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1003 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1004 ScopedObjectAccess soa(env);
1005 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1006 }
1007
CallNonvirtualByteMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1008 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1009 jvalue* args) {
1010 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1011 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1012 ScopedObjectAccess soa(env);
1013 return InvokeWithJValues(soa, obj, mid, args).GetB();
1014 }
1015
CallNonvirtualCharMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1016 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1017 va_list ap;
1018 va_start(ap, mid);
1019 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1020 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1021 ScopedObjectAccess soa(env);
1022 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1023 va_end(ap);
1024 return result.GetC();
1025 }
1026
CallNonvirtualCharMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1027 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1028 va_list args) {
1029 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1030 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1031 ScopedObjectAccess soa(env);
1032 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1033 }
1034
CallNonvirtualCharMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1035 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1036 jvalue* args) {
1037 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1038 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1039 ScopedObjectAccess soa(env);
1040 return InvokeWithJValues(soa, obj, mid, args).GetC();
1041 }
1042
CallNonvirtualShortMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1043 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1044 va_list ap;
1045 va_start(ap, mid);
1046 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1047 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1048 ScopedObjectAccess soa(env);
1049 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1050 va_end(ap);
1051 return result.GetS();
1052 }
1053
CallNonvirtualShortMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1054 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1055 va_list args) {
1056 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1057 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1058 ScopedObjectAccess soa(env);
1059 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1060 }
1061
CallNonvirtualShortMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1062 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1063 jvalue* args) {
1064 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1065 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1066 ScopedObjectAccess soa(env);
1067 return InvokeWithJValues(soa, obj, mid, args).GetS();
1068 }
1069
CallNonvirtualIntMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1070 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1071 va_list ap;
1072 va_start(ap, mid);
1073 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1074 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1075 ScopedObjectAccess soa(env);
1076 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1077 va_end(ap);
1078 return result.GetI();
1079 }
1080
CallNonvirtualIntMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1081 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1082 va_list args) {
1083 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1084 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1085 ScopedObjectAccess soa(env);
1086 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1087 }
1088
CallNonvirtualIntMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1089 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1090 jvalue* args) {
1091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1092 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1093 ScopedObjectAccess soa(env);
1094 return InvokeWithJValues(soa, obj, mid, args).GetI();
1095 }
1096
CallNonvirtualLongMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1097 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1098 va_list ap;
1099 va_start(ap, mid);
1100 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1101 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1102 ScopedObjectAccess soa(env);
1103 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1104 va_end(ap);
1105 return result.GetJ();
1106 }
1107
CallNonvirtualLongMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1108 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1109 va_list args) {
1110 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1111 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1112 ScopedObjectAccess soa(env);
1113 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1114 }
1115
CallNonvirtualLongMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1116 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1117 jvalue* args) {
1118 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1119 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1120 ScopedObjectAccess soa(env);
1121 return InvokeWithJValues(soa, obj, mid, args).GetJ();
1122 }
1123
CallNonvirtualFloatMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1124 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1125 va_list ap;
1126 va_start(ap, mid);
1127 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1128 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1129 ScopedObjectAccess soa(env);
1130 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1131 va_end(ap);
1132 return result.GetF();
1133 }
1134
CallNonvirtualFloatMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1135 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1136 va_list args) {
1137 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1138 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1139 ScopedObjectAccess soa(env);
1140 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1141 }
1142
CallNonvirtualFloatMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1143 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1144 jvalue* args) {
1145 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1146 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1147 ScopedObjectAccess soa(env);
1148 return InvokeWithJValues(soa, obj, mid, args).GetF();
1149 }
1150
CallNonvirtualDoubleMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1151 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1152 va_list ap;
1153 va_start(ap, mid);
1154 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1155 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1156 ScopedObjectAccess soa(env);
1157 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1158 va_end(ap);
1159 return result.GetD();
1160 }
1161
CallNonvirtualDoubleMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1162 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1163 va_list args) {
1164 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1165 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1166 ScopedObjectAccess soa(env);
1167 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1168 }
1169
CallNonvirtualDoubleMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1170 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1171 jvalue* args) {
1172 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1173 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1174 ScopedObjectAccess soa(env);
1175 return InvokeWithJValues(soa, obj, mid, args).GetD();
1176 }
1177
CallNonvirtualVoidMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1178 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1179 va_list ap;
1180 va_start(ap, mid);
1181 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1182 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1183 ScopedObjectAccess soa(env);
1184 InvokeWithVarArgs(soa, obj, mid, ap);
1185 va_end(ap);
1186 }
1187
CallNonvirtualVoidMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1188 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1189 va_list args) {
1190 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1191 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1192 ScopedObjectAccess soa(env);
1193 InvokeWithVarArgs(soa, obj, mid, args);
1194 }
1195
CallNonvirtualVoidMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1196 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1197 jvalue* args) {
1198 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1199 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1200 ScopedObjectAccess soa(env);
1201 InvokeWithJValues(soa, obj, mid, args);
1202 }
1203
GetFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1204 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1205 CHECK_NON_NULL_ARGUMENT(java_class);
1206 CHECK_NON_NULL_ARGUMENT(name);
1207 CHECK_NON_NULL_ARGUMENT(sig);
1208 ScopedObjectAccess soa(env);
1209 return FindFieldID(soa, java_class, name, sig, false);
1210 }
1211
GetStaticFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1212 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1213 const char* sig) {
1214 CHECK_NON_NULL_ARGUMENT(java_class);
1215 CHECK_NON_NULL_ARGUMENT(name);
1216 CHECK_NON_NULL_ARGUMENT(sig);
1217 ScopedObjectAccess soa(env);
1218 return FindFieldID(soa, java_class, name, sig, true);
1219 }
1220
GetObjectField(JNIEnv * env,jobject obj,jfieldID fid)1221 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1222 CHECK_NON_NULL_ARGUMENT(obj);
1223 CHECK_NON_NULL_ARGUMENT(fid);
1224 ScopedObjectAccess soa(env);
1225 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1226 ArtField* f = soa.DecodeField(fid);
1227 return soa.AddLocalReference<jobject>(f->GetObject(o));
1228 }
1229
GetStaticObjectField(JNIEnv * env,jclass,jfieldID fid)1230 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1231 CHECK_NON_NULL_ARGUMENT(fid);
1232 ScopedObjectAccess soa(env);
1233 ArtField* f = soa.DecodeField(fid);
1234 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1235 }
1236
SetObjectField(JNIEnv * env,jobject java_object,jfieldID fid,jobject java_value)1237 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1238 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1239 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1240 ScopedObjectAccess soa(env);
1241 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1242 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1243 ArtField* f = soa.DecodeField(fid);
1244 f->SetObject<false>(o, v);
1245 }
1246
SetStaticObjectField(JNIEnv * env,jclass,jfieldID fid,jobject java_value)1247 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1248 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1249 ScopedObjectAccess soa(env);
1250 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1251 ArtField* f = soa.DecodeField(fid);
1252 f->SetObject<false>(f->GetDeclaringClass(), v);
1253 }
1254
1255 #define GET_PRIMITIVE_FIELD(fn, instance) \
1256 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1257 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1258 ScopedObjectAccess soa(env); \
1259 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1260 ArtField* f = soa.DecodeField(fid); \
1261 return f->Get ##fn (o)
1262
1263 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
1264 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1265 ScopedObjectAccess soa(env); \
1266 ArtField* f = soa.DecodeField(fid); \
1267 return f->Get ##fn (f->GetDeclaringClass())
1268
1269 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
1270 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1271 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1272 ScopedObjectAccess soa(env); \
1273 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1274 ArtField* f = soa.DecodeField(fid); \
1275 f->Set ##fn <false>(o, value)
1276
1277 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1278 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1279 ScopedObjectAccess soa(env); \
1280 ArtField* f = soa.DecodeField(fid); \
1281 f->Set ##fn <false>(f->GetDeclaringClass(), value)
1282
GetBooleanField(JNIEnv * env,jobject obj,jfieldID fid)1283 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1284 GET_PRIMITIVE_FIELD(Boolean, obj);
1285 }
1286
GetByteField(JNIEnv * env,jobject obj,jfieldID fid)1287 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1288 GET_PRIMITIVE_FIELD(Byte, obj);
1289 }
1290
GetCharField(JNIEnv * env,jobject obj,jfieldID fid)1291 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1292 GET_PRIMITIVE_FIELD(Char, obj);
1293 }
1294
GetShortField(JNIEnv * env,jobject obj,jfieldID fid)1295 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1296 GET_PRIMITIVE_FIELD(Short, obj);
1297 }
1298
GetIntField(JNIEnv * env,jobject obj,jfieldID fid)1299 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1300 GET_PRIMITIVE_FIELD(Int, obj);
1301 }
1302
GetLongField(JNIEnv * env,jobject obj,jfieldID fid)1303 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1304 GET_PRIMITIVE_FIELD(Long, obj);
1305 }
1306
GetFloatField(JNIEnv * env,jobject obj,jfieldID fid)1307 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1308 GET_PRIMITIVE_FIELD(Float, obj);
1309 }
1310
GetDoubleField(JNIEnv * env,jobject obj,jfieldID fid)1311 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1312 GET_PRIMITIVE_FIELD(Double, obj);
1313 }
1314
GetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid)1315 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1316 GET_STATIC_PRIMITIVE_FIELD(Boolean);
1317 }
1318
GetStaticByteField(JNIEnv * env,jclass,jfieldID fid)1319 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1320 GET_STATIC_PRIMITIVE_FIELD(Byte);
1321 }
1322
GetStaticCharField(JNIEnv * env,jclass,jfieldID fid)1323 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1324 GET_STATIC_PRIMITIVE_FIELD(Char);
1325 }
1326
GetStaticShortField(JNIEnv * env,jclass,jfieldID fid)1327 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1328 GET_STATIC_PRIMITIVE_FIELD(Short);
1329 }
1330
GetStaticIntField(JNIEnv * env,jclass,jfieldID fid)1331 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1332 GET_STATIC_PRIMITIVE_FIELD(Int);
1333 }
1334
GetStaticLongField(JNIEnv * env,jclass,jfieldID fid)1335 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1336 GET_STATIC_PRIMITIVE_FIELD(Long);
1337 }
1338
GetStaticFloatField(JNIEnv * env,jclass,jfieldID fid)1339 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1340 GET_STATIC_PRIMITIVE_FIELD(Float);
1341 }
1342
GetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid)1343 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1344 GET_STATIC_PRIMITIVE_FIELD(Double);
1345 }
1346
SetBooleanField(JNIEnv * env,jobject obj,jfieldID fid,jboolean v)1347 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1348 SET_PRIMITIVE_FIELD(Boolean, obj, v);
1349 }
1350
SetByteField(JNIEnv * env,jobject obj,jfieldID fid,jbyte v)1351 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1352 SET_PRIMITIVE_FIELD(Byte, obj, v);
1353 }
1354
SetCharField(JNIEnv * env,jobject obj,jfieldID fid,jchar v)1355 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1356 SET_PRIMITIVE_FIELD(Char, obj, v);
1357 }
1358
SetFloatField(JNIEnv * env,jobject obj,jfieldID fid,jfloat v)1359 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1360 SET_PRIMITIVE_FIELD(Float, obj, v);
1361 }
1362
SetDoubleField(JNIEnv * env,jobject obj,jfieldID fid,jdouble v)1363 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1364 SET_PRIMITIVE_FIELD(Double, obj, v);
1365 }
1366
SetIntField(JNIEnv * env,jobject obj,jfieldID fid,jint v)1367 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1368 SET_PRIMITIVE_FIELD(Int, obj, v);
1369 }
1370
SetLongField(JNIEnv * env,jobject obj,jfieldID fid,jlong v)1371 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1372 SET_PRIMITIVE_FIELD(Long, obj, v);
1373 }
1374
SetShortField(JNIEnv * env,jobject obj,jfieldID fid,jshort v)1375 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1376 SET_PRIMITIVE_FIELD(Short, obj, v);
1377 }
1378
SetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid,jboolean v)1379 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1380 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1381 }
1382
SetStaticByteField(JNIEnv * env,jclass,jfieldID fid,jbyte v)1383 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1384 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1385 }
1386
SetStaticCharField(JNIEnv * env,jclass,jfieldID fid,jchar v)1387 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1388 SET_STATIC_PRIMITIVE_FIELD(Char, v);
1389 }
1390
SetStaticFloatField(JNIEnv * env,jclass,jfieldID fid,jfloat v)1391 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1392 SET_STATIC_PRIMITIVE_FIELD(Float, v);
1393 }
1394
SetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid,jdouble v)1395 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1396 SET_STATIC_PRIMITIVE_FIELD(Double, v);
1397 }
1398
SetStaticIntField(JNIEnv * env,jclass,jfieldID fid,jint v)1399 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1400 SET_STATIC_PRIMITIVE_FIELD(Int, v);
1401 }
1402
SetStaticLongField(JNIEnv * env,jclass,jfieldID fid,jlong v)1403 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1404 SET_STATIC_PRIMITIVE_FIELD(Long, v);
1405 }
1406
SetStaticShortField(JNIEnv * env,jclass,jfieldID fid,jshort v)1407 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1408 SET_STATIC_PRIMITIVE_FIELD(Short, v);
1409 }
1410
CallStaticObjectMethod(JNIEnv * env,jclass,jmethodID mid,...)1411 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1412 va_list ap;
1413 va_start(ap, mid);
1414 CHECK_NON_NULL_ARGUMENT(mid);
1415 ScopedObjectAccess soa(env);
1416 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1417 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1418 va_end(ap);
1419 return local_result;
1420 }
1421
CallStaticObjectMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1422 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1423 CHECK_NON_NULL_ARGUMENT(mid);
1424 ScopedObjectAccess soa(env);
1425 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
1426 return soa.AddLocalReference<jobject>(result.GetL());
1427 }
1428
CallStaticObjectMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1429 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1430 CHECK_NON_NULL_ARGUMENT(mid);
1431 ScopedObjectAccess soa(env);
1432 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
1433 return soa.AddLocalReference<jobject>(result.GetL());
1434 }
1435
CallStaticBooleanMethod(JNIEnv * env,jclass,jmethodID mid,...)1436 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1437 va_list ap;
1438 va_start(ap, mid);
1439 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1440 ScopedObjectAccess soa(env);
1441 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1442 va_end(ap);
1443 return result.GetZ();
1444 }
1445
CallStaticBooleanMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1446 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1447 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1448 ScopedObjectAccess soa(env);
1449 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1450 }
1451
CallStaticBooleanMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1452 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1453 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1454 ScopedObjectAccess soa(env);
1455 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1456 }
1457
CallStaticByteMethod(JNIEnv * env,jclass,jmethodID mid,...)1458 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1459 va_list ap;
1460 va_start(ap, mid);
1461 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1462 ScopedObjectAccess soa(env);
1463 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1464 va_end(ap);
1465 return result.GetB();
1466 }
1467
CallStaticByteMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1468 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1469 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1470 ScopedObjectAccess soa(env);
1471 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1472 }
1473
CallStaticByteMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1474 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1475 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1476 ScopedObjectAccess soa(env);
1477 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1478 }
1479
CallStaticCharMethod(JNIEnv * env,jclass,jmethodID mid,...)1480 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1481 va_list ap;
1482 va_start(ap, mid);
1483 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1484 ScopedObjectAccess soa(env);
1485 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1486 va_end(ap);
1487 return result.GetC();
1488 }
1489
CallStaticCharMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1490 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1491 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1492 ScopedObjectAccess soa(env);
1493 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1494 }
1495
CallStaticCharMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1496 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1497 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1498 ScopedObjectAccess soa(env);
1499 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1500 }
1501
CallStaticShortMethod(JNIEnv * env,jclass,jmethodID mid,...)1502 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1503 va_list ap;
1504 va_start(ap, mid);
1505 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1506 ScopedObjectAccess soa(env);
1507 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1508 va_end(ap);
1509 return result.GetS();
1510 }
1511
CallStaticShortMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1512 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1513 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1514 ScopedObjectAccess soa(env);
1515 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1516 }
1517
CallStaticShortMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1518 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1519 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1520 ScopedObjectAccess soa(env);
1521 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1522 }
1523
CallStaticIntMethod(JNIEnv * env,jclass,jmethodID mid,...)1524 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1525 va_list ap;
1526 va_start(ap, mid);
1527 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1528 ScopedObjectAccess soa(env);
1529 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1530 va_end(ap);
1531 return result.GetI();
1532 }
1533
CallStaticIntMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1534 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1535 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1536 ScopedObjectAccess soa(env);
1537 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1538 }
1539
CallStaticIntMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1540 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1541 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1542 ScopedObjectAccess soa(env);
1543 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1544 }
1545
CallStaticLongMethod(JNIEnv * env,jclass,jmethodID mid,...)1546 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1547 va_list ap;
1548 va_start(ap, mid);
1549 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1550 ScopedObjectAccess soa(env);
1551 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1552 va_end(ap);
1553 return result.GetJ();
1554 }
1555
CallStaticLongMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1556 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1557 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1558 ScopedObjectAccess soa(env);
1559 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1560 }
1561
CallStaticLongMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1562 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1563 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1564 ScopedObjectAccess soa(env);
1565 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1566 }
1567
CallStaticFloatMethod(JNIEnv * env,jclass,jmethodID mid,...)1568 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1569 va_list ap;
1570 va_start(ap, mid);
1571 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1572 ScopedObjectAccess soa(env);
1573 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1574 va_end(ap);
1575 return result.GetF();
1576 }
1577
CallStaticFloatMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1578 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1579 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1580 ScopedObjectAccess soa(env);
1581 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1582 }
1583
CallStaticFloatMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1584 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1585 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1586 ScopedObjectAccess soa(env);
1587 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1588 }
1589
CallStaticDoubleMethod(JNIEnv * env,jclass,jmethodID mid,...)1590 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1591 va_list ap;
1592 va_start(ap, mid);
1593 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1594 ScopedObjectAccess soa(env);
1595 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1596 va_end(ap);
1597 return result.GetD();
1598 }
1599
CallStaticDoubleMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1600 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1601 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1602 ScopedObjectAccess soa(env);
1603 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1604 }
1605
CallStaticDoubleMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1606 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1607 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1608 ScopedObjectAccess soa(env);
1609 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1610 }
1611
CallStaticVoidMethod(JNIEnv * env,jclass,jmethodID mid,...)1612 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1613 va_list ap;
1614 va_start(ap, mid);
1615 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1616 ScopedObjectAccess soa(env);
1617 InvokeWithVarArgs(soa, nullptr, mid, ap);
1618 va_end(ap);
1619 }
1620
CallStaticVoidMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1621 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1622 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1623 ScopedObjectAccess soa(env);
1624 InvokeWithVarArgs(soa, nullptr, mid, args);
1625 }
1626
CallStaticVoidMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1627 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1628 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1629 ScopedObjectAccess soa(env);
1630 InvokeWithJValues(soa, nullptr, mid, args);
1631 }
1632
NewString(JNIEnv * env,const jchar * chars,jsize char_count)1633 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1634 if (UNLIKELY(char_count < 0)) {
1635 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
1636 return nullptr;
1637 }
1638 if (UNLIKELY(chars == nullptr && char_count > 0)) {
1639 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
1640 return nullptr;
1641 }
1642 ScopedObjectAccess soa(env);
1643 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
1644 return soa.AddLocalReference<jstring>(result);
1645 }
1646
NewStringUTF(JNIEnv * env,const char * utf)1647 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1648 if (utf == nullptr) {
1649 return nullptr;
1650 }
1651 ScopedObjectAccess soa(env);
1652 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
1653 return soa.AddLocalReference<jstring>(result);
1654 }
1655
GetStringLength(JNIEnv * env,jstring java_string)1656 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1657 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1658 ScopedObjectAccess soa(env);
1659 return soa.Decode<mirror::String*>(java_string)->GetLength();
1660 }
1661
GetStringUTFLength(JNIEnv * env,jstring java_string)1662 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1663 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1664 ScopedObjectAccess soa(env);
1665 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1666 }
1667
GetStringRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,jchar * buf)1668 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1669 jchar* buf) {
1670 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1671 ScopedObjectAccess soa(env);
1672 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1673 if (start < 0 || length < 0 || start + length > s->GetLength()) {
1674 ThrowSIOOBE(soa, start, length, s->GetLength());
1675 } else {
1676 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1677 const jchar* chars = s->GetValue();
1678 memcpy(buf, chars + start, length * sizeof(jchar));
1679 }
1680 }
1681
GetStringUTFRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,char * buf)1682 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1683 char* buf) {
1684 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1685 ScopedObjectAccess soa(env);
1686 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1687 if (start < 0 || length < 0 || start + length > s->GetLength()) {
1688 ThrowSIOOBE(soa, start, length, s->GetLength());
1689 } else {
1690 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1691 const jchar* chars = s->GetValue();
1692 ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1693 }
1694 }
1695
GetStringChars(JNIEnv * env,jstring java_string,jboolean * is_copy)1696 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1697 CHECK_NON_NULL_ARGUMENT(java_string);
1698 ScopedObjectAccess soa(env);
1699 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1700 gc::Heap* heap = Runtime::Current()->GetHeap();
1701 if (heap->IsMovableObject(s)) {
1702 jchar* chars = new jchar[s->GetLength()];
1703 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1704 if (is_copy != nullptr) {
1705 *is_copy = JNI_TRUE;
1706 }
1707 return chars;
1708 }
1709 if (is_copy != nullptr) {
1710 *is_copy = JNI_FALSE;
1711 }
1712 return static_cast<jchar*>(s->GetValue());
1713 }
1714
ReleaseStringChars(JNIEnv * env,jstring java_string,const jchar * chars)1715 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
1716 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1717 ScopedObjectAccess soa(env);
1718 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1719 if (chars != s->GetValue()) {
1720 delete[] chars;
1721 }
1722 }
1723
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * is_copy)1724 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1725 CHECK_NON_NULL_ARGUMENT(java_string);
1726 ScopedObjectAccess soa(env);
1727 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1728 gc::Heap* heap = Runtime::Current()->GetHeap();
1729 if (heap->IsMovableObject(s)) {
1730 StackHandleScope<1> hs(soa.Self());
1731 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
1732 heap->IncrementDisableMovingGC(soa.Self());
1733 }
1734 if (is_copy != nullptr) {
1735 *is_copy = JNI_FALSE;
1736 }
1737 return static_cast<jchar*>(s->GetValue());
1738 }
1739
ReleaseStringCritical(JNIEnv * env,jstring java_string,const jchar * chars)1740 static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
1741 UNUSED(chars);
1742 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1743 ScopedObjectAccess soa(env);
1744 gc::Heap* heap = Runtime::Current()->GetHeap();
1745 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1746 if (heap->IsMovableObject(s)) {
1747 heap->DecrementDisableMovingGC(soa.Self());
1748 }
1749 }
1750
GetStringUTFChars(JNIEnv * env,jstring java_string,jboolean * is_copy)1751 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1752 if (java_string == nullptr) {
1753 return nullptr;
1754 }
1755 if (is_copy != nullptr) {
1756 *is_copy = JNI_TRUE;
1757 }
1758 ScopedObjectAccess soa(env);
1759 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1760 size_t byte_count = s->GetUtfLength();
1761 char* bytes = new char[byte_count + 1];
1762 CHECK(bytes != nullptr); // bionic aborts anyway.
1763 const uint16_t* chars = s->GetValue();
1764 ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
1765 bytes[byte_count] = '\0';
1766 return bytes;
1767 }
1768
ReleaseStringUTFChars(JNIEnv *,jstring,const char * chars)1769 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
1770 delete[] chars;
1771 }
1772
GetArrayLength(JNIEnv * env,jarray java_array)1773 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
1774 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
1775 ScopedObjectAccess soa(env);
1776 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
1777 if (UNLIKELY(!obj->IsArrayInstance())) {
1778 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1779 return 0;
1780 }
1781 mirror::Array* array = obj->AsArray();
1782 return array->GetLength();
1783 }
1784
GetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index)1785 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
1786 CHECK_NON_NULL_ARGUMENT(java_array);
1787 ScopedObjectAccess soa(env);
1788 mirror::ObjectArray<mirror::Object>* array =
1789 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1790 return soa.AddLocalReference<jobject>(array->Get(index));
1791 }
1792
SetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index,jobject java_value)1793 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1794 jobject java_value) {
1795 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1796 ScopedObjectAccess soa(env);
1797 mirror::ObjectArray<mirror::Object>* array =
1798 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1799 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
1800 array->Set<false>(index, value);
1801 }
1802
NewBooleanArray(JNIEnv * env,jsize length)1803 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
1804 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
1805 }
1806
NewByteArray(JNIEnv * env,jsize length)1807 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
1808 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
1809 }
1810
NewCharArray(JNIEnv * env,jsize length)1811 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
1812 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
1813 }
1814
NewDoubleArray(JNIEnv * env,jsize length)1815 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
1816 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
1817 }
1818
NewFloatArray(JNIEnv * env,jsize length)1819 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
1820 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
1821 }
1822
NewIntArray(JNIEnv * env,jsize length)1823 static jintArray NewIntArray(JNIEnv* env, jsize length) {
1824 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
1825 }
1826
NewLongArray(JNIEnv * env,jsize length)1827 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
1828 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
1829 }
1830
NewObjectArray(JNIEnv * env,jsize length,jclass element_jclass,jobject initial_element)1831 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1832 jobject initial_element) {
1833 if (UNLIKELY(length < 0)) {
1834 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
1835 return nullptr;
1836 }
1837 CHECK_NON_NULL_ARGUMENT(element_jclass);
1838
1839 // Compute the array class corresponding to the given element class.
1840 ScopedObjectAccess soa(env);
1841 mirror::Class* array_class;
1842 {
1843 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
1844 if (UNLIKELY(element_class->IsPrimitive())) {
1845 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1846 PrettyDescriptor(element_class).c_str());
1847 return nullptr;
1848 }
1849 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1850 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
1851 if (UNLIKELY(array_class == nullptr)) {
1852 return nullptr;
1853 }
1854 }
1855
1856 // Allocate and initialize if necessary.
1857 mirror::ObjectArray<mirror::Object>* result =
1858 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
1859 if (result != nullptr && initial_element != nullptr) {
1860 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
1861 if (initial_object != nullptr) {
1862 mirror::Class* element_class = result->GetClass()->GetComponentType();
1863 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
1864 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1865 "element type of '%s'",
1866 PrettyDescriptor(initial_object->GetClass()).c_str(),
1867 PrettyDescriptor(element_class).c_str());
1868 return nullptr;
1869 } else {
1870 for (jsize i = 0; i < length; ++i) {
1871 result->SetWithoutChecks<false>(i, initial_object);
1872 }
1873 }
1874 }
1875 }
1876 return soa.AddLocalReference<jobjectArray>(result);
1877 }
1878
NewShortArray(JNIEnv * env,jsize length)1879 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
1880 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
1881 }
1882
GetPrimitiveArrayCritical(JNIEnv * env,jarray java_array,jboolean * is_copy)1883 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
1884 CHECK_NON_NULL_ARGUMENT(java_array);
1885 ScopedObjectAccess soa(env);
1886 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1887 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
1888 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1889 PrettyDescriptor(array->GetClass()).c_str());
1890 return nullptr;
1891 }
1892 gc::Heap* heap = Runtime::Current()->GetHeap();
1893 if (heap->IsMovableObject(array)) {
1894 heap->IncrementDisableMovingGC(soa.Self());
1895 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
1896 array = soa.Decode<mirror::Array*>(java_array);
1897 }
1898 if (is_copy != nullptr) {
1899 *is_copy = JNI_FALSE;
1900 }
1901 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
1902 }
1903
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray java_array,void * elements,jint mode)1904 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1905 jint mode) {
1906 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1907 ScopedObjectAccess soa(env);
1908 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1909 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
1910 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1911 PrettyDescriptor(array->GetClass()).c_str());
1912 return;
1913 }
1914 const size_t component_size = array->GetClass()->GetComponentSize();
1915 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
1916 }
1917
GetBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * is_copy)1918 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
1919 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
1920 }
1921
GetByteArrayElements(JNIEnv * env,jbyteArray array,jboolean * is_copy)1922 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
1923 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
1924 }
1925
GetCharArrayElements(JNIEnv * env,jcharArray array,jboolean * is_copy)1926 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
1927 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
1928 }
1929
GetDoubleArrayElements(JNIEnv * env,jdoubleArray array,jboolean * is_copy)1930 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
1931 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
1932 }
1933
GetFloatArrayElements(JNIEnv * env,jfloatArray array,jboolean * is_copy)1934 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
1935 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
1936 }
1937
GetIntArrayElements(JNIEnv * env,jintArray array,jboolean * is_copy)1938 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
1939 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
1940 }
1941
GetLongArrayElements(JNIEnv * env,jlongArray array,jboolean * is_copy)1942 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
1943 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
1944 }
1945
GetShortArrayElements(JNIEnv * env,jshortArray array,jboolean * is_copy)1946 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
1947 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
1948 }
1949
ReleaseBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * elements,jint mode)1950 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1951 jint mode) {
1952 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
1953 mode);
1954 }
1955
ReleaseByteArrayElements(JNIEnv * env,jbyteArray array,jbyte * elements,jint mode)1956 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
1957 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
1958 }
1959
ReleaseCharArrayElements(JNIEnv * env,jcharArray array,jchar * elements,jint mode)1960 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
1961 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
1962 }
1963
ReleaseDoubleArrayElements(JNIEnv * env,jdoubleArray array,jdouble * elements,jint mode)1964 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1965 jint mode) {
1966 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
1967 }
1968
ReleaseFloatArrayElements(JNIEnv * env,jfloatArray array,jfloat * elements,jint mode)1969 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1970 jint mode) {
1971 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
1972 }
1973
ReleaseIntArrayElements(JNIEnv * env,jintArray array,jint * elements,jint mode)1974 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
1975 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
1976 }
1977
ReleaseLongArrayElements(JNIEnv * env,jlongArray array,jlong * elements,jint mode)1978 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
1979 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
1980 }
1981
ReleaseShortArrayElements(JNIEnv * env,jshortArray array,jshort * elements,jint mode)1982 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
1983 jint mode) {
1984 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
1985 }
1986
GetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,jboolean * buf)1987 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
1988 jboolean* buf) {
1989 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
1990 length, buf);
1991 }
1992
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,jbyte * buf)1993 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
1994 jbyte* buf) {
1995 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
1996 }
1997
GetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,jchar * buf)1998 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
1999 jchar* buf) {
2000 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2001 }
2002
GetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,jdouble * buf)2003 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2004 jdouble* buf) {
2005 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2006 buf);
2007 }
2008
GetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,jfloat * buf)2009 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2010 jfloat* buf) {
2011 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2012 buf);
2013 }
2014
GetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,jint * buf)2015 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2016 jint* buf) {
2017 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2018 }
2019
GetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,jlong * buf)2020 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2021 jlong* buf) {
2022 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2023 }
2024
GetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,jshort * buf)2025 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2026 jshort* buf) {
2027 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2028 buf);
2029 }
2030
SetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,const jboolean * buf)2031 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2032 const jboolean* buf) {
2033 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2034 length, buf);
2035 }
2036
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,const jbyte * buf)2037 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2038 const jbyte* buf) {
2039 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2040 }
2041
SetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,const jchar * buf)2042 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2043 const jchar* buf) {
2044 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2045 }
2046
SetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,const jdouble * buf)2047 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2048 const jdouble* buf) {
2049 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2050 buf);
2051 }
2052
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,const jfloat * buf)2053 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2054 const jfloat* buf) {
2055 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2056 buf);
2057 }
2058
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,const jint * buf)2059 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2060 const jint* buf) {
2061 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2062 }
2063
SetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,const jlong * buf)2064 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2065 const jlong* buf) {
2066 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2067 }
2068
SetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,const jshort * buf)2069 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2070 const jshort* buf) {
2071 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2072 buf);
2073 }
2074
RegisterNatives(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count)2075 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2076 jint method_count) {
2077 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2078 }
2079
RegisterNativeMethods(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count,bool return_errors)2080 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2081 jint method_count, bool return_errors) {
2082 if (UNLIKELY(method_count < 0)) {
2083 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2084 method_count);
2085 return JNI_ERR; // Not reached except in unit tests.
2086 }
2087 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
2088 ScopedObjectAccess soa(env);
2089 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2090 if (UNLIKELY(method_count == 0)) {
2091 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2092 << PrettyDescriptor(c);
2093 return JNI_OK;
2094 }
2095 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2096 for (jint i = 0; i < method_count; ++i) {
2097 const char* name = methods[i].name;
2098 const char* sig = methods[i].signature;
2099 const void* fnPtr = methods[i].fnPtr;
2100 if (UNLIKELY(name == nullptr)) {
2101 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2102 return JNI_ERR;
2103 } else if (UNLIKELY(sig == nullptr)) {
2104 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2105 return JNI_ERR;
2106 } else if (UNLIKELY(fnPtr == nullptr)) {
2107 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2108 return JNI_ERR;
2109 }
2110 bool is_fast = false;
2111 // Notes about fast JNI calls:
2112 //
2113 // On a normal JNI call, the calling thread usually transitions
2114 // from the kRunnable state to the kNative state. But if the
2115 // called native function needs to access any Java object, it
2116 // will have to transition back to the kRunnable state.
2117 //
2118 // There is a cost to this double transition. For a JNI call
2119 // that should be quick, this cost may dominate the call cost.
2120 //
2121 // On a fast JNI call, the calling thread avoids this double
2122 // transition by not transitioning from kRunnable to kNative and
2123 // stays in the kRunnable state.
2124 //
2125 // There are risks to using a fast JNI call because it can delay
2126 // a response to a thread suspension request which is typically
2127 // used for a GC root scanning, etc. If a fast JNI call takes a
2128 // long time, it could cause longer thread suspension latency
2129 // and GC pauses.
2130 //
2131 // Thus, fast JNI should be used with care. It should be used
2132 // for a JNI call that takes a short amount of time (eg. no
2133 // long-running loop) and does not block (eg. no locks, I/O,
2134 // etc.)
2135 //
2136 // A '!' prefix in the signature in the JNINativeMethod
2137 // indicates that it's a fast JNI call and the runtime omits the
2138 // thread state transition from kRunnable to kNative at the
2139 // entry.
2140 if (*sig == '!') {
2141 is_fast = true;
2142 ++sig;
2143 }
2144
2145 // Note: the right order is to try to find the method locally
2146 // first, either as a direct or a virtual method. Then move to
2147 // the parent.
2148 ArtMethod* m = nullptr;
2149 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2150 for (mirror::Class* current_class = c;
2151 current_class != nullptr;
2152 current_class = current_class->GetSuperClass()) {
2153 // Search first only comparing methods which are native.
2154 m = FindMethod<true>(current_class, name, sig);
2155 if (m != nullptr) {
2156 break;
2157 }
2158
2159 // Search again comparing to all methods, to find non-native methods that match.
2160 m = FindMethod<false>(current_class, name, sig);
2161 if (m != nullptr) {
2162 break;
2163 }
2164
2165 if (warn_on_going_to_parent) {
2166 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2167 << "This is slow, consider changing your RegisterNatives calls.";
2168 warn_on_going_to_parent = false;
2169 }
2170 }
2171
2172 if (m == nullptr) {
2173 LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
2174 << PrettyDescriptor(c) << "." << name << sig << " in "
2175 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2176 // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2177 // out of scope after the DumpClass is done executing.
2178 c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
2179 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2180 return JNI_ERR;
2181 } else if (!m->IsNative()) {
2182 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2183 << PrettyDescriptor(c) << "." << name << sig
2184 << " as native";
2185 ThrowNoSuchMethodError(soa, c, name, sig, "native");
2186 return JNI_ERR;
2187 }
2188
2189 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
2190
2191 m->RegisterNative(fnPtr, is_fast);
2192 }
2193 return JNI_OK;
2194 }
2195
UnregisterNatives(JNIEnv * env,jclass java_class)2196 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2197 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
2198 ScopedObjectAccess soa(env);
2199 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2200
2201 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
2202
2203 size_t unregistered_count = 0;
2204 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
2205 for (auto& m : c->GetDirectMethods(pointer_size)) {
2206 if (m.IsNative()) {
2207 m.UnregisterNative();
2208 unregistered_count++;
2209 }
2210 }
2211 for (auto& m : c->GetVirtualMethods(pointer_size)) {
2212 if (m.IsNative()) {
2213 m.UnregisterNative();
2214 unregistered_count++;
2215 }
2216 }
2217
2218 if (unregistered_count == 0) {
2219 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2220 << PrettyDescriptor(c) << "' that contains no native methods";
2221 }
2222 return JNI_OK;
2223 }
2224
MonitorEnter(JNIEnv * env,jobject java_object)2225 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2226 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2227 ScopedObjectAccess soa(env);
2228 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2229 o = o->MonitorEnter(soa.Self());
2230 if (soa.Self()->IsExceptionPending()) {
2231 return JNI_ERR;
2232 }
2233 soa.Env()->monitors.Add(o);
2234 return JNI_OK;
2235 }
2236
MonitorExit(JNIEnv * env,jobject java_object)2237 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2238 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2239 ScopedObjectAccess soa(env);
2240 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2241 o->MonitorExit(soa.Self());
2242 if (soa.Self()->IsExceptionPending()) {
2243 return JNI_ERR;
2244 }
2245 soa.Env()->monitors.Remove(o);
2246 return JNI_OK;
2247 }
2248
GetJavaVM(JNIEnv * env,JavaVM ** vm)2249 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2250 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2251 Runtime* runtime = Runtime::Current();
2252 if (runtime != nullptr) {
2253 *vm = runtime->GetJavaVM();
2254 } else {
2255 *vm = nullptr;
2256 }
2257 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2258 }
2259
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)2260 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2261 if (capacity < 0) {
2262 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2263 capacity);
2264 return nullptr;
2265 }
2266 if (address == nullptr && capacity != 0) {
2267 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2268 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
2269 return nullptr;
2270 }
2271
2272 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
2273 if (capacity > INT_MAX) {
2274 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2275 "buffer capacity greater than maximum jint: %" PRId64,
2276 capacity);
2277 return nullptr;
2278 }
2279 jlong address_arg = reinterpret_cast<jlong>(address);
2280 jint capacity_arg = static_cast<jint>(capacity);
2281
2282 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2283 WellKnownClasses::java_nio_DirectByteBuffer_init,
2284 address_arg, capacity_arg);
2285 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2286 }
2287
GetDirectBufferAddress(JNIEnv * env,jobject java_buffer)2288 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2289 return reinterpret_cast<void*>(env->GetLongField(
2290 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2291 }
2292
GetDirectBufferCapacity(JNIEnv * env,jobject java_buffer)2293 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2294 return static_cast<jlong>(env->GetIntField(
2295 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2296 }
2297
GetObjectRefType(JNIEnv * env ATTRIBUTE_UNUSED,jobject java_object)2298 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2299 if (java_object == nullptr) {
2300 return JNIInvalidRefType;
2301 }
2302
2303 // Do we definitely know what kind of reference this is?
2304 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2305 IndirectRefKind kind = GetIndirectRefKind(ref);
2306 switch (kind) {
2307 case kLocal:
2308 return JNILocalRefType;
2309 case kGlobal:
2310 return JNIGlobalRefType;
2311 case kWeakGlobal:
2312 return JNIWeakGlobalRefType;
2313 case kHandleScopeOrInvalid:
2314 // Assume value is in a handle scope.
2315 return JNILocalRefType;
2316 }
2317 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2318 UNREACHABLE();
2319 }
2320
2321 private:
EnsureLocalCapacityInternal(ScopedObjectAccess & soa,jint desired_capacity,const char * caller)2322 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2323 const char* caller)
2324 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2325 // TODO: we should try to expand the table if necessary.
2326 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
2327 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2328 return JNI_ERR;
2329 }
2330 // TODO: this isn't quite right, since "capacity" includes holes.
2331 const size_t capacity = soa.Env()->locals.Capacity();
2332 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2333 if (!okay) {
2334 soa.Self()->ThrowOutOfMemoryError(caller);
2335 }
2336 return okay ? JNI_OK : JNI_ERR;
2337 }
2338
2339 template<typename JniT, typename ArtT>
NewPrimitiveArray(JNIEnv * env,jsize length)2340 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
2341 ScopedObjectAccess soa(env);
2342 if (UNLIKELY(length < 0)) {
2343 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2344 return nullptr;
2345 }
2346 ArtT* result = ArtT::Alloc(soa.Self(), length);
2347 return soa.AddLocalReference<JniT>(result);
2348 }
2349
2350 template <typename JArrayT, typename ElementT, typename ArtArrayT>
DecodeAndCheckArrayType(ScopedObjectAccess & soa,JArrayT java_array,const char * fn_name,const char * operation)2351 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2352 const char* fn_name, const char* operation)
2353 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2354 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
2355 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
2356 soa.Vm()->JniAbortF(fn_name,
2357 "attempt to %s %s primitive array elements with an object of type %s",
2358 operation,
2359 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2360 PrettyDescriptor(array->GetClass()).c_str());
2361 return nullptr;
2362 }
2363 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2364 return array;
2365 }
2366
2367 template <typename ArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArray(JNIEnv * env,ArrayT java_array,jboolean * is_copy)2368 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2369 CHECK_NON_NULL_ARGUMENT(java_array);
2370 ScopedObjectAccess soa(env);
2371 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2372 "GetArrayElements",
2373 "get");
2374 if (UNLIKELY(array == nullptr)) {
2375 return nullptr;
2376 }
2377 // Only make a copy if necessary.
2378 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2379 if (is_copy != nullptr) {
2380 *is_copy = JNI_TRUE;
2381 }
2382 const size_t component_size = sizeof(ElementT);
2383 size_t size = array->GetLength() * component_size;
2384 void* data = new uint64_t[RoundUp(size, 8) / 8];
2385 memcpy(data, array->GetData(), size);
2386 return reinterpret_cast<ElementT*>(data);
2387 } else {
2388 if (is_copy != nullptr) {
2389 *is_copy = JNI_FALSE;
2390 }
2391 return reinterpret_cast<ElementT*>(array->GetData());
2392 }
2393 }
2394
2395 template <typename ArrayT, typename ElementT, typename ArtArrayT>
ReleasePrimitiveArray(JNIEnv * env,ArrayT java_array,ElementT * elements,jint mode)2396 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
2397 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2398 ScopedObjectAccess soa(env);
2399 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2400 "ReleaseArrayElements",
2401 "release");
2402 if (array == nullptr) {
2403 return;
2404 }
2405 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2406 }
2407
ReleasePrimitiveArray(ScopedObjectAccess & soa,mirror::Array * array,size_t component_size,void * elements,jint mode)2408 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2409 size_t component_size, void* elements, jint mode)
2410 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2411 void* array_data = array->GetRawData(component_size, 0);
2412 gc::Heap* heap = Runtime::Current()->GetHeap();
2413 bool is_copy = array_data != elements;
2414 size_t bytes = array->GetLength() * component_size;
2415 VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
2416 << " elements " << elements;
2417 if (is_copy) {
2418 // Sanity check: If elements is not the same as the java array's data, it better not be a
2419 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2420 // copies we make?
2421 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
2422 soa.Vm()->JniAbortF("ReleaseArrayElements",
2423 "invalid element pointer %p, array elements are %p",
2424 reinterpret_cast<void*>(elements), array_data);
2425 return;
2426 }
2427 if (mode != JNI_ABORT) {
2428 memcpy(array_data, elements, bytes);
2429 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2430 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2431 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2432 soa.Self()->DumpJavaStack(LOG(WARNING));
2433 }
2434 }
2435 if (mode != JNI_COMMIT) {
2436 if (is_copy) {
2437 delete[] reinterpret_cast<uint64_t*>(elements);
2438 } else if (heap->IsMovableObject(array)) {
2439 // Non copy to a movable object must means that we had disabled the moving GC.
2440 heap->DecrementDisableMovingGC(soa.Self());
2441 }
2442 }
2443 }
2444
2445 template <typename JArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,ElementT * buf)2446 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2447 jsize start, jsize length, ElementT* buf) {
2448 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2449 ScopedObjectAccess soa(env);
2450 ArtArrayT* array =
2451 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2452 "GetPrimitiveArrayRegion",
2453 "get region of");
2454 if (array != nullptr) {
2455 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2456 ThrowAIOOBE(soa, array, start, length, "src");
2457 } else {
2458 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2459 ElementT* data = array->GetData();
2460 memcpy(buf, data + start, length * sizeof(ElementT));
2461 }
2462 }
2463 }
2464
2465 template <typename JArrayT, typename ElementT, typename ArtArrayT>
SetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,const ElementT * buf)2466 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2467 jsize start, jsize length, const ElementT* buf) {
2468 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2469 ScopedObjectAccess soa(env);
2470 ArtArrayT* array =
2471 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2472 "SetPrimitiveArrayRegion",
2473 "set region of");
2474 if (array != nullptr) {
2475 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2476 ThrowAIOOBE(soa, array, start, length, "dst");
2477 } else {
2478 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2479 ElementT* data = array->GetData();
2480 memcpy(data + start, buf, length * sizeof(ElementT));
2481 }
2482 }
2483 }
2484 };
2485
2486 const JNINativeInterface gJniNativeInterface = {
2487 nullptr, // reserved0.
2488 nullptr, // reserved1.
2489 nullptr, // reserved2.
2490 nullptr, // reserved3.
2491 JNI::GetVersion,
2492 JNI::DefineClass,
2493 JNI::FindClass,
2494 JNI::FromReflectedMethod,
2495 JNI::FromReflectedField,
2496 JNI::ToReflectedMethod,
2497 JNI::GetSuperclass,
2498 JNI::IsAssignableFrom,
2499 JNI::ToReflectedField,
2500 JNI::Throw,
2501 JNI::ThrowNew,
2502 JNI::ExceptionOccurred,
2503 JNI::ExceptionDescribe,
2504 JNI::ExceptionClear,
2505 JNI::FatalError,
2506 JNI::PushLocalFrame,
2507 JNI::PopLocalFrame,
2508 JNI::NewGlobalRef,
2509 JNI::DeleteGlobalRef,
2510 JNI::DeleteLocalRef,
2511 JNI::IsSameObject,
2512 JNI::NewLocalRef,
2513 JNI::EnsureLocalCapacity,
2514 JNI::AllocObject,
2515 JNI::NewObject,
2516 JNI::NewObjectV,
2517 JNI::NewObjectA,
2518 JNI::GetObjectClass,
2519 JNI::IsInstanceOf,
2520 JNI::GetMethodID,
2521 JNI::CallObjectMethod,
2522 JNI::CallObjectMethodV,
2523 JNI::CallObjectMethodA,
2524 JNI::CallBooleanMethod,
2525 JNI::CallBooleanMethodV,
2526 JNI::CallBooleanMethodA,
2527 JNI::CallByteMethod,
2528 JNI::CallByteMethodV,
2529 JNI::CallByteMethodA,
2530 JNI::CallCharMethod,
2531 JNI::CallCharMethodV,
2532 JNI::CallCharMethodA,
2533 JNI::CallShortMethod,
2534 JNI::CallShortMethodV,
2535 JNI::CallShortMethodA,
2536 JNI::CallIntMethod,
2537 JNI::CallIntMethodV,
2538 JNI::CallIntMethodA,
2539 JNI::CallLongMethod,
2540 JNI::CallLongMethodV,
2541 JNI::CallLongMethodA,
2542 JNI::CallFloatMethod,
2543 JNI::CallFloatMethodV,
2544 JNI::CallFloatMethodA,
2545 JNI::CallDoubleMethod,
2546 JNI::CallDoubleMethodV,
2547 JNI::CallDoubleMethodA,
2548 JNI::CallVoidMethod,
2549 JNI::CallVoidMethodV,
2550 JNI::CallVoidMethodA,
2551 JNI::CallNonvirtualObjectMethod,
2552 JNI::CallNonvirtualObjectMethodV,
2553 JNI::CallNonvirtualObjectMethodA,
2554 JNI::CallNonvirtualBooleanMethod,
2555 JNI::CallNonvirtualBooleanMethodV,
2556 JNI::CallNonvirtualBooleanMethodA,
2557 JNI::CallNonvirtualByteMethod,
2558 JNI::CallNonvirtualByteMethodV,
2559 JNI::CallNonvirtualByteMethodA,
2560 JNI::CallNonvirtualCharMethod,
2561 JNI::CallNonvirtualCharMethodV,
2562 JNI::CallNonvirtualCharMethodA,
2563 JNI::CallNonvirtualShortMethod,
2564 JNI::CallNonvirtualShortMethodV,
2565 JNI::CallNonvirtualShortMethodA,
2566 JNI::CallNonvirtualIntMethod,
2567 JNI::CallNonvirtualIntMethodV,
2568 JNI::CallNonvirtualIntMethodA,
2569 JNI::CallNonvirtualLongMethod,
2570 JNI::CallNonvirtualLongMethodV,
2571 JNI::CallNonvirtualLongMethodA,
2572 JNI::CallNonvirtualFloatMethod,
2573 JNI::CallNonvirtualFloatMethodV,
2574 JNI::CallNonvirtualFloatMethodA,
2575 JNI::CallNonvirtualDoubleMethod,
2576 JNI::CallNonvirtualDoubleMethodV,
2577 JNI::CallNonvirtualDoubleMethodA,
2578 JNI::CallNonvirtualVoidMethod,
2579 JNI::CallNonvirtualVoidMethodV,
2580 JNI::CallNonvirtualVoidMethodA,
2581 JNI::GetFieldID,
2582 JNI::GetObjectField,
2583 JNI::GetBooleanField,
2584 JNI::GetByteField,
2585 JNI::GetCharField,
2586 JNI::GetShortField,
2587 JNI::GetIntField,
2588 JNI::GetLongField,
2589 JNI::GetFloatField,
2590 JNI::GetDoubleField,
2591 JNI::SetObjectField,
2592 JNI::SetBooleanField,
2593 JNI::SetByteField,
2594 JNI::SetCharField,
2595 JNI::SetShortField,
2596 JNI::SetIntField,
2597 JNI::SetLongField,
2598 JNI::SetFloatField,
2599 JNI::SetDoubleField,
2600 JNI::GetStaticMethodID,
2601 JNI::CallStaticObjectMethod,
2602 JNI::CallStaticObjectMethodV,
2603 JNI::CallStaticObjectMethodA,
2604 JNI::CallStaticBooleanMethod,
2605 JNI::CallStaticBooleanMethodV,
2606 JNI::CallStaticBooleanMethodA,
2607 JNI::CallStaticByteMethod,
2608 JNI::CallStaticByteMethodV,
2609 JNI::CallStaticByteMethodA,
2610 JNI::CallStaticCharMethod,
2611 JNI::CallStaticCharMethodV,
2612 JNI::CallStaticCharMethodA,
2613 JNI::CallStaticShortMethod,
2614 JNI::CallStaticShortMethodV,
2615 JNI::CallStaticShortMethodA,
2616 JNI::CallStaticIntMethod,
2617 JNI::CallStaticIntMethodV,
2618 JNI::CallStaticIntMethodA,
2619 JNI::CallStaticLongMethod,
2620 JNI::CallStaticLongMethodV,
2621 JNI::CallStaticLongMethodA,
2622 JNI::CallStaticFloatMethod,
2623 JNI::CallStaticFloatMethodV,
2624 JNI::CallStaticFloatMethodA,
2625 JNI::CallStaticDoubleMethod,
2626 JNI::CallStaticDoubleMethodV,
2627 JNI::CallStaticDoubleMethodA,
2628 JNI::CallStaticVoidMethod,
2629 JNI::CallStaticVoidMethodV,
2630 JNI::CallStaticVoidMethodA,
2631 JNI::GetStaticFieldID,
2632 JNI::GetStaticObjectField,
2633 JNI::GetStaticBooleanField,
2634 JNI::GetStaticByteField,
2635 JNI::GetStaticCharField,
2636 JNI::GetStaticShortField,
2637 JNI::GetStaticIntField,
2638 JNI::GetStaticLongField,
2639 JNI::GetStaticFloatField,
2640 JNI::GetStaticDoubleField,
2641 JNI::SetStaticObjectField,
2642 JNI::SetStaticBooleanField,
2643 JNI::SetStaticByteField,
2644 JNI::SetStaticCharField,
2645 JNI::SetStaticShortField,
2646 JNI::SetStaticIntField,
2647 JNI::SetStaticLongField,
2648 JNI::SetStaticFloatField,
2649 JNI::SetStaticDoubleField,
2650 JNI::NewString,
2651 JNI::GetStringLength,
2652 JNI::GetStringChars,
2653 JNI::ReleaseStringChars,
2654 JNI::NewStringUTF,
2655 JNI::GetStringUTFLength,
2656 JNI::GetStringUTFChars,
2657 JNI::ReleaseStringUTFChars,
2658 JNI::GetArrayLength,
2659 JNI::NewObjectArray,
2660 JNI::GetObjectArrayElement,
2661 JNI::SetObjectArrayElement,
2662 JNI::NewBooleanArray,
2663 JNI::NewByteArray,
2664 JNI::NewCharArray,
2665 JNI::NewShortArray,
2666 JNI::NewIntArray,
2667 JNI::NewLongArray,
2668 JNI::NewFloatArray,
2669 JNI::NewDoubleArray,
2670 JNI::GetBooleanArrayElements,
2671 JNI::GetByteArrayElements,
2672 JNI::GetCharArrayElements,
2673 JNI::GetShortArrayElements,
2674 JNI::GetIntArrayElements,
2675 JNI::GetLongArrayElements,
2676 JNI::GetFloatArrayElements,
2677 JNI::GetDoubleArrayElements,
2678 JNI::ReleaseBooleanArrayElements,
2679 JNI::ReleaseByteArrayElements,
2680 JNI::ReleaseCharArrayElements,
2681 JNI::ReleaseShortArrayElements,
2682 JNI::ReleaseIntArrayElements,
2683 JNI::ReleaseLongArrayElements,
2684 JNI::ReleaseFloatArrayElements,
2685 JNI::ReleaseDoubleArrayElements,
2686 JNI::GetBooleanArrayRegion,
2687 JNI::GetByteArrayRegion,
2688 JNI::GetCharArrayRegion,
2689 JNI::GetShortArrayRegion,
2690 JNI::GetIntArrayRegion,
2691 JNI::GetLongArrayRegion,
2692 JNI::GetFloatArrayRegion,
2693 JNI::GetDoubleArrayRegion,
2694 JNI::SetBooleanArrayRegion,
2695 JNI::SetByteArrayRegion,
2696 JNI::SetCharArrayRegion,
2697 JNI::SetShortArrayRegion,
2698 JNI::SetIntArrayRegion,
2699 JNI::SetLongArrayRegion,
2700 JNI::SetFloatArrayRegion,
2701 JNI::SetDoubleArrayRegion,
2702 JNI::RegisterNatives,
2703 JNI::UnregisterNatives,
2704 JNI::MonitorEnter,
2705 JNI::MonitorExit,
2706 JNI::GetJavaVM,
2707 JNI::GetStringRegion,
2708 JNI::GetStringUTFRegion,
2709 JNI::GetPrimitiveArrayCritical,
2710 JNI::ReleasePrimitiveArrayCritical,
2711 JNI::GetStringCritical,
2712 JNI::ReleaseStringCritical,
2713 JNI::NewWeakGlobalRef,
2714 JNI::DeleteWeakGlobalRef,
2715 JNI::ExceptionCheck,
2716 JNI::NewDirectByteBuffer,
2717 JNI::GetDirectBufferAddress,
2718 JNI::GetDirectBufferCapacity,
2719 JNI::GetObjectRefType,
2720 };
2721
GetJniNativeInterface()2722 const JNINativeInterface* GetJniNativeInterface() {
2723 return &gJniNativeInterface;
2724 }
2725
RegisterNativeMethods(JNIEnv * env,const char * jni_class_name,const JNINativeMethod * methods,jint method_count)2726 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
2727 jint method_count) {
2728 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
2729 if (c.get() == nullptr) {
2730 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2731 }
2732 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2733 }
2734
2735 } // namespace art
2736
operator <<(std::ostream & os,const jobjectRefType & rhs)2737 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2738 switch (rhs) {
2739 case JNIInvalidRefType:
2740 os << "JNIInvalidRefType";
2741 return os;
2742 case JNILocalRefType:
2743 os << "JNILocalRefType";
2744 return os;
2745 case JNIGlobalRefType:
2746 os << "JNIGlobalRefType";
2747 return os;
2748 case JNIWeakGlobalRefType:
2749 os << "JNIWeakGlobalRefType";
2750 return os;
2751 default:
2752 LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
2753 UNREACHABLE();
2754 }
2755 }
2756