blob: 5418d3569e1b29e59034b8228c9b88befa332825 [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 Chartier6b3d12b2016-10-13 13:59:58 -070091static void ThrowNoSuchMethodError(ScopedObjectAccess& soa,
92 ObjPtr<mirror::Class> c,
93 const char* name,
94 const char* sig,
95 const char* kind)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070096 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -070097 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000098 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Ian Rogers62d6c772013-02-27 08:32:07 -080099 "no %s method \"%s.%s%s\"",
Mathieu Chartier6b3d12b2016-10-13 13:59:58 -0700100 kind,
101 c->GetDescriptor(&temp),
102 name,
103 sig);
Elliott Hughes14134a12011-09-30 16:55:51 -0700104}
105
Mathieu Chartier3398c782016-09-30 10:27:43 -0700106static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa,
107 ObjPtr<mirror::Class> c,
108 const char* kind,
109 jint idx,
110 bool return_errors)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700111 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -0700112 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
David Sehr709b0702016-10-13 09:12:37 -0700113 << "Failed to register native method in " << c->PrettyDescriptor()
Andreas Gampe3fec9ac2016-09-13 10:47:28 -0700114 << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200115 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000116 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Mathieu Chartier3398c782016-09-30 10:27:43 -0700117 "%s is null at index %d",
118 kind,
119 idx);
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200120}
121
Mathieu Chartier0795f232016-09-27 18:43:30 -0700122static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700123 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800124 if (LIKELY(klass->IsInitialized())) {
125 return klass;
126 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700127 StackHandleScope<1> hs(self);
128 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700129 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800130 return nullptr;
131 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700132 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800133}
134
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700135static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
136 const char* name, const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700137 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700138 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800139 if (c == nullptr) {
140 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700141 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700142 ArtMethod* method = nullptr;
143 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700144 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700145 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700146 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700147 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700148 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700149 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800150 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700151 // No virtual method matching the signature. Search declared
152 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700153 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700154 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700155 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800156 if (method == nullptr || method->IsStatic() != is_static) {
Mathieu Chartier6b3d12b2016-10-13 13:59:58 -0700157 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800158 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700159 }
Andreas Gampe13b27842016-11-07 16:48:23 -0800160 return jni::EncodeArtMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700161}
162
Mathieu Chartier0795f232016-09-27 18:43:30 -0700163static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700164 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700165 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700166 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
Andreas Gampe13b27842016-11-07 16:48:23 -0800167 if (method == jni::DecodeArtMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700168 return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700169 }
Brian Carlstromce888532013-10-10 00:32:58 -0700170 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800171 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700172 return method->GetDeclaringClass()->GetClassLoader();
173 }
174 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700175 ObjPtr<mirror::ClassLoader> class_loader =
176 soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800177 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700178 return class_loader;
179 }
180 // See if the override ClassLoader is set for gtests.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700181 class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800182 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700183 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
184 // image.
185 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700186 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700187 return class_loader;
188 }
189 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800190 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700191}
192
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700193static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
194 const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700195 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700196 StackHandleScope<2> hs(soa.Self());
197 Handle<mirror::Class> c(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700198 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class))));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800199 if (c == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800200 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700201 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700202 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800203 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700204 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
205 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700206 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800207 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700208 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700209 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700210 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800211 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700212 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700213 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800214 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000215 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700216 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700217 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000218 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800219 "no type \"%s\" found and so no field \"%s\" "
220 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700221 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000222 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800223 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700224 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700225 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700226 if (is_static) {
Vladimir Marko19a4d372016-12-08 14:41:46 +0000227 field = mirror::Class::FindStaticField(
228 soa.Self(), c.Get(), name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700229 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700230 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700231 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800232 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000233 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800234 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700235 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800236 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700237 }
Andreas Gampe08883de2016-11-08 13:20:52 -0800238 return jni::EncodeArtField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700239}
240
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800241static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700242 jsize length, const char* identifier)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700243 REQUIRES_SHARED(Locks::mutator_lock_) {
David Sehr709b0702016-10-13 09:12:37 -0700244 std::string type(array->PrettyTypeOf());
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000245 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800246 "%s offset=%d length=%d %s.length=%d",
247 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700248}
Ian Rogers0571d352011-11-03 19:51:38 -0700249
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700250static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
251 jsize array_length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700252 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000253 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800254 "offset=%d length=%d string.length()=%d", start, length,
255 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700256}
Elliott Hughes814e4032011-08-23 12:07:56 -0700257
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700258int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700259 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700260 // Turn the const char* into a java.lang.String.
261 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800262 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700263 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700264 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700265
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266 // Choose an appropriate constructor and set up the arguments.
267 jvalue args[2];
268 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800269 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700270 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800271 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700272 signature = "(Ljava/lang/String;)V";
273 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800274 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700275 signature = "(Ljava/lang/Throwable;)V";
276 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700277 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700278 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
279 args[0].l = s.get();
280 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700281 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700282 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800283 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800284 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700285 LOG(ERROR) << "No <init>" << signature << " in "
David Sehr709b0702016-10-13 09:12:37 -0700286 << mirror::Class::PrettyClass(soa.Decode<mirror::Class>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700287 return JNI_ERR;
288 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700289
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800290 ScopedLocalRef<jthrowable> exception(
291 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
292 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700293 return JNI_ERR;
294 }
Ian Rogersef28b142012-11-30 14:22:18 -0800295 ScopedObjectAccess soa(env);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700296 soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700297 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700298}
299
Ian Rogers68d8b422014-07-17 11:09:10 -0700300static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
301 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700302}
303
Ian Rogers2d10b202014-05-12 19:15:18 -0700304#define CHECK_NON_NULL_ARGUMENT(value) \
305 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700306
Ian Rogers2d10b202014-05-12 19:15:18 -0700307#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
308 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
309
310#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
311 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
312
313#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
314 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
315
316#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700317 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700318 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700319 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700320 }
321
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700322#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700323 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700324 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700325 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700326 }
327
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700328template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700329static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700330 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700331 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800332 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700333 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
334 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700335 }
336 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700337 return nullptr;
338}
339
Elliott Hughescdf53122011-08-19 15:46:09 -0700340class JNI {
341 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700342 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700343 return JNI_VERSION_1_6;
344 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700345
Ian Rogers25e8b912012-09-07 11:31:36 -0700346 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700347 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800348 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700349 }
350
Elliott Hughescdf53122011-08-19 15:46:09 -0700351 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700352 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700353 Runtime* runtime = Runtime::Current();
354 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700355 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700356 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800357 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700358 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700359 StackHandleScope<1> hs(soa.Self());
360 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800361 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700362 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800363 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700364 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700365 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700366 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700367
Ian Rogers62f05122014-03-21 11:21:29 -0700368 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700369 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700370 ScopedObjectAccess soa(env);
Andreas Gampe13b27842016-11-07 16:48:23 -0800371 return jni::EncodeArtMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700372 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700373
Ian Rogers62f05122014-03-21 11:21:29 -0700374 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700375 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700376 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700377 ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700378 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700379 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700380 return nullptr;
381 }
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700382 ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(obj_field);
Andreas Gampe08883de2016-11-08 13:20:52 -0800383 return jni::EncodeArtField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700384 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700385
Elliott Hughescdf53122011-08-19 15:46:09 -0700386 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700387 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700388 ScopedObjectAccess soa(env);
Andreas Gampe13b27842016-11-07 16:48:23 -0800389 ArtMethod* m = jni::DecodeArtMethod(mid);
Neil Fuller0e844392016-09-08 13:43:31 +0100390 mirror::Executable* method;
Andreas Gampe542451c2016-07-26 09:02:02 -0700391 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
Andreas Gampee01e3642016-07-25 13:06:04 -0700392 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200393 if (m->IsConstructor()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700394 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200395 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700396 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200397 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700398 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700399 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700400
Elliott Hughescdf53122011-08-19 15:46:09 -0700401 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700402 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700403 ScopedObjectAccess soa(env);
Andreas Gampe08883de2016-11-08 13:20:52 -0800404 ArtField* f = jni::DecodeArtField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700405 return soa.AddLocalReference<jobject>(
Andreas Gampe542451c2016-07-26 09:02:02 -0700406 mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700407 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700408
Elliott Hughes37f7a402011-08-22 18:56:01 -0700409 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700410 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700411 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700412 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700413 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700414 }
415
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700416 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700417 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700418 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700419 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700420 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700421 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700422
Narayan Kamath1268b742014-07-11 19:15:11 +0100423 // Note: java_class1 should be safely castable to java_class2, and
424 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700425 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700426 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
427 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700428 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700429 ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
430 ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700431 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700432 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700433
Elliott Hughese84278b2012-03-22 10:06:53 -0700434 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700435 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800436 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700437 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700438 return JNI_TRUE;
439 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700440 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700441 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj);
442 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700443 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700444 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700445 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700446
Elliott Hughes37f7a402011-08-22 18:56:01 -0700447 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700448 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700449 ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800450 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700451 return JNI_ERR;
452 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700453 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700454 return JNI_OK;
455 }
456
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700457 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700458 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800459 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700460 }
461
462 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700463 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700464 }
465
466 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700467 ScopedObjectAccess soa(env);
468 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700469 }
470
471 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700472 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700473
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700474 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000475 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700476 return;
477 }
478
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000479 StackHandleScope<1> hs(soa.Self());
480 Handle<mirror::Throwable> old_exception(
481 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
482 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800483 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700484 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700485 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
486 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800487 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700488 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
David Sehr709b0702016-10-13 09:12:37 -0700489 << mirror::Object::PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700490 } else {
491 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800492 if (soa.Self()->IsExceptionPending()) {
David Sehr709b0702016-10-13 09:12:37 -0700493 LOG(WARNING) << "JNI WARNING: " << mirror::Object::PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700494 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800495 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700496 }
497 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000498 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700499 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700500
Elliott Hughescdf53122011-08-19 15:46:09 -0700501 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700502 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000503 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700504 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700505 }
506
Ian Rogers25e8b912012-09-07 11:31:36 -0700507 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700508 LOG(FATAL) << "JNI FatalError called: " << msg;
509 }
510
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700511 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700512 // TODO: SOA may not be necessary but I do it to please lock annotations.
513 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700514 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700515 return JNI_ERR;
516 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700517 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700518 return JNI_OK;
519 }
520
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700521 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700522 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700523 ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700524 soa.Env()->PopFrame();
525 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700526 }
527
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700528 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700529 // TODO: SOA may not be necessary but I do it to please lock annotations.
530 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700531 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700532 }
533
Elliott Hughescdf53122011-08-19 15:46:09 -0700534 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700535 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700536 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc4f39252016-10-05 18:32:08 -0700537 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700538 }
539
540 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700541 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
542 Thread* self = down_cast<JNIEnvExt*>(env)->self;
543 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700544 }
545
546 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700547 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700548 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc4f39252016-10-05 18:32:08 -0700549 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700550 }
551
552 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700553 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
554 Thread* self = down_cast<JNIEnvExt*>(env)->self;
555 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700556 }
557
558 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700559 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700560 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800561 // Check for null after decoding the object to handle cleared weak globals.
562 if (decoded_obj == nullptr) {
563 return nullptr;
564 }
565 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700566 }
567
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700568 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800569 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700570 return;
571 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700572 // SOA is only necessary to have exclusion between GC root marking and removing.
573 // We don't want to have the GC attempt to mark a null root if we just removed
574 // it. b/22119403
575 ScopedObjectAccess soa(env);
576 auto* ext_env = down_cast<JNIEnvExt*>(env);
577 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700578 // Attempting to delete a local reference that is not in the
579 // topmost local reference frame is a no-op. DeleteLocalRef returns
580 // void and doesn't throw any exceptions, but we should probably
581 // complain about it so the user will notice that things aren't
582 // going quite the way they expect.
583 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
584 << "failed to find entry";
585 }
586 }
587
588 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700589 if (obj1 == obj2) {
590 return JNI_TRUE;
591 } else {
592 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700593 return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2))
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800594 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700595 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700596 }
597
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700598 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700599 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700600 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700601 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800602 if (c == nullptr) {
603 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700604 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800605 if (c->IsStringClass()) {
606 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700607 return soa.AddLocalReference<jobject>(mirror::String::AllocEmptyString<true>(soa.Self(),
608 allocator_type));
Jeff Hao848f70a2014-01-15 13:49:50 -0800609 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700610 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700611 }
612
Ian Rogersbc939662013-08-15 10:26:54 -0700613 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700614 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700615 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700616 CHECK_NON_NULL_ARGUMENT(java_class);
617 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700618 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700619 va_end(args);
620 return result;
621 }
622
Elliott Hughes72025e52011-08-23 17:50:30 -0700623 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700624 CHECK_NON_NULL_ARGUMENT(java_class);
625 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700626 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700627 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
628 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800629 if (c == nullptr) {
630 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700631 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800632 if (c->IsStringClass()) {
633 // Replace calls to String.<init> with equivalent StringFactory call.
Andreas Gampe13b27842016-11-07 16:48:23 -0800634 jmethodID sf_mid = jni::EncodeArtMethod(
635 WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800636 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
637 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700638 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800639 if (result == nullptr) {
640 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700641 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700642 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700643 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800644 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800645 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700646 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800647 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700648 }
649
Elliott Hughes72025e52011-08-23 17:50:30 -0700650 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700651 CHECK_NON_NULL_ARGUMENT(java_class);
652 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700653 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700654 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
655 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800656 if (c == nullptr) {
657 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700658 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800659 if (c->IsStringClass()) {
660 // Replace calls to String.<init> with equivalent StringFactory call.
Andreas Gampe13b27842016-11-07 16:48:23 -0800661 jmethodID sf_mid = jni::EncodeArtMethod(
662 WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800663 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
664 }
Mathieu Chartier28bd2e42016-10-04 13:54:57 -0700665 ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800666 if (result == nullptr) {
667 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700668 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700669 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700670 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800671 if (soa.Self()->IsExceptionPending()) {
672 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700673 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800674 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700675 }
676
Ian Rogersbc939662013-08-15 10:26:54 -0700677 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700678 CHECK_NON_NULL_ARGUMENT(java_class);
679 CHECK_NON_NULL_ARGUMENT(name);
680 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700681 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700682 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700683 }
684
Ian Rogersbc939662013-08-15 10:26:54 -0700685 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
686 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700687 CHECK_NON_NULL_ARGUMENT(java_class);
688 CHECK_NON_NULL_ARGUMENT(name);
689 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700690 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700691 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700692 }
693
Elliott Hughes72025e52011-08-23 17:50:30 -0700694 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700695 va_list ap;
696 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700697 CHECK_NON_NULL_ARGUMENT(obj);
698 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700699 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700700 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700701 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700702 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700703 }
704
Elliott Hughes72025e52011-08-23 17:50:30 -0700705 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700706 CHECK_NON_NULL_ARGUMENT(obj);
707 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700708 ScopedObjectAccess soa(env);
709 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
710 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700711 }
712
Elliott Hughes72025e52011-08-23 17:50:30 -0700713 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700714 CHECK_NON_NULL_ARGUMENT(obj);
715 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700716 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700717 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700718 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700719 }
720
Elliott Hughes72025e52011-08-23 17:50:30 -0700721 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700722 va_list ap;
723 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700724 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
725 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700726 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700727 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700728 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700729 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700730 }
731
Elliott Hughes72025e52011-08-23 17:50:30 -0700732 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700733 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700735 ScopedObjectAccess soa(env);
736 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700737 }
738
Elliott Hughes72025e52011-08-23 17:50:30 -0700739 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700740 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
741 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700742 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700743 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700744 }
745
Elliott Hughes72025e52011-08-23 17:50:30 -0700746 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700747 va_list ap;
748 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700749 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
750 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700751 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700752 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700753 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700754 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700755 }
756
Elliott Hughes72025e52011-08-23 17:50:30 -0700757 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700758 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700760 ScopedObjectAccess soa(env);
761 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700762 }
763
Elliott Hughes72025e52011-08-23 17:50:30 -0700764 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700765 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
766 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700767 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700768 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700769 }
770
Elliott Hughes72025e52011-08-23 17:50:30 -0700771 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700772 va_list ap;
773 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700774 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
775 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700776 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700777 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700778 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700779 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700780 }
781
Elliott Hughes72025e52011-08-23 17:50:30 -0700782 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700783 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700785 ScopedObjectAccess soa(env);
786 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700787 }
788
Elliott Hughes72025e52011-08-23 17:50:30 -0700789 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700790 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
791 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700792 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700793 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700794 }
795
Elliott Hughes72025e52011-08-23 17:50:30 -0700796 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700797 va_list ap;
798 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700799 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
800 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700801 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700802 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700803 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700804 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700805 }
806
Elliott Hughes72025e52011-08-23 17:50:30 -0700807 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700808 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
809 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700810 ScopedObjectAccess soa(env);
811 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700812 }
813
Elliott Hughes72025e52011-08-23 17:50:30 -0700814 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700815 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
816 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700817 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700818 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700819 }
820
Elliott Hughes72025e52011-08-23 17:50:30 -0700821 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700822 va_list ap;
823 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700824 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700826 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700827 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700828 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700829 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700830 }
831
Elliott Hughes72025e52011-08-23 17:50:30 -0700832 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700833 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700835 ScopedObjectAccess soa(env);
836 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700837 }
838
Elliott Hughes72025e52011-08-23 17:50:30 -0700839 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700840 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
841 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700842 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700843 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700844 }
845
Elliott Hughes72025e52011-08-23 17:50:30 -0700846 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700847 va_list ap;
848 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700849 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
850 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700851 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700852 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700853 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700854 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700855 }
856
Elliott Hughes72025e52011-08-23 17:50:30 -0700857 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700858 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
859 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700860 ScopedObjectAccess soa(env);
861 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700862 }
863
Elliott Hughes72025e52011-08-23 17:50:30 -0700864 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700865 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
866 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700867 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700868 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700869 }
870
Elliott Hughes72025e52011-08-23 17:50:30 -0700871 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700872 va_list ap;
873 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700874 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
875 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700876 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700877 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700878 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700879 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700880 }
881
Elliott Hughes72025e52011-08-23 17:50:30 -0700882 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700883 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
884 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700885 ScopedObjectAccess soa(env);
886 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700887 }
888
Elliott Hughes72025e52011-08-23 17:50:30 -0700889 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700890 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
891 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700892 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700893 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700894 }
895
Elliott Hughes72025e52011-08-23 17:50:30 -0700896 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700897 va_list ap;
898 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700899 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
900 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700901 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700902 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700903 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700904 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700905 }
906
Elliott Hughes72025e52011-08-23 17:50:30 -0700907 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700908 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
909 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700910 ScopedObjectAccess soa(env);
911 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700912 }
913
Elliott Hughes72025e52011-08-23 17:50:30 -0700914 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700915 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
916 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700917 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700918 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700919 }
920
Elliott Hughes72025e52011-08-23 17:50:30 -0700921 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700922 va_list ap;
923 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700924 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
925 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700926 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700927 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700928 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700929 }
930
Elliott Hughes72025e52011-08-23 17:50:30 -0700931 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700932 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
933 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700934 ScopedObjectAccess soa(env);
935 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700936 }
937
Elliott Hughes72025e52011-08-23 17:50:30 -0700938 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700939 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
940 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700941 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700942 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700943 }
944
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700945 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700946 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700947 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700948 CHECK_NON_NULL_ARGUMENT(obj);
949 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700950 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700951 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
952 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700953 va_end(ap);
954 return local_result;
955 }
956
Ian Rogersbc939662013-08-15 10:26:54 -0700957 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
958 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700959 CHECK_NON_NULL_ARGUMENT(obj);
960 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700961 ScopedObjectAccess soa(env);
962 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
963 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700964 }
965
Ian Rogersbc939662013-08-15 10:26:54 -0700966 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
967 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700968 CHECK_NON_NULL_ARGUMENT(obj);
969 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700970 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700971 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700972 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700973 }
974
Ian Rogersbc939662013-08-15 10:26:54 -0700975 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
976 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700977 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700978 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700979 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
980 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700981 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700982 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700983 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700984 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700985 }
986
Ian Rogersbc939662013-08-15 10:26:54 -0700987 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
988 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700989 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
990 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700991 ScopedObjectAccess soa(env);
992 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700993 }
994
Ian Rogersbc939662013-08-15 10:26:54 -0700995 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
996 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700997 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
998 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700999 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001000 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001001 }
1002
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001003 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001004 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001005 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001006 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1007 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001008 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001009 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001010 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001011 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001012 }
1013
Ian Rogersbc939662013-08-15 10:26:54 -07001014 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1015 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001016 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1017 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001018 ScopedObjectAccess soa(env);
1019 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001020 }
1021
Ian Rogersbc939662013-08-15 10:26:54 -07001022 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1023 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001024 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1025 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001026 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001027 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001028 }
1029
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001030 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001031 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001032 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001033 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1034 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001035 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001036 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001037 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001038 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001039 }
1040
Ian Rogersbc939662013-08-15 10:26:54 -07001041 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1042 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001043 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1044 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001045 ScopedObjectAccess soa(env);
1046 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001047 }
1048
Ian Rogersbc939662013-08-15 10:26:54 -07001049 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1050 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001051 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1052 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001053 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001054 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001055 }
1056
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001057 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001058 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001059 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001060 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1061 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001062 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001063 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001064 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001065 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001066 }
1067
Ian Rogersbc939662013-08-15 10:26:54 -07001068 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1069 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001070 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1071 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001072 ScopedObjectAccess soa(env);
1073 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001074 }
1075
Ian Rogersbc939662013-08-15 10:26:54 -07001076 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1077 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001078 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1079 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001080 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001081 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001082 }
1083
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001084 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001085 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001086 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001087 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1088 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001089 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001090 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001091 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001092 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001093 }
1094
Ian Rogersbc939662013-08-15 10:26:54 -07001095 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1096 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001097 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1098 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001099 ScopedObjectAccess soa(env);
1100 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001101 }
1102
Ian Rogersbc939662013-08-15 10:26:54 -07001103 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1104 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001105 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1106 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001107 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001108 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001109 }
1110
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001111 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001112 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001113 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001114 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1115 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001116 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001117 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001118 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001119 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001120 }
1121
Ian Rogersbc939662013-08-15 10:26:54 -07001122 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1123 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001124 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1125 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001126 ScopedObjectAccess soa(env);
1127 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001128 }
1129
Ian Rogersbc939662013-08-15 10:26:54 -07001130 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1131 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001132 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1133 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001134 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001135 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001136 }
1137
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001138 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001139 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001140 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001141 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1142 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001143 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001144 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001145 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001146 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001147 }
1148
Ian Rogersbc939662013-08-15 10:26:54 -07001149 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1150 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001151 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1152 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001153 ScopedObjectAccess soa(env);
1154 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001155 }
1156
Ian Rogersbc939662013-08-15 10:26:54 -07001157 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1158 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001159 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1160 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001161 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001162 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001163 }
1164
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001165 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001166 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001167 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001168 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1169 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001170 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001171 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001172 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001173 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001174 }
1175
Ian Rogersbc939662013-08-15 10:26:54 -07001176 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1177 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001178 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1179 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001180 ScopedObjectAccess soa(env);
1181 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001182 }
1183
Ian Rogersbc939662013-08-15 10:26:54 -07001184 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1185 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001186 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1187 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001188 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001189 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001190 }
1191
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001192 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001193 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001194 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001195 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1196 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001197 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001198 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001199 va_end(ap);
1200 }
1201
Brian Carlstromea46f952013-07-30 01:26:50 -07001202 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1203 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001204 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1205 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001206 ScopedObjectAccess soa(env);
1207 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001208 }
1209
Ian Rogersbc939662013-08-15 10:26:54 -07001210 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1211 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001212 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1213 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001214 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001215 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001216 }
1217
Ian Rogersbc939662013-08-15 10:26:54 -07001218 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001219 CHECK_NON_NULL_ARGUMENT(java_class);
1220 CHECK_NON_NULL_ARGUMENT(name);
1221 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001222 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001223 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001224 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001225
Ian Rogersbc939662013-08-15 10:26:54 -07001226 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1227 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001228 CHECK_NON_NULL_ARGUMENT(java_class);
1229 CHECK_NON_NULL_ARGUMENT(name);
1230 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001231 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001232 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001233 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001234
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001235 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001236 CHECK_NON_NULL_ARGUMENT(obj);
1237 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001238 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001239 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
Andreas Gampe08883de2016-11-08 13:20:52 -08001240 ArtField* f = jni::DecodeArtField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001241 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001242 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001243
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001244 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001245 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001246 ScopedObjectAccess soa(env);
Andreas Gampe08883de2016-11-08 13:20:52 -08001247 ArtField* f = jni::DecodeArtField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001248 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001249 }
1250
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001251 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001252 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1253 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001254 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001255 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
1256 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Andreas Gampe08883de2016-11-08 13:20:52 -08001257 ArtField* f = jni::DecodeArtField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001258 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001259 }
1260
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001261 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001262 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001263 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001264 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Andreas Gampe08883de2016-11-08 13:20:52 -08001265 ArtField* f = jni::DecodeArtField(fid);
Mathieu Chartier3398c782016-09-30 10:27:43 -07001266 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001267 }
1268
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001269#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001270 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1271 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001272 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001273 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Andreas Gampe08883de2016-11-08 13:20:52 -08001274 ArtField* f = jni::DecodeArtField(fid); \
Mathieu Chartier3398c782016-09-30 10:27:43 -07001275 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001276
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001277#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001278 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001279 ScopedObjectAccess soa(env); \
Andreas Gampe08883de2016-11-08 13:20:52 -08001280 ArtField* f = jni::DecodeArtField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001281 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001282
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001283#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001284 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1285 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001286 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001287 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Andreas Gampe08883de2016-11-08 13:20:52 -08001288 ArtField* f = jni::DecodeArtField(fid); \
Mathieu Chartier3398c782016-09-30 10:27:43 -07001289 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001290
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001291#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001292 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001293 ScopedObjectAccess soa(env); \
Andreas Gampe08883de2016-11-08 13:20:52 -08001294 ArtField* f = jni::DecodeArtField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001295 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001296
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001297 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001298 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001299 }
1300
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001301 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001302 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001303 }
1304
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001305 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001306 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001307 }
1308
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001309 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001310 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001311 }
1312
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001313 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001314 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001315 }
1316
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001317 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001318 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001319 }
1320
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001321 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001322 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001323 }
1324
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001325 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001326 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001327 }
1328
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001329 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001330 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001331 }
1332
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001333 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001334 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001335 }
1336
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001337 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001338 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001339 }
1340
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001341 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001342 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001343 }
1344
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001345 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001346 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001347 }
1348
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001349 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001350 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001351 }
1352
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001353 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001354 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001355 }
1356
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001357 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001358 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001359 }
1360
1361 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001362 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001363 }
1364
1365 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001366 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001367 }
1368
1369 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001370 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001371 }
1372
1373 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001374 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001375 }
1376
1377 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001378 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001379 }
1380
1381 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001382 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001383 }
1384
1385 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001386 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001387 }
1388
1389 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001390 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001391 }
1392
1393 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001394 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001395 }
1396
1397 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001398 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001399 }
1400
1401 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001402 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001403 }
1404
1405 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001406 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001407 }
1408
1409 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001410 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001411 }
1412
1413 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001414 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001415 }
1416
1417 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001418 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001419 }
1420
1421 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001422 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001423 }
1424
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001425 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001427 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001428 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001429 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001430 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001431 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001432 va_end(ap);
1433 return local_result;
1434 }
1435
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001436 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001437 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001438 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001439 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001440 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001441 }
1442
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001443 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001444 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001445 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001446 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001447 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001448 }
1449
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001450 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001451 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001452 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001453 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001454 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001455 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001456 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001457 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001458 }
1459
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001460 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001464 }
1465
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001466 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001467 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001468 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001469 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001470 }
1471
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001472 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001473 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001474 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001475 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001476 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001477 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001478 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001479 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 }
1481
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001482 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001486 }
1487
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001488 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001489 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001490 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001491 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001492 }
1493
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001494 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001495 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001496 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001497 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001498 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001499 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001500 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001501 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001502 }
1503
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001504 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001508 }
1509
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001510 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001511 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001512 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001513 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001514 }
1515
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001516 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001517 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001518 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001519 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001520 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001521 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001522 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001523 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001524 }
1525
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001526 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001530 }
1531
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001532 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001533 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001534 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001535 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001536 }
1537
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001538 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001539 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001540 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001541 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001542 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001543 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001544 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001545 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001546 }
1547
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001548 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001552 }
1553
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001554 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001555 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001556 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001557 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001558 }
1559
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001560 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001561 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001562 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001563 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001564 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001565 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001566 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001567 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001568 }
1569
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001570 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001574 }
1575
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001576 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001577 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001578 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001579 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001580 }
1581
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001582 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001583 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001584 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001585 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001586 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001587 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001588 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001589 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001590 }
1591
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001592 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001596 }
1597
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001598 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001599 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001600 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001601 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001602 }
1603
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001604 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001605 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001606 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001607 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001608 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001609 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001610 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001611 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001612 }
1613
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001614 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001618 }
1619
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001620 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001621 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001622 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001623 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001624 }
1625
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001626 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001627 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001628 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001629 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001630 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001631 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001632 va_end(ap);
1633 }
1634
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001635 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list 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 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001639 }
1640
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001641 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001642 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001643 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001644 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001645 }
1646
Elliott Hughes814e4032011-08-23 12:07:56 -07001647 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001648 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001649 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001650 return nullptr;
1651 }
1652 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001653 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001654 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001655 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001656 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001657 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001658 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001659 }
1660
1661 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001662 if (utf == nullptr) {
1663 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001664 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001665 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001666 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001667 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001668 }
1669
Elliott Hughes814e4032011-08-23 12:07:56 -07001670 static jsize GetStringLength(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)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001674 }
1675
1676 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001677 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001678 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001679 return soa.Decode<mirror::String>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001680 }
1681
Ian Rogersbc939662013-08-15 10:26:54 -07001682 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1683 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001684 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001685 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001686 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001687 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001688 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001689 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001690 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001691 if (s->IsCompressed()) {
1692 for (int i = 0; i < length; ++i) {
1693 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1694 }
1695 } else {
1696 const jchar* chars = static_cast<jchar*>(s->GetValue());
1697 memcpy(buf, chars + start, length * sizeof(jchar));
1698 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001699 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001700 }
1701
Ian Rogersbc939662013-08-15 10:26:54 -07001702 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1703 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001704 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001705 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001706 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001707 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001708 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001709 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001710 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001711 if (s->IsCompressed()) {
1712 for (int i = 0; i < length; ++i) {
1713 buf[i] = s->CharAt(start+i);
1714 }
1715 } else {
1716 const jchar* chars = s->GetValue();
1717 size_t bytes = CountUtf8Bytes(chars + start, length);
1718 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1719 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001720 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001721 }
1722
Elliott Hughes75770752011-08-24 17:52:38 -07001723 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001724 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001725 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001726 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001727 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001728 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001729 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001730 if (s->IsCompressed()) {
1731 int32_t length = s->GetLength();
1732 for (int i = 0; i < length; ++i) {
1733 chars[i] = s->CharAt(i);
1734 }
1735 } else {
1736 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1737 }
Fred Shih56890e22014-06-02 11:11:52 -07001738 if (is_copy != nullptr) {
1739 *is_copy = JNI_TRUE;
1740 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001741 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001742 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001743 if (is_copy != nullptr) {
1744 *is_copy = JNI_FALSE;
1745 }
1746 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001747 }
1748
Mathieu Chartier590fee92013-09-13 13:46:47 -07001749 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001750 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001751 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001752 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001753 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001754 delete[] chars;
1755 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001756 }
1757
Elliott Hughes75770752011-08-24 17:52:38 -07001758 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001759 CHECK_NON_NULL_ARGUMENT(java_string);
1760 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001761 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001762 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001763 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001764 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -07001765 HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001766 if (!kUseReadBarrier) {
1767 heap->IncrementDisableMovingGC(soa.Self());
1768 } else {
1769 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1770 // to occur thanks to the to-space invariant.
1771 heap->IncrementDisableThreadFlip(soa.Self());
1772 }
Fred Shih56890e22014-06-02 11:11:52 -07001773 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001774 if (s->IsCompressed()) {
1775 if (is_copy != nullptr) {
1776 *is_copy = JNI_TRUE;
1777 }
1778 int32_t length = s->GetLength();
1779 jchar* chars = new jchar[length];
1780 for (int i = 0; i < length; ++i) {
1781 chars[i] = s->CharAt(i);
1782 }
1783 return chars;
1784 } else {
1785 if (is_copy != nullptr) {
1786 *is_copy = JNI_FALSE;
1787 }
1788 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001789 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001790 }
1791
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001792 static void ReleaseStringCritical(JNIEnv* env,
1793 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001794 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001795 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1796 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001797 gc::Heap* heap = Runtime::Current()->GetHeap();
Mathieu Chartier0795f232016-09-27 18:43:30 -07001798 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001799 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001800 if (!kUseReadBarrier) {
1801 heap->DecrementDisableMovingGC(soa.Self());
1802 } else {
1803 heap->DecrementDisableThreadFlip(soa.Self());
1804 }
Fred Shih56890e22014-06-02 11:11:52 -07001805 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001806 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1807 delete[] chars;
1808 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001809 }
1810
Elliott Hughes75770752011-08-24 17:52:38 -07001811 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001812 if (java_string == nullptr) {
1813 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001814 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001815 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001816 *is_copy = JNI_TRUE;
1817 }
Ian Rogersef28b142012-11-30 14:22:18 -08001818 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001819 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001820 size_t byte_count = s->GetUtfLength();
1821 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001822 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001823 if (s->IsCompressed()) {
1824 for (size_t i = 0; i < byte_count; ++i) {
1825 bytes[i] = s->CharAt(i);
1826 }
1827 } else {
1828 const uint16_t* chars = s->GetValue();
1829 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1830 }
Elliott Hughes75770752011-08-24 17:52:38 -07001831 bytes[byte_count] = '\0';
1832 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001833 }
1834
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001835 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001836 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001837 }
1838
Elliott Hughesbd935992011-08-22 11:59:34 -07001839 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001840 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001841 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001842 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001843 if (UNLIKELY(!obj->IsArrayInstance())) {
David Sehr709b0702016-10-13 09:12:37 -07001844 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", obj->PrettyTypeOf().c_str());
Ian Rogers68d8b422014-07-17 11:09:10 -07001845 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001846 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001847 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001848 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001849 }
1850
Elliott Hughes814e4032011-08-23 12:07:56 -07001851 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001852 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001853 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001854 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1855 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001856 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001857 }
1858
Ian Rogersbc939662013-08-15 10:26:54 -07001859 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1860 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001861 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001862 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001863 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1864 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
1865 ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value);
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001866 array->Set<false>(index, value.Ptr());
Elliott Hughescdf53122011-08-19 15:46:09 -07001867 }
1868
1869 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001870 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001871 }
1872
1873 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001874 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001875 }
1876
1877 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001878 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001879 }
1880
1881 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001882 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001883 }
1884
1885 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001886 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001887 }
1888
1889 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001890 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001891 }
1892
1893 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001894 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001895 }
1896
Ian Rogers1d99e452014-01-02 17:36:41 -08001897 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1898 jobject initial_element) {
1899 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001900 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001901 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001902 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001903 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001904
1905 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001906 ScopedObjectAccess soa(env);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001907 ObjPtr<mirror::Class> array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001908 {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001909 ObjPtr<mirror::Class> element_class = soa.Decode<mirror::Class>(element_jclass).Ptr();
Ian Rogers1d99e452014-01-02 17:36:41 -08001910 if (UNLIKELY(element_class->IsPrimitive())) {
Mathieu Chartierbc5a7952016-10-17 15:46:31 -07001911 soa.Vm()->JniAbortF("NewObjectArray",
1912 "not an object type: %s",
David Sehr709b0702016-10-13 09:12:37 -07001913 element_class->PrettyDescriptor().c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001914 return nullptr;
1915 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001916 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001917 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001918 if (UNLIKELY(array_class == nullptr)) {
1919 return nullptr;
1920 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001921 }
1922
Elliott Hughes75770752011-08-24 17:52:38 -07001923 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001924 mirror::ObjectArray<mirror::Object>* result =
1925 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001926 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001927 ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001928 if (initial_object != nullptr) {
1929 mirror::Class* element_class = result->GetClass()->GetComponentType();
1930 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001931 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1932 "element type of '%s'",
David Sehr709b0702016-10-13 09:12:37 -07001933 mirror::Class::PrettyDescriptor(initial_object->GetClass()).c_str(),
1934 element_class->PrettyDescriptor().c_str());
Ian Rogers68d8b422014-07-17 11:09:10 -07001935 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001936 } else {
1937 for (jsize i = 0; i < length; ++i) {
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001938 result->SetWithoutChecks<false>(i, initial_object.Ptr());
Ian Rogers1d99e452014-01-02 17:36:41 -08001939 }
1940 }
Elliott Hughes75770752011-08-24 17:52:38 -07001941 }
1942 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001943 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001944 }
1945
1946 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001947 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001948 }
1949
Ian Rogersa15e67d2012-02-28 13:51:55 -08001950 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001951 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001952 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001953 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001954 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001955 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
David Sehr709b0702016-10-13 09:12:37 -07001956 array->GetClass()->PrettyDescriptor().c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001957 return nullptr;
1958 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001959 gc::Heap* heap = Runtime::Current()->GetHeap();
1960 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001961 if (!kUseReadBarrier) {
1962 heap->IncrementDisableMovingGC(soa.Self());
1963 } else {
1964 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1965 // to occur thanks to the to-space invariant.
1966 heap->IncrementDisableThreadFlip(soa.Self());
1967 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001968 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartier0795f232016-09-27 18:43:30 -07001969 array = soa.Decode<mirror::Array>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001970 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001971 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001972 *is_copy = JNI_FALSE;
1973 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001974 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001975 }
1976
Ian Rogers2d10b202014-05-12 19:15:18 -07001977 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1978 jint mode) {
1979 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1980 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001981 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001982 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001983 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
David Sehr709b0702016-10-13 09:12:37 -07001984 array->GetClass()->PrettyDescriptor().c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001985 return;
1986 }
1987 const size_t component_size = array->GetClass()->GetComponentSize();
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07001988 ReleasePrimitiveArray(soa, array.Ptr(), component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001989 }
1990
Elliott Hughes75770752011-08-24 17:52:38 -07001991 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001992 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001993 }
1994
Elliott Hughes75770752011-08-24 17:52:38 -07001995 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001996 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001997 }
1998
Elliott Hughes75770752011-08-24 17:52:38 -07001999 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002000 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002001 }
2002
Elliott Hughes75770752011-08-24 17:52:38 -07002003 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002004 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002005 }
2006
Elliott Hughes75770752011-08-24 17:52:38 -07002007 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002008 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002009 }
2010
Elliott Hughes75770752011-08-24 17:52:38 -07002011 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002012 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002013 }
2014
Elliott Hughes75770752011-08-24 17:52:38 -07002015 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002016 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002017 }
2018
Elliott Hughes75770752011-08-24 17:52:38 -07002019 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002020 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002021 }
2022
Mathieu Chartier590fee92013-09-13 13:46:47 -07002023 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2024 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002025 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2026 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002027 }
2028
Mathieu Chartier590fee92013-09-13 13:46:47 -07002029 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002030 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002031 }
2032
Mathieu Chartier590fee92013-09-13 13:46:47 -07002033 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002034 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002035 }
2036
Mathieu Chartier590fee92013-09-13 13:46:47 -07002037 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2038 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002039 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002040 }
2041
Mathieu Chartier590fee92013-09-13 13:46:47 -07002042 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2043 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002044 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002045 }
2046
Mathieu Chartier590fee92013-09-13 13:46:47 -07002047 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002048 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002049 }
2050
Mathieu Chartier590fee92013-09-13 13:46:47 -07002051 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002052 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002053 }
2054
Mathieu Chartier590fee92013-09-13 13:46:47 -07002055 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2056 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002057 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002058 }
2059
Ian Rogersbc939662013-08-15 10:26:54 -07002060 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2061 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002062 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002063 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002064 }
2065
Ian Rogersbc939662013-08-15 10:26:54 -07002066 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2067 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002068 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002069 }
2070
Ian Rogersbc939662013-08-15 10:26:54 -07002071 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2072 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002073 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002074 }
2075
Ian Rogersbc939662013-08-15 10:26:54 -07002076 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2077 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002078 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002079 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002080 }
2081
Ian Rogersbc939662013-08-15 10:26:54 -07002082 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2083 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002084 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002085 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002086 }
2087
Ian Rogersbc939662013-08-15 10:26:54 -07002088 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2089 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002090 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002091 }
2092
Ian Rogersbc939662013-08-15 10:26:54 -07002093 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2094 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002095 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002096 }
2097
Ian Rogersbc939662013-08-15 10:26:54 -07002098 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2099 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002100 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002101 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002102 }
2103
Ian Rogersbc939662013-08-15 10:26:54 -07002104 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2105 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002106 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002107 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002108 }
2109
Ian Rogersbc939662013-08-15 10:26:54 -07002110 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2111 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002112 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002113 }
2114
Ian Rogersbc939662013-08-15 10:26:54 -07002115 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2116 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002117 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002118 }
2119
Ian Rogersbc939662013-08-15 10:26:54 -07002120 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2121 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002122 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002123 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002124 }
2125
Ian Rogersbc939662013-08-15 10:26:54 -07002126 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2127 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002128 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002129 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002130 }
2131
Ian Rogersbc939662013-08-15 10:26:54 -07002132 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2133 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002134 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002135 }
2136
Ian Rogersbc939662013-08-15 10:26:54 -07002137 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2138 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002139 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002140 }
2141
Ian Rogersbc939662013-08-15 10:26:54 -07002142 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2143 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002144 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002145 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002146 }
2147
Ian Rogersbc939662013-08-15 10:26:54 -07002148 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2149 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002150 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2151 }
2152
Ian Rogersbc939662013-08-15 10:26:54 -07002153 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2154 jint method_count, bool return_errors) {
2155 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002156 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2157 method_count);
2158 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002159 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002160 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002161 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002162 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002163 if (UNLIKELY(method_count == 0)) {
2164 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
David Sehr709b0702016-10-13 09:12:37 -07002165 << mirror::Class::PrettyDescriptor(c);
Ian Rogersbc939662013-08-15 10:26:54 -07002166 return JNI_OK;
2167 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002168 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002169 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002170 const char* name = methods[i].name;
2171 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002172 const void* fnPtr = methods[i].fnPtr;
2173 if (UNLIKELY(name == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002174 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002175 return JNI_ERR;
2176 } else if (UNLIKELY(sig == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002177 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002178 return JNI_ERR;
2179 } else if (UNLIKELY(fnPtr == nullptr)) {
Mathieu Chartier3398c782016-09-30 10:27:43 -07002180 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002181 return JNI_ERR;
2182 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002183 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002184 // Notes about fast JNI calls:
2185 //
2186 // On a normal JNI call, the calling thread usually transitions
2187 // from the kRunnable state to the kNative state. But if the
2188 // called native function needs to access any Java object, it
2189 // will have to transition back to the kRunnable state.
2190 //
2191 // There is a cost to this double transition. For a JNI call
2192 // that should be quick, this cost may dominate the call cost.
2193 //
2194 // On a fast JNI call, the calling thread avoids this double
2195 // transition by not transitioning from kRunnable to kNative and
2196 // stays in the kRunnable state.
2197 //
2198 // There are risks to using a fast JNI call because it can delay
2199 // a response to a thread suspension request which is typically
2200 // used for a GC root scanning, etc. If a fast JNI call takes a
2201 // long time, it could cause longer thread suspension latency
2202 // and GC pauses.
2203 //
2204 // Thus, fast JNI should be used with care. It should be used
2205 // for a JNI call that takes a short amount of time (eg. no
2206 // long-running loop) and does not block (eg. no locks, I/O,
2207 // etc.)
2208 //
2209 // A '!' prefix in the signature in the JNINativeMethod
2210 // indicates that it's a fast JNI call and the runtime omits the
2211 // thread state transition from kRunnable to kNative at the
2212 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002213 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002214 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002215 ++sig;
2216 }
2217
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002218 // Note: the right order is to try to find the method locally
2219 // first, either as a direct or a virtual method. Then move to
2220 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002221 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002222 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
Mathieu Chartier0795f232016-09-27 18:43:30 -07002223 for (ObjPtr<mirror::Class> current_class = c;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002224 current_class != nullptr;
2225 current_class = current_class->GetSuperClass()) {
2226 // Search first only comparing methods which are native.
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002227 m = FindMethod<true>(current_class.Ptr(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002228 if (m != nullptr) {
2229 break;
2230 }
2231
2232 // Search again comparing to all methods, to find non-native methods that match.
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002233 m = FindMethod<false>(current_class.Ptr(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002234 if (m != nullptr) {
2235 break;
2236 }
2237
2238 if (warn_on_going_to_parent) {
2239 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2240 << "This is slow, consider changing your RegisterNatives calls.";
2241 warn_on_going_to_parent = false;
2242 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002243 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002244
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002245 if (m == nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002246 c->DumpClass(
2247 LOG_STREAM(return_errors
2248 ? ::android::base::ERROR
2249 : ::android::base::FATAL_WITHOUT_ABORT),
2250 mirror::Class::kDumpClassFullDetail);
2251 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2252 << "Failed to register native method "
David Sehr709b0702016-10-13 09:12:37 -07002253 << c->PrettyDescriptor() << "." << name << sig << " in "
Ian Rogers0177e532014-02-11 16:30:46 -08002254 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier6b3d12b2016-10-13 13:59:58 -07002255 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002256 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002257 } else if (!m->IsNative()) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002258 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2259 << "Failed to register non-native method "
David Sehr709b0702016-10-13 09:12:37 -07002260 << c->PrettyDescriptor() << "." << name << sig
Ian Rogersbc939662013-08-15 10:26:54 -07002261 << " as native";
Mathieu Chartier6b3d12b2016-10-13 13:59:58 -07002262 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002263 return JNI_ERR;
2264 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002265
David Sehr709b0702016-10-13 09:12:37 -07002266 VLOG(jni) << "[Registering JNI native method " << m->PrettyMethod() << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002267
Igor Murashkin3b6f4402017-02-16 16:13:17 -08002268 if (UNLIKELY(is_fast)) {
2269 // There are a few reasons to switch:
2270 // 1) We don't support !bang JNI anymore, it will turn to a hard error later.
2271 // 2) @FastNative is actually faster. At least 1.5x faster than !bang JNI.
2272 // and switching is super easy, remove ! in C code, add annotation in .java code.
2273 // 3) Good chance of hitting DCHECK failures in ScopedFastNativeObjectAccess
2274 // since that checks for presence of @FastNative and not for ! in the descriptor.
2275 LOG(WARNING) << "!bang JNI is deprecated. Switch to @FastNative for " << m->PrettyMethod();
2276 is_fast = false;
2277 // TODO: make this a hard register error in the future.
2278 }
2279
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002280 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002281 }
2282 return JNI_OK;
2283 }
2284
Elliott Hughes5174fe62011-08-23 15:12:35 -07002285 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002286 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002287 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002288 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002289
David Sehr709b0702016-10-13 09:12:37 -07002290 VLOG(jni) << "[Unregistering JNI native methods for " << mirror::Class::PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002291
Ian Rogers2d10b202014-05-12 19:15:18 -07002292 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002293 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002294 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002295 if (m.IsNative()) {
2296 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002297 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002298 }
2299 }
2300
Ian Rogers2d10b202014-05-12 19:15:18 -07002301 if (unregistered_count == 0) {
2302 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
David Sehr709b0702016-10-13 09:12:37 -07002303 << mirror::Class::PrettyDescriptor(c) << "' that contains no native methods";
Ian Rogers2d10b202014-05-12 19:15:18 -07002304 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002305 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002306 }
2307
Ian Rogers719d1a32014-03-06 12:13:39 -08002308 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002309 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002310 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002311 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002312 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002313 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002314 return JNI_ERR;
2315 }
Mathieu Chartierc4f39252016-10-05 18:32:08 -07002316 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002317 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002318 }
2319
Ian Rogers719d1a32014-03-06 12:13:39 -08002320 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002321 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002322 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002323 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002324 o->MonitorExit(soa.Self());
2325 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002326 return JNI_ERR;
2327 }
Mathieu Chartierc4f39252016-10-05 18:32:08 -07002328 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002329 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002330 }
2331
2332 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002333 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002334 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002335 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002336 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002337 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002338 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002339 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002340 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002341 }
2342
Elliott Hughescdf53122011-08-19 15:46:09 -07002343 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002344 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002345 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2346 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002347 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002348 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002349 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002350 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2351 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002352 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002353 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002354
Brian Carlstrom85a93362014-06-25 09:30:52 -07002355 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002356 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002357 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2358 "buffer capacity greater than maximum jint: %" PRId64,
2359 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002360 return nullptr;
2361 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002362 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002363 jint capacity_arg = static_cast<jint>(capacity);
2364
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002365 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2366 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002367 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002368 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002369 }
2370
Elliott Hughesb465ab02011-08-24 11:21:21 -07002371 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002372 return reinterpret_cast<void*>(env->GetLongField(
2373 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002374 }
2375
Elliott Hughesb465ab02011-08-24 11:21:21 -07002376 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002377 return static_cast<jlong>(env->GetIntField(
2378 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002379 }
2380
Andreas Gampea8763072014-12-20 00:08:35 -08002381 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2382 if (java_object == nullptr) {
2383 return JNIInvalidRefType;
2384 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002385
2386 // Do we definitely know what kind of reference this is?
2387 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
Andreas Gampedc061d02016-10-24 13:19:37 -07002388 IndirectRefKind kind = IndirectReferenceTable::GetIndirectRefKind(ref);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002389 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002390 case kLocal:
2391 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002392 case kGlobal:
2393 return JNIGlobalRefType;
2394 case kWeakGlobal:
2395 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002396 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002397 // Assume value is in a handle scope.
2398 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002399 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002400 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002401 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002402 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002403
2404 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002405 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2406 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002407 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002408 // TODO: we should try to expand the table if necessary.
Andreas Gampea8e3b862016-10-17 20:12:52 -07002409 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsInitial)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002410 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2411 return JNI_ERR;
2412 }
2413 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002414 const size_t capacity = soa.Env()->locals.Capacity();
Andreas Gampea8e3b862016-10-17 20:12:52 -07002415 bool okay = (static_cast<jint>(kLocalsInitial - capacity) >= desired_capacity);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002416 if (!okay) {
2417 soa.Self()->ThrowOutOfMemoryError(caller);
2418 }
2419 return okay ? JNI_OK : JNI_ERR;
2420 }
2421
2422 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002423 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002424 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002425 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002426 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002427 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002428 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002429 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002430 return soa.AddLocalReference<JniT>(result);
2431 }
2432
Ian Rogers2d10b202014-05-12 19:15:18 -07002433 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2434 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2435 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002436 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002437 ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002438 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002439 soa.Vm()->JniAbortF(fn_name,
2440 "attempt to %s %s primitive array elements with an object of type %s",
2441 operation,
David Sehr709b0702016-10-13 09:12:37 -07002442 mirror::Class::PrettyDescriptor(
2443 ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2444 mirror::Class::PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002445 return nullptr;
2446 }
2447 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
Mathieu Chartier1cc62e42016-10-03 18:01:28 -07002448 return array.Ptr();
Ian Rogers2d10b202014-05-12 19:15:18 -07002449 }
2450
2451 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2452 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2453 CHECK_NON_NULL_ARGUMENT(java_array);
2454 ScopedObjectAccess soa(env);
2455 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2456 "GetArrayElements",
2457 "get");
2458 if (UNLIKELY(array == nullptr)) {
2459 return nullptr;
2460 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002461 // Only make a copy if necessary.
2462 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2463 if (is_copy != nullptr) {
2464 *is_copy = JNI_TRUE;
2465 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002466 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002467 size_t size = array->GetLength() * component_size;
2468 void* data = new uint64_t[RoundUp(size, 8) / 8];
2469 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002470 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002471 } else {
2472 if (is_copy != nullptr) {
2473 *is_copy = JNI_FALSE;
2474 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002475 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002476 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002477 }
2478
Ian Rogers2d10b202014-05-12 19:15:18 -07002479 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002480 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002481 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002482 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002483 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2484 "ReleaseArrayElements",
2485 "release");
2486 if (array == nullptr) {
2487 return;
2488 }
2489 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2490 }
2491
2492 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2493 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002494 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002495 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002496 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002497 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002498 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002499 if (is_copy) {
2500 // Sanity check: If elements is not the same as the java array's data, it better not be a
2501 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2502 // copies we make?
Mathieu Chartier9d156d52016-10-06 17:44:26 -07002503 if (heap->IsNonDiscontinuousSpaceHeapAddress(elements)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002504 soa.Vm()->JniAbortF("ReleaseArrayElements",
2505 "invalid element pointer %p, array elements are %p",
2506 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002507 return;
2508 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002509 if (mode != JNI_ABORT) {
2510 memcpy(array_data, elements, bytes);
2511 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2512 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2513 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002514 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002515 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002516 }
2517 if (mode != JNI_COMMIT) {
2518 if (is_copy) {
2519 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002520 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002521 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002522 if (!kUseReadBarrier) {
2523 heap->DecrementDisableMovingGC(soa.Self());
2524 } else {
2525 heap->DecrementDisableThreadFlip(soa.Self());
2526 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002527 }
2528 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002529 }
2530
Ian Rogers2d10b202014-05-12 19:15:18 -07002531 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2532 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2533 jsize start, jsize length, ElementT* buf) {
2534 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2535 ScopedObjectAccess soa(env);
2536 ArtArrayT* array =
2537 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2538 "GetPrimitiveArrayRegion",
2539 "get region of");
2540 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002541 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002542 ThrowAIOOBE(soa, array, start, length, "src");
2543 } else {
2544 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2545 ElementT* data = array->GetData();
2546 memcpy(buf, data + start, length * sizeof(ElementT));
2547 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002548 }
2549 }
2550
Ian Rogers2d10b202014-05-12 19:15:18 -07002551 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2552 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2553 jsize start, jsize length, const ElementT* buf) {
2554 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2555 ScopedObjectAccess soa(env);
2556 ArtArrayT* array =
2557 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2558 "SetPrimitiveArrayRegion",
2559 "set region of");
2560 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002561 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002562 ThrowAIOOBE(soa, array, start, length, "dst");
2563 } else {
2564 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2565 ElementT* data = array->GetData();
2566 memcpy(data + start, buf, length * sizeof(ElementT));
2567 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002568 }
2569 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002570};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002571
Elliott Hughes88c5c352012-03-15 18:49:48 -07002572const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002573 nullptr, // reserved0.
2574 nullptr, // reserved1.
2575 nullptr, // reserved2.
2576 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002577 JNI::GetVersion,
2578 JNI::DefineClass,
2579 JNI::FindClass,
2580 JNI::FromReflectedMethod,
2581 JNI::FromReflectedField,
2582 JNI::ToReflectedMethod,
2583 JNI::GetSuperclass,
2584 JNI::IsAssignableFrom,
2585 JNI::ToReflectedField,
2586 JNI::Throw,
2587 JNI::ThrowNew,
2588 JNI::ExceptionOccurred,
2589 JNI::ExceptionDescribe,
2590 JNI::ExceptionClear,
2591 JNI::FatalError,
2592 JNI::PushLocalFrame,
2593 JNI::PopLocalFrame,
2594 JNI::NewGlobalRef,
2595 JNI::DeleteGlobalRef,
2596 JNI::DeleteLocalRef,
2597 JNI::IsSameObject,
2598 JNI::NewLocalRef,
2599 JNI::EnsureLocalCapacity,
2600 JNI::AllocObject,
2601 JNI::NewObject,
2602 JNI::NewObjectV,
2603 JNI::NewObjectA,
2604 JNI::GetObjectClass,
2605 JNI::IsInstanceOf,
2606 JNI::GetMethodID,
2607 JNI::CallObjectMethod,
2608 JNI::CallObjectMethodV,
2609 JNI::CallObjectMethodA,
2610 JNI::CallBooleanMethod,
2611 JNI::CallBooleanMethodV,
2612 JNI::CallBooleanMethodA,
2613 JNI::CallByteMethod,
2614 JNI::CallByteMethodV,
2615 JNI::CallByteMethodA,
2616 JNI::CallCharMethod,
2617 JNI::CallCharMethodV,
2618 JNI::CallCharMethodA,
2619 JNI::CallShortMethod,
2620 JNI::CallShortMethodV,
2621 JNI::CallShortMethodA,
2622 JNI::CallIntMethod,
2623 JNI::CallIntMethodV,
2624 JNI::CallIntMethodA,
2625 JNI::CallLongMethod,
2626 JNI::CallLongMethodV,
2627 JNI::CallLongMethodA,
2628 JNI::CallFloatMethod,
2629 JNI::CallFloatMethodV,
2630 JNI::CallFloatMethodA,
2631 JNI::CallDoubleMethod,
2632 JNI::CallDoubleMethodV,
2633 JNI::CallDoubleMethodA,
2634 JNI::CallVoidMethod,
2635 JNI::CallVoidMethodV,
2636 JNI::CallVoidMethodA,
2637 JNI::CallNonvirtualObjectMethod,
2638 JNI::CallNonvirtualObjectMethodV,
2639 JNI::CallNonvirtualObjectMethodA,
2640 JNI::CallNonvirtualBooleanMethod,
2641 JNI::CallNonvirtualBooleanMethodV,
2642 JNI::CallNonvirtualBooleanMethodA,
2643 JNI::CallNonvirtualByteMethod,
2644 JNI::CallNonvirtualByteMethodV,
2645 JNI::CallNonvirtualByteMethodA,
2646 JNI::CallNonvirtualCharMethod,
2647 JNI::CallNonvirtualCharMethodV,
2648 JNI::CallNonvirtualCharMethodA,
2649 JNI::CallNonvirtualShortMethod,
2650 JNI::CallNonvirtualShortMethodV,
2651 JNI::CallNonvirtualShortMethodA,
2652 JNI::CallNonvirtualIntMethod,
2653 JNI::CallNonvirtualIntMethodV,
2654 JNI::CallNonvirtualIntMethodA,
2655 JNI::CallNonvirtualLongMethod,
2656 JNI::CallNonvirtualLongMethodV,
2657 JNI::CallNonvirtualLongMethodA,
2658 JNI::CallNonvirtualFloatMethod,
2659 JNI::CallNonvirtualFloatMethodV,
2660 JNI::CallNonvirtualFloatMethodA,
2661 JNI::CallNonvirtualDoubleMethod,
2662 JNI::CallNonvirtualDoubleMethodV,
2663 JNI::CallNonvirtualDoubleMethodA,
2664 JNI::CallNonvirtualVoidMethod,
2665 JNI::CallNonvirtualVoidMethodV,
2666 JNI::CallNonvirtualVoidMethodA,
2667 JNI::GetFieldID,
2668 JNI::GetObjectField,
2669 JNI::GetBooleanField,
2670 JNI::GetByteField,
2671 JNI::GetCharField,
2672 JNI::GetShortField,
2673 JNI::GetIntField,
2674 JNI::GetLongField,
2675 JNI::GetFloatField,
2676 JNI::GetDoubleField,
2677 JNI::SetObjectField,
2678 JNI::SetBooleanField,
2679 JNI::SetByteField,
2680 JNI::SetCharField,
2681 JNI::SetShortField,
2682 JNI::SetIntField,
2683 JNI::SetLongField,
2684 JNI::SetFloatField,
2685 JNI::SetDoubleField,
2686 JNI::GetStaticMethodID,
2687 JNI::CallStaticObjectMethod,
2688 JNI::CallStaticObjectMethodV,
2689 JNI::CallStaticObjectMethodA,
2690 JNI::CallStaticBooleanMethod,
2691 JNI::CallStaticBooleanMethodV,
2692 JNI::CallStaticBooleanMethodA,
2693 JNI::CallStaticByteMethod,
2694 JNI::CallStaticByteMethodV,
2695 JNI::CallStaticByteMethodA,
2696 JNI::CallStaticCharMethod,
2697 JNI::CallStaticCharMethodV,
2698 JNI::CallStaticCharMethodA,
2699 JNI::CallStaticShortMethod,
2700 JNI::CallStaticShortMethodV,
2701 JNI::CallStaticShortMethodA,
2702 JNI::CallStaticIntMethod,
2703 JNI::CallStaticIntMethodV,
2704 JNI::CallStaticIntMethodA,
2705 JNI::CallStaticLongMethod,
2706 JNI::CallStaticLongMethodV,
2707 JNI::CallStaticLongMethodA,
2708 JNI::CallStaticFloatMethod,
2709 JNI::CallStaticFloatMethodV,
2710 JNI::CallStaticFloatMethodA,
2711 JNI::CallStaticDoubleMethod,
2712 JNI::CallStaticDoubleMethodV,
2713 JNI::CallStaticDoubleMethodA,
2714 JNI::CallStaticVoidMethod,
2715 JNI::CallStaticVoidMethodV,
2716 JNI::CallStaticVoidMethodA,
2717 JNI::GetStaticFieldID,
2718 JNI::GetStaticObjectField,
2719 JNI::GetStaticBooleanField,
2720 JNI::GetStaticByteField,
2721 JNI::GetStaticCharField,
2722 JNI::GetStaticShortField,
2723 JNI::GetStaticIntField,
2724 JNI::GetStaticLongField,
2725 JNI::GetStaticFloatField,
2726 JNI::GetStaticDoubleField,
2727 JNI::SetStaticObjectField,
2728 JNI::SetStaticBooleanField,
2729 JNI::SetStaticByteField,
2730 JNI::SetStaticCharField,
2731 JNI::SetStaticShortField,
2732 JNI::SetStaticIntField,
2733 JNI::SetStaticLongField,
2734 JNI::SetStaticFloatField,
2735 JNI::SetStaticDoubleField,
2736 JNI::NewString,
2737 JNI::GetStringLength,
2738 JNI::GetStringChars,
2739 JNI::ReleaseStringChars,
2740 JNI::NewStringUTF,
2741 JNI::GetStringUTFLength,
2742 JNI::GetStringUTFChars,
2743 JNI::ReleaseStringUTFChars,
2744 JNI::GetArrayLength,
2745 JNI::NewObjectArray,
2746 JNI::GetObjectArrayElement,
2747 JNI::SetObjectArrayElement,
2748 JNI::NewBooleanArray,
2749 JNI::NewByteArray,
2750 JNI::NewCharArray,
2751 JNI::NewShortArray,
2752 JNI::NewIntArray,
2753 JNI::NewLongArray,
2754 JNI::NewFloatArray,
2755 JNI::NewDoubleArray,
2756 JNI::GetBooleanArrayElements,
2757 JNI::GetByteArrayElements,
2758 JNI::GetCharArrayElements,
2759 JNI::GetShortArrayElements,
2760 JNI::GetIntArrayElements,
2761 JNI::GetLongArrayElements,
2762 JNI::GetFloatArrayElements,
2763 JNI::GetDoubleArrayElements,
2764 JNI::ReleaseBooleanArrayElements,
2765 JNI::ReleaseByteArrayElements,
2766 JNI::ReleaseCharArrayElements,
2767 JNI::ReleaseShortArrayElements,
2768 JNI::ReleaseIntArrayElements,
2769 JNI::ReleaseLongArrayElements,
2770 JNI::ReleaseFloatArrayElements,
2771 JNI::ReleaseDoubleArrayElements,
2772 JNI::GetBooleanArrayRegion,
2773 JNI::GetByteArrayRegion,
2774 JNI::GetCharArrayRegion,
2775 JNI::GetShortArrayRegion,
2776 JNI::GetIntArrayRegion,
2777 JNI::GetLongArrayRegion,
2778 JNI::GetFloatArrayRegion,
2779 JNI::GetDoubleArrayRegion,
2780 JNI::SetBooleanArrayRegion,
2781 JNI::SetByteArrayRegion,
2782 JNI::SetCharArrayRegion,
2783 JNI::SetShortArrayRegion,
2784 JNI::SetIntArrayRegion,
2785 JNI::SetLongArrayRegion,
2786 JNI::SetFloatArrayRegion,
2787 JNI::SetDoubleArrayRegion,
2788 JNI::RegisterNatives,
2789 JNI::UnregisterNatives,
2790 JNI::MonitorEnter,
2791 JNI::MonitorExit,
2792 JNI::GetJavaVM,
2793 JNI::GetStringRegion,
2794 JNI::GetStringUTFRegion,
2795 JNI::GetPrimitiveArrayCritical,
2796 JNI::ReleasePrimitiveArrayCritical,
2797 JNI::GetStringCritical,
2798 JNI::ReleaseStringCritical,
2799 JNI::NewWeakGlobalRef,
2800 JNI::DeleteWeakGlobalRef,
2801 JNI::ExceptionCheck,
2802 JNI::NewDirectByteBuffer,
2803 JNI::GetDirectBufferAddress,
2804 JNI::GetDirectBufferCapacity,
2805 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002806};
2807
Ian Rogers68d8b422014-07-17 11:09:10 -07002808const JNINativeInterface* GetJniNativeInterface() {
2809 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002810}
2811
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002812void (*gJniSleepForeverStub[])() = {
2813 nullptr, // reserved0.
2814 nullptr, // reserved1.
2815 nullptr, // reserved2.
2816 nullptr, // reserved3.
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 SleepForever,
3028 SleepForever,
3029 SleepForever,
3030 SleepForever,
3031 SleepForever,
3032 SleepForever,
3033 SleepForever,
3034 SleepForever,
3035 SleepForever,
3036 SleepForever,
3037 SleepForever,
3038 SleepForever,
3039 SleepForever,
3040 SleepForever,
3041 SleepForever,
3042 SleepForever,
3043 SleepForever,
3044 SleepForever,
3045 SleepForever,
3046};
3047
3048const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3049 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3050}
3051
Elliott Hughesc8fece32013-01-02 11:27:23 -08003052void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003053 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003054 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003055 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003056 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3057 }
3058 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3059}
3060
Ian Rogersdf20fe02011-07-20 20:34:16 -07003061} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003062
3063std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3064 switch (rhs) {
3065 case JNIInvalidRefType:
3066 os << "JNIInvalidRefType";
3067 return os;
3068 case JNILocalRefType:
3069 os << "JNILocalRefType";
3070 return os;
3071 case JNIGlobalRefType:
3072 os << "JNIGlobalRefType";
3073 return os;
3074 case JNIWeakGlobalRefType:
3075 os << "JNIWeakGlobalRefType";
3076 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003077 default:
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07003078 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Ian Rogersc7dd2952014-10-21 23:31:19 -07003079 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003080 }
3081}