blob: e1a4e2a7b69a247c56f830ca873eb3543a1db9c6 [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"
Andreas Gampe542451c2016-07-26 09:02:02 -070030#include "base/enums.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080032#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080033#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080034#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070035#include "dex_file-inl.h"
Mathieu Chartierd0004802014-10-15 16:59:47 -070036#include "fault_handler.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070037#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070038#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070039#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070040#include "interpreter/interpreter.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070041#include "jni_env_ext.h"
42#include "java_vm_ext.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043#include "mirror/class-inl.h"
44#include "mirror/class_loader.h"
Hiroshi Yamauchi02d2f292015-04-03 13:35:16 -070045#include "mirror/field-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070046#include "mirror/method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047#include "mirror/object-inl.h"
48#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070049#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050#include "mirror/throwable.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080051#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070052#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070053#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070054#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070055#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070056#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070057#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070059#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070060
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070061namespace art {
62
Mathieu Chartier24555ad2014-10-06 13:41:33 -070063// Consider turning this on when there is errors which could be related to JNI array copies such as
64// things not rendering correctly. E.g. b/16858794
65static constexpr bool kWarnJniAbort = false;
66
Elliott Hughes6b436852011-08-12 10:16:44 -070067// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
68// separated with slashes but aren't wrapped with "L;" like regular descriptors
69// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
70// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
71// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -070072static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070073 std::string result;
74 // Add the missing "L;" if necessary.
75 if (name[0] == '[') {
76 result = name;
77 } else {
78 result += 'L';
79 result += name;
80 result += ';';
81 }
82 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070083 if (result.find('.') != std::string::npos) {
84 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
85 << "\"" << name << "\"";
86 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -070087 }
88 return result;
89}
90
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080091static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070092 const char* name, const char* sig, const char* kind)
Mathieu Chartier90443472015-07-16 20:32:27 -070093 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -070094 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000095 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Ian Rogers62d6c772013-02-27 08:32:07 -080096 "no %s method \"%s.%s%s\"",
Ian Rogers1ff3c982014-08-12 02:30:58 -070097 kind, c->GetDescriptor(&temp), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -070098}
99
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200100static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
101 const char* kind, jint idx, bool return_errors)
Mathieu Chartier90443472015-07-16 20:32:27 -0700102 SHARED_REQUIRES(Locks::mutator_lock_) {
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200103 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
104 << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
105 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000106 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200107 "%s is null at index %d", kind, idx);
108}
109
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800110static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
Mathieu Chartier90443472015-07-16 20:32:27 -0700111 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800112 if (LIKELY(klass->IsInitialized())) {
113 return klass;
114 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700115 StackHandleScope<1> hs(self);
116 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700117 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800118 return nullptr;
119 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700120 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800121}
122
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700123static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
124 const char* name, const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700125 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800126 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800127 if (c == nullptr) {
128 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700129 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700130 ArtMethod* method = nullptr;
131 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700132 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700133 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700134 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700135 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700136 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700137 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800138 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700139 // No virtual method matching the signature. Search declared
140 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700141 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700142 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700143 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800144 if (method == nullptr || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700145 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800146 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700147 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700148 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700149}
150
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800151static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Mathieu Chartier90443472015-07-16 20:32:27 -0700152 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700153 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700154 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
155 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700156 return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700157 }
Brian Carlstromce888532013-10-10 00:32:58 -0700158 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800159 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700160 return method->GetDeclaringClass()->GetClassLoader();
161 }
162 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800163 mirror::ClassLoader* class_loader =
164 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
165 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700166 return class_loader;
167 }
168 // See if the override ClassLoader is set for gtests.
Ian Rogers68d8b422014-07-17 11:09:10 -0700169 class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800170 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700171 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
172 // image.
173 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700174 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700175 return class_loader;
176 }
177 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800178 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700179}
180
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700181static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
182 const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700183 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700184 StackHandleScope<2> hs(soa.Self());
185 Handle<mirror::Class> c(
186 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
187 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800188 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700189 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700190 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800191 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700192 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
193 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700194 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800195 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700196 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700197 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700198 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800199 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700200 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700201 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800202 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000203 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700204 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700205 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000206 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800207 "no type \"%s\" found and so no field \"%s\" "
208 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700209 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000210 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800211 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700212 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700213 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700214 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700215 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700216 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700217 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700218 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700219 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800220 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000221 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800222 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700223 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800224 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700225 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700226 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700227}
228
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800229static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 jsize length, const char* identifier)
Mathieu Chartier90443472015-07-16 20:32:27 -0700231 SHARED_REQUIRES(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700232 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000233 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800234 "%s offset=%d length=%d %s.length=%d",
235 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700236}
Ian Rogers0571d352011-11-03 19:51:38 -0700237
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700238static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
239 jsize array_length)
Mathieu Chartier90443472015-07-16 20:32:27 -0700240 SHARED_REQUIRES(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000241 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800242 "offset=%d length=%d string.length()=%d", start, length,
243 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700244}
Elliott Hughes814e4032011-08-23 12:07:56 -0700245
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700246int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700247 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700248 // Turn the const char* into a java.lang.String.
249 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800250 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700251 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700252 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700253
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700254 // Choose an appropriate constructor and set up the arguments.
255 jvalue args[2];
256 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800257 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700258 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800259 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700260 signature = "(Ljava/lang/String;)V";
261 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800262 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700263 signature = "(Ljava/lang/Throwable;)V";
264 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700265 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
267 args[0].l = s.get();
268 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700269 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700270 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800271 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800272 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700273 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800274 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700275 return JNI_ERR;
276 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700277
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800278 ScopedLocalRef<jthrowable> exception(
279 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
280 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 return JNI_ERR;
282 }
Ian Rogersef28b142012-11-30 14:22:18 -0800283 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000284 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700285 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700286}
287
Ian Rogers68d8b422014-07-17 11:09:10 -0700288static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
289 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700290}
291
Ian Rogers2d10b202014-05-12 19:15:18 -0700292#define CHECK_NON_NULL_ARGUMENT(value) \
293 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700294
Ian Rogers2d10b202014-05-12 19:15:18 -0700295#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
296 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
297
298#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
299 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
300
301#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
302 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
303
304#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700305 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700306 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700307 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700308 }
309
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700310#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700311 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700312 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700313 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700314 }
315
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700316template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700317static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Mathieu Chartier90443472015-07-16 20:32:27 -0700318 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700319 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800320 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700321 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
322 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700323 }
324 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700325 return nullptr;
326}
327
Elliott Hughescdf53122011-08-19 15:46:09 -0700328class JNI {
329 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700330 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700331 return JNI_VERSION_1_6;
332 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700333
Ian Rogers25e8b912012-09-07 11:31:36 -0700334 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700335 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800336 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700337 }
338
Elliott Hughescdf53122011-08-19 15:46:09 -0700339 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700340 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700341 Runtime* runtime = Runtime::Current();
342 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700343 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700344 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800345 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700346 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700347 StackHandleScope<1> hs(soa.Self());
348 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800349 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700350 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800351 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700352 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700353 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700354 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700355
Ian Rogers62f05122014-03-21 11:21:29 -0700356 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700357 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700358 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700359 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700360 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700361
Ian Rogers62f05122014-03-21 11:21:29 -0700362 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700363 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700364 ScopedObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700365 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
366 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700367 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700368 return nullptr;
369 }
370 auto* field = static_cast<mirror::Field*>(obj_field);
371 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700372 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700373
Elliott Hughescdf53122011-08-19 15:46:09 -0700374 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700375 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700376 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700377 ArtMethod* m = soa.DecodeMethod(mid);
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700378 mirror::AbstractMethod* method;
Andreas Gampe542451c2016-07-26 09:02:02 -0700379 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
Andreas Gampee01e3642016-07-25 13:06:04 -0700380 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200381 if (m->IsConstructor()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700382 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200383 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700384 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200385 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700386 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700387 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700388
Elliott Hughescdf53122011-08-19 15:46:09 -0700389 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700390 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700391 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700392 ArtField* f = soa.DecodeField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700393 return soa.AddLocalReference<jobject>(
Andreas Gampe542451c2016-07-26 09:02:02 -0700394 mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700395 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700396
Elliott Hughes37f7a402011-08-22 18:56:01 -0700397 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700398 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700399 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800400 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700401 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700402 }
403
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700404 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700405 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700406 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800407 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700408 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700409 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700410
Narayan Kamath1268b742014-07-11 19:15:11 +0100411 // Note: java_class1 should be safely castable to java_class2, and
412 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700413 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700414 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
415 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700416 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800417 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
418 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100419 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700420 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700421
Elliott Hughese84278b2012-03-22 10:06:53 -0700422 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700423 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800424 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700425 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700426 return JNI_TRUE;
427 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700428 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800429 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
430 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700431 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700432 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700433 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700434
Elliott Hughes37f7a402011-08-22 18:56:01 -0700435 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700436 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800437 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
438 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700439 return JNI_ERR;
440 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000441 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700442 return JNI_OK;
443 }
444
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700445 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700446 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800447 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700448 }
449
450 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700451 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700452 }
453
454 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700455 ScopedObjectAccess soa(env);
456 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700457 }
458
459 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700460 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700461
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700462 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000463 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700464 return;
465 }
466
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000467 StackHandleScope<1> hs(soa.Self());
468 Handle<mirror::Throwable> old_exception(
469 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
470 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800471 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700472 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700473 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
474 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800475 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700476 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700477 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700478 } else {
479 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800480 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000481 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700482 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800483 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700484 }
485 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000486 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700487 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700488
Elliott Hughescdf53122011-08-19 15:46:09 -0700489 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700490 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000491 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700492 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700493 }
494
Ian Rogers25e8b912012-09-07 11:31:36 -0700495 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700496 LOG(FATAL) << "JNI FatalError called: " << msg;
497 }
498
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700499 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700500 // TODO: SOA may not be necessary but I do it to please lock annotations.
501 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700502 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700503 return JNI_ERR;
504 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700505 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700506 return JNI_OK;
507 }
508
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700509 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700510 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800511 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700512 soa.Env()->PopFrame();
513 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700514 }
515
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700516 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700517 // TODO: SOA may not be necessary but I do it to please lock annotations.
518 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700519 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700520 }
521
Elliott Hughescdf53122011-08-19 15:46:09 -0700522 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700523 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800524 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Ian Rogers68d8b422014-07-17 11:09:10 -0700525 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700526 }
527
528 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700529 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
530 Thread* self = down_cast<JNIEnvExt*>(env)->self;
531 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700532 }
533
534 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700535 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700536 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
537 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700538 }
539
540 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700541 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
542 Thread* self = down_cast<JNIEnvExt*>(env)->self;
543 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700544 }
545
546 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700547 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800548 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800549 // Check for null after decoding the object to handle cleared weak globals.
550 if (decoded_obj == nullptr) {
551 return nullptr;
552 }
553 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700554 }
555
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700556 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800557 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700558 return;
559 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700560 // SOA is only necessary to have exclusion between GC root marking and removing.
561 // We don't want to have the GC attempt to mark a null root if we just removed
562 // it. b/22119403
563 ScopedObjectAccess soa(env);
564 auto* ext_env = down_cast<JNIEnvExt*>(env);
565 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700566 // Attempting to delete a local reference that is not in the
567 // topmost local reference frame is a no-op. DeleteLocalRef returns
568 // void and doesn't throw any exceptions, but we should probably
569 // complain about it so the user will notice that things aren't
570 // going quite the way they expect.
571 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
572 << "failed to find entry";
573 }
574 }
575
576 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700577 if (obj1 == obj2) {
578 return JNI_TRUE;
579 } else {
580 ScopedObjectAccess soa(env);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800581 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
582 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700583 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700584 }
585
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700586 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700587 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700588 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800589 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800590 if (c == nullptr) {
591 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700592 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800593 if (c->IsStringClass()) {
594 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
595 mirror::SetStringCountVisitor visitor(0);
596 return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
597 allocator_type, visitor));
598 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700599 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700600 }
601
Ian Rogersbc939662013-08-15 10:26:54 -0700602 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700603 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700604 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700605 CHECK_NON_NULL_ARGUMENT(java_class);
606 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700607 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700608 va_end(args);
609 return result;
610 }
611
Elliott Hughes72025e52011-08-23 17:50:30 -0700612 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700613 CHECK_NON_NULL_ARGUMENT(java_class);
614 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700615 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800616 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800617 if (c == nullptr) {
618 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700619 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800620 if (c->IsStringClass()) {
621 // Replace calls to String.<init> with equivalent StringFactory call.
622 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
623 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
624 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800625 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800626 if (result == nullptr) {
627 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700628 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700629 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700630 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800631 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800632 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700633 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800634 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700635 }
636
Elliott Hughes72025e52011-08-23 17:50:30 -0700637 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700638 CHECK_NON_NULL_ARGUMENT(java_class);
639 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700640 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800641 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800642 if (c == nullptr) {
643 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700644 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800645 if (c->IsStringClass()) {
646 // Replace calls to String.<init> with equivalent StringFactory call.
647 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
648 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
649 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800650 mirror::Object* result = c->AllocObject(soa.Self());
651 if (result == nullptr) {
652 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700653 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700654 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700655 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800656 if (soa.Self()->IsExceptionPending()) {
657 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700658 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800659 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700660 }
661
Ian Rogersbc939662013-08-15 10:26:54 -0700662 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700663 CHECK_NON_NULL_ARGUMENT(java_class);
664 CHECK_NON_NULL_ARGUMENT(name);
665 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700666 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700667 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700668 }
669
Ian Rogersbc939662013-08-15 10:26:54 -0700670 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
671 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700672 CHECK_NON_NULL_ARGUMENT(java_class);
673 CHECK_NON_NULL_ARGUMENT(name);
674 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700675 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700676 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700677 }
678
Elliott Hughes72025e52011-08-23 17:50:30 -0700679 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700680 va_list ap;
681 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700682 CHECK_NON_NULL_ARGUMENT(obj);
683 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700684 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700685 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700686 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700687 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700688 }
689
Elliott Hughes72025e52011-08-23 17:50:30 -0700690 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700691 CHECK_NON_NULL_ARGUMENT(obj);
692 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700693 ScopedObjectAccess soa(env);
694 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
695 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700696 }
697
Elliott Hughes72025e52011-08-23 17:50:30 -0700698 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700699 CHECK_NON_NULL_ARGUMENT(obj);
700 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700701 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700702 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700703 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700704 }
705
Elliott Hughes72025e52011-08-23 17:50:30 -0700706 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700707 va_list ap;
708 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700709 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
710 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700711 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700712 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700713 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700714 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700715 }
716
Elliott Hughes72025e52011-08-23 17:50:30 -0700717 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700718 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
719 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700720 ScopedObjectAccess soa(env);
721 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700722 }
723
Elliott Hughes72025e52011-08-23 17:50:30 -0700724 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700725 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
726 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700727 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700728 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700729 }
730
Elliott Hughes72025e52011-08-23 17:50:30 -0700731 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700732 va_list ap;
733 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
735 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700736 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700737 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700738 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700739 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700740 }
741
Elliott Hughes72025e52011-08-23 17:50:30 -0700742 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700743 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
744 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700745 ScopedObjectAccess soa(env);
746 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700747 }
748
Elliott Hughes72025e52011-08-23 17:50:30 -0700749 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700750 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
751 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700752 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700753 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700754 }
755
Elliott Hughes72025e52011-08-23 17:50:30 -0700756 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700757 va_list ap;
758 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
760 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700761 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700762 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700763 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700764 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700765 }
766
Elliott Hughes72025e52011-08-23 17:50:30 -0700767 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700768 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
769 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700770 ScopedObjectAccess soa(env);
771 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700772 }
773
Elliott Hughes72025e52011-08-23 17:50:30 -0700774 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700775 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
776 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700777 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700778 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700779 }
780
Elliott Hughes72025e52011-08-23 17:50:30 -0700781 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700782 va_list ap;
783 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
785 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700786 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700787 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700788 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700789 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700790 }
791
Elliott Hughes72025e52011-08-23 17:50:30 -0700792 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700793 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
794 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700795 ScopedObjectAccess soa(env);
796 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700797 }
798
Elliott Hughes72025e52011-08-23 17:50:30 -0700799 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700800 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
801 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700802 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700803 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700804 }
805
Elliott Hughes72025e52011-08-23 17:50:30 -0700806 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700807 va_list ap;
808 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700809 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
810 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700811 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700812 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700813 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700814 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700815 }
816
Elliott Hughes72025e52011-08-23 17:50:30 -0700817 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700818 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
819 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700820 ScopedObjectAccess soa(env);
821 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700822 }
823
Elliott Hughes72025e52011-08-23 17:50:30 -0700824 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
826 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700827 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700828 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700829 }
830
Elliott Hughes72025e52011-08-23 17:50:30 -0700831 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700832 va_list ap;
833 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
835 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700836 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700837 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700838 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700839 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700840 }
841
Elliott Hughes72025e52011-08-23 17:50:30 -0700842 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700843 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
844 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700845 ScopedObjectAccess soa(env);
846 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700847 }
848
Elliott Hughes72025e52011-08-23 17:50:30 -0700849 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700850 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
851 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700852 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700853 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700854 }
855
Elliott Hughes72025e52011-08-23 17:50:30 -0700856 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700857 va_list ap;
858 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700859 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
860 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700861 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700862 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700863 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700864 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700865 }
866
Elliott Hughes72025e52011-08-23 17:50:30 -0700867 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700868 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
869 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700870 ScopedObjectAccess soa(env);
871 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700872 }
873
Elliott Hughes72025e52011-08-23 17:50:30 -0700874 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700875 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
876 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700877 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700878 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700879 }
880
Elliott Hughes72025e52011-08-23 17:50:30 -0700881 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700882 va_list ap;
883 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700884 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
885 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700886 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700887 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700888 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700889 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700890 }
891
Elliott Hughes72025e52011-08-23 17:50:30 -0700892 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700893 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
894 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700895 ScopedObjectAccess soa(env);
896 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700897 }
898
Elliott Hughes72025e52011-08-23 17:50:30 -0700899 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700900 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
901 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700902 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700903 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700904 }
905
Elliott Hughes72025e52011-08-23 17:50:30 -0700906 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700907 va_list ap;
908 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700909 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
910 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700911 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700912 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700913 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700914 }
915
Elliott Hughes72025e52011-08-23 17:50:30 -0700916 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700917 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
918 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700919 ScopedObjectAccess soa(env);
920 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700921 }
922
Elliott Hughes72025e52011-08-23 17:50:30 -0700923 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700924 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
925 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700926 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700927 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700928 }
929
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700930 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700931 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700932 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700933 CHECK_NON_NULL_ARGUMENT(obj);
934 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700935 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700936 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
937 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700938 va_end(ap);
939 return local_result;
940 }
941
Ian Rogersbc939662013-08-15 10:26:54 -0700942 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
943 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700944 CHECK_NON_NULL_ARGUMENT(obj);
945 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700946 ScopedObjectAccess soa(env);
947 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
948 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700949 }
950
Ian Rogersbc939662013-08-15 10:26:54 -0700951 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
952 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700953 CHECK_NON_NULL_ARGUMENT(obj);
954 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700955 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700956 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700957 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700958 }
959
Ian Rogersbc939662013-08-15 10:26:54 -0700960 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
961 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700962 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700963 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700964 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
965 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700966 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700967 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700968 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700969 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700970 }
971
Ian Rogersbc939662013-08-15 10:26:54 -0700972 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
973 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700974 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
975 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700976 ScopedObjectAccess soa(env);
977 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700978 }
979
Ian Rogersbc939662013-08-15 10:26:54 -0700980 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
981 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700982 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
983 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700984 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700985 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700986 }
987
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700988 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700989 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700990 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700991 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
992 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700993 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700994 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700995 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700996 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700997 }
998
Ian Rogersbc939662013-08-15 10:26:54 -0700999 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1000 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001001 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1002 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001003 ScopedObjectAccess soa(env);
1004 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001005 }
1006
Ian Rogersbc939662013-08-15 10:26:54 -07001007 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1008 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001009 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1010 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001011 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001012 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001013 }
1014
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001015 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001016 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001017 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001018 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1019 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001020 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001021 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001022 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001023 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001024 }
1025
Ian Rogersbc939662013-08-15 10:26:54 -07001026 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1027 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001028 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1029 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001030 ScopedObjectAccess soa(env);
1031 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001032 }
1033
Ian Rogersbc939662013-08-15 10:26:54 -07001034 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1035 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001036 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1037 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001038 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001039 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001040 }
1041
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001042 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001043 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001044 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001045 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1046 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001047 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001048 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001049 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001050 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001051 }
1052
Ian Rogersbc939662013-08-15 10:26:54 -07001053 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1054 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001055 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1056 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001057 ScopedObjectAccess soa(env);
1058 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001059 }
1060
Ian Rogersbc939662013-08-15 10:26:54 -07001061 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1062 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001063 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1064 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001065 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001066 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001067 }
1068
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001069 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001070 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001071 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001072 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1073 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001074 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001075 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001076 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001077 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001078 }
1079
Ian Rogersbc939662013-08-15 10:26:54 -07001080 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1081 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001082 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1083 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001084 ScopedObjectAccess soa(env);
1085 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001086 }
1087
Ian Rogersbc939662013-08-15 10:26:54 -07001088 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1089 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001090 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001092 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001093 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001094 }
1095
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001096 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001097 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001098 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001099 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1100 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001101 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001102 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001103 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001104 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001105 }
1106
Ian Rogersbc939662013-08-15 10:26:54 -07001107 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1108 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001109 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1110 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001111 ScopedObjectAccess soa(env);
1112 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001113 }
1114
Ian Rogersbc939662013-08-15 10:26:54 -07001115 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1116 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001117 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1118 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001119 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001120 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001121 }
1122
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001123 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001124 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001125 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001126 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1127 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001128 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001129 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001130 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001131 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001132 }
1133
Ian Rogersbc939662013-08-15 10:26:54 -07001134 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1135 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001136 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1137 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001138 ScopedObjectAccess soa(env);
1139 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001140 }
1141
Ian Rogersbc939662013-08-15 10:26:54 -07001142 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1143 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001144 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1145 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001146 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001147 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001148 }
1149
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001150 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001151 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001152 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001153 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1154 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001155 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001156 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001157 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001158 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001159 }
1160
Ian Rogersbc939662013-08-15 10:26:54 -07001161 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1162 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001163 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1164 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001165 ScopedObjectAccess soa(env);
1166 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001167 }
1168
Ian Rogersbc939662013-08-15 10:26:54 -07001169 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1170 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001171 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1172 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001173 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001174 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001175 }
1176
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001177 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001178 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001179 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001180 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1181 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001182 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001183 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001184 va_end(ap);
1185 }
1186
Brian Carlstromea46f952013-07-30 01:26:50 -07001187 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1188 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001189 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1190 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001191 ScopedObjectAccess soa(env);
1192 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001193 }
1194
Ian Rogersbc939662013-08-15 10:26:54 -07001195 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1196 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001197 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1198 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001199 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001200 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001201 }
1202
Ian Rogersbc939662013-08-15 10:26:54 -07001203 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001204 CHECK_NON_NULL_ARGUMENT(java_class);
1205 CHECK_NON_NULL_ARGUMENT(name);
1206 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001207 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001208 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001209 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001210
Ian Rogersbc939662013-08-15 10:26:54 -07001211 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1212 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001213 CHECK_NON_NULL_ARGUMENT(java_class);
1214 CHECK_NON_NULL_ARGUMENT(name);
1215 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001216 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001217 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001218 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001219
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001220 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001221 CHECK_NON_NULL_ARGUMENT(obj);
1222 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001223 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001224 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001225 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001226 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001227 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001228
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001229 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001230 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001231 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001232 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001233 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001234 }
1235
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001236 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001237 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1238 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001239 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001240 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1241 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001242 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001243 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001244 }
1245
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001246 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001247 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001248 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001249 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001250 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001251 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001252 }
1253
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001254#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001255 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1256 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001257 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001258 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001259 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001260 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001261
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001262#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001263 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001264 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001265 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001266 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001267
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001268#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001269 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1270 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001271 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001272 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001273 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001274 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001275
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001276#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001277 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001278 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001279 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001280 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001281
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001282 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001283 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001284 }
1285
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001286 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001287 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001288 }
1289
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001290 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001291 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001292 }
1293
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001294 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001295 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001296 }
1297
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001298 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001299 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001300 }
1301
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001302 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001303 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001304 }
1305
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001306 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001307 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001308 }
1309
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001310 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001311 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001312 }
1313
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001314 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001315 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001316 }
1317
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001318 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001319 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001320 }
1321
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001322 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001323 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001324 }
1325
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001326 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001327 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001328 }
1329
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001330 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001331 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001332 }
1333
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001334 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001335 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001336 }
1337
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001338 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001339 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001340 }
1341
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001342 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001343 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001344 }
1345
1346 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001347 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001348 }
1349
1350 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001351 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001352 }
1353
1354 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001355 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001356 }
1357
1358 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001359 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001360 }
1361
1362 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001363 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001364 }
1365
1366 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001367 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001368 }
1369
1370 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001371 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001372 }
1373
1374 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001375 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001376 }
1377
1378 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001379 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001380 }
1381
1382 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001383 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001384 }
1385
1386 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001387 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001388 }
1389
1390 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001391 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001392 }
1393
1394 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001395 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001396 }
1397
1398 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001399 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001400 }
1401
1402 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001403 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001404 }
1405
1406 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001407 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001408 }
1409
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001410 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001411 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001412 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001413 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001414 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001415 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001416 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001417 va_end(ap);
1418 return local_result;
1419 }
1420
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001421 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001422 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001423 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001424 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001425 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 }
1427
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001428 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001429 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001430 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001431 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001432 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001433 }
1434
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001435 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001436 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001437 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001438 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001439 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001440 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001441 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001442 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001443 }
1444
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001445 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001446 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001447 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001448 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001449 }
1450
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001451 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001452 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001453 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001454 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001455 }
1456
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001457 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001458 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001459 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001460 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001461 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001462 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001463 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001464 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001465 }
1466
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001467 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001468 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001469 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001470 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001471 }
1472
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001473 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001474 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001475 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001476 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001477 }
1478
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001479 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001481 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001482 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001483 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001484 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001485 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001486 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001487 }
1488
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001489 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001490 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001491 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001492 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001493 }
1494
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001495 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001496 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001497 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001498 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001499 }
1500
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001501 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001502 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001503 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001504 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001505 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001506 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001507 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001508 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001509 }
1510
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001511 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001512 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001513 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001514 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001515 }
1516
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001517 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001518 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001519 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001520 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001521 }
1522
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001523 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001524 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001525 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001526 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001527 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001528 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001529 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001530 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001531 }
1532
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001533 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001534 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001535 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001536 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001537 }
1538
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001539 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001540 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001541 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001542 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001543 }
1544
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001545 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001546 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001547 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001548 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001549 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001550 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001551 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001552 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001553 }
1554
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001555 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001556 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001557 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001558 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001559 }
1560
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001561 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001562 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001563 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001564 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001565 }
1566
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001567 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001568 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001569 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001570 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001571 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001572 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001573 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001574 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001575 }
1576
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001577 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001578 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001579 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001580 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001581 }
1582
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001583 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001584 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001585 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001586 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001587 }
1588
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001589 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001590 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001591 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001592 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001593 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001594 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001595 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001596 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001597 }
1598
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001599 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001600 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001601 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001602 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001603 }
1604
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001605 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001606 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001607 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001608 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001609 }
1610
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001611 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001612 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001613 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001614 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001615 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001616 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001617 va_end(ap);
1618 }
1619
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001620 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001621 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001622 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001623 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001624 }
1625
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001626 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001627 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001628 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001629 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001630 }
1631
Elliott Hughes814e4032011-08-23 12:07:56 -07001632 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001633 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001634 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001635 return nullptr;
1636 }
1637 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001638 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001639 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001640 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001641 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001642 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001643 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001644 }
1645
1646 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001647 if (utf == nullptr) {
1648 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001649 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001650 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001651 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001652 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001653 }
1654
Elliott Hughes814e4032011-08-23 12:07:56 -07001655 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001656 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001657 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001658 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001659 }
1660
1661 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001662 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001663 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001664 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001665 }
1666
Ian Rogersbc939662013-08-15 10:26:54 -07001667 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1668 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001669 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001670 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001671 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001672 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001673 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001674 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001675 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Jeff Hao848f70a2014-01-15 13:49:50 -08001676 const jchar* chars = s->GetValue();
Elliott Hughesb465ab02011-08-24 11:21:21 -07001677 memcpy(buf, chars + start, length * sizeof(jchar));
1678 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001679 }
1680
Ian Rogersbc939662013-08-15 10:26:54 -07001681 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1682 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001683 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001684 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001685 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001686 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001687 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001688 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001689 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Jeff Hao848f70a2014-01-15 13:49:50 -08001690 const jchar* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001691 size_t bytes = CountUtf8Bytes(chars + start, length);
1692 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001693 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001694 }
1695
Elliott Hughes75770752011-08-24 17:52:38 -07001696 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001697 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001698 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001699 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001700 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001701 if (heap->IsMovableObject(s)) {
1702 jchar* chars = new jchar[s->GetLength()];
1703 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
Fred Shih56890e22014-06-02 11:11:52 -07001704 if (is_copy != nullptr) {
1705 *is_copy = JNI_TRUE;
1706 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001707 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001708 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001709 if (is_copy != nullptr) {
1710 *is_copy = JNI_FALSE;
1711 }
1712 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001713 }
1714
Mathieu Chartier590fee92013-09-13 13:46:47 -07001715 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001716 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001717 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001718 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001719 if (chars != s->GetValue()) {
Fred Shih56890e22014-06-02 11:11:52 -07001720 delete[] chars;
1721 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001722 }
1723
Elliott Hughes75770752011-08-24 17:52:38 -07001724 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001725 CHECK_NON_NULL_ARGUMENT(java_string);
1726 ScopedObjectAccess soa(env);
1727 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001728 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001729 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001730 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001731 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001732 if (!kUseReadBarrier) {
1733 heap->IncrementDisableMovingGC(soa.Self());
1734 } else {
1735 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1736 // to occur thanks to the to-space invariant.
1737 heap->IncrementDisableThreadFlip(soa.Self());
1738 }
Fred Shih56890e22014-06-02 11:11:52 -07001739 }
1740 if (is_copy != nullptr) {
1741 *is_copy = JNI_FALSE;
1742 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001743 return static_cast<jchar*>(s->GetValue());
Elliott Hughescdf53122011-08-19 15:46:09 -07001744 }
1745
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001746 static void ReleaseStringCritical(JNIEnv* env,
1747 jstring java_string,
1748 const jchar* chars ATTRIBUTE_UNUSED) {
Fred Shih56890e22014-06-02 11:11:52 -07001749 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1750 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001751 gc::Heap* heap = Runtime::Current()->GetHeap();
1752 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001753 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001754 if (!kUseReadBarrier) {
1755 heap->DecrementDisableMovingGC(soa.Self());
1756 } else {
1757 heap->DecrementDisableThreadFlip(soa.Self());
1758 }
Fred Shih56890e22014-06-02 11:11:52 -07001759 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001760 }
1761
Elliott Hughes75770752011-08-24 17:52:38 -07001762 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001763 if (java_string == nullptr) {
1764 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001765 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001766 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001767 *is_copy = JNI_TRUE;
1768 }
Ian Rogersef28b142012-11-30 14:22:18 -08001769 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001770 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001771 size_t byte_count = s->GetUtfLength();
1772 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001773 CHECK(bytes != nullptr); // bionic aborts anyway.
Jeff Hao848f70a2014-01-15 13:49:50 -08001774 const uint16_t* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001775 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
Elliott Hughes75770752011-08-24 17:52:38 -07001776 bytes[byte_count] = '\0';
1777 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001778 }
1779
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001780 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001781 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001782 }
1783
Elliott Hughesbd935992011-08-22 11:59:34 -07001784 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001785 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001786 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001787 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001788 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001789 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1790 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001791 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001792 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001793 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001794 }
1795
Elliott Hughes814e4032011-08-23 12:07:56 -07001796 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001797 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001798 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001799 mirror::ObjectArray<mirror::Object>* array =
1800 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001801 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001802 }
1803
Ian Rogersbc939662013-08-15 10:26:54 -07001804 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1805 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001806 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001807 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001808 mirror::ObjectArray<mirror::Object>* array =
1809 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1810 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001811 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001812 }
1813
1814 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001815 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001816 }
1817
1818 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001819 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001820 }
1821
1822 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001823 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001824 }
1825
1826 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001827 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001828 }
1829
1830 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001831 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001832 }
1833
1834 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001835 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001836 }
1837
1838 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001839 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001840 }
1841
Ian Rogers1d99e452014-01-02 17:36:41 -08001842 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1843 jobject initial_element) {
1844 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001845 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001846 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001847 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001848 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001849
1850 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001851 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001852 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001853 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001854 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001855 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001856 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1857 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001858 return nullptr;
1859 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001860 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001861 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001862 if (UNLIKELY(array_class == nullptr)) {
1863 return nullptr;
1864 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001865 }
1866
Elliott Hughes75770752011-08-24 17:52:38 -07001867 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001868 mirror::ObjectArray<mirror::Object>* result =
1869 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001870 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001871 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001872 if (initial_object != nullptr) {
1873 mirror::Class* element_class = result->GetClass()->GetComponentType();
1874 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001875 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1876 "element type of '%s'",
1877 PrettyDescriptor(initial_object->GetClass()).c_str(),
1878 PrettyDescriptor(element_class).c_str());
1879 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001880 } else {
1881 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001882 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001883 }
1884 }
Elliott Hughes75770752011-08-24 17:52:38 -07001885 }
1886 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001887 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001888 }
1889
1890 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001891 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001892 }
1893
Ian Rogersa15e67d2012-02-28 13:51:55 -08001894 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001895 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001896 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001897 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001898 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001899 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1900 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001901 return nullptr;
1902 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001903 gc::Heap* heap = Runtime::Current()->GetHeap();
1904 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001905 if (!kUseReadBarrier) {
1906 heap->IncrementDisableMovingGC(soa.Self());
1907 } else {
1908 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1909 // to occur thanks to the to-space invariant.
1910 heap->IncrementDisableThreadFlip(soa.Self());
1911 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001912 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001913 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001914 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001915 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001916 *is_copy = JNI_FALSE;
1917 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001918 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001919 }
1920
Ian Rogers2d10b202014-05-12 19:15:18 -07001921 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1922 jint mode) {
1923 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1924 ScopedObjectAccess soa(env);
1925 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1926 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001927 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1928 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001929 return;
1930 }
1931 const size_t component_size = array->GetClass()->GetComponentSize();
1932 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001933 }
1934
Elliott Hughes75770752011-08-24 17:52:38 -07001935 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001936 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001937 }
1938
Elliott Hughes75770752011-08-24 17:52:38 -07001939 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001940 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001941 }
1942
Elliott Hughes75770752011-08-24 17:52:38 -07001943 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001944 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001945 }
1946
Elliott Hughes75770752011-08-24 17:52:38 -07001947 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001948 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001949 }
1950
Elliott Hughes75770752011-08-24 17:52:38 -07001951 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001952 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001953 }
1954
Elliott Hughes75770752011-08-24 17:52:38 -07001955 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001956 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001957 }
1958
Elliott Hughes75770752011-08-24 17:52:38 -07001959 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001960 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001961 }
1962
Elliott Hughes75770752011-08-24 17:52:38 -07001963 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001964 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001965 }
1966
Mathieu Chartier590fee92013-09-13 13:46:47 -07001967 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1968 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001969 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
1970 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001971 }
1972
Mathieu Chartier590fee92013-09-13 13:46:47 -07001973 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001974 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001975 }
1976
Mathieu Chartier590fee92013-09-13 13:46:47 -07001977 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001978 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001979 }
1980
Mathieu Chartier590fee92013-09-13 13:46:47 -07001981 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1982 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001983 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001984 }
1985
Mathieu Chartier590fee92013-09-13 13:46:47 -07001986 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1987 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001988 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001989 }
1990
Mathieu Chartier590fee92013-09-13 13:46:47 -07001991 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001992 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001993 }
1994
Mathieu Chartier590fee92013-09-13 13:46:47 -07001995 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001996 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001997 }
1998
Mathieu Chartier590fee92013-09-13 13:46:47 -07001999 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2000 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002001 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002002 }
2003
Ian Rogersbc939662013-08-15 10:26:54 -07002004 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2005 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002006 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002007 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002008 }
2009
Ian Rogersbc939662013-08-15 10:26:54 -07002010 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2011 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002012 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002013 }
2014
Ian Rogersbc939662013-08-15 10:26:54 -07002015 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2016 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002017 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002018 }
2019
Ian Rogersbc939662013-08-15 10:26:54 -07002020 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2021 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002022 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002023 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002024 }
2025
Ian Rogersbc939662013-08-15 10:26:54 -07002026 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2027 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002028 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002029 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002030 }
2031
Ian Rogersbc939662013-08-15 10:26:54 -07002032 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2033 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002034 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002035 }
2036
Ian Rogersbc939662013-08-15 10:26:54 -07002037 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2038 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002039 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002040 }
2041
Ian Rogersbc939662013-08-15 10:26:54 -07002042 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2043 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002044 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002045 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002046 }
2047
Ian Rogersbc939662013-08-15 10:26:54 -07002048 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2049 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002050 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002051 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002052 }
2053
Ian Rogersbc939662013-08-15 10:26:54 -07002054 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2055 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002056 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002057 }
2058
Ian Rogersbc939662013-08-15 10:26:54 -07002059 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2060 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002061 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002062 }
2063
Ian Rogersbc939662013-08-15 10:26:54 -07002064 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2065 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002066 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002067 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002068 }
2069
Ian Rogersbc939662013-08-15 10:26:54 -07002070 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2071 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002072 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002073 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002074 }
2075
Ian Rogersbc939662013-08-15 10:26:54 -07002076 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2077 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002078 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002079 }
2080
Ian Rogersbc939662013-08-15 10:26:54 -07002081 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2082 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002083 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002084 }
2085
Ian Rogersbc939662013-08-15 10:26:54 -07002086 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2087 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002088 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002089 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002090 }
2091
Ian Rogersbc939662013-08-15 10:26:54 -07002092 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2093 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002094 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2095 }
2096
Ian Rogersbc939662013-08-15 10:26:54 -07002097 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2098 jint method_count, bool return_errors) {
2099 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002100 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2101 method_count);
2102 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002103 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002104 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002105 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002106 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002107 if (UNLIKELY(method_count == 0)) {
2108 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2109 << PrettyDescriptor(c);
2110 return JNI_OK;
2111 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002112 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002113 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002114 const char* name = methods[i].name;
2115 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002116 const void* fnPtr = methods[i].fnPtr;
2117 if (UNLIKELY(name == nullptr)) {
2118 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2119 return JNI_ERR;
2120 } else if (UNLIKELY(sig == nullptr)) {
2121 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2122 return JNI_ERR;
2123 } else if (UNLIKELY(fnPtr == nullptr)) {
2124 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2125 return JNI_ERR;
2126 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002127 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002128 // Notes about fast JNI calls:
2129 //
2130 // On a normal JNI call, the calling thread usually transitions
2131 // from the kRunnable state to the kNative state. But if the
2132 // called native function needs to access any Java object, it
2133 // will have to transition back to the kRunnable state.
2134 //
2135 // There is a cost to this double transition. For a JNI call
2136 // that should be quick, this cost may dominate the call cost.
2137 //
2138 // On a fast JNI call, the calling thread avoids this double
2139 // transition by not transitioning from kRunnable to kNative and
2140 // stays in the kRunnable state.
2141 //
2142 // There are risks to using a fast JNI call because it can delay
2143 // a response to a thread suspension request which is typically
2144 // used for a GC root scanning, etc. If a fast JNI call takes a
2145 // long time, it could cause longer thread suspension latency
2146 // and GC pauses.
2147 //
2148 // Thus, fast JNI should be used with care. It should be used
2149 // for a JNI call that takes a short amount of time (eg. no
2150 // long-running loop) and does not block (eg. no locks, I/O,
2151 // etc.)
2152 //
2153 // A '!' prefix in the signature in the JNINativeMethod
2154 // indicates that it's a fast JNI call and the runtime omits the
2155 // thread state transition from kRunnable to kNative at the
2156 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002157 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002158 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002159 ++sig;
2160 }
2161
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002162 // Note: the right order is to try to find the method locally
2163 // first, either as a direct or a virtual method. Then move to
2164 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002165 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002166 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2167 for (mirror::Class* current_class = c;
2168 current_class != nullptr;
2169 current_class = current_class->GetSuperClass()) {
2170 // Search first only comparing methods which are native.
2171 m = FindMethod<true>(current_class, name, sig);
2172 if (m != nullptr) {
2173 break;
2174 }
2175
2176 // Search again comparing to all methods, to find non-native methods that match.
2177 m = FindMethod<false>(current_class, name, sig);
2178 if (m != nullptr) {
2179 break;
2180 }
2181
2182 if (warn_on_going_to_parent) {
2183 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2184 << "This is slow, consider changing your RegisterNatives calls.";
2185 warn_on_going_to_parent = false;
2186 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002187 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002188
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002189 if (m == nullptr) {
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002190 LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002191 << PrettyDescriptor(c) << "." << name << sig << " in "
2192 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002193 // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2194 // out of scope after the DumpClass is done executing.
2195 c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002196 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002197 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002198 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002199 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002200 << PrettyDescriptor(c) << "." << name << sig
2201 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002202 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002203 return JNI_ERR;
2204 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002205
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002206 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002207
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002208 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002209 }
2210 return JNI_OK;
2211 }
2212
Elliott Hughes5174fe62011-08-23 15:12:35 -07002213 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002214 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002215 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002216 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002217
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002218 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002219
Ian Rogers2d10b202014-05-12 19:15:18 -07002220 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002221 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002222 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002223 if (m.IsNative()) {
2224 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002225 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002226 }
2227 }
2228
Ian Rogers2d10b202014-05-12 19:15:18 -07002229 if (unregistered_count == 0) {
2230 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2231 << PrettyDescriptor(c) << "' that contains no native methods";
2232 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002233 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002234 }
2235
Ian Rogers719d1a32014-03-06 12:13:39 -08002236 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002237 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002238 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002239 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2240 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002241 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002242 return JNI_ERR;
2243 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002244 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002245 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002246 }
2247
Ian Rogers719d1a32014-03-06 12:13:39 -08002248 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002249 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002250 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002251 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002252 o->MonitorExit(soa.Self());
2253 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002254 return JNI_ERR;
2255 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002256 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002257 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002258 }
2259
2260 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002261 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002262 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002263 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002264 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002265 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002266 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002267 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002268 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002269 }
2270
Elliott Hughescdf53122011-08-19 15:46:09 -07002271 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002272 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002273 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2274 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002275 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002276 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002277 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002278 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2279 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002280 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002281 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002282
Brian Carlstrom85a93362014-06-25 09:30:52 -07002283 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002284 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002285 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2286 "buffer capacity greater than maximum jint: %" PRId64,
2287 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002288 return nullptr;
2289 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002290 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002291 jint capacity_arg = static_cast<jint>(capacity);
2292
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002293 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2294 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002295 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002296 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002297 }
2298
Elliott Hughesb465ab02011-08-24 11:21:21 -07002299 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002300 return reinterpret_cast<void*>(env->GetLongField(
2301 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002302 }
2303
Elliott Hughesb465ab02011-08-24 11:21:21 -07002304 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002305 return static_cast<jlong>(env->GetIntField(
2306 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002307 }
2308
Andreas Gampea8763072014-12-20 00:08:35 -08002309 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2310 if (java_object == nullptr) {
2311 return JNIInvalidRefType;
2312 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002313
2314 // Do we definitely know what kind of reference this is?
2315 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2316 IndirectRefKind kind = GetIndirectRefKind(ref);
2317 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002318 case kLocal:
2319 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002320 case kGlobal:
2321 return JNIGlobalRefType;
2322 case kWeakGlobal:
2323 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002324 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002325 // Assume value is in a handle scope.
2326 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002327 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002328 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002329 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002330 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002331
2332 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002333 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2334 const char* caller)
Mathieu Chartier90443472015-07-16 20:32:27 -07002335 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002336 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002337 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002338 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2339 return JNI_ERR;
2340 }
2341 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002342 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002343 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2344 if (!okay) {
2345 soa.Self()->ThrowOutOfMemoryError(caller);
2346 }
2347 return okay ? JNI_OK : JNI_ERR;
2348 }
2349
2350 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002351 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002352 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002353 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002354 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002355 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002356 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002357 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002358 return soa.AddLocalReference<JniT>(result);
2359 }
2360
Ian Rogers2d10b202014-05-12 19:15:18 -07002361 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2362 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2363 const char* fn_name, const char* operation)
Mathieu Chartier90443472015-07-16 20:32:27 -07002364 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002365 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002366 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002367 soa.Vm()->JniAbortF(fn_name,
2368 "attempt to %s %s primitive array elements with an object of type %s",
2369 operation,
2370 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2371 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002372 return nullptr;
2373 }
2374 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2375 return array;
2376 }
2377
2378 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2379 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2380 CHECK_NON_NULL_ARGUMENT(java_array);
2381 ScopedObjectAccess soa(env);
2382 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2383 "GetArrayElements",
2384 "get");
2385 if (UNLIKELY(array == nullptr)) {
2386 return nullptr;
2387 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002388 // Only make a copy if necessary.
2389 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2390 if (is_copy != nullptr) {
2391 *is_copy = JNI_TRUE;
2392 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002393 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002394 size_t size = array->GetLength() * component_size;
2395 void* data = new uint64_t[RoundUp(size, 8) / 8];
2396 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002397 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002398 } else {
2399 if (is_copy != nullptr) {
2400 *is_copy = JNI_FALSE;
2401 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002402 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002403 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002404 }
2405
Ian Rogers2d10b202014-05-12 19:15:18 -07002406 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002407 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002408 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002409 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002410 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2411 "ReleaseArrayElements",
2412 "release");
2413 if (array == nullptr) {
2414 return;
2415 }
2416 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2417 }
2418
2419 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2420 size_t component_size, void* elements, jint mode)
Mathieu Chartier90443472015-07-16 20:32:27 -07002421 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002422 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002423 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002424 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002425 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002426 if (is_copy) {
2427 // Sanity check: If elements is not the same as the java array's data, it better not be a
2428 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2429 // copies we make?
2430 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002431 soa.Vm()->JniAbortF("ReleaseArrayElements",
2432 "invalid element pointer %p, array elements are %p",
2433 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002434 return;
2435 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002436 if (mode != JNI_ABORT) {
2437 memcpy(array_data, elements, bytes);
2438 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2439 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2440 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2441 soa.Self()->DumpJavaStack(LOG(WARNING));
2442 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002443 }
2444 if (mode != JNI_COMMIT) {
2445 if (is_copy) {
2446 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002447 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002448 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002449 if (!kUseReadBarrier) {
2450 heap->DecrementDisableMovingGC(soa.Self());
2451 } else {
2452 heap->DecrementDisableThreadFlip(soa.Self());
2453 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002454 }
2455 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002456 }
2457
Ian Rogers2d10b202014-05-12 19:15:18 -07002458 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2459 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2460 jsize start, jsize length, ElementT* buf) {
2461 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2462 ScopedObjectAccess soa(env);
2463 ArtArrayT* array =
2464 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2465 "GetPrimitiveArrayRegion",
2466 "get region of");
2467 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002468 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002469 ThrowAIOOBE(soa, array, start, length, "src");
2470 } else {
2471 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2472 ElementT* data = array->GetData();
2473 memcpy(buf, data + start, length * sizeof(ElementT));
2474 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002475 }
2476 }
2477
Ian Rogers2d10b202014-05-12 19:15:18 -07002478 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2479 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2480 jsize start, jsize length, const ElementT* buf) {
2481 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2482 ScopedObjectAccess soa(env);
2483 ArtArrayT* array =
2484 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2485 "SetPrimitiveArrayRegion",
2486 "set region of");
2487 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002488 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002489 ThrowAIOOBE(soa, array, start, length, "dst");
2490 } else {
2491 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2492 ElementT* data = array->GetData();
2493 memcpy(data + start, buf, length * sizeof(ElementT));
2494 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002495 }
2496 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002497};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002498
Elliott Hughes88c5c352012-03-15 18:49:48 -07002499const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002500 nullptr, // reserved0.
2501 nullptr, // reserved1.
2502 nullptr, // reserved2.
2503 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002504 JNI::GetVersion,
2505 JNI::DefineClass,
2506 JNI::FindClass,
2507 JNI::FromReflectedMethod,
2508 JNI::FromReflectedField,
2509 JNI::ToReflectedMethod,
2510 JNI::GetSuperclass,
2511 JNI::IsAssignableFrom,
2512 JNI::ToReflectedField,
2513 JNI::Throw,
2514 JNI::ThrowNew,
2515 JNI::ExceptionOccurred,
2516 JNI::ExceptionDescribe,
2517 JNI::ExceptionClear,
2518 JNI::FatalError,
2519 JNI::PushLocalFrame,
2520 JNI::PopLocalFrame,
2521 JNI::NewGlobalRef,
2522 JNI::DeleteGlobalRef,
2523 JNI::DeleteLocalRef,
2524 JNI::IsSameObject,
2525 JNI::NewLocalRef,
2526 JNI::EnsureLocalCapacity,
2527 JNI::AllocObject,
2528 JNI::NewObject,
2529 JNI::NewObjectV,
2530 JNI::NewObjectA,
2531 JNI::GetObjectClass,
2532 JNI::IsInstanceOf,
2533 JNI::GetMethodID,
2534 JNI::CallObjectMethod,
2535 JNI::CallObjectMethodV,
2536 JNI::CallObjectMethodA,
2537 JNI::CallBooleanMethod,
2538 JNI::CallBooleanMethodV,
2539 JNI::CallBooleanMethodA,
2540 JNI::CallByteMethod,
2541 JNI::CallByteMethodV,
2542 JNI::CallByteMethodA,
2543 JNI::CallCharMethod,
2544 JNI::CallCharMethodV,
2545 JNI::CallCharMethodA,
2546 JNI::CallShortMethod,
2547 JNI::CallShortMethodV,
2548 JNI::CallShortMethodA,
2549 JNI::CallIntMethod,
2550 JNI::CallIntMethodV,
2551 JNI::CallIntMethodA,
2552 JNI::CallLongMethod,
2553 JNI::CallLongMethodV,
2554 JNI::CallLongMethodA,
2555 JNI::CallFloatMethod,
2556 JNI::CallFloatMethodV,
2557 JNI::CallFloatMethodA,
2558 JNI::CallDoubleMethod,
2559 JNI::CallDoubleMethodV,
2560 JNI::CallDoubleMethodA,
2561 JNI::CallVoidMethod,
2562 JNI::CallVoidMethodV,
2563 JNI::CallVoidMethodA,
2564 JNI::CallNonvirtualObjectMethod,
2565 JNI::CallNonvirtualObjectMethodV,
2566 JNI::CallNonvirtualObjectMethodA,
2567 JNI::CallNonvirtualBooleanMethod,
2568 JNI::CallNonvirtualBooleanMethodV,
2569 JNI::CallNonvirtualBooleanMethodA,
2570 JNI::CallNonvirtualByteMethod,
2571 JNI::CallNonvirtualByteMethodV,
2572 JNI::CallNonvirtualByteMethodA,
2573 JNI::CallNonvirtualCharMethod,
2574 JNI::CallNonvirtualCharMethodV,
2575 JNI::CallNonvirtualCharMethodA,
2576 JNI::CallNonvirtualShortMethod,
2577 JNI::CallNonvirtualShortMethodV,
2578 JNI::CallNonvirtualShortMethodA,
2579 JNI::CallNonvirtualIntMethod,
2580 JNI::CallNonvirtualIntMethodV,
2581 JNI::CallNonvirtualIntMethodA,
2582 JNI::CallNonvirtualLongMethod,
2583 JNI::CallNonvirtualLongMethodV,
2584 JNI::CallNonvirtualLongMethodA,
2585 JNI::CallNonvirtualFloatMethod,
2586 JNI::CallNonvirtualFloatMethodV,
2587 JNI::CallNonvirtualFloatMethodA,
2588 JNI::CallNonvirtualDoubleMethod,
2589 JNI::CallNonvirtualDoubleMethodV,
2590 JNI::CallNonvirtualDoubleMethodA,
2591 JNI::CallNonvirtualVoidMethod,
2592 JNI::CallNonvirtualVoidMethodV,
2593 JNI::CallNonvirtualVoidMethodA,
2594 JNI::GetFieldID,
2595 JNI::GetObjectField,
2596 JNI::GetBooleanField,
2597 JNI::GetByteField,
2598 JNI::GetCharField,
2599 JNI::GetShortField,
2600 JNI::GetIntField,
2601 JNI::GetLongField,
2602 JNI::GetFloatField,
2603 JNI::GetDoubleField,
2604 JNI::SetObjectField,
2605 JNI::SetBooleanField,
2606 JNI::SetByteField,
2607 JNI::SetCharField,
2608 JNI::SetShortField,
2609 JNI::SetIntField,
2610 JNI::SetLongField,
2611 JNI::SetFloatField,
2612 JNI::SetDoubleField,
2613 JNI::GetStaticMethodID,
2614 JNI::CallStaticObjectMethod,
2615 JNI::CallStaticObjectMethodV,
2616 JNI::CallStaticObjectMethodA,
2617 JNI::CallStaticBooleanMethod,
2618 JNI::CallStaticBooleanMethodV,
2619 JNI::CallStaticBooleanMethodA,
2620 JNI::CallStaticByteMethod,
2621 JNI::CallStaticByteMethodV,
2622 JNI::CallStaticByteMethodA,
2623 JNI::CallStaticCharMethod,
2624 JNI::CallStaticCharMethodV,
2625 JNI::CallStaticCharMethodA,
2626 JNI::CallStaticShortMethod,
2627 JNI::CallStaticShortMethodV,
2628 JNI::CallStaticShortMethodA,
2629 JNI::CallStaticIntMethod,
2630 JNI::CallStaticIntMethodV,
2631 JNI::CallStaticIntMethodA,
2632 JNI::CallStaticLongMethod,
2633 JNI::CallStaticLongMethodV,
2634 JNI::CallStaticLongMethodA,
2635 JNI::CallStaticFloatMethod,
2636 JNI::CallStaticFloatMethodV,
2637 JNI::CallStaticFloatMethodA,
2638 JNI::CallStaticDoubleMethod,
2639 JNI::CallStaticDoubleMethodV,
2640 JNI::CallStaticDoubleMethodA,
2641 JNI::CallStaticVoidMethod,
2642 JNI::CallStaticVoidMethodV,
2643 JNI::CallStaticVoidMethodA,
2644 JNI::GetStaticFieldID,
2645 JNI::GetStaticObjectField,
2646 JNI::GetStaticBooleanField,
2647 JNI::GetStaticByteField,
2648 JNI::GetStaticCharField,
2649 JNI::GetStaticShortField,
2650 JNI::GetStaticIntField,
2651 JNI::GetStaticLongField,
2652 JNI::GetStaticFloatField,
2653 JNI::GetStaticDoubleField,
2654 JNI::SetStaticObjectField,
2655 JNI::SetStaticBooleanField,
2656 JNI::SetStaticByteField,
2657 JNI::SetStaticCharField,
2658 JNI::SetStaticShortField,
2659 JNI::SetStaticIntField,
2660 JNI::SetStaticLongField,
2661 JNI::SetStaticFloatField,
2662 JNI::SetStaticDoubleField,
2663 JNI::NewString,
2664 JNI::GetStringLength,
2665 JNI::GetStringChars,
2666 JNI::ReleaseStringChars,
2667 JNI::NewStringUTF,
2668 JNI::GetStringUTFLength,
2669 JNI::GetStringUTFChars,
2670 JNI::ReleaseStringUTFChars,
2671 JNI::GetArrayLength,
2672 JNI::NewObjectArray,
2673 JNI::GetObjectArrayElement,
2674 JNI::SetObjectArrayElement,
2675 JNI::NewBooleanArray,
2676 JNI::NewByteArray,
2677 JNI::NewCharArray,
2678 JNI::NewShortArray,
2679 JNI::NewIntArray,
2680 JNI::NewLongArray,
2681 JNI::NewFloatArray,
2682 JNI::NewDoubleArray,
2683 JNI::GetBooleanArrayElements,
2684 JNI::GetByteArrayElements,
2685 JNI::GetCharArrayElements,
2686 JNI::GetShortArrayElements,
2687 JNI::GetIntArrayElements,
2688 JNI::GetLongArrayElements,
2689 JNI::GetFloatArrayElements,
2690 JNI::GetDoubleArrayElements,
2691 JNI::ReleaseBooleanArrayElements,
2692 JNI::ReleaseByteArrayElements,
2693 JNI::ReleaseCharArrayElements,
2694 JNI::ReleaseShortArrayElements,
2695 JNI::ReleaseIntArrayElements,
2696 JNI::ReleaseLongArrayElements,
2697 JNI::ReleaseFloatArrayElements,
2698 JNI::ReleaseDoubleArrayElements,
2699 JNI::GetBooleanArrayRegion,
2700 JNI::GetByteArrayRegion,
2701 JNI::GetCharArrayRegion,
2702 JNI::GetShortArrayRegion,
2703 JNI::GetIntArrayRegion,
2704 JNI::GetLongArrayRegion,
2705 JNI::GetFloatArrayRegion,
2706 JNI::GetDoubleArrayRegion,
2707 JNI::SetBooleanArrayRegion,
2708 JNI::SetByteArrayRegion,
2709 JNI::SetCharArrayRegion,
2710 JNI::SetShortArrayRegion,
2711 JNI::SetIntArrayRegion,
2712 JNI::SetLongArrayRegion,
2713 JNI::SetFloatArrayRegion,
2714 JNI::SetDoubleArrayRegion,
2715 JNI::RegisterNatives,
2716 JNI::UnregisterNatives,
2717 JNI::MonitorEnter,
2718 JNI::MonitorExit,
2719 JNI::GetJavaVM,
2720 JNI::GetStringRegion,
2721 JNI::GetStringUTFRegion,
2722 JNI::GetPrimitiveArrayCritical,
2723 JNI::ReleasePrimitiveArrayCritical,
2724 JNI::GetStringCritical,
2725 JNI::ReleaseStringCritical,
2726 JNI::NewWeakGlobalRef,
2727 JNI::DeleteWeakGlobalRef,
2728 JNI::ExceptionCheck,
2729 JNI::NewDirectByteBuffer,
2730 JNI::GetDirectBufferAddress,
2731 JNI::GetDirectBufferCapacity,
2732 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002733};
2734
Ian Rogers68d8b422014-07-17 11:09:10 -07002735const JNINativeInterface* GetJniNativeInterface() {
2736 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002737}
2738
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002739void (*gJniSleepForeverStub[])() = {
2740 nullptr, // reserved0.
2741 nullptr, // reserved1.
2742 nullptr, // reserved2.
2743 nullptr, // reserved3.
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 SleepForever,
2972 SleepForever,
2973};
2974
2975const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
2976 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
2977}
2978
Elliott Hughesc8fece32013-01-02 11:27:23 -08002979void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07002980 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002981 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002982 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002983 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2984 }
2985 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2986}
2987
Ian Rogersdf20fe02011-07-20 20:34:16 -07002988} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07002989
2990std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2991 switch (rhs) {
2992 case JNIInvalidRefType:
2993 os << "JNIInvalidRefType";
2994 return os;
2995 case JNILocalRefType:
2996 os << "JNILocalRefType";
2997 return os;
2998 case JNIGlobalRefType:
2999 os << "JNIGlobalRefType";
3000 return os;
3001 case JNIWeakGlobalRefType:
3002 os << "JNIWeakGlobalRefType";
3003 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003004 default:
Ian Rogersc7dd2952014-10-21 23:31:19 -07003005 LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3006 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003007 }
3008}