blob: c893a0fc9dce3a54a61b2f71e7fbf69d6d205641 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
Ian Rogersdf20fe02011-07-20 20:34:16 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "jni_internal.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070018
Elliott Hughes0af55432011-08-17 18:37:28 -070019#include <dlfcn.h>
Elliott Hughes79082e32011-08-25 12:07:32 -070020
21#include <cstdarg>
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Elliott Hughes0af55432011-08-17 18:37:28 -070023#include <utility>
24#include <vector>
Carl Shapiro2ed144c2011-07-26 16:52:08 -070025
Mathieu Chartierc7853442015-03-27 14:35:38 -070026#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070027#include "art_method-inl.h"
Ian Rogersef7d42f2014-01-06 12:55:46 -080028#include "atomic.h"
Mathieu Chartierbad02672014-08-25 13:08:22 -070029#include "base/allocator.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080030#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080031#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080032#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080033#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070034#include "dex_file-inl.h"
Mathieu Chartierd0004802014-10-15 16:59:47 -070035#include "fault_handler.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070036#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070037#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070038#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070039#include "interpreter/interpreter.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070040#include "jni_env_ext.h"
41#include "java_vm_ext.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042#include "mirror/class-inl.h"
43#include "mirror/class_loader.h"
Hiroshi Yamauchi02d2f292015-04-03 13:35:16 -070044#include "mirror/field-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070045#include "mirror/method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080046#include "mirror/object-inl.h"
47#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070048#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049#include "mirror/throwable.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080050#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070051#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070052#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070053#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070054#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070055#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070056#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070058#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070059
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070060namespace art {
61
Mathieu Chartier24555ad2014-10-06 13:41:33 -070062// 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
64static constexpr bool kWarnJniAbort = false;
65
Elliott Hughes6b436852011-08-12 10:16:44 -070066// 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").
Ian Rogers0571d352011-11-03 19:51:38 -070071static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070072 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.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070082 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(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -070086 }
87 return result;
88}
89
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080090static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070091 const char* name, const char* sig, const char* kind)
Mathieu Chartier90443472015-07-16 20:32:27 -070092 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -070093 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000094 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Ian Rogers62d6c772013-02-27 08:32:07 -080095 "no %s method \"%s.%s%s\"",
Ian Rogers1ff3c982014-08-12 02:30:58 -070096 kind, c->GetDescriptor(&temp), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -070097}
98
Sebastien Hertzfa65e842014-07-03 09:39:53 +020099static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
100 const char* kind, jint idx, bool return_errors)
Mathieu Chartier90443472015-07-16 20:32:27 -0700101 SHARED_REQUIRES(Locks::mutator_lock_) {
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200102 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;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000105 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200106 "%s is null at index %d", kind, idx);
107}
108
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800109static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
Mathieu Chartier90443472015-07-16 20:32:27 -0700110 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800111 if (LIKELY(klass->IsInitialized())) {
112 return klass;
113 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700114 StackHandleScope<1> hs(self);
115 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700116 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800117 return nullptr;
118 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700119 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800120}
121
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700122static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
123 const char* name, const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700124 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800125 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800126 if (c == nullptr) {
127 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700128 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700129 ArtMethod* method = nullptr;
130 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700131 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700132 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700133 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700134 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700135 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800137 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700138 // No virtual method matching the signature. Search declared
139 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700140 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700141 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700142 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800143 if (method == nullptr || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700144 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800145 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700146 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700147 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700148}
149
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800150static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Mathieu Chartier90443472015-07-16 20:32:27 -0700151 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700152 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700153 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
154 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700155 return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700156 }
Brian Carlstromce888532013-10-10 00:32:58 -0700157 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800158 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700159 return method->GetDeclaringClass()->GetClassLoader();
160 }
161 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800162 mirror::ClassLoader* class_loader =
163 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
164 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700165 return class_loader;
166 }
167 // See if the override ClassLoader is set for gtests.
Ian Rogers68d8b422014-07-17 11:09:10 -0700168 class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800169 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700170 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
171 // image.
172 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700173 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700174 return class_loader;
175 }
176 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800177 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700178}
179
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700180static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
181 const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700182 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700183 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) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800187 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700188 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700189 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800190 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700191 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
192 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700193 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800194 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700195 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700196 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700197 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800198 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700199 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700200 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800201 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000202 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700203 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700204 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000205 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800206 "no type \"%s\" found and so no field \"%s\" "
207 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700208 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000209 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800210 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700211 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700212 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700213 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700214 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700215 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700216 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700217 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700218 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800219 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000220 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800221 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700222 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800223 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700224 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700225 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700226}
227
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800228static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700229 jsize length, const char* identifier)
Mathieu Chartier90443472015-07-16 20:32:27 -0700230 SHARED_REQUIRES(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700231 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000232 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800233 "%s offset=%d length=%d %s.length=%d",
234 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700235}
Ian Rogers0571d352011-11-03 19:51:38 -0700236
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700237static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
238 jsize array_length)
Mathieu Chartier90443472015-07-16 20:32:27 -0700239 SHARED_REQUIRES(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000240 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800241 "offset=%d length=%d string.length()=%d", start, length,
242 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700243}
Elliott Hughes814e4032011-08-23 12:07:56 -0700244
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700245int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700246 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247 // Turn the const char* into a java.lang.String.
248 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800249 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700250 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700251 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700252
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700253 // Choose an appropriate constructor and set up the arguments.
254 jvalue args[2];
255 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800256 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700257 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800258 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700259 signature = "(Ljava/lang/String;)V";
260 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800261 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700262 signature = "(Ljava/lang/Throwable;)V";
263 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700264 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700265 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
266 args[0].l = s.get();
267 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700268 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700269 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800270 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800271 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700272 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800273 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700274 return JNI_ERR;
275 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700276
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800277 ScopedLocalRef<jthrowable> exception(
278 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
279 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700280 return JNI_ERR;
281 }
Ian Rogersef28b142012-11-30 14:22:18 -0800282 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000283 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700284 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700285}
286
Ian Rogers68d8b422014-07-17 11:09:10 -0700287static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
288 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700289}
290
Ian Rogers2d10b202014-05-12 19:15:18 -0700291#define CHECK_NON_NULL_ARGUMENT(value) \
292 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700293
Ian Rogers2d10b202014-05-12 19:15:18 -0700294#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) \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800304 if (UNLIKELY(value == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700305 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700306 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700307 }
308
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700309#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800310 if (UNLIKELY(length != 0 && value == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700311 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700312 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700313 }
314
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700315template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700316static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Mathieu Chartier90443472015-07-16 20:32:27 -0700317 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700318 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800319 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
321 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700322 }
323 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700324 return nullptr;
325}
326
Elliott Hughescdf53122011-08-19 15:46:09 -0700327class JNI {
328 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700329 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700330 return JNI_VERSION_1_6;
331 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700332
Ian Rogers25e8b912012-09-07 11:31:36 -0700333 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700334 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800335 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700336 }
337
Elliott Hughescdf53122011-08-19 15:46:09 -0700338 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700339 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700340 Runtime* runtime = Runtime::Current();
341 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700342 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700343 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800344 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700345 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700346 StackHandleScope<1> hs(soa.Self());
347 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800348 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700349 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800350 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700351 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700352 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700353 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700354
Ian Rogers62f05122014-03-21 11:21:29 -0700355 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700356 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700357 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700358 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700359 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700360
Ian Rogers62f05122014-03-21 11:21:29 -0700361 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700362 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700363 ScopedObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700364 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
365 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700366 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700367 return nullptr;
368 }
369 auto* field = static_cast<mirror::Field*>(obj_field);
370 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700371 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700372
Elliott Hughescdf53122011-08-19 15:46:09 -0700373 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700374 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700375 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700376 ArtMethod* m = soa.DecodeMethod(mid);
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700377 mirror::AbstractMethod* method;
Sebastien Hertzd3333762014-06-26 14:45:07 +0200378 if (m->IsConstructor()) {
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700379 method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200380 } else {
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700381 method = mirror::Method::CreateFromArtMethod(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200382 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700383 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700384 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700385
Elliott Hughescdf53122011-08-19 15:46:09 -0700386 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700387 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700388 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700389 ArtField* f = soa.DecodeField(fid);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700390 return soa.AddLocalReference<jobject>(mirror::Field::CreateFromArtField(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700391 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700392
Elliott Hughes37f7a402011-08-22 18:56:01 -0700393 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700394 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700395 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800396 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700397 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700398 }
399
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700400 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700401 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700402 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800403 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700404 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700405 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700406
Narayan Kamath1268b742014-07-11 19:15:11 +0100407 // Note: java_class1 should be safely castable to java_class2, and
408 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700409 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700410 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
411 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700412 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800413 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
414 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100415 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700416 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700417
Elliott Hughese84278b2012-03-22 10:06:53 -0700418 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700419 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800420 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700421 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700422 return JNI_TRUE;
423 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700424 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800425 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
426 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700427 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700428 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700429 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700430
Elliott Hughes37f7a402011-08-22 18:56:01 -0700431 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700432 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800433 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
434 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700435 return JNI_ERR;
436 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000437 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700438 return JNI_OK;
439 }
440
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700441 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700442 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800443 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700444 }
445
446 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700447 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700448 }
449
450 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700451 ScopedObjectAccess soa(env);
452 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700453 }
454
455 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700456 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700457
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700458 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000459 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700460 return;
461 }
462
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000463 StackHandleScope<1> hs(soa.Self());
464 Handle<mirror::Throwable> old_exception(
465 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
466 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800467 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700468 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700469 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
470 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800471 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700472 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700473 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700474 } else {
475 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800476 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000477 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700478 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800479 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700480 }
481 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000482 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700483 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700484
Elliott Hughescdf53122011-08-19 15:46:09 -0700485 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700486 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000487 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700488 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700489 }
490
Ian Rogers25e8b912012-09-07 11:31:36 -0700491 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700492 LOG(FATAL) << "JNI FatalError called: " << msg;
493 }
494
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700495 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700496 // TODO: SOA may not be necessary but I do it to please lock annotations.
497 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700498 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700499 return JNI_ERR;
500 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700501 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700502 return JNI_OK;
503 }
504
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700505 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700506 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800507 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700508 soa.Env()->PopFrame();
509 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700510 }
511
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700512 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700513 // TODO: SOA may not be necessary but I do it to please lock annotations.
514 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700515 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700516 }
517
Elliott Hughescdf53122011-08-19 15:46:09 -0700518 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700519 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800520 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Ian Rogers68d8b422014-07-17 11:09:10 -0700521 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700522 }
523
524 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700525 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
526 Thread* self = down_cast<JNIEnvExt*>(env)->self;
527 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700528 }
529
530 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700531 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700532 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
533 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700534 }
535
536 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700537 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
538 Thread* self = down_cast<JNIEnvExt*>(env)->self;
539 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700540 }
541
542 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700543 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800544 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800545 // Check for null after decoding the object to handle cleared weak globals.
546 if (decoded_obj == nullptr) {
547 return nullptr;
548 }
549 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700550 }
551
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700552 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800553 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700554 return;
555 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700556 // SOA is only necessary to have exclusion between GC root marking and removing.
557 // We don't want to have the GC attempt to mark a null root if we just removed
558 // it. b/22119403
559 ScopedObjectAccess soa(env);
560 auto* ext_env = down_cast<JNIEnvExt*>(env);
561 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700562 // Attempting to delete a local reference that is not in the
563 // topmost local reference frame is a no-op. DeleteLocalRef returns
564 // void and doesn't throw any exceptions, but we should probably
565 // complain about it so the user will notice that things aren't
566 // going quite the way they expect.
567 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
568 << "failed to find entry";
569 }
570 }
571
572 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700573 if (obj1 == obj2) {
574 return JNI_TRUE;
575 } else {
576 ScopedObjectAccess soa(env);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800577 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
578 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700579 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700580 }
581
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700582 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700583 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700584 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800585 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800586 if (c == nullptr) {
587 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700588 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800589 if (c->IsStringClass()) {
590 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
591 mirror::SetStringCountVisitor visitor(0);
592 return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
593 allocator_type, visitor));
594 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700595 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700596 }
597
Ian Rogersbc939662013-08-15 10:26:54 -0700598 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700599 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700600 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700601 CHECK_NON_NULL_ARGUMENT(java_class);
602 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700603 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700604 va_end(args);
605 return result;
606 }
607
Elliott Hughes72025e52011-08-23 17:50:30 -0700608 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700609 CHECK_NON_NULL_ARGUMENT(java_class);
610 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700611 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800612 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800613 if (c == nullptr) {
614 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700615 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800616 if (c->IsStringClass()) {
617 // Replace calls to String.<init> with equivalent StringFactory call.
618 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
619 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
620 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800621 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800622 if (result == nullptr) {
623 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700624 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700625 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700626 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800627 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800628 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700629 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800630 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700631 }
632
Elliott Hughes72025e52011-08-23 17:50:30 -0700633 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700634 CHECK_NON_NULL_ARGUMENT(java_class);
635 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700636 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800637 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800638 if (c == nullptr) {
639 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700640 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800641 if (c->IsStringClass()) {
642 // Replace calls to String.<init> with equivalent StringFactory call.
643 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
644 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
645 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800646 mirror::Object* result = c->AllocObject(soa.Self());
647 if (result == nullptr) {
648 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700649 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700650 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700651 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800652 if (soa.Self()->IsExceptionPending()) {
653 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700654 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800655 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700656 }
657
Ian Rogersbc939662013-08-15 10:26:54 -0700658 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700659 CHECK_NON_NULL_ARGUMENT(java_class);
660 CHECK_NON_NULL_ARGUMENT(name);
661 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700662 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700663 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700664 }
665
Ian Rogersbc939662013-08-15 10:26:54 -0700666 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
667 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700668 CHECK_NON_NULL_ARGUMENT(java_class);
669 CHECK_NON_NULL_ARGUMENT(name);
670 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700671 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700672 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700673 }
674
Elliott Hughes72025e52011-08-23 17:50:30 -0700675 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700676 va_list ap;
677 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700678 CHECK_NON_NULL_ARGUMENT(obj);
679 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700680 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700681 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700682 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700683 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700684 }
685
Elliott Hughes72025e52011-08-23 17:50:30 -0700686 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700687 CHECK_NON_NULL_ARGUMENT(obj);
688 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700689 ScopedObjectAccess soa(env);
690 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
691 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700692 }
693
Elliott Hughes72025e52011-08-23 17:50:30 -0700694 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700695 CHECK_NON_NULL_ARGUMENT(obj);
696 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700697 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700698 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700699 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700700 }
701
Elliott Hughes72025e52011-08-23 17:50:30 -0700702 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700703 va_list ap;
704 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700705 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
706 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700707 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700708 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700709 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700710 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700711 }
712
Elliott Hughes72025e52011-08-23 17:50:30 -0700713 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700714 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
715 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700716 ScopedObjectAccess soa(env);
717 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700718 }
719
Elliott Hughes72025e52011-08-23 17:50:30 -0700720 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700721 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
722 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700723 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700724 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700725 }
726
Elliott Hughes72025e52011-08-23 17:50:30 -0700727 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700728 va_list ap;
729 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700730 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
731 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700732 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700733 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700734 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700735 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700736 }
737
Elliott Hughes72025e52011-08-23 17:50:30 -0700738 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700739 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
740 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700741 ScopedObjectAccess soa(env);
742 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700743 }
744
Elliott Hughes72025e52011-08-23 17:50:30 -0700745 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700746 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
747 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700748 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700749 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700750 }
751
Elliott Hughes72025e52011-08-23 17:50:30 -0700752 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700753 va_list ap;
754 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700755 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
756 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700757 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700758 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700759 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700760 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700761 }
762
Elliott Hughes72025e52011-08-23 17:50:30 -0700763 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700764 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
765 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700766 ScopedObjectAccess soa(env);
767 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700768 }
769
Elliott Hughes72025e52011-08-23 17:50:30 -0700770 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700771 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
772 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700773 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700774 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700775 }
776
Elliott Hughes72025e52011-08-23 17:50:30 -0700777 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700778 va_list ap;
779 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700780 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
781 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700782 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700783 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700784 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700785 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700786 }
787
Elliott Hughes72025e52011-08-23 17:50:30 -0700788 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700789 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
790 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700791 ScopedObjectAccess soa(env);
792 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700793 }
794
Elliott Hughes72025e52011-08-23 17:50:30 -0700795 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700796 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
797 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700798 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700799 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700800 }
801
Elliott Hughes72025e52011-08-23 17:50:30 -0700802 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700803 va_list ap;
804 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700805 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
806 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700807 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700808 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700809 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700810 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700811 }
812
Elliott Hughes72025e52011-08-23 17:50:30 -0700813 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700814 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
815 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700816 ScopedObjectAccess soa(env);
817 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700818 }
819
Elliott Hughes72025e52011-08-23 17:50:30 -0700820 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700821 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
822 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700823 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700824 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700825 }
826
Elliott Hughes72025e52011-08-23 17:50:30 -0700827 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700828 va_list ap;
829 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700830 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
831 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700832 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700833 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700834 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700835 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700836 }
837
Elliott Hughes72025e52011-08-23 17:50:30 -0700838 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700839 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
840 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700841 ScopedObjectAccess soa(env);
842 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700843 }
844
Elliott Hughes72025e52011-08-23 17:50:30 -0700845 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700846 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
847 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700848 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700849 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700850 }
851
Elliott Hughes72025e52011-08-23 17:50:30 -0700852 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700853 va_list ap;
854 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700855 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
856 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700857 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700858 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700859 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700860 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700861 }
862
Elliott Hughes72025e52011-08-23 17:50:30 -0700863 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700864 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
865 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700866 ScopedObjectAccess soa(env);
867 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700868 }
869
Elliott Hughes72025e52011-08-23 17:50:30 -0700870 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700871 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
872 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700873 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700874 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700875 }
876
Elliott Hughes72025e52011-08-23 17:50:30 -0700877 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700878 va_list ap;
879 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700880 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
881 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700882 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700883 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700884 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700885 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700886 }
887
Elliott Hughes72025e52011-08-23 17:50:30 -0700888 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700889 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
890 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700891 ScopedObjectAccess soa(env);
892 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700893 }
894
Elliott Hughes72025e52011-08-23 17:50:30 -0700895 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700896 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
897 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700898 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700899 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700900 }
901
Elliott Hughes72025e52011-08-23 17:50:30 -0700902 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700903 va_list ap;
904 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700905 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
906 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700907 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700908 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700909 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700910 }
911
Elliott Hughes72025e52011-08-23 17:50:30 -0700912 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700913 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
914 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700915 ScopedObjectAccess soa(env);
916 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700917 }
918
Elliott Hughes72025e52011-08-23 17:50:30 -0700919 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700920 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
921 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700922 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700923 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700924 }
925
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700926 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700927 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700928 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700929 CHECK_NON_NULL_ARGUMENT(obj);
930 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700931 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700932 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
933 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700934 va_end(ap);
935 return local_result;
936 }
937
Ian Rogersbc939662013-08-15 10:26:54 -0700938 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
939 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700940 CHECK_NON_NULL_ARGUMENT(obj);
941 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700942 ScopedObjectAccess soa(env);
943 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
944 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700945 }
946
Ian Rogersbc939662013-08-15 10:26:54 -0700947 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
948 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700949 CHECK_NON_NULL_ARGUMENT(obj);
950 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700951 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700952 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700953 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700954 }
955
Ian Rogersbc939662013-08-15 10:26:54 -0700956 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
957 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700958 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700959 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700960 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
961 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700962 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700963 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700964 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700965 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700966 }
967
Ian Rogersbc939662013-08-15 10:26:54 -0700968 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
969 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700970 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
971 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700972 ScopedObjectAccess soa(env);
973 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700974 }
975
Ian Rogersbc939662013-08-15 10:26:54 -0700976 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
977 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700978 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
979 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700980 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700981 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700982 }
983
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700984 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700985 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700986 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700987 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
988 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700989 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700990 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700991 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700992 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700993 }
994
Ian Rogersbc939662013-08-15 10:26:54 -0700995 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
996 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700997 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
998 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700999 ScopedObjectAccess soa(env);
1000 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001001 }
1002
Ian Rogersbc939662013-08-15 10:26:54 -07001003 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1004 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001005 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1006 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001007 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001008 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001009 }
1010
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001011 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001012 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001013 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001014 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1015 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001016 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001017 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001018 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001019 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001020 }
1021
Ian Rogersbc939662013-08-15 10:26:54 -07001022 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1023 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001024 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1025 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001026 ScopedObjectAccess soa(env);
1027 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001028 }
1029
Ian Rogersbc939662013-08-15 10:26:54 -07001030 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1031 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001032 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1033 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001034 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001035 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001036 }
1037
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001038 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001039 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001040 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001041 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1042 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001043 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001044 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001045 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001046 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001047 }
1048
Ian Rogersbc939662013-08-15 10:26:54 -07001049 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1050 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001051 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1052 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001053 ScopedObjectAccess soa(env);
1054 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001055 }
1056
Ian Rogersbc939662013-08-15 10:26:54 -07001057 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1058 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001059 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1060 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001061 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001062 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001063 }
1064
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001065 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001066 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001067 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001068 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1069 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001070 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001071 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001072 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001073 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001074 }
1075
Ian Rogersbc939662013-08-15 10:26:54 -07001076 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1077 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001078 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1079 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001080 ScopedObjectAccess soa(env);
1081 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001082 }
1083
Ian Rogersbc939662013-08-15 10:26:54 -07001084 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1085 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001086 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1087 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001088 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001089 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001090 }
1091
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001092 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001093 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001094 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001095 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1096 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001097 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001098 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001099 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001100 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001101 }
1102
Ian Rogersbc939662013-08-15 10:26:54 -07001103 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1104 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001105 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1106 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001107 ScopedObjectAccess soa(env);
1108 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001109 }
1110
Ian Rogersbc939662013-08-15 10:26:54 -07001111 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1112 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001113 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1114 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001115 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001116 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001117 }
1118
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001119 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001120 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001121 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001122 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1123 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001124 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001125 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001126 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001127 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001128 }
1129
Ian Rogersbc939662013-08-15 10:26:54 -07001130 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1131 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001132 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1133 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001134 ScopedObjectAccess soa(env);
1135 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001136 }
1137
Ian Rogersbc939662013-08-15 10:26:54 -07001138 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1139 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001140 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1141 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001142 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001143 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001144 }
1145
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001146 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001147 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001148 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001149 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1150 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001151 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001152 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001153 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001154 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001155 }
1156
Ian Rogersbc939662013-08-15 10:26:54 -07001157 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1158 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001159 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1160 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001161 ScopedObjectAccess soa(env);
1162 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001163 }
1164
Ian Rogersbc939662013-08-15 10:26:54 -07001165 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1166 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001167 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1168 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001169 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001170 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001171 }
1172
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001173 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001174 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001175 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001176 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1177 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001178 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001179 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001180 va_end(ap);
1181 }
1182
Brian Carlstromea46f952013-07-30 01:26:50 -07001183 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1184 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001185 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1186 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001187 ScopedObjectAccess soa(env);
1188 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001189 }
1190
Ian Rogersbc939662013-08-15 10:26:54 -07001191 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1192 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001193 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1194 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001195 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001196 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001197 }
1198
Ian Rogersbc939662013-08-15 10:26:54 -07001199 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001200 CHECK_NON_NULL_ARGUMENT(java_class);
1201 CHECK_NON_NULL_ARGUMENT(name);
1202 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001203 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001204 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001205 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001206
Ian Rogersbc939662013-08-15 10:26:54 -07001207 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1208 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001209 CHECK_NON_NULL_ARGUMENT(java_class);
1210 CHECK_NON_NULL_ARGUMENT(name);
1211 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001212 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001213 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001214 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001215
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001216 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001217 CHECK_NON_NULL_ARGUMENT(obj);
1218 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001219 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001220 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001221 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001222 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001223 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001224
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001225 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001226 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001227 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001228 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001229 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001230 }
1231
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001232 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001233 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1234 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001235 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001236 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1237 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001238 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001239 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001240 }
1241
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001242 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001243 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001244 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001245 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001246 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001247 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001248 }
1249
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001250#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001251 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1252 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001253 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001254 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001255 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001256 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001257
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001258#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001259 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001260 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001261 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001262 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001263
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001264#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001265 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1266 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001267 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001268 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001269 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001270 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001271
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001272#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001273 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001274 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001275 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001276 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001277
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001278 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001279 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001280 }
1281
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001282 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001283 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001284 }
1285
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001286 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001287 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001288 }
1289
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001290 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001291 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001292 }
1293
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001294 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001295 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001296 }
1297
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001298 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001299 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001300 }
1301
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001302 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001303 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001304 }
1305
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001306 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001307 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001308 }
1309
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001310 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001311 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001312 }
1313
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001314 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001315 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001316 }
1317
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001318 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001319 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001320 }
1321
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001322 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001323 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001324 }
1325
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001326 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001327 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001328 }
1329
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001330 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001331 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001332 }
1333
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001334 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001335 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001336 }
1337
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001338 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001339 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001340 }
1341
1342 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001343 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001344 }
1345
1346 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001347 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001348 }
1349
1350 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001351 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001352 }
1353
1354 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001355 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001356 }
1357
1358 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001359 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001360 }
1361
1362 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001363 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001364 }
1365
1366 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001367 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001368 }
1369
1370 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001371 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001372 }
1373
1374 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001375 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001376 }
1377
1378 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001379 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001380 }
1381
1382 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001383 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001384 }
1385
1386 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001387 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001388 }
1389
1390 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001391 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001392 }
1393
1394 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001395 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001396 }
1397
1398 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001399 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001400 }
1401
1402 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001403 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001404 }
1405
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001406 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001407 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001408 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001409 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001410 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001411 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001412 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001413 va_end(ap);
1414 return local_result;
1415 }
1416
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001417 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001418 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001419 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001420 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001421 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001422 }
1423
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001424 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001425 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001426 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001427 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001428 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001429 }
1430
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001431 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001432 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001433 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001434 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001435 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001436 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001437 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001438 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001439 }
1440
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001441 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001442 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001443 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001444 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001445 }
1446
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001447 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001448 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001449 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001450 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001451 }
1452
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001453 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001454 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001455 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001456 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001457 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001458 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001459 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001460 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001461 }
1462
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001463 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001464 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001465 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001466 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001467 }
1468
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001469 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001470 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001471 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001472 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001473 }
1474
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001475 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001476 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001477 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001478 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001479 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001480 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001481 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001482 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001483 }
1484
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001485 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001486 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001487 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001488 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001489 }
1490
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001491 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001492 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001493 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001494 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001495 }
1496
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001497 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001498 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001499 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001500 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001501 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001502 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001503 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001504 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001505 }
1506
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001507 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001508 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001509 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001510 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001511 }
1512
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001513 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001514 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001515 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001516 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001517 }
1518
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001519 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001520 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001521 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001522 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001523 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001524 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001525 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001526 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001527 }
1528
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001529 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001530 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001531 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001532 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001533 }
1534
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001535 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001536 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001537 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001538 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001539 }
1540
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001541 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001542 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001543 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001544 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001545 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001546 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001547 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001548 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001549 }
1550
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001551 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001552 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001553 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001554 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001555 }
1556
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001557 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001558 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001559 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001560 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001561 }
1562
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001563 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001564 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001565 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001566 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001567 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001568 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001569 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001570 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001571 }
1572
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001573 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001574 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001575 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001576 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001577 }
1578
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001579 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001580 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001581 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001582 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001583 }
1584
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001585 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001586 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001587 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001588 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001589 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001590 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001591 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001592 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001593 }
1594
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001595 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001596 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001597 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001598 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001599 }
1600
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001601 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001602 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001603 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001604 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001605 }
1606
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001607 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001608 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001609 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001610 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001611 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001612 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001613 va_end(ap);
1614 }
1615
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001616 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001617 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001618 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001619 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001620 }
1621
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001622 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001623 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001624 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001625 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001626 }
1627
Elliott Hughes814e4032011-08-23 12:07:56 -07001628 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001629 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001630 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001631 return nullptr;
1632 }
1633 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001634 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001635 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001636 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001637 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001638 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001639 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001640 }
1641
1642 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001643 if (utf == nullptr) {
1644 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001645 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001646 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001647 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001648 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001649 }
1650
Elliott Hughes814e4032011-08-23 12:07:56 -07001651 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001652 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001653 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001654 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001655 }
1656
1657 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001658 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001659 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001660 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001661 }
1662
Ian Rogersbc939662013-08-15 10:26:54 -07001663 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1664 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001665 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001666 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001667 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001668 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001669 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001670 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001671 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Jeff Hao848f70a2014-01-15 13:49:50 -08001672 const jchar* chars = s->GetValue();
Elliott Hughesb465ab02011-08-24 11:21:21 -07001673 memcpy(buf, chars + start, length * sizeof(jchar));
1674 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001675 }
1676
Ian Rogersbc939662013-08-15 10:26:54 -07001677 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1678 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001679 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001680 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001681 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001682 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001683 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001684 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001685 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Jeff Hao848f70a2014-01-15 13:49:50 -08001686 const jchar* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001687 size_t bytes = CountUtf8Bytes(chars + start, length);
1688 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001689 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001690 }
1691
Elliott Hughes75770752011-08-24 17:52:38 -07001692 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001693 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001694 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001695 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001696 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001697 if (heap->IsMovableObject(s)) {
1698 jchar* chars = new jchar[s->GetLength()];
1699 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
Fred Shih56890e22014-06-02 11:11:52 -07001700 if (is_copy != nullptr) {
1701 *is_copy = JNI_TRUE;
1702 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001703 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001704 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001705 if (is_copy != nullptr) {
1706 *is_copy = JNI_FALSE;
1707 }
1708 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001709 }
1710
Mathieu Chartier590fee92013-09-13 13:46:47 -07001711 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001712 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001713 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001714 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001715 if (chars != s->GetValue()) {
Fred Shih56890e22014-06-02 11:11:52 -07001716 delete[] chars;
1717 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001718 }
1719
Elliott Hughes75770752011-08-24 17:52:38 -07001720 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001721 CHECK_NON_NULL_ARGUMENT(java_string);
1722 ScopedObjectAccess soa(env);
1723 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001724 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001725 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001726 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001727 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001728 if (!kUseReadBarrier) {
1729 heap->IncrementDisableMovingGC(soa.Self());
1730 } else {
1731 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1732 // to occur thanks to the to-space invariant.
1733 heap->IncrementDisableThreadFlip(soa.Self());
1734 }
Fred Shih56890e22014-06-02 11:11:52 -07001735 }
1736 if (is_copy != nullptr) {
1737 *is_copy = JNI_FALSE;
1738 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001739 return static_cast<jchar*>(s->GetValue());
Elliott Hughescdf53122011-08-19 15:46:09 -07001740 }
1741
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001742 static void ReleaseStringCritical(JNIEnv* env,
1743 jstring java_string,
1744 const jchar* chars ATTRIBUTE_UNUSED) {
Fred Shih56890e22014-06-02 11:11:52 -07001745 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1746 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001747 gc::Heap* heap = Runtime::Current()->GetHeap();
1748 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001749 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001750 if (!kUseReadBarrier) {
1751 heap->DecrementDisableMovingGC(soa.Self());
1752 } else {
1753 heap->DecrementDisableThreadFlip(soa.Self());
1754 }
Fred Shih56890e22014-06-02 11:11:52 -07001755 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001756 }
1757
Elliott Hughes75770752011-08-24 17:52:38 -07001758 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001759 if (java_string == nullptr) {
1760 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001761 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001762 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001763 *is_copy = JNI_TRUE;
1764 }
Ian Rogersef28b142012-11-30 14:22:18 -08001765 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001766 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001767 size_t byte_count = s->GetUtfLength();
1768 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001769 CHECK(bytes != nullptr); // bionic aborts anyway.
Jeff Hao848f70a2014-01-15 13:49:50 -08001770 const uint16_t* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001771 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
Elliott Hughes75770752011-08-24 17:52:38 -07001772 bytes[byte_count] = '\0';
1773 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001774 }
1775
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001776 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001777 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001778 }
1779
Elliott Hughesbd935992011-08-22 11:59:34 -07001780 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001781 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001782 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001783 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001784 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001785 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1786 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001787 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001788 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001789 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001790 }
1791
Elliott Hughes814e4032011-08-23 12:07:56 -07001792 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001793 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001794 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001795 mirror::ObjectArray<mirror::Object>* array =
1796 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001797 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001798 }
1799
Ian Rogersbc939662013-08-15 10:26:54 -07001800 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1801 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001802 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001803 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001804 mirror::ObjectArray<mirror::Object>* array =
1805 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1806 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001807 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001808 }
1809
1810 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001811 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001812 }
1813
1814 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001815 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001816 }
1817
1818 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001819 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001820 }
1821
1822 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001823 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001824 }
1825
1826 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001827 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001828 }
1829
1830 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001831 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001832 }
1833
1834 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001835 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001836 }
1837
Ian Rogers1d99e452014-01-02 17:36:41 -08001838 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1839 jobject initial_element) {
1840 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001841 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001842 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001843 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001844 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001845
1846 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001847 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001848 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001849 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001850 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001851 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001852 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1853 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001854 return nullptr;
1855 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001856 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001857 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001858 if (UNLIKELY(array_class == nullptr)) {
1859 return nullptr;
1860 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001861 }
1862
Elliott Hughes75770752011-08-24 17:52:38 -07001863 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001864 mirror::ObjectArray<mirror::Object>* result =
1865 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001866 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001867 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001868 if (initial_object != nullptr) {
1869 mirror::Class* element_class = result->GetClass()->GetComponentType();
1870 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001871 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1872 "element type of '%s'",
1873 PrettyDescriptor(initial_object->GetClass()).c_str(),
1874 PrettyDescriptor(element_class).c_str());
1875 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001876 } else {
1877 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001878 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001879 }
1880 }
Elliott Hughes75770752011-08-24 17:52:38 -07001881 }
1882 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001883 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001884 }
1885
1886 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001887 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001888 }
1889
Ian Rogersa15e67d2012-02-28 13:51:55 -08001890 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001891 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001892 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001893 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001894 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001895 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1896 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001897 return nullptr;
1898 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001899 gc::Heap* heap = Runtime::Current()->GetHeap();
1900 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001901 if (!kUseReadBarrier) {
1902 heap->IncrementDisableMovingGC(soa.Self());
1903 } else {
1904 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1905 // to occur thanks to the to-space invariant.
1906 heap->IncrementDisableThreadFlip(soa.Self());
1907 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001908 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001909 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001910 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001911 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001912 *is_copy = JNI_FALSE;
1913 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001914 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001915 }
1916
Ian Rogers2d10b202014-05-12 19:15:18 -07001917 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1918 jint mode) {
1919 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1920 ScopedObjectAccess soa(env);
1921 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1922 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001923 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1924 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001925 return;
1926 }
1927 const size_t component_size = array->GetClass()->GetComponentSize();
1928 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001929 }
1930
Elliott Hughes75770752011-08-24 17:52:38 -07001931 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001932 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001933 }
1934
Elliott Hughes75770752011-08-24 17:52:38 -07001935 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001936 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001937 }
1938
Elliott Hughes75770752011-08-24 17:52:38 -07001939 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001940 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001941 }
1942
Elliott Hughes75770752011-08-24 17:52:38 -07001943 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001944 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001945 }
1946
Elliott Hughes75770752011-08-24 17:52:38 -07001947 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001948 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001949 }
1950
Elliott Hughes75770752011-08-24 17:52:38 -07001951 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001952 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001953 }
1954
Elliott Hughes75770752011-08-24 17:52:38 -07001955 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001956 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001957 }
1958
Elliott Hughes75770752011-08-24 17:52:38 -07001959 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001960 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001961 }
1962
Mathieu Chartier590fee92013-09-13 13:46:47 -07001963 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1964 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001965 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
1966 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001967 }
1968
Mathieu Chartier590fee92013-09-13 13:46:47 -07001969 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001970 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001971 }
1972
Mathieu Chartier590fee92013-09-13 13:46:47 -07001973 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001974 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001975 }
1976
Mathieu Chartier590fee92013-09-13 13:46:47 -07001977 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1978 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001979 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001980 }
1981
Mathieu Chartier590fee92013-09-13 13:46:47 -07001982 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1983 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001984 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001985 }
1986
Mathieu Chartier590fee92013-09-13 13:46:47 -07001987 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001988 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001989 }
1990
Mathieu Chartier590fee92013-09-13 13:46:47 -07001991 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001992 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001993 }
1994
Mathieu Chartier590fee92013-09-13 13:46:47 -07001995 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
1996 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001997 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001998 }
1999
Ian Rogersbc939662013-08-15 10:26:54 -07002000 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2001 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002002 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002003 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002004 }
2005
Ian Rogersbc939662013-08-15 10:26:54 -07002006 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2007 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002008 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002009 }
2010
Ian Rogersbc939662013-08-15 10:26:54 -07002011 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2012 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002013 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002014 }
2015
Ian Rogersbc939662013-08-15 10:26:54 -07002016 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2017 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002018 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002019 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002020 }
2021
Ian Rogersbc939662013-08-15 10:26:54 -07002022 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2023 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002024 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002025 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002026 }
2027
Ian Rogersbc939662013-08-15 10:26:54 -07002028 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2029 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002030 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002031 }
2032
Ian Rogersbc939662013-08-15 10:26:54 -07002033 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2034 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002035 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002036 }
2037
Ian Rogersbc939662013-08-15 10:26:54 -07002038 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2039 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002040 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002041 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002042 }
2043
Ian Rogersbc939662013-08-15 10:26:54 -07002044 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2045 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002046 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002047 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002048 }
2049
Ian Rogersbc939662013-08-15 10:26:54 -07002050 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2051 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002052 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002053 }
2054
Ian Rogersbc939662013-08-15 10:26:54 -07002055 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2056 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002057 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002058 }
2059
Ian Rogersbc939662013-08-15 10:26:54 -07002060 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2061 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002062 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002063 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002064 }
2065
Ian Rogersbc939662013-08-15 10:26:54 -07002066 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2067 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002068 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002069 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002070 }
2071
Ian Rogersbc939662013-08-15 10:26:54 -07002072 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2073 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002074 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002075 }
2076
Ian Rogersbc939662013-08-15 10:26:54 -07002077 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2078 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002079 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002080 }
2081
Ian Rogersbc939662013-08-15 10:26:54 -07002082 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2083 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002084 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002085 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002086 }
2087
Ian Rogersbc939662013-08-15 10:26:54 -07002088 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2089 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002090 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2091 }
2092
Ian Rogersbc939662013-08-15 10:26:54 -07002093 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2094 jint method_count, bool return_errors) {
2095 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002096 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2097 method_count);
2098 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002099 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002100 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002101 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002102 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002103 if (UNLIKELY(method_count == 0)) {
2104 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2105 << PrettyDescriptor(c);
2106 return JNI_OK;
2107 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002108 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002109 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002110 const char* name = methods[i].name;
2111 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002112 const void* fnPtr = methods[i].fnPtr;
2113 if (UNLIKELY(name == nullptr)) {
2114 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2115 return JNI_ERR;
2116 } else if (UNLIKELY(sig == nullptr)) {
2117 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2118 return JNI_ERR;
2119 } else if (UNLIKELY(fnPtr == nullptr)) {
2120 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2121 return JNI_ERR;
2122 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002123 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002124 // Notes about fast JNI calls:
2125 //
2126 // On a normal JNI call, the calling thread usually transitions
2127 // from the kRunnable state to the kNative state. But if the
2128 // called native function needs to access any Java object, it
2129 // will have to transition back to the kRunnable state.
2130 //
2131 // There is a cost to this double transition. For a JNI call
2132 // that should be quick, this cost may dominate the call cost.
2133 //
2134 // On a fast JNI call, the calling thread avoids this double
2135 // transition by not transitioning from kRunnable to kNative and
2136 // stays in the kRunnable state.
2137 //
2138 // There are risks to using a fast JNI call because it can delay
2139 // a response to a thread suspension request which is typically
2140 // used for a GC root scanning, etc. If a fast JNI call takes a
2141 // long time, it could cause longer thread suspension latency
2142 // and GC pauses.
2143 //
2144 // Thus, fast JNI should be used with care. It should be used
2145 // for a JNI call that takes a short amount of time (eg. no
2146 // long-running loop) and does not block (eg. no locks, I/O,
2147 // etc.)
2148 //
2149 // A '!' prefix in the signature in the JNINativeMethod
2150 // indicates that it's a fast JNI call and the runtime omits the
2151 // thread state transition from kRunnable to kNative at the
2152 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002153 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002154 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002155 ++sig;
2156 }
2157
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002158 // Note: the right order is to try to find the method locally
2159 // first, either as a direct or a virtual method. Then move to
2160 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002161 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002162 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2163 for (mirror::Class* current_class = c;
2164 current_class != nullptr;
2165 current_class = current_class->GetSuperClass()) {
2166 // Search first only comparing methods which are native.
2167 m = FindMethod<true>(current_class, name, sig);
2168 if (m != nullptr) {
2169 break;
2170 }
2171
2172 // Search again comparing to all methods, to find non-native methods that match.
2173 m = FindMethod<false>(current_class, name, sig);
2174 if (m != nullptr) {
2175 break;
2176 }
2177
2178 if (warn_on_going_to_parent) {
2179 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2180 << "This is slow, consider changing your RegisterNatives calls.";
2181 warn_on_going_to_parent = false;
2182 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002183 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002184
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002185 if (m == nullptr) {
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002186 LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002187 << PrettyDescriptor(c) << "." << name << sig << " in "
2188 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002189 // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2190 // out of scope after the DumpClass is done executing.
2191 c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002192 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002193 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002194 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002195 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002196 << PrettyDescriptor(c) << "." << name << sig
2197 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002198 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002199 return JNI_ERR;
2200 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002201
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002202 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002203
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002204 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002205 }
2206 return JNI_OK;
2207 }
2208
Elliott Hughes5174fe62011-08-23 15:12:35 -07002209 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002210 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002211 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002212 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002213
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002214 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002215
Ian Rogers2d10b202014-05-12 19:15:18 -07002216 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002217 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002218 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002219 if (m.IsNative()) {
2220 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002221 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002222 }
2223 }
2224
Ian Rogers2d10b202014-05-12 19:15:18 -07002225 if (unregistered_count == 0) {
2226 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2227 << PrettyDescriptor(c) << "' that contains no native methods";
2228 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002229 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002230 }
2231
Ian Rogers719d1a32014-03-06 12:13:39 -08002232 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002233 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002234 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002235 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2236 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002237 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002238 return JNI_ERR;
2239 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002240 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002241 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002242 }
2243
Ian Rogers719d1a32014-03-06 12:13:39 -08002244 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002245 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002246 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002247 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002248 o->MonitorExit(soa.Self());
2249 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002250 return JNI_ERR;
2251 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002252 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002253 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002254 }
2255
2256 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002257 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002258 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002259 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002260 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002261 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002262 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002263 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002264 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002265 }
2266
Elliott Hughescdf53122011-08-19 15:46:09 -07002267 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002268 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002269 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2270 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002271 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002272 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002273 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002274 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2275 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002276 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002277 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002278
Brian Carlstrom85a93362014-06-25 09:30:52 -07002279 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002280 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002281 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2282 "buffer capacity greater than maximum jint: %" PRId64,
2283 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002284 return nullptr;
2285 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002286 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002287 jint capacity_arg = static_cast<jint>(capacity);
2288
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002289 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2290 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002291 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002292 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002293 }
2294
Elliott Hughesb465ab02011-08-24 11:21:21 -07002295 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002296 return reinterpret_cast<void*>(env->GetLongField(
2297 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002298 }
2299
Elliott Hughesb465ab02011-08-24 11:21:21 -07002300 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002301 return static_cast<jlong>(env->GetIntField(
2302 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002303 }
2304
Andreas Gampea8763072014-12-20 00:08:35 -08002305 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2306 if (java_object == nullptr) {
2307 return JNIInvalidRefType;
2308 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002309
2310 // Do we definitely know what kind of reference this is?
2311 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2312 IndirectRefKind kind = GetIndirectRefKind(ref);
2313 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002314 case kLocal:
2315 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002316 case kGlobal:
2317 return JNIGlobalRefType;
2318 case kWeakGlobal:
2319 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002320 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002321 // Assume value is in a handle scope.
2322 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002323 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002324 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002325 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002326 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002327
2328 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002329 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2330 const char* caller)
Mathieu Chartier90443472015-07-16 20:32:27 -07002331 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002332 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002333 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002334 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2335 return JNI_ERR;
2336 }
2337 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002338 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002339 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2340 if (!okay) {
2341 soa.Self()->ThrowOutOfMemoryError(caller);
2342 }
2343 return okay ? JNI_OK : JNI_ERR;
2344 }
2345
2346 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002347 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002348 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002349 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002350 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002351 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002352 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002353 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002354 return soa.AddLocalReference<JniT>(result);
2355 }
2356
Ian Rogers2d10b202014-05-12 19:15:18 -07002357 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2358 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2359 const char* fn_name, const char* operation)
Mathieu Chartier90443472015-07-16 20:32:27 -07002360 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002361 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002362 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002363 soa.Vm()->JniAbortF(fn_name,
2364 "attempt to %s %s primitive array elements with an object of type %s",
2365 operation,
2366 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2367 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002368 return nullptr;
2369 }
2370 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2371 return array;
2372 }
2373
2374 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2375 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2376 CHECK_NON_NULL_ARGUMENT(java_array);
2377 ScopedObjectAccess soa(env);
2378 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2379 "GetArrayElements",
2380 "get");
2381 if (UNLIKELY(array == nullptr)) {
2382 return nullptr;
2383 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002384 // Only make a copy if necessary.
2385 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2386 if (is_copy != nullptr) {
2387 *is_copy = JNI_TRUE;
2388 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002389 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002390 size_t size = array->GetLength() * component_size;
2391 void* data = new uint64_t[RoundUp(size, 8) / 8];
2392 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002393 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002394 } else {
2395 if (is_copy != nullptr) {
2396 *is_copy = JNI_FALSE;
2397 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002398 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002399 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002400 }
2401
Ian Rogers2d10b202014-05-12 19:15:18 -07002402 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002403 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002404 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002405 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002406 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2407 "ReleaseArrayElements",
2408 "release");
2409 if (array == nullptr) {
2410 return;
2411 }
2412 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2413 }
2414
2415 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2416 size_t component_size, void* elements, jint mode)
Mathieu Chartier90443472015-07-16 20:32:27 -07002417 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002418 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002419 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002420 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002421 size_t bytes = array->GetLength() * component_size;
Ian Rogers2d10b202014-05-12 19:15:18 -07002422 VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
2423 << " elements " << elements;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002424 if (is_copy) {
2425 // Sanity check: If elements is not the same as the java array's data, it better not be a
2426 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2427 // copies we make?
2428 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002429 soa.Vm()->JniAbortF("ReleaseArrayElements",
2430 "invalid element pointer %p, array elements are %p",
2431 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002432 return;
2433 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002434 if (mode != JNI_ABORT) {
2435 memcpy(array_data, elements, bytes);
2436 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2437 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2438 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2439 soa.Self()->DumpJavaStack(LOG(WARNING));
2440 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002441 }
2442 if (mode != JNI_COMMIT) {
2443 if (is_copy) {
2444 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002445 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002446 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002447 if (!kUseReadBarrier) {
2448 heap->DecrementDisableMovingGC(soa.Self());
2449 } else {
2450 heap->DecrementDisableThreadFlip(soa.Self());
2451 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002452 }
2453 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002454 }
2455
Ian Rogers2d10b202014-05-12 19:15:18 -07002456 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2457 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2458 jsize start, jsize length, ElementT* buf) {
2459 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2460 ScopedObjectAccess soa(env);
2461 ArtArrayT* array =
2462 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2463 "GetPrimitiveArrayRegion",
2464 "get region of");
2465 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002466 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002467 ThrowAIOOBE(soa, array, start, length, "src");
2468 } else {
2469 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2470 ElementT* data = array->GetData();
2471 memcpy(buf, data + start, length * sizeof(ElementT));
2472 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002473 }
2474 }
2475
Ian Rogers2d10b202014-05-12 19:15:18 -07002476 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2477 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2478 jsize start, jsize length, const ElementT* buf) {
2479 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2480 ScopedObjectAccess soa(env);
2481 ArtArrayT* array =
2482 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2483 "SetPrimitiveArrayRegion",
2484 "set region of");
2485 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002486 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002487 ThrowAIOOBE(soa, array, start, length, "dst");
2488 } else {
2489 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2490 ElementT* data = array->GetData();
2491 memcpy(data + start, buf, length * sizeof(ElementT));
2492 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002493 }
2494 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002495};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002496
Elliott Hughes88c5c352012-03-15 18:49:48 -07002497const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002498 nullptr, // reserved0.
2499 nullptr, // reserved1.
2500 nullptr, // reserved2.
2501 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002502 JNI::GetVersion,
2503 JNI::DefineClass,
2504 JNI::FindClass,
2505 JNI::FromReflectedMethod,
2506 JNI::FromReflectedField,
2507 JNI::ToReflectedMethod,
2508 JNI::GetSuperclass,
2509 JNI::IsAssignableFrom,
2510 JNI::ToReflectedField,
2511 JNI::Throw,
2512 JNI::ThrowNew,
2513 JNI::ExceptionOccurred,
2514 JNI::ExceptionDescribe,
2515 JNI::ExceptionClear,
2516 JNI::FatalError,
2517 JNI::PushLocalFrame,
2518 JNI::PopLocalFrame,
2519 JNI::NewGlobalRef,
2520 JNI::DeleteGlobalRef,
2521 JNI::DeleteLocalRef,
2522 JNI::IsSameObject,
2523 JNI::NewLocalRef,
2524 JNI::EnsureLocalCapacity,
2525 JNI::AllocObject,
2526 JNI::NewObject,
2527 JNI::NewObjectV,
2528 JNI::NewObjectA,
2529 JNI::GetObjectClass,
2530 JNI::IsInstanceOf,
2531 JNI::GetMethodID,
2532 JNI::CallObjectMethod,
2533 JNI::CallObjectMethodV,
2534 JNI::CallObjectMethodA,
2535 JNI::CallBooleanMethod,
2536 JNI::CallBooleanMethodV,
2537 JNI::CallBooleanMethodA,
2538 JNI::CallByteMethod,
2539 JNI::CallByteMethodV,
2540 JNI::CallByteMethodA,
2541 JNI::CallCharMethod,
2542 JNI::CallCharMethodV,
2543 JNI::CallCharMethodA,
2544 JNI::CallShortMethod,
2545 JNI::CallShortMethodV,
2546 JNI::CallShortMethodA,
2547 JNI::CallIntMethod,
2548 JNI::CallIntMethodV,
2549 JNI::CallIntMethodA,
2550 JNI::CallLongMethod,
2551 JNI::CallLongMethodV,
2552 JNI::CallLongMethodA,
2553 JNI::CallFloatMethod,
2554 JNI::CallFloatMethodV,
2555 JNI::CallFloatMethodA,
2556 JNI::CallDoubleMethod,
2557 JNI::CallDoubleMethodV,
2558 JNI::CallDoubleMethodA,
2559 JNI::CallVoidMethod,
2560 JNI::CallVoidMethodV,
2561 JNI::CallVoidMethodA,
2562 JNI::CallNonvirtualObjectMethod,
2563 JNI::CallNonvirtualObjectMethodV,
2564 JNI::CallNonvirtualObjectMethodA,
2565 JNI::CallNonvirtualBooleanMethod,
2566 JNI::CallNonvirtualBooleanMethodV,
2567 JNI::CallNonvirtualBooleanMethodA,
2568 JNI::CallNonvirtualByteMethod,
2569 JNI::CallNonvirtualByteMethodV,
2570 JNI::CallNonvirtualByteMethodA,
2571 JNI::CallNonvirtualCharMethod,
2572 JNI::CallNonvirtualCharMethodV,
2573 JNI::CallNonvirtualCharMethodA,
2574 JNI::CallNonvirtualShortMethod,
2575 JNI::CallNonvirtualShortMethodV,
2576 JNI::CallNonvirtualShortMethodA,
2577 JNI::CallNonvirtualIntMethod,
2578 JNI::CallNonvirtualIntMethodV,
2579 JNI::CallNonvirtualIntMethodA,
2580 JNI::CallNonvirtualLongMethod,
2581 JNI::CallNonvirtualLongMethodV,
2582 JNI::CallNonvirtualLongMethodA,
2583 JNI::CallNonvirtualFloatMethod,
2584 JNI::CallNonvirtualFloatMethodV,
2585 JNI::CallNonvirtualFloatMethodA,
2586 JNI::CallNonvirtualDoubleMethod,
2587 JNI::CallNonvirtualDoubleMethodV,
2588 JNI::CallNonvirtualDoubleMethodA,
2589 JNI::CallNonvirtualVoidMethod,
2590 JNI::CallNonvirtualVoidMethodV,
2591 JNI::CallNonvirtualVoidMethodA,
2592 JNI::GetFieldID,
2593 JNI::GetObjectField,
2594 JNI::GetBooleanField,
2595 JNI::GetByteField,
2596 JNI::GetCharField,
2597 JNI::GetShortField,
2598 JNI::GetIntField,
2599 JNI::GetLongField,
2600 JNI::GetFloatField,
2601 JNI::GetDoubleField,
2602 JNI::SetObjectField,
2603 JNI::SetBooleanField,
2604 JNI::SetByteField,
2605 JNI::SetCharField,
2606 JNI::SetShortField,
2607 JNI::SetIntField,
2608 JNI::SetLongField,
2609 JNI::SetFloatField,
2610 JNI::SetDoubleField,
2611 JNI::GetStaticMethodID,
2612 JNI::CallStaticObjectMethod,
2613 JNI::CallStaticObjectMethodV,
2614 JNI::CallStaticObjectMethodA,
2615 JNI::CallStaticBooleanMethod,
2616 JNI::CallStaticBooleanMethodV,
2617 JNI::CallStaticBooleanMethodA,
2618 JNI::CallStaticByteMethod,
2619 JNI::CallStaticByteMethodV,
2620 JNI::CallStaticByteMethodA,
2621 JNI::CallStaticCharMethod,
2622 JNI::CallStaticCharMethodV,
2623 JNI::CallStaticCharMethodA,
2624 JNI::CallStaticShortMethod,
2625 JNI::CallStaticShortMethodV,
2626 JNI::CallStaticShortMethodA,
2627 JNI::CallStaticIntMethod,
2628 JNI::CallStaticIntMethodV,
2629 JNI::CallStaticIntMethodA,
2630 JNI::CallStaticLongMethod,
2631 JNI::CallStaticLongMethodV,
2632 JNI::CallStaticLongMethodA,
2633 JNI::CallStaticFloatMethod,
2634 JNI::CallStaticFloatMethodV,
2635 JNI::CallStaticFloatMethodA,
2636 JNI::CallStaticDoubleMethod,
2637 JNI::CallStaticDoubleMethodV,
2638 JNI::CallStaticDoubleMethodA,
2639 JNI::CallStaticVoidMethod,
2640 JNI::CallStaticVoidMethodV,
2641 JNI::CallStaticVoidMethodA,
2642 JNI::GetStaticFieldID,
2643 JNI::GetStaticObjectField,
2644 JNI::GetStaticBooleanField,
2645 JNI::GetStaticByteField,
2646 JNI::GetStaticCharField,
2647 JNI::GetStaticShortField,
2648 JNI::GetStaticIntField,
2649 JNI::GetStaticLongField,
2650 JNI::GetStaticFloatField,
2651 JNI::GetStaticDoubleField,
2652 JNI::SetStaticObjectField,
2653 JNI::SetStaticBooleanField,
2654 JNI::SetStaticByteField,
2655 JNI::SetStaticCharField,
2656 JNI::SetStaticShortField,
2657 JNI::SetStaticIntField,
2658 JNI::SetStaticLongField,
2659 JNI::SetStaticFloatField,
2660 JNI::SetStaticDoubleField,
2661 JNI::NewString,
2662 JNI::GetStringLength,
2663 JNI::GetStringChars,
2664 JNI::ReleaseStringChars,
2665 JNI::NewStringUTF,
2666 JNI::GetStringUTFLength,
2667 JNI::GetStringUTFChars,
2668 JNI::ReleaseStringUTFChars,
2669 JNI::GetArrayLength,
2670 JNI::NewObjectArray,
2671 JNI::GetObjectArrayElement,
2672 JNI::SetObjectArrayElement,
2673 JNI::NewBooleanArray,
2674 JNI::NewByteArray,
2675 JNI::NewCharArray,
2676 JNI::NewShortArray,
2677 JNI::NewIntArray,
2678 JNI::NewLongArray,
2679 JNI::NewFloatArray,
2680 JNI::NewDoubleArray,
2681 JNI::GetBooleanArrayElements,
2682 JNI::GetByteArrayElements,
2683 JNI::GetCharArrayElements,
2684 JNI::GetShortArrayElements,
2685 JNI::GetIntArrayElements,
2686 JNI::GetLongArrayElements,
2687 JNI::GetFloatArrayElements,
2688 JNI::GetDoubleArrayElements,
2689 JNI::ReleaseBooleanArrayElements,
2690 JNI::ReleaseByteArrayElements,
2691 JNI::ReleaseCharArrayElements,
2692 JNI::ReleaseShortArrayElements,
2693 JNI::ReleaseIntArrayElements,
2694 JNI::ReleaseLongArrayElements,
2695 JNI::ReleaseFloatArrayElements,
2696 JNI::ReleaseDoubleArrayElements,
2697 JNI::GetBooleanArrayRegion,
2698 JNI::GetByteArrayRegion,
2699 JNI::GetCharArrayRegion,
2700 JNI::GetShortArrayRegion,
2701 JNI::GetIntArrayRegion,
2702 JNI::GetLongArrayRegion,
2703 JNI::GetFloatArrayRegion,
2704 JNI::GetDoubleArrayRegion,
2705 JNI::SetBooleanArrayRegion,
2706 JNI::SetByteArrayRegion,
2707 JNI::SetCharArrayRegion,
2708 JNI::SetShortArrayRegion,
2709 JNI::SetIntArrayRegion,
2710 JNI::SetLongArrayRegion,
2711 JNI::SetFloatArrayRegion,
2712 JNI::SetDoubleArrayRegion,
2713 JNI::RegisterNatives,
2714 JNI::UnregisterNatives,
2715 JNI::MonitorEnter,
2716 JNI::MonitorExit,
2717 JNI::GetJavaVM,
2718 JNI::GetStringRegion,
2719 JNI::GetStringUTFRegion,
2720 JNI::GetPrimitiveArrayCritical,
2721 JNI::ReleasePrimitiveArrayCritical,
2722 JNI::GetStringCritical,
2723 JNI::ReleaseStringCritical,
2724 JNI::NewWeakGlobalRef,
2725 JNI::DeleteWeakGlobalRef,
2726 JNI::ExceptionCheck,
2727 JNI::NewDirectByteBuffer,
2728 JNI::GetDirectBufferAddress,
2729 JNI::GetDirectBufferCapacity,
2730 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002731};
2732
Ian Rogers68d8b422014-07-17 11:09:10 -07002733const JNINativeInterface* GetJniNativeInterface() {
2734 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002735}
2736
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002737void (*gJniSleepForeverStub[])() = {
2738 nullptr, // reserved0.
2739 nullptr, // reserved1.
2740 nullptr, // reserved2.
2741 nullptr, // reserved3.
2742 SleepForever,
2743 SleepForever,
2744 SleepForever,
2745 SleepForever,
2746 SleepForever,
2747 SleepForever,
2748 SleepForever,
2749 SleepForever,
2750 SleepForever,
2751 SleepForever,
2752 SleepForever,
2753 SleepForever,
2754 SleepForever,
2755 SleepForever,
2756 SleepForever,
2757 SleepForever,
2758 SleepForever,
2759 SleepForever,
2760 SleepForever,
2761 SleepForever,
2762 SleepForever,
2763 SleepForever,
2764 SleepForever,
2765 SleepForever,
2766 SleepForever,
2767 SleepForever,
2768 SleepForever,
2769 SleepForever,
2770 SleepForever,
2771 SleepForever,
2772 SleepForever,
2773 SleepForever,
2774 SleepForever,
2775 SleepForever,
2776 SleepForever,
2777 SleepForever,
2778 SleepForever,
2779 SleepForever,
2780 SleepForever,
2781 SleepForever,
2782 SleepForever,
2783 SleepForever,
2784 SleepForever,
2785 SleepForever,
2786 SleepForever,
2787 SleepForever,
2788 SleepForever,
2789 SleepForever,
2790 SleepForever,
2791 SleepForever,
2792 SleepForever,
2793 SleepForever,
2794 SleepForever,
2795 SleepForever,
2796 SleepForever,
2797 SleepForever,
2798 SleepForever,
2799 SleepForever,
2800 SleepForever,
2801 SleepForever,
2802 SleepForever,
2803 SleepForever,
2804 SleepForever,
2805 SleepForever,
2806 SleepForever,
2807 SleepForever,
2808 SleepForever,
2809 SleepForever,
2810 SleepForever,
2811 SleepForever,
2812 SleepForever,
2813 SleepForever,
2814 SleepForever,
2815 SleepForever,
2816 SleepForever,
2817 SleepForever,
2818 SleepForever,
2819 SleepForever,
2820 SleepForever,
2821 SleepForever,
2822 SleepForever,
2823 SleepForever,
2824 SleepForever,
2825 SleepForever,
2826 SleepForever,
2827 SleepForever,
2828 SleepForever,
2829 SleepForever,
2830 SleepForever,
2831 SleepForever,
2832 SleepForever,
2833 SleepForever,
2834 SleepForever,
2835 SleepForever,
2836 SleepForever,
2837 SleepForever,
2838 SleepForever,
2839 SleepForever,
2840 SleepForever,
2841 SleepForever,
2842 SleepForever,
2843 SleepForever,
2844 SleepForever,
2845 SleepForever,
2846 SleepForever,
2847 SleepForever,
2848 SleepForever,
2849 SleepForever,
2850 SleepForever,
2851 SleepForever,
2852 SleepForever,
2853 SleepForever,
2854 SleepForever,
2855 SleepForever,
2856 SleepForever,
2857 SleepForever,
2858 SleepForever,
2859 SleepForever,
2860 SleepForever,
2861 SleepForever,
2862 SleepForever,
2863 SleepForever,
2864 SleepForever,
2865 SleepForever,
2866 SleepForever,
2867 SleepForever,
2868 SleepForever,
2869 SleepForever,
2870 SleepForever,
2871 SleepForever,
2872 SleepForever,
2873 SleepForever,
2874 SleepForever,
2875 SleepForever,
2876 SleepForever,
2877 SleepForever,
2878 SleepForever,
2879 SleepForever,
2880 SleepForever,
2881 SleepForever,
2882 SleepForever,
2883 SleepForever,
2884 SleepForever,
2885 SleepForever,
2886 SleepForever,
2887 SleepForever,
2888 SleepForever,
2889 SleepForever,
2890 SleepForever,
2891 SleepForever,
2892 SleepForever,
2893 SleepForever,
2894 SleepForever,
2895 SleepForever,
2896 SleepForever,
2897 SleepForever,
2898 SleepForever,
2899 SleepForever,
2900 SleepForever,
2901 SleepForever,
2902 SleepForever,
2903 SleepForever,
2904 SleepForever,
2905 SleepForever,
2906 SleepForever,
2907 SleepForever,
2908 SleepForever,
2909 SleepForever,
2910 SleepForever,
2911 SleepForever,
2912 SleepForever,
2913 SleepForever,
2914 SleepForever,
2915 SleepForever,
2916 SleepForever,
2917 SleepForever,
2918 SleepForever,
2919 SleepForever,
2920 SleepForever,
2921 SleepForever,
2922 SleepForever,
2923 SleepForever,
2924 SleepForever,
2925 SleepForever,
2926 SleepForever,
2927 SleepForever,
2928 SleepForever,
2929 SleepForever,
2930 SleepForever,
2931 SleepForever,
2932 SleepForever,
2933 SleepForever,
2934 SleepForever,
2935 SleepForever,
2936 SleepForever,
2937 SleepForever,
2938 SleepForever,
2939 SleepForever,
2940 SleepForever,
2941 SleepForever,
2942 SleepForever,
2943 SleepForever,
2944 SleepForever,
2945 SleepForever,
2946 SleepForever,
2947 SleepForever,
2948 SleepForever,
2949 SleepForever,
2950 SleepForever,
2951 SleepForever,
2952 SleepForever,
2953 SleepForever,
2954 SleepForever,
2955 SleepForever,
2956 SleepForever,
2957 SleepForever,
2958 SleepForever,
2959 SleepForever,
2960 SleepForever,
2961 SleepForever,
2962 SleepForever,
2963 SleepForever,
2964 SleepForever,
2965 SleepForever,
2966 SleepForever,
2967 SleepForever,
2968 SleepForever,
2969 SleepForever,
2970 SleepForever,
2971};
2972
2973const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
2974 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
2975}
2976
Elliott Hughesc8fece32013-01-02 11:27:23 -08002977void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07002978 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002979 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002980 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002981 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2982 }
2983 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2984}
2985
Ian Rogersdf20fe02011-07-20 20:34:16 -07002986} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07002987
2988std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2989 switch (rhs) {
2990 case JNIInvalidRefType:
2991 os << "JNIInvalidRefType";
2992 return os;
2993 case JNILocalRefType:
2994 os << "JNILocalRefType";
2995 return os;
2996 case JNIGlobalRefType:
2997 os << "JNIGlobalRefType";
2998 return os;
2999 case JNIWeakGlobalRefType:
3000 os << "JNIWeakGlobalRefType";
3001 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003002 default:
Ian Rogersc7dd2952014-10-21 23:31:19 -07003003 LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3004 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003005 }
3006}