blob: d00e3a37b8bebc1fc104cd486e2f48684461faa2 [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"
Mathieu Chartier0795f232016-09-27 18:43:30 -070055#include "scoped_thread_state_change-inl.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)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 REQUIRES_SHARED(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
Mathieu Chartier3398c782016-09-30 10:27:43 -0700100static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa,
101 ObjPtr<mirror::Class> c,
102 const char* kind,
103 jint idx,
104 bool return_errors)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700105 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -0700106 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
107 << "Failed to register native method in " << PrettyDescriptor(c)
108 << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200109 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000110 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Mathieu Chartier3398c782016-09-30 10:27:43 -0700111 "%s is null at index %d",
112 kind,
113 idx);
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200114}
115
Mathieu Chartier0795f232016-09-27 18:43:30 -0700116static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700117 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800118 if (LIKELY(klass->IsInitialized())) {
119 return klass;
120 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700121 StackHandleScope<1> hs(self);
122 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700123 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800124 return nullptr;
125 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700126 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800127}
128
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700129static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
130 const char* name, const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700131 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700132 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800133 if (c == nullptr) {
134 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700135 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 ArtMethod* method = nullptr;
137 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700138 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700139 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700140 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700141 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700142 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700143 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800144 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700145 // No virtual method matching the signature. Search declared
146 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700147 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700148 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700149 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800150 if (method == nullptr || method->IsStatic() != is_static) {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700151 ThrowNoSuchMethodError(soa, c.Ptr(), name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800152 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700153 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700154 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700155}
156
Mathieu Chartier0795f232016-09-27 18:43:30 -0700157static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700158 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700159 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700160 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
161 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700162 return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700163 }
Brian Carlstromce888532013-10-10 00:32:58 -0700164 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800165 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700166 return method->GetDeclaringClass()->GetClassLoader();
167 }
168 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700169 ObjPtr<mirror::ClassLoader> class_loader =
170 soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800171 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700172 return class_loader;
173 }
174 // See if the override ClassLoader is set for gtests.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700175 class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800176 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700177 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
178 // image.
179 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700180 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700181 return class_loader;
182 }
183 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800184 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700185}
186
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700187static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
188 const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700189 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700190 StackHandleScope<2> hs(soa.Self());
191 Handle<mirror::Class> c(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700192 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class))));
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700193 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800194 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700195 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700196 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800197 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700198 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
199 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700200 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800201 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700202 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700203 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700204 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800205 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700206 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700207 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800208 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000209 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700210 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700211 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000212 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800213 "no type \"%s\" found and so no field \"%s\" "
214 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700215 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000216 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800217 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700218 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700219 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700220 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700221 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700222 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700223 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700224 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700225 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800226 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000227 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800228 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700229 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800230 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700231 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700232 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700233}
234
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800235static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700236 jsize length, const char* identifier)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700237 REQUIRES_SHARED(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700238 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000239 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800240 "%s offset=%d length=%d %s.length=%d",
241 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700242}
Ian Rogers0571d352011-11-03 19:51:38 -0700243
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700244static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
245 jsize array_length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700246 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000247 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800248 "offset=%d length=%d string.length()=%d", start, length,
249 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700250}
Elliott Hughes814e4032011-08-23 12:07:56 -0700251
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700252int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700253 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700254 // Turn the const char* into a java.lang.String.
255 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800256 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700257 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700258 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700259
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700260 // Choose an appropriate constructor and set up the arguments.
261 jvalue args[2];
262 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800263 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700264 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800265 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266 signature = "(Ljava/lang/String;)V";
267 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800268 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700269 signature = "(Ljava/lang/Throwable;)V";
270 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700271 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700272 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
273 args[0].l = s.get();
274 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700275 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700276 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800277 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800278 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700279 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartier0795f232016-09-27 18:43:30 -0700280 << PrettyClass(soa.Decode<mirror::Class>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 return JNI_ERR;
282 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700283
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800284 ScopedLocalRef<jthrowable> exception(
285 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
286 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700287 return JNI_ERR;
288 }
Ian Rogersef28b142012-11-30 14:22:18 -0800289 ScopedObjectAccess soa(env);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700290 soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700291 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700292}
293
Ian Rogers68d8b422014-07-17 11:09:10 -0700294static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
295 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700296}
297
Ian Rogers2d10b202014-05-12 19:15:18 -0700298#define CHECK_NON_NULL_ARGUMENT(value) \
299 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700300
Ian Rogers2d10b202014-05-12 19:15:18 -0700301#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
302 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
303
304#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
305 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
306
307#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
308 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
309
310#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700311 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700312 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700313 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700314 }
315
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700316#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700317 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700318 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700319 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700320 }
321
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700322template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700323static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700324 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700325 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800326 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700327 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
328 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700329 }
330 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700331 return nullptr;
332}
333
Elliott Hughescdf53122011-08-19 15:46:09 -0700334class JNI {
335 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700336 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700337 return JNI_VERSION_1_6;
338 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700339
Ian Rogers25e8b912012-09-07 11:31:36 -0700340 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700341 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800342 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700343 }
344
Elliott Hughescdf53122011-08-19 15:46:09 -0700345 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700346 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700347 Runtime* runtime = Runtime::Current();
348 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700349 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700350 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800351 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700352 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700353 StackHandleScope<1> hs(soa.Self());
354 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800355 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700356 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800357 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700358 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700359 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700360 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700361
Ian Rogers62f05122014-03-21 11:21:29 -0700362 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700363 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700364 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700365 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700366 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700367
Ian Rogers62f05122014-03-21 11:21:29 -0700368 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700369 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700370 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700371 ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700372 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700373 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700374 return nullptr;
375 }
Mathieu Chartier1cc62e42016-10-03 18:01:28 -0700376 ObjPtr<mirror::Field> field = down_cast<mirror::Field*>(obj_field.Ptr());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700377 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700378 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700379
Elliott Hughescdf53122011-08-19 15:46:09 -0700380 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700381 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700382 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700383 ArtMethod* m = soa.DecodeMethod(mid);
Neil Fuller0e844392016-09-08 13:43:31 +0100384 mirror::Executable* method;
Andreas Gampe542451c2016-07-26 09:02:02 -0700385 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
Andreas Gampee01e3642016-07-25 13:06:04 -0700386 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200387 if (m->IsConstructor()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700388 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200389 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700390 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200391 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700392 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700393 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700394
Elliott Hughescdf53122011-08-19 15:46:09 -0700395 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700396 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700397 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700398 ArtField* f = soa.DecodeField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700399 return soa.AddLocalReference<jobject>(
Andreas Gampe542451c2016-07-26 09:02:02 -0700400 mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700401 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700402
Elliott Hughes37f7a402011-08-22 18:56:01 -0700403 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700404 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700405 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700406 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700407 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700408 }
409
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700410 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700411 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700412 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700413 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700414 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700415 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700416
Narayan Kamath1268b742014-07-11 19:15:11 +0100417 // Note: java_class1 should be safely castable to java_class2, and
418 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700419 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700420 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
421 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700422 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700423 ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
424 ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700425 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700426 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700427
Elliott Hughese84278b2012-03-22 10:06:53 -0700428 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700429 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800430 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700431 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700432 return JNI_TRUE;
433 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700434 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700435 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj);
436 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700437 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700438 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700439 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700440
Elliott Hughes37f7a402011-08-22 18:56:01 -0700441 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700442 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700443 ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800444 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700445 return JNI_ERR;
446 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700447 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700448 return JNI_OK;
449 }
450
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700451 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700452 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800453 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700454 }
455
456 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700457 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700458 }
459
460 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700461 ScopedObjectAccess soa(env);
462 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700463 }
464
465 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700466 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700467
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700468 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000469 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700470 return;
471 }
472
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000473 StackHandleScope<1> hs(soa.Self());
474 Handle<mirror::Throwable> old_exception(
475 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
476 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800477 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700478 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700479 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
480 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800481 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700482 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700483 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700484 } else {
485 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800486 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000487 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700488 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800489 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700490 }
491 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000492 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700493 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700494
Elliott Hughescdf53122011-08-19 15:46:09 -0700495 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700496 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000497 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700498 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700499 }
500
Ian Rogers25e8b912012-09-07 11:31:36 -0700501 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700502 LOG(FATAL) << "JNI FatalError called: " << msg;
503 }
504
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700505 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700506 // TODO: SOA may not be necessary but I do it to please lock annotations.
507 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700508 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700509 return JNI_ERR;
510 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700511 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700512 return JNI_OK;
513 }
514
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700515 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700516 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700517 ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700518 soa.Env()->PopFrame();
519 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700520 }
521
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700522 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700523 // TODO: SOA may not be necessary but I do it to please lock annotations.
524 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700525 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700526 }
527
Elliott Hughescdf53122011-08-19 15:46:09 -0700528 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700529 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700530 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc4f39252016-10-05 18:32:08 -0700531 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700532 }
533
534 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700535 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
536 Thread* self = down_cast<JNIEnvExt*>(env)->self;
537 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700538 }
539
540 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700541 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700542 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc4f39252016-10-05 18:32:08 -0700543 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700544 }
545
546 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700547 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
548 Thread* self = down_cast<JNIEnvExt*>(env)->self;
549 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700550 }
551
552 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700553 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700554 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800555 // Check for null after decoding the object to handle cleared weak globals.
556 if (decoded_obj == nullptr) {
557 return nullptr;
558 }
559 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700560 }
561
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700562 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800563 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700564 return;
565 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700566 // SOA is only necessary to have exclusion between GC root marking and removing.
567 // We don't want to have the GC attempt to mark a null root if we just removed
568 // it. b/22119403
569 ScopedObjectAccess soa(env);
570 auto* ext_env = down_cast<JNIEnvExt*>(env);
571 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700572 // Attempting to delete a local reference that is not in the
573 // topmost local reference frame is a no-op. DeleteLocalRef returns
574 // void and doesn't throw any exceptions, but we should probably
575 // complain about it so the user will notice that things aren't
576 // going quite the way they expect.
577 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
578 << "failed to find entry";
579 }
580 }
581
582 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700583 if (obj1 == obj2) {
584 return JNI_TRUE;
585 } else {
586 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700587 return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2))
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800588 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700589 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700590 }
591
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700592 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700593 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700594 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700595 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800596 if (c == nullptr) {
597 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700598 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800599 if (c->IsStringClass()) {
600 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700601 return soa.AddLocalReference<jobject>(mirror::String::AllocEmptyString<true>(soa.Self(),
602 allocator_type));
Jeff Hao848f70a2014-01-15 13:49:50 -0800603 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700604 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700605 }
606
Ian Rogersbc939662013-08-15 10:26:54 -0700607 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700608 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700609 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700610 CHECK_NON_NULL_ARGUMENT(java_class);
611 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700612 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700613 va_end(args);
614 return result;
615 }
616
Elliott Hughes72025e52011-08-23 17:50:30 -0700617 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700618 CHECK_NON_NULL_ARGUMENT(java_class);
619 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700620 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700621 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
622 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800623 if (c == nullptr) {
624 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700625 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800626 if (c->IsStringClass()) {
627 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100628 jmethodID sf_mid = soa.EncodeMethod(
629 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800630 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
631 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700632 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800633 if (result == nullptr) {
634 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700635 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700636 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700637 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800638 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800639 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700640 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800641 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700642 }
643
Elliott Hughes72025e52011-08-23 17:50:30 -0700644 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700645 CHECK_NON_NULL_ARGUMENT(java_class);
646 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700647 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700648 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
649 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800650 if (c == nullptr) {
651 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700652 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800653 if (c->IsStringClass()) {
654 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100655 jmethodID sf_mid = soa.EncodeMethod(
656 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800657 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
658 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700659 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800660 if (result == nullptr) {
661 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700662 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700663 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700664 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800665 if (soa.Self()->IsExceptionPending()) {
666 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700667 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800668 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700669 }
670
Ian Rogersbc939662013-08-15 10:26:54 -0700671 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, 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, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700677 }
678
Ian Rogersbc939662013-08-15 10:26:54 -0700679 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
680 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700681 CHECK_NON_NULL_ARGUMENT(java_class);
682 CHECK_NON_NULL_ARGUMENT(name);
683 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700684 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700685 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700686 }
687
Elliott Hughes72025e52011-08-23 17:50:30 -0700688 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700689 va_list ap;
690 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700691 CHECK_NON_NULL_ARGUMENT(obj);
692 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700693 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700694 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700695 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700696 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700697 }
698
Elliott Hughes72025e52011-08-23 17:50:30 -0700699 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700700 CHECK_NON_NULL_ARGUMENT(obj);
701 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700702 ScopedObjectAccess soa(env);
703 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
704 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700705 }
706
Elliott Hughes72025e52011-08-23 17:50:30 -0700707 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700708 CHECK_NON_NULL_ARGUMENT(obj);
709 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700710 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700711 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700712 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700713 }
714
Elliott Hughes72025e52011-08-23 17:50:30 -0700715 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700716 va_list ap;
717 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700718 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
719 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700720 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700721 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700722 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700723 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700724 }
725
Elliott Hughes72025e52011-08-23 17:50:30 -0700726 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700727 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
728 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700729 ScopedObjectAccess soa(env);
730 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700731 }
732
Elliott Hughes72025e52011-08-23 17:50:30 -0700733 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
735 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700736 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700737 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700738 }
739
Elliott Hughes72025e52011-08-23 17:50:30 -0700740 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700741 va_list ap;
742 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700743 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
744 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700745 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700746 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700747 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700748 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700749 }
750
Elliott Hughes72025e52011-08-23 17:50:30 -0700751 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700752 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
753 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700754 ScopedObjectAccess soa(env);
755 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700756 }
757
Elliott Hughes72025e52011-08-23 17:50:30 -0700758 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
760 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700761 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700762 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700763 }
764
Elliott Hughes72025e52011-08-23 17:50:30 -0700765 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700766 va_list ap;
767 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700768 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
769 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700770 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700771 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700772 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700773 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700774 }
775
Elliott Hughes72025e52011-08-23 17:50:30 -0700776 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700777 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
778 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700779 ScopedObjectAccess soa(env);
780 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700781 }
782
Elliott Hughes72025e52011-08-23 17:50:30 -0700783 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
785 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700786 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700787 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700788 }
789
Elliott Hughes72025e52011-08-23 17:50:30 -0700790 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700791 va_list ap;
792 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700793 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
794 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700795 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700796 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700797 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700798 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700799 }
800
Elliott Hughes72025e52011-08-23 17:50:30 -0700801 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700802 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
803 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700804 ScopedObjectAccess soa(env);
805 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700806 }
807
Elliott Hughes72025e52011-08-23 17:50:30 -0700808 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700809 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
810 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700811 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700812 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700813 }
814
Elliott Hughes72025e52011-08-23 17:50:30 -0700815 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700816 va_list ap;
817 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700818 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
819 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700820 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700821 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700822 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700823 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700824 }
825
Elliott Hughes72025e52011-08-23 17:50:30 -0700826 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700827 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
828 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700829 ScopedObjectAccess soa(env);
830 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700831 }
832
Elliott Hughes72025e52011-08-23 17:50:30 -0700833 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
835 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700836 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700837 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700838 }
839
Elliott Hughes72025e52011-08-23 17:50:30 -0700840 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700841 va_list ap;
842 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700843 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
844 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700845 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700846 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700847 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700848 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700849 }
850
Elliott Hughes72025e52011-08-23 17:50:30 -0700851 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700852 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
853 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700854 ScopedObjectAccess soa(env);
855 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700856 }
857
Elliott Hughes72025e52011-08-23 17:50:30 -0700858 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700859 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
860 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700861 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700862 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700863 }
864
Elliott Hughes72025e52011-08-23 17:50:30 -0700865 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700866 va_list ap;
867 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700868 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
869 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700870 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700871 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700872 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700873 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700874 }
875
Elliott Hughes72025e52011-08-23 17:50:30 -0700876 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700877 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
878 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700879 ScopedObjectAccess soa(env);
880 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700881 }
882
Elliott Hughes72025e52011-08-23 17:50:30 -0700883 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700884 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
885 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700886 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700887 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700888 }
889
Elliott Hughes72025e52011-08-23 17:50:30 -0700890 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700891 va_list ap;
892 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700893 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
894 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700895 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700896 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700897 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700898 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700899 }
900
Elliott Hughes72025e52011-08-23 17:50:30 -0700901 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700902 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
903 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700904 ScopedObjectAccess soa(env);
905 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700906 }
907
Elliott Hughes72025e52011-08-23 17:50:30 -0700908 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700909 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
910 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700911 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700912 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700913 }
914
Elliott Hughes72025e52011-08-23 17:50:30 -0700915 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700916 va_list ap;
917 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700918 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
919 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700920 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700921 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700922 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700923 }
924
Elliott Hughes72025e52011-08-23 17:50:30 -0700925 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700926 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
927 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700928 ScopedObjectAccess soa(env);
929 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700930 }
931
Elliott Hughes72025e52011-08-23 17:50:30 -0700932 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700933 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
934 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700935 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700936 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700937 }
938
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700939 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700940 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700941 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700942 CHECK_NON_NULL_ARGUMENT(obj);
943 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700944 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700945 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
946 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700947 va_end(ap);
948 return local_result;
949 }
950
Ian Rogersbc939662013-08-15 10:26:54 -0700951 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
952 va_list 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);
956 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
957 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700958 }
959
Ian Rogersbc939662013-08-15 10:26:54 -0700960 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
961 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700962 CHECK_NON_NULL_ARGUMENT(obj);
963 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700964 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700965 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700966 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700967 }
968
Ian Rogersbc939662013-08-15 10:26:54 -0700969 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
970 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700971 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700972 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700973 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
974 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700975 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700976 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700977 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700978 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700979 }
980
Ian Rogersbc939662013-08-15 10:26:54 -0700981 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
982 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700983 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
984 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700985 ScopedObjectAccess soa(env);
986 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700987 }
988
Ian Rogersbc939662013-08-15 10:26:54 -0700989 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
990 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700991 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
992 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700993 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700994 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700995 }
996
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700997 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700998 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700999 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001000 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1001 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001002 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001003 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001004 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001005 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001006 }
1007
Ian Rogersbc939662013-08-15 10:26:54 -07001008 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1009 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001010 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1011 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001012 ScopedObjectAccess soa(env);
1013 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001014 }
1015
Ian Rogersbc939662013-08-15 10:26:54 -07001016 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1017 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001018 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1019 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001020 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001021 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001022 }
1023
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001024 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001025 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001026 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001027 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1028 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001029 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001030 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001031 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001032 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001033 }
1034
Ian Rogersbc939662013-08-15 10:26:54 -07001035 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1036 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001037 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1038 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001039 ScopedObjectAccess soa(env);
1040 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001041 }
1042
Ian Rogersbc939662013-08-15 10:26:54 -07001043 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1044 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001045 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1046 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001047 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001048 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001049 }
1050
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001051 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001052 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001053 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001054 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1055 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001056 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001057 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001058 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001059 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001060 }
1061
Ian Rogersbc939662013-08-15 10:26:54 -07001062 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1063 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001064 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1065 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001066 ScopedObjectAccess soa(env);
1067 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001068 }
1069
Ian Rogersbc939662013-08-15 10:26:54 -07001070 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1071 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001072 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1073 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001074 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001075 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001076 }
1077
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001078 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001079 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001080 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001081 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1082 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001083 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001084 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001085 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001086 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001087 }
1088
Ian Rogersbc939662013-08-15 10:26:54 -07001089 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1090 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1092 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001093 ScopedObjectAccess soa(env);
1094 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001095 }
1096
Ian Rogersbc939662013-08-15 10:26:54 -07001097 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1098 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001099 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1100 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001101 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001102 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001103 }
1104
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001105 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001106 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001107 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001108 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1109 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001110 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001111 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001112 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001113 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001114 }
1115
Ian Rogersbc939662013-08-15 10:26:54 -07001116 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1117 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001118 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1119 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001120 ScopedObjectAccess soa(env);
1121 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001122 }
1123
Ian Rogersbc939662013-08-15 10:26:54 -07001124 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1125 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001126 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1127 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001128 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001129 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001130 }
1131
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001132 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001133 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001134 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001135 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1136 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001137 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001138 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001139 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001140 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001141 }
1142
Ian Rogersbc939662013-08-15 10:26:54 -07001143 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1144 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001145 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1146 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001147 ScopedObjectAccess soa(env);
1148 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001149 }
1150
Ian Rogersbc939662013-08-15 10:26:54 -07001151 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1152 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001153 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1154 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001155 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001156 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001157 }
1158
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001159 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001160 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001161 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001162 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1163 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001164 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001165 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001166 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001167 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001168 }
1169
Ian Rogersbc939662013-08-15 10:26:54 -07001170 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1171 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001172 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1173 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001174 ScopedObjectAccess soa(env);
1175 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001176 }
1177
Ian Rogersbc939662013-08-15 10:26:54 -07001178 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1179 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001180 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1181 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001182 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001183 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001184 }
1185
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001186 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001187 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001188 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001189 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1190 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001191 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001192 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001193 va_end(ap);
1194 }
1195
Brian Carlstromea46f952013-07-30 01:26:50 -07001196 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1197 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001198 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1199 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001200 ScopedObjectAccess soa(env);
1201 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001202 }
1203
Ian Rogersbc939662013-08-15 10:26:54 -07001204 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1205 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001206 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1207 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001208 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001209 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001210 }
1211
Ian Rogersbc939662013-08-15 10:26:54 -07001212 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, 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, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001218 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001219
Ian Rogersbc939662013-08-15 10:26:54 -07001220 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1221 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001222 CHECK_NON_NULL_ARGUMENT(java_class);
1223 CHECK_NON_NULL_ARGUMENT(name);
1224 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001225 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001226 return FindFieldID(soa, java_class, name, sig, true);
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 GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001230 CHECK_NON_NULL_ARGUMENT(obj);
1231 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001232 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001233 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001234 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001235 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001236 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001237
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001238 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001239 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001240 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001241 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001242 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001243 }
1244
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001245 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001246 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1247 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001248 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001249 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
1250 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001251 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001252 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001253 }
1254
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001255 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001256 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001257 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001258 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001259 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001260 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001261 }
1262
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001263#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001264 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1265 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001266 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001267 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001268 ArtField* f = soa.DecodeField(fid); \
Mathieu Chartier3398c782016-09-30 10:27:43 -07001269 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001270
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001271#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001272 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001273 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001274 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001275 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001276
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001277#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001278 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1279 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001280 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001281 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001282 ArtField* f = soa.DecodeField(fid); \
Mathieu Chartier3398c782016-09-30 10:27:43 -07001283 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001284
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001285#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001286 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001287 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001288 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001289 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001290
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001291 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001292 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001293 }
1294
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001295 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001296 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001297 }
1298
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001299 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001300 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001301 }
1302
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001303 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001304 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001305 }
1306
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001307 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001308 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001309 }
1310
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001311 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001312 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001313 }
1314
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001315 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001316 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001317 }
1318
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001319 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001320 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001321 }
1322
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001323 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001324 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001325 }
1326
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001327 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001328 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001329 }
1330
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001331 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001332 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001333 }
1334
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001335 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001336 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001337 }
1338
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001339 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001340 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001341 }
1342
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001343 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001344 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001345 }
1346
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001347 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001348 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001349 }
1350
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001351 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001352 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001353 }
1354
1355 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001356 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001357 }
1358
1359 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001360 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001361 }
1362
1363 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001364 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001365 }
1366
1367 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001368 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001369 }
1370
1371 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001372 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001373 }
1374
1375 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001376 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001377 }
1378
1379 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001380 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001381 }
1382
1383 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001384 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001385 }
1386
1387 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001388 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001389 }
1390
1391 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001392 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001393 }
1394
1395 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001396 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001397 }
1398
1399 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001400 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001401 }
1402
1403 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001404 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001405 }
1406
1407 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001408 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001409 }
1410
1411 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001412 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001413 }
1414
1415 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001416 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001417 }
1418
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001419 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001420 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001421 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001422 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001423 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001424 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001425 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 va_end(ap);
1427 return local_result;
1428 }
1429
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001430 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001431 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001432 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001433 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001434 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001435 }
1436
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001437 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001438 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001439 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001440 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001441 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001442 }
1443
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001444 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001445 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001446 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001447 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001448 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001449 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001450 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001451 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001452 }
1453
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001454 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001455 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001456 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001457 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001458 }
1459
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001460 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001461 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001462 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001463 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001464 }
1465
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001466 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001467 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001468 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001469 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001470 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001471 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001472 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001473 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001474 }
1475
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001476 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001477 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001478 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001479 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 }
1481
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001482 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001483 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001484 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001485 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001486 }
1487
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001488 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001489 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001490 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001491 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001492 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001493 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001494 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001495 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001496 }
1497
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001498 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001499 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001500 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001501 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001502 }
1503
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001504 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001505 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001506 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001507 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001508 }
1509
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001510 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001511 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001512 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001513 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001514 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001515 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001516 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001517 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001518 }
1519
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001520 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001521 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001522 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001523 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001524 }
1525
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001526 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001527 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001528 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001529 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001530 }
1531
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001532 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001533 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001534 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001535 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001536 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001537 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001538 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001539 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001540 }
1541
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001542 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001543 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001544 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001545 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001546 }
1547
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001548 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001549 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001550 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001551 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001552 }
1553
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001554 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001555 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001556 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001557 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001558 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001559 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001560 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001561 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001562 }
1563
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001564 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001565 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001566 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001567 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001568 }
1569
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001570 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001571 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001572 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001573 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001574 }
1575
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001576 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001577 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001578 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001579 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001580 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001581 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001582 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001583 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001584 }
1585
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001586 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001587 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001588 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001589 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001590 }
1591
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001592 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001593 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001594 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001595 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001596 }
1597
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001598 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001599 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001600 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001601 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001602 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001603 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001604 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001605 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001606 }
1607
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001608 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001609 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001610 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001611 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001612 }
1613
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001614 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001615 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001616 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001617 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001618 }
1619
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001620 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001621 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001622 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001623 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001624 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001625 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001626 va_end(ap);
1627 }
1628
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001629 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001630 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001631 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001632 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001633 }
1634
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001635 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001636 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001637 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001638 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001639 }
1640
Elliott Hughes814e4032011-08-23 12:07:56 -07001641 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001642 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001643 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001644 return nullptr;
1645 }
1646 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001647 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001648 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -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::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001652 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001653 }
1654
1655 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001656 if (utf == nullptr) {
1657 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001658 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001659 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001660 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001661 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001662 }
1663
Elliott Hughes814e4032011-08-23 12:07:56 -07001664 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001665 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001666 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001667 return soa.Decode<mirror::String>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001668 }
1669
1670 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001671 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001672 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001673 return soa.Decode<mirror::String>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001674 }
1675
Ian Rogersbc939662013-08-15 10:26:54 -07001676 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1677 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001678 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001679 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001680 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001681 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001682 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001683 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001684 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001685 if (s->IsCompressed()) {
1686 for (int i = 0; i < length; ++i) {
1687 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1688 }
1689 } else {
1690 const jchar* chars = static_cast<jchar*>(s->GetValue());
1691 memcpy(buf, chars + start, length * sizeof(jchar));
1692 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001693 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001694 }
1695
Ian Rogersbc939662013-08-15 10:26:54 -07001696 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1697 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001698 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001699 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001700 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001701 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001702 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001703 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001704 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001705 if (s->IsCompressed()) {
1706 for (int i = 0; i < length; ++i) {
1707 buf[i] = s->CharAt(start+i);
1708 }
1709 } else {
1710 const jchar* chars = s->GetValue();
1711 size_t bytes = CountUtf8Bytes(chars + start, length);
1712 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1713 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001714 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001715 }
1716
Elliott Hughes75770752011-08-24 17:52:38 -07001717 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001718 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001719 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001720 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001721 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001722 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001723 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001724 if (s->IsCompressed()) {
1725 int32_t length = s->GetLength();
1726 for (int i = 0; i < length; ++i) {
1727 chars[i] = s->CharAt(i);
1728 }
1729 } else {
1730 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1731 }
Fred Shih56890e22014-06-02 11:11:52 -07001732 if (is_copy != nullptr) {
1733 *is_copy = JNI_TRUE;
1734 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001735 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001736 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001737 if (is_copy != nullptr) {
1738 *is_copy = JNI_FALSE;
1739 }
1740 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001741 }
1742
Mathieu Chartier590fee92013-09-13 13:46:47 -07001743 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001744 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001745 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001746 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001747 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001748 delete[] chars;
1749 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001750 }
1751
Elliott Hughes75770752011-08-24 17:52:38 -07001752 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001753 CHECK_NON_NULL_ARGUMENT(java_string);
1754 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001755 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001756 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001757 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001758 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -07001759 HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001760 if (!kUseReadBarrier) {
1761 heap->IncrementDisableMovingGC(soa.Self());
1762 } else {
1763 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1764 // to occur thanks to the to-space invariant.
1765 heap->IncrementDisableThreadFlip(soa.Self());
1766 }
Fred Shih56890e22014-06-02 11:11:52 -07001767 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001768 if (s->IsCompressed()) {
1769 if (is_copy != nullptr) {
1770 *is_copy = JNI_TRUE;
1771 }
1772 int32_t length = s->GetLength();
1773 jchar* chars = new jchar[length];
1774 for (int i = 0; i < length; ++i) {
1775 chars[i] = s->CharAt(i);
1776 }
1777 return chars;
1778 } else {
1779 if (is_copy != nullptr) {
1780 *is_copy = JNI_FALSE;
1781 }
1782 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001783 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001784 }
1785
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001786 static void ReleaseStringCritical(JNIEnv* env,
1787 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001788 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001789 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1790 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001791 gc::Heap* heap = Runtime::Current()->GetHeap();
Mathieu Chartier0795f232016-09-27 18:43:30 -07001792 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001793 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001794 if (!kUseReadBarrier) {
1795 heap->DecrementDisableMovingGC(soa.Self());
1796 } else {
1797 heap->DecrementDisableThreadFlip(soa.Self());
1798 }
Fred Shih56890e22014-06-02 11:11:52 -07001799 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001800 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1801 delete[] chars;
1802 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001803 }
1804
Elliott Hughes75770752011-08-24 17:52:38 -07001805 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001806 if (java_string == nullptr) {
1807 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001808 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001809 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001810 *is_copy = JNI_TRUE;
1811 }
Ian Rogersef28b142012-11-30 14:22:18 -08001812 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001813 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001814 size_t byte_count = s->GetUtfLength();
1815 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001816 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001817 if (s->IsCompressed()) {
1818 for (size_t i = 0; i < byte_count; ++i) {
1819 bytes[i] = s->CharAt(i);
1820 }
1821 } else {
1822 const uint16_t* chars = s->GetValue();
1823 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1824 }
Elliott Hughes75770752011-08-24 17:52:38 -07001825 bytes[byte_count] = '\0';
1826 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001827 }
1828
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001829 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001830 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001831 }
1832
Elliott Hughesbd935992011-08-22 11:59:34 -07001833 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001835 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001836 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001837 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001838 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1839 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001840 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001841 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001842 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001843 }
1844
Elliott Hughes814e4032011-08-23 12:07:56 -07001845 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001846 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001847 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001848 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1849 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001850 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001851 }
1852
Ian Rogersbc939662013-08-15 10:26:54 -07001853 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1854 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001855 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001856 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001857 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1858 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
1859 ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value);
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001860 array->Set<false>(index, value.Ptr());
Elliott Hughescdf53122011-08-19 15:46:09 -07001861 }
1862
1863 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001864 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001865 }
1866
1867 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001868 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001869 }
1870
1871 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001872 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001873 }
1874
1875 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001876 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001877 }
1878
1879 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001880 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001881 }
1882
1883 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001884 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001885 }
1886
1887 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001888 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001889 }
1890
Ian Rogers1d99e452014-01-02 17:36:41 -08001891 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1892 jobject initial_element) {
1893 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001894 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001895 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001896 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001897 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001898
1899 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001900 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001901 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001902 {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001903 mirror::Class* element_class = soa.Decode<mirror::Class>(element_jclass).Ptr();
Ian Rogers1d99e452014-01-02 17:36:41 -08001904 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001905 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1906 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001907 return nullptr;
1908 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001909 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001910 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001911 if (UNLIKELY(array_class == nullptr)) {
1912 return nullptr;
1913 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001914 }
1915
Elliott Hughes75770752011-08-24 17:52:38 -07001916 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001917 mirror::ObjectArray<mirror::Object>* result =
1918 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001919 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001920 ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001921 if (initial_object != nullptr) {
1922 mirror::Class* element_class = result->GetClass()->GetComponentType();
1923 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001924 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1925 "element type of '%s'",
1926 PrettyDescriptor(initial_object->GetClass()).c_str(),
1927 PrettyDescriptor(element_class).c_str());
1928 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001929 } else {
1930 for (jsize i = 0; i < length; ++i) {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001931 result->SetWithoutChecks<false>(i, initial_object.Ptr());
Ian Rogers1d99e452014-01-02 17:36:41 -08001932 }
1933 }
Elliott Hughes75770752011-08-24 17:52:38 -07001934 }
1935 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001936 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001937 }
1938
1939 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001940 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001941 }
1942
Ian Rogersa15e67d2012-02-28 13:51:55 -08001943 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001944 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001945 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001946 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001947 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001948 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1949 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001950 return nullptr;
1951 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001952 gc::Heap* heap = Runtime::Current()->GetHeap();
1953 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001954 if (!kUseReadBarrier) {
1955 heap->IncrementDisableMovingGC(soa.Self());
1956 } else {
1957 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1958 // to occur thanks to the to-space invariant.
1959 heap->IncrementDisableThreadFlip(soa.Self());
1960 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001961 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartier0795f232016-09-27 18:43:30 -07001962 array = soa.Decode<mirror::Array>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001963 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001964 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001965 *is_copy = JNI_FALSE;
1966 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001967 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001968 }
1969
Ian Rogers2d10b202014-05-12 19:15:18 -07001970 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1971 jint mode) {
1972 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1973 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001974 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001975 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001976 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1977 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001978 return;
1979 }
1980 const size_t component_size = array->GetClass()->GetComponentSize();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001981 ReleasePrimitiveArray(soa, array.Ptr(), component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001982 }
1983
Elliott Hughes75770752011-08-24 17:52:38 -07001984 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001985 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001986 }
1987
Elliott Hughes75770752011-08-24 17:52:38 -07001988 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001989 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001990 }
1991
Elliott Hughes75770752011-08-24 17:52:38 -07001992 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001993 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001994 }
1995
Elliott Hughes75770752011-08-24 17:52:38 -07001996 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001997 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001998 }
1999
Elliott Hughes75770752011-08-24 17:52:38 -07002000 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002001 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002002 }
2003
Elliott Hughes75770752011-08-24 17:52:38 -07002004 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002005 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002006 }
2007
Elliott Hughes75770752011-08-24 17:52:38 -07002008 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002009 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002010 }
2011
Elliott Hughes75770752011-08-24 17:52:38 -07002012 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002013 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002014 }
2015
Mathieu Chartier590fee92013-09-13 13:46:47 -07002016 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2017 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002018 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2019 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002020 }
2021
Mathieu Chartier590fee92013-09-13 13:46:47 -07002022 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002023 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002024 }
2025
Mathieu Chartier590fee92013-09-13 13:46:47 -07002026 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002027 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002028 }
2029
Mathieu Chartier590fee92013-09-13 13:46:47 -07002030 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2031 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002032 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002033 }
2034
Mathieu Chartier590fee92013-09-13 13:46:47 -07002035 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2036 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002037 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002038 }
2039
Mathieu Chartier590fee92013-09-13 13:46:47 -07002040 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002041 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002042 }
2043
Mathieu Chartier590fee92013-09-13 13:46:47 -07002044 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002045 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002046 }
2047
Mathieu Chartier590fee92013-09-13 13:46:47 -07002048 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2049 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002050 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002051 }
2052
Ian Rogersbc939662013-08-15 10:26:54 -07002053 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2054 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002055 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002056 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002057 }
2058
Ian Rogersbc939662013-08-15 10:26:54 -07002059 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2060 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002061 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002062 }
2063
Ian Rogersbc939662013-08-15 10:26:54 -07002064 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2065 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002066 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002067 }
2068
Ian Rogersbc939662013-08-15 10:26:54 -07002069 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2070 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002071 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002072 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002073 }
2074
Ian Rogersbc939662013-08-15 10:26:54 -07002075 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2076 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002077 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002078 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002079 }
2080
Ian Rogersbc939662013-08-15 10:26:54 -07002081 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2082 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002083 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002084 }
2085
Ian Rogersbc939662013-08-15 10:26:54 -07002086 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2087 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002088 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002089 }
2090
Ian Rogersbc939662013-08-15 10:26:54 -07002091 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2092 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002093 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002094 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002095 }
2096
Ian Rogersbc939662013-08-15 10:26:54 -07002097 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2098 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002099 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002100 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002101 }
2102
Ian Rogersbc939662013-08-15 10:26:54 -07002103 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2104 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002105 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002106 }
2107
Ian Rogersbc939662013-08-15 10:26:54 -07002108 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2109 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002110 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002111 }
2112
Ian Rogersbc939662013-08-15 10:26:54 -07002113 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2114 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002115 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002116 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002117 }
2118
Ian Rogersbc939662013-08-15 10:26:54 -07002119 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2120 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002121 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002122 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002123 }
2124
Ian Rogersbc939662013-08-15 10:26:54 -07002125 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2126 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002127 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002128 }
2129
Ian Rogersbc939662013-08-15 10:26:54 -07002130 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2131 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002132 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002133 }
2134
Ian Rogersbc939662013-08-15 10:26:54 -07002135 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2136 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002137 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002138 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002139 }
2140
Ian Rogersbc939662013-08-15 10:26:54 -07002141 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2142 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002143 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2144 }
2145
Ian Rogersbc939662013-08-15 10:26:54 -07002146 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2147 jint method_count, bool return_errors) {
2148 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002149 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2150 method_count);
2151 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002152 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002153 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002154 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002155 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002156 if (UNLIKELY(method_count == 0)) {
2157 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2158 << PrettyDescriptor(c);
2159 return JNI_OK;
2160 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002161 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002162 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002163 const char* name = methods[i].name;
2164 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002165 const void* fnPtr = methods[i].fnPtr;
2166 if (UNLIKELY(name == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002167 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002168 return JNI_ERR;
2169 } else if (UNLIKELY(sig == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002170 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002171 return JNI_ERR;
2172 } else if (UNLIKELY(fnPtr == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002173 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002174 return JNI_ERR;
2175 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002176 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002177 // Notes about fast JNI calls:
2178 //
2179 // On a normal JNI call, the calling thread usually transitions
2180 // from the kRunnable state to the kNative state. But if the
2181 // called native function needs to access any Java object, it
2182 // will have to transition back to the kRunnable state.
2183 //
2184 // There is a cost to this double transition. For a JNI call
2185 // that should be quick, this cost may dominate the call cost.
2186 //
2187 // On a fast JNI call, the calling thread avoids this double
2188 // transition by not transitioning from kRunnable to kNative and
2189 // stays in the kRunnable state.
2190 //
2191 // There are risks to using a fast JNI call because it can delay
2192 // a response to a thread suspension request which is typically
2193 // used for a GC root scanning, etc. If a fast JNI call takes a
2194 // long time, it could cause longer thread suspension latency
2195 // and GC pauses.
2196 //
2197 // Thus, fast JNI should be used with care. It should be used
2198 // for a JNI call that takes a short amount of time (eg. no
2199 // long-running loop) and does not block (eg. no locks, I/O,
2200 // etc.)
2201 //
2202 // A '!' prefix in the signature in the JNINativeMethod
2203 // indicates that it's a fast JNI call and the runtime omits the
2204 // thread state transition from kRunnable to kNative at the
2205 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002206 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002207 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002208 ++sig;
2209 }
2210
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002211 // Note: the right order is to try to find the method locally
2212 // first, either as a direct or a virtual method. Then move to
2213 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002214 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002215 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
Mathieu Chartier0795f232016-09-27 18:43:30 -07002216 for (ObjPtr<mirror::Class> current_class = c;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002217 current_class != nullptr;
2218 current_class = current_class->GetSuperClass()) {
2219 // Search first only comparing methods which are native.
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002220 m = FindMethod<true>(current_class.Ptr(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002221 if (m != nullptr) {
2222 break;
2223 }
2224
2225 // Search again comparing to all methods, to find non-native methods that match.
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002226 m = FindMethod<false>(current_class.Ptr(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002227 if (m != nullptr) {
2228 break;
2229 }
2230
2231 if (warn_on_going_to_parent) {
2232 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2233 << "This is slow, consider changing your RegisterNatives calls.";
2234 warn_on_going_to_parent = false;
2235 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002236 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002237
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002238 if (m == nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002239 c->DumpClass(
2240 LOG_STREAM(return_errors
2241 ? ::android::base::ERROR
2242 : ::android::base::FATAL_WITHOUT_ABORT),
2243 mirror::Class::kDumpClassFullDetail);
2244 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2245 << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002246 << PrettyDescriptor(c) << "." << name << sig << " in "
2247 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002248 ThrowNoSuchMethodError(soa, c.Ptr(), name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002249 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002250 } else if (!m->IsNative()) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002251 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2252 << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002253 << PrettyDescriptor(c) << "." << name << sig
2254 << " as native";
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002255 ThrowNoSuchMethodError(soa, c.Ptr(), name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002256 return JNI_ERR;
2257 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002258
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002259 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002260
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002261 is_fast = is_fast || m->IsFastNative(); // Merge with @FastNative state.
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002262 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002263 }
2264 return JNI_OK;
2265 }
2266
Elliott Hughes5174fe62011-08-23 15:12:35 -07002267 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002268 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002269 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002270 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002271
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002272 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002273
Ian Rogers2d10b202014-05-12 19:15:18 -07002274 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002275 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002276 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002277 if (m.IsNative()) {
2278 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002279 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002280 }
2281 }
2282
Ian Rogers2d10b202014-05-12 19:15:18 -07002283 if (unregistered_count == 0) {
2284 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2285 << PrettyDescriptor(c) << "' that contains no native methods";
2286 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002287 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002288 }
2289
Ian Rogers719d1a32014-03-06 12:13:39 -08002290 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002291 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002292 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002293 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002294 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002295 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002296 return JNI_ERR;
2297 }
Mathieu Chartierc4f39252016-10-05 18:32:08 -07002298 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002299 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002300 }
2301
Ian Rogers719d1a32014-03-06 12:13:39 -08002302 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002303 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002304 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002305 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002306 o->MonitorExit(soa.Self());
2307 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002308 return JNI_ERR;
2309 }
Mathieu Chartierc4f39252016-10-05 18:32:08 -07002310 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002311 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002312 }
2313
2314 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002315 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002316 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002317 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002318 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002319 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002320 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002321 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002322 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002323 }
2324
Elliott Hughescdf53122011-08-19 15:46:09 -07002325 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002326 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002327 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2328 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002329 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002330 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002331 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002332 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2333 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002334 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002335 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002336
Brian Carlstrom85a93362014-06-25 09:30:52 -07002337 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002338 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002339 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2340 "buffer capacity greater than maximum jint: %" PRId64,
2341 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002342 return nullptr;
2343 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002344 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002345 jint capacity_arg = static_cast<jint>(capacity);
2346
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002347 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2348 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002349 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002350 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002351 }
2352
Elliott Hughesb465ab02011-08-24 11:21:21 -07002353 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002354 return reinterpret_cast<void*>(env->GetLongField(
2355 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002356 }
2357
Elliott Hughesb465ab02011-08-24 11:21:21 -07002358 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002359 return static_cast<jlong>(env->GetIntField(
2360 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002361 }
2362
Andreas Gampea8763072014-12-20 00:08:35 -08002363 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2364 if (java_object == nullptr) {
2365 return JNIInvalidRefType;
2366 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002367
2368 // Do we definitely know what kind of reference this is?
2369 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2370 IndirectRefKind kind = GetIndirectRefKind(ref);
2371 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002372 case kLocal:
2373 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002374 case kGlobal:
2375 return JNIGlobalRefType;
2376 case kWeakGlobal:
2377 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002378 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002379 // Assume value is in a handle scope.
2380 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002381 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002382 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002383 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002384 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002385
2386 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002387 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2388 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002389 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002390 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002391 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002392 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2393 return JNI_ERR;
2394 }
2395 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002396 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002397 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2398 if (!okay) {
2399 soa.Self()->ThrowOutOfMemoryError(caller);
2400 }
2401 return okay ? JNI_OK : JNI_ERR;
2402 }
2403
2404 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002405 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002406 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002407 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002408 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002409 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002410 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002411 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002412 return soa.AddLocalReference<JniT>(result);
2413 }
2414
Ian Rogers2d10b202014-05-12 19:15:18 -07002415 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2416 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2417 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002418 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002419 ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002420 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002421 soa.Vm()->JniAbortF(fn_name,
2422 "attempt to %s %s primitive array elements with an object of type %s",
2423 operation,
2424 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2425 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002426 return nullptr;
2427 }
2428 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002429 return array.Ptr();
Ian Rogers2d10b202014-05-12 19:15:18 -07002430 }
2431
2432 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2433 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2434 CHECK_NON_NULL_ARGUMENT(java_array);
2435 ScopedObjectAccess soa(env);
2436 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2437 "GetArrayElements",
2438 "get");
2439 if (UNLIKELY(array == nullptr)) {
2440 return nullptr;
2441 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002442 // Only make a copy if necessary.
2443 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2444 if (is_copy != nullptr) {
2445 *is_copy = JNI_TRUE;
2446 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002447 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002448 size_t size = array->GetLength() * component_size;
2449 void* data = new uint64_t[RoundUp(size, 8) / 8];
2450 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002451 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002452 } else {
2453 if (is_copy != nullptr) {
2454 *is_copy = JNI_FALSE;
2455 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002456 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002457 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002458 }
2459
Ian Rogers2d10b202014-05-12 19:15:18 -07002460 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002461 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002462 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002463 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002464 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2465 "ReleaseArrayElements",
2466 "release");
2467 if (array == nullptr) {
2468 return;
2469 }
2470 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2471 }
2472
2473 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2474 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002475 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002476 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002477 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002478 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002479 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002480 if (is_copy) {
2481 // Sanity check: If elements is not the same as the java array's data, it better not be a
2482 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2483 // copies we make?
Mathieu Chartier9d156d52016-10-06 17:44:26 -07002484 if (heap->IsNonDiscontinuousSpaceHeapAddress(elements)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002485 soa.Vm()->JniAbortF("ReleaseArrayElements",
2486 "invalid element pointer %p, array elements are %p",
2487 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002488 return;
2489 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002490 if (mode != JNI_ABORT) {
2491 memcpy(array_data, elements, bytes);
2492 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2493 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2494 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002495 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002496 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002497 }
2498 if (mode != JNI_COMMIT) {
2499 if (is_copy) {
2500 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002501 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002502 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002503 if (!kUseReadBarrier) {
2504 heap->DecrementDisableMovingGC(soa.Self());
2505 } else {
2506 heap->DecrementDisableThreadFlip(soa.Self());
2507 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002508 }
2509 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002510 }
2511
Ian Rogers2d10b202014-05-12 19:15:18 -07002512 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2513 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2514 jsize start, jsize length, ElementT* buf) {
2515 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2516 ScopedObjectAccess soa(env);
2517 ArtArrayT* array =
2518 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2519 "GetPrimitiveArrayRegion",
2520 "get region of");
2521 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002522 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002523 ThrowAIOOBE(soa, array, start, length, "src");
2524 } else {
2525 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2526 ElementT* data = array->GetData();
2527 memcpy(buf, data + start, length * sizeof(ElementT));
2528 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002529 }
2530 }
2531
Ian Rogers2d10b202014-05-12 19:15:18 -07002532 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2533 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2534 jsize start, jsize length, const ElementT* buf) {
2535 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2536 ScopedObjectAccess soa(env);
2537 ArtArrayT* array =
2538 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2539 "SetPrimitiveArrayRegion",
2540 "set region of");
2541 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002542 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002543 ThrowAIOOBE(soa, array, start, length, "dst");
2544 } else {
2545 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2546 ElementT* data = array->GetData();
2547 memcpy(data + start, buf, length * sizeof(ElementT));
2548 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002549 }
2550 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002551};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002552
Elliott Hughes88c5c352012-03-15 18:49:48 -07002553const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002554 nullptr, // reserved0.
2555 nullptr, // reserved1.
2556 nullptr, // reserved2.
2557 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002558 JNI::GetVersion,
2559 JNI::DefineClass,
2560 JNI::FindClass,
2561 JNI::FromReflectedMethod,
2562 JNI::FromReflectedField,
2563 JNI::ToReflectedMethod,
2564 JNI::GetSuperclass,
2565 JNI::IsAssignableFrom,
2566 JNI::ToReflectedField,
2567 JNI::Throw,
2568 JNI::ThrowNew,
2569 JNI::ExceptionOccurred,
2570 JNI::ExceptionDescribe,
2571 JNI::ExceptionClear,
2572 JNI::FatalError,
2573 JNI::PushLocalFrame,
2574 JNI::PopLocalFrame,
2575 JNI::NewGlobalRef,
2576 JNI::DeleteGlobalRef,
2577 JNI::DeleteLocalRef,
2578 JNI::IsSameObject,
2579 JNI::NewLocalRef,
2580 JNI::EnsureLocalCapacity,
2581 JNI::AllocObject,
2582 JNI::NewObject,
2583 JNI::NewObjectV,
2584 JNI::NewObjectA,
2585 JNI::GetObjectClass,
2586 JNI::IsInstanceOf,
2587 JNI::GetMethodID,
2588 JNI::CallObjectMethod,
2589 JNI::CallObjectMethodV,
2590 JNI::CallObjectMethodA,
2591 JNI::CallBooleanMethod,
2592 JNI::CallBooleanMethodV,
2593 JNI::CallBooleanMethodA,
2594 JNI::CallByteMethod,
2595 JNI::CallByteMethodV,
2596 JNI::CallByteMethodA,
2597 JNI::CallCharMethod,
2598 JNI::CallCharMethodV,
2599 JNI::CallCharMethodA,
2600 JNI::CallShortMethod,
2601 JNI::CallShortMethodV,
2602 JNI::CallShortMethodA,
2603 JNI::CallIntMethod,
2604 JNI::CallIntMethodV,
2605 JNI::CallIntMethodA,
2606 JNI::CallLongMethod,
2607 JNI::CallLongMethodV,
2608 JNI::CallLongMethodA,
2609 JNI::CallFloatMethod,
2610 JNI::CallFloatMethodV,
2611 JNI::CallFloatMethodA,
2612 JNI::CallDoubleMethod,
2613 JNI::CallDoubleMethodV,
2614 JNI::CallDoubleMethodA,
2615 JNI::CallVoidMethod,
2616 JNI::CallVoidMethodV,
2617 JNI::CallVoidMethodA,
2618 JNI::CallNonvirtualObjectMethod,
2619 JNI::CallNonvirtualObjectMethodV,
2620 JNI::CallNonvirtualObjectMethodA,
2621 JNI::CallNonvirtualBooleanMethod,
2622 JNI::CallNonvirtualBooleanMethodV,
2623 JNI::CallNonvirtualBooleanMethodA,
2624 JNI::CallNonvirtualByteMethod,
2625 JNI::CallNonvirtualByteMethodV,
2626 JNI::CallNonvirtualByteMethodA,
2627 JNI::CallNonvirtualCharMethod,
2628 JNI::CallNonvirtualCharMethodV,
2629 JNI::CallNonvirtualCharMethodA,
2630 JNI::CallNonvirtualShortMethod,
2631 JNI::CallNonvirtualShortMethodV,
2632 JNI::CallNonvirtualShortMethodA,
2633 JNI::CallNonvirtualIntMethod,
2634 JNI::CallNonvirtualIntMethodV,
2635 JNI::CallNonvirtualIntMethodA,
2636 JNI::CallNonvirtualLongMethod,
2637 JNI::CallNonvirtualLongMethodV,
2638 JNI::CallNonvirtualLongMethodA,
2639 JNI::CallNonvirtualFloatMethod,
2640 JNI::CallNonvirtualFloatMethodV,
2641 JNI::CallNonvirtualFloatMethodA,
2642 JNI::CallNonvirtualDoubleMethod,
2643 JNI::CallNonvirtualDoubleMethodV,
2644 JNI::CallNonvirtualDoubleMethodA,
2645 JNI::CallNonvirtualVoidMethod,
2646 JNI::CallNonvirtualVoidMethodV,
2647 JNI::CallNonvirtualVoidMethodA,
2648 JNI::GetFieldID,
2649 JNI::GetObjectField,
2650 JNI::GetBooleanField,
2651 JNI::GetByteField,
2652 JNI::GetCharField,
2653 JNI::GetShortField,
2654 JNI::GetIntField,
2655 JNI::GetLongField,
2656 JNI::GetFloatField,
2657 JNI::GetDoubleField,
2658 JNI::SetObjectField,
2659 JNI::SetBooleanField,
2660 JNI::SetByteField,
2661 JNI::SetCharField,
2662 JNI::SetShortField,
2663 JNI::SetIntField,
2664 JNI::SetLongField,
2665 JNI::SetFloatField,
2666 JNI::SetDoubleField,
2667 JNI::GetStaticMethodID,
2668 JNI::CallStaticObjectMethod,
2669 JNI::CallStaticObjectMethodV,
2670 JNI::CallStaticObjectMethodA,
2671 JNI::CallStaticBooleanMethod,
2672 JNI::CallStaticBooleanMethodV,
2673 JNI::CallStaticBooleanMethodA,
2674 JNI::CallStaticByteMethod,
2675 JNI::CallStaticByteMethodV,
2676 JNI::CallStaticByteMethodA,
2677 JNI::CallStaticCharMethod,
2678 JNI::CallStaticCharMethodV,
2679 JNI::CallStaticCharMethodA,
2680 JNI::CallStaticShortMethod,
2681 JNI::CallStaticShortMethodV,
2682 JNI::CallStaticShortMethodA,
2683 JNI::CallStaticIntMethod,
2684 JNI::CallStaticIntMethodV,
2685 JNI::CallStaticIntMethodA,
2686 JNI::CallStaticLongMethod,
2687 JNI::CallStaticLongMethodV,
2688 JNI::CallStaticLongMethodA,
2689 JNI::CallStaticFloatMethod,
2690 JNI::CallStaticFloatMethodV,
2691 JNI::CallStaticFloatMethodA,
2692 JNI::CallStaticDoubleMethod,
2693 JNI::CallStaticDoubleMethodV,
2694 JNI::CallStaticDoubleMethodA,
2695 JNI::CallStaticVoidMethod,
2696 JNI::CallStaticVoidMethodV,
2697 JNI::CallStaticVoidMethodA,
2698 JNI::GetStaticFieldID,
2699 JNI::GetStaticObjectField,
2700 JNI::GetStaticBooleanField,
2701 JNI::GetStaticByteField,
2702 JNI::GetStaticCharField,
2703 JNI::GetStaticShortField,
2704 JNI::GetStaticIntField,
2705 JNI::GetStaticLongField,
2706 JNI::GetStaticFloatField,
2707 JNI::GetStaticDoubleField,
2708 JNI::SetStaticObjectField,
2709 JNI::SetStaticBooleanField,
2710 JNI::SetStaticByteField,
2711 JNI::SetStaticCharField,
2712 JNI::SetStaticShortField,
2713 JNI::SetStaticIntField,
2714 JNI::SetStaticLongField,
2715 JNI::SetStaticFloatField,
2716 JNI::SetStaticDoubleField,
2717 JNI::NewString,
2718 JNI::GetStringLength,
2719 JNI::GetStringChars,
2720 JNI::ReleaseStringChars,
2721 JNI::NewStringUTF,
2722 JNI::GetStringUTFLength,
2723 JNI::GetStringUTFChars,
2724 JNI::ReleaseStringUTFChars,
2725 JNI::GetArrayLength,
2726 JNI::NewObjectArray,
2727 JNI::GetObjectArrayElement,
2728 JNI::SetObjectArrayElement,
2729 JNI::NewBooleanArray,
2730 JNI::NewByteArray,
2731 JNI::NewCharArray,
2732 JNI::NewShortArray,
2733 JNI::NewIntArray,
2734 JNI::NewLongArray,
2735 JNI::NewFloatArray,
2736 JNI::NewDoubleArray,
2737 JNI::GetBooleanArrayElements,
2738 JNI::GetByteArrayElements,
2739 JNI::GetCharArrayElements,
2740 JNI::GetShortArrayElements,
2741 JNI::GetIntArrayElements,
2742 JNI::GetLongArrayElements,
2743 JNI::GetFloatArrayElements,
2744 JNI::GetDoubleArrayElements,
2745 JNI::ReleaseBooleanArrayElements,
2746 JNI::ReleaseByteArrayElements,
2747 JNI::ReleaseCharArrayElements,
2748 JNI::ReleaseShortArrayElements,
2749 JNI::ReleaseIntArrayElements,
2750 JNI::ReleaseLongArrayElements,
2751 JNI::ReleaseFloatArrayElements,
2752 JNI::ReleaseDoubleArrayElements,
2753 JNI::GetBooleanArrayRegion,
2754 JNI::GetByteArrayRegion,
2755 JNI::GetCharArrayRegion,
2756 JNI::GetShortArrayRegion,
2757 JNI::GetIntArrayRegion,
2758 JNI::GetLongArrayRegion,
2759 JNI::GetFloatArrayRegion,
2760 JNI::GetDoubleArrayRegion,
2761 JNI::SetBooleanArrayRegion,
2762 JNI::SetByteArrayRegion,
2763 JNI::SetCharArrayRegion,
2764 JNI::SetShortArrayRegion,
2765 JNI::SetIntArrayRegion,
2766 JNI::SetLongArrayRegion,
2767 JNI::SetFloatArrayRegion,
2768 JNI::SetDoubleArrayRegion,
2769 JNI::RegisterNatives,
2770 JNI::UnregisterNatives,
2771 JNI::MonitorEnter,
2772 JNI::MonitorExit,
2773 JNI::GetJavaVM,
2774 JNI::GetStringRegion,
2775 JNI::GetStringUTFRegion,
2776 JNI::GetPrimitiveArrayCritical,
2777 JNI::ReleasePrimitiveArrayCritical,
2778 JNI::GetStringCritical,
2779 JNI::ReleaseStringCritical,
2780 JNI::NewWeakGlobalRef,
2781 JNI::DeleteWeakGlobalRef,
2782 JNI::ExceptionCheck,
2783 JNI::NewDirectByteBuffer,
2784 JNI::GetDirectBufferAddress,
2785 JNI::GetDirectBufferCapacity,
2786 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002787};
2788
Ian Rogers68d8b422014-07-17 11:09:10 -07002789const JNINativeInterface* GetJniNativeInterface() {
2790 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002791}
2792
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002793void (*gJniSleepForeverStub[])() = {
2794 nullptr, // reserved0.
2795 nullptr, // reserved1.
2796 nullptr, // reserved2.
2797 nullptr, // reserved3.
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 SleepForever,
2974 SleepForever,
2975 SleepForever,
2976 SleepForever,
2977 SleepForever,
2978 SleepForever,
2979 SleepForever,
2980 SleepForever,
2981 SleepForever,
2982 SleepForever,
2983 SleepForever,
2984 SleepForever,
2985 SleepForever,
2986 SleepForever,
2987 SleepForever,
2988 SleepForever,
2989 SleepForever,
2990 SleepForever,
2991 SleepForever,
2992 SleepForever,
2993 SleepForever,
2994 SleepForever,
2995 SleepForever,
2996 SleepForever,
2997 SleepForever,
2998 SleepForever,
2999 SleepForever,
3000 SleepForever,
3001 SleepForever,
3002 SleepForever,
3003 SleepForever,
3004 SleepForever,
3005 SleepForever,
3006 SleepForever,
3007 SleepForever,
3008 SleepForever,
3009 SleepForever,
3010 SleepForever,
3011 SleepForever,
3012 SleepForever,
3013 SleepForever,
3014 SleepForever,
3015 SleepForever,
3016 SleepForever,
3017 SleepForever,
3018 SleepForever,
3019 SleepForever,
3020 SleepForever,
3021 SleepForever,
3022 SleepForever,
3023 SleepForever,
3024 SleepForever,
3025 SleepForever,
3026 SleepForever,
3027};
3028
3029const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3030 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3031}
3032
Elliott Hughesc8fece32013-01-02 11:27:23 -08003033void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003034 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003035 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003036 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003037 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3038 }
3039 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3040}
3041
Ian Rogersdf20fe02011-07-20 20:34:16 -07003042} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003043
3044std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3045 switch (rhs) {
3046 case JNIInvalidRefType:
3047 os << "JNIInvalidRefType";
3048 return os;
3049 case JNILocalRefType:
3050 os << "JNILocalRefType";
3051 return os;
3052 case JNIGlobalRefType:
3053 os << "JNIGlobalRefType";
3054 return os;
3055 case JNIWeakGlobalRefType:
3056 os << "JNIWeakGlobalRefType";
3057 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003058 default:
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07003059 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Ian Rogersc7dd2952014-10-21 23:31:19 -07003060 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003061 }
3062}