blob: 7b2757897e482dc620dce5ecd810158bd0e53b20 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Ian Rogersdf20fe02011-07-20 20:34:16 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "jni_internal.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070018
Elliott Hughes0af55432011-08-17 18:37:28 -070019#include <dlfcn.h>
Elliott Hughes79082e32011-08-25 12:07:32 -070020
21#include <cstdarg>
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Elliott Hughes0af55432011-08-17 18:37:28 -070023#include <utility>
24#include <vector>
Carl Shapiro2ed144c2011-07-26 16:52:08 -070025
Mathieu Chartierc7853442015-03-27 14:35:38 -070026#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070027#include "art_method-inl.h"
Ian Rogersef7d42f2014-01-06 12:55:46 -080028#include "atomic.h"
Mathieu Chartierbad02672014-08-25 13:08:22 -070029#include "base/allocator.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070030#include "base/enums.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080032#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080033#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080034#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070035#include "dex_file-inl.h"
Mathieu Chartierd0004802014-10-15 16:59:47 -070036#include "fault_handler.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070037#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070038#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070039#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070040#include "interpreter/interpreter.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070041#include "jni_env_ext.h"
42#include "java_vm_ext.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043#include "mirror/class-inl.h"
44#include "mirror/class_loader.h"
Hiroshi Yamauchi02d2f292015-04-03 13:35:16 -070045#include "mirror/field-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070046#include "mirror/method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047#include "mirror/object-inl.h"
48#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070049#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050#include "mirror/throwable.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080051#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070052#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070053#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070054#include "safe_map.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070055#include "scoped_thread_state_change-inl.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070056#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070057#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070059#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070060
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070061namespace art {
62
Mathieu Chartier24555ad2014-10-06 13:41:33 -070063// Consider turning this on when there is errors which could be related to JNI array copies such as
64// things not rendering correctly. E.g. b/16858794
65static constexpr bool kWarnJniAbort = false;
66
Elliott Hughes6b436852011-08-12 10:16:44 -070067// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
68// separated with slashes but aren't wrapped with "L;" like regular descriptors
69// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
70// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
71// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -070072static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070073 std::string result;
74 // Add the missing "L;" if necessary.
75 if (name[0] == '[') {
76 result = name;
77 } else {
78 result += 'L';
79 result += name;
80 result += ';';
81 }
82 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070083 if (result.find('.') != std::string::npos) {
84 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
85 << "\"" << name << "\"";
86 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -070087 }
88 return result;
89}
90
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080091static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070092 const char* name, const char* sig, const char* kind)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070093 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -070094 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000095 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Ian Rogers62d6c772013-02-27 08:32:07 -080096 "no %s method \"%s.%s%s\"",
Ian Rogers1ff3c982014-08-12 02:30:58 -070097 kind, c->GetDescriptor(&temp), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -070098}
99
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200100static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
101 const char* kind, jint idx, bool return_errors)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700102 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -0700103 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
104 << "Failed to register native method in " << PrettyDescriptor(c)
105 << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200106 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000107 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200108 "%s is null at index %d", kind, idx);
109}
110
Mathieu Chartier0795f232016-09-27 18:43:30 -0700111static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700112 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800113 if (LIKELY(klass->IsInitialized())) {
114 return klass;
115 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700116 StackHandleScope<1> hs(self);
117 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700118 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800119 return nullptr;
120 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700121 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800122}
123
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700124static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
125 const char* name, const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700126 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700127 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800128 if (c == nullptr) {
129 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700130 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700131 ArtMethod* method = nullptr;
132 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700133 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700134 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700135 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700137 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700138 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800139 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700140 // No virtual method matching the signature. Search declared
141 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700142 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700143 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700144 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800145 if (method == nullptr || method->IsStatic() != is_static) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700146 ThrowNoSuchMethodError(soa, c.Decode(), name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800147 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700148 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700149 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700150}
151
Mathieu Chartier0795f232016-09-27 18:43:30 -0700152static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700153 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700154 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700155 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
156 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -0700157 return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700158 }
Brian Carlstromce888532013-10-10 00:32:58 -0700159 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800160 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700161 return method->GetDeclaringClass()->GetClassLoader();
162 }
163 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700164 ObjPtr<mirror::ClassLoader> class_loader =
165 soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800166 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700167 return class_loader;
168 }
169 // See if the override ClassLoader is set for gtests.
Mathieu Chartier0795f232016-09-27 18:43:30 -0700170 class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800171 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700172 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
173 // image.
174 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700175 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700176 return class_loader;
177 }
178 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800179 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700180}
181
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700182static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
183 const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700184 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700185 StackHandleScope<2> hs(soa.Self());
186 Handle<mirror::Class> c(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700187 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class))));
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700188 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800189 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700190 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700191 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800192 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700193 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
194 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700195 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800196 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700197 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700198 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700199 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800200 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700201 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700202 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800203 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000204 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700205 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700206 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000207 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800208 "no type \"%s\" found and so no field \"%s\" "
209 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700210 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000211 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800212 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700213 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700214 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700215 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700216 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700217 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700218 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700219 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700220 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800221 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000222 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800223 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700224 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800225 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700226 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700227 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700228}
229
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800230static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700231 jsize length, const char* identifier)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700232 REQUIRES_SHARED(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700233 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000234 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800235 "%s offset=%d length=%d %s.length=%d",
236 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700237}
Ian Rogers0571d352011-11-03 19:51:38 -0700238
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700239static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
240 jsize array_length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700241 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000242 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800243 "offset=%d length=%d string.length()=%d", start, length,
244 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700245}
Elliott Hughes814e4032011-08-23 12:07:56 -0700246
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700248 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700249 // Turn the const char* into a java.lang.String.
250 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800251 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700252 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700253 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700254
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700255 // Choose an appropriate constructor and set up the arguments.
256 jvalue args[2];
257 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800258 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700259 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800260 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700261 signature = "(Ljava/lang/String;)V";
262 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800263 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700264 signature = "(Ljava/lang/Throwable;)V";
265 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700266 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700267 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
268 args[0].l = s.get();
269 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700270 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700271 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800272 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800273 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700274 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartier0795f232016-09-27 18:43:30 -0700275 << PrettyClass(soa.Decode<mirror::Class>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700276 return JNI_ERR;
277 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700278
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800279 ScopedLocalRef<jthrowable> exception(
280 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
281 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700282 return JNI_ERR;
283 }
Ian Rogersef28b142012-11-30 14:22:18 -0800284 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700285 soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()).Decode());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700286 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700287}
288
Ian Rogers68d8b422014-07-17 11:09:10 -0700289static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
290 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700291}
292
Ian Rogers2d10b202014-05-12 19:15:18 -0700293#define CHECK_NON_NULL_ARGUMENT(value) \
294 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700295
Ian Rogers2d10b202014-05-12 19:15:18 -0700296#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
297 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
298
299#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
300 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
301
302#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
303 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
304
305#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700306 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700307 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700308 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700309 }
310
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700311#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700312 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700313 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700314 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700315 }
316
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700317template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700318static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700319 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800321 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700322 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
323 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700324 }
325 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700326 return nullptr;
327}
328
Elliott Hughescdf53122011-08-19 15:46:09 -0700329class JNI {
330 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700331 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700332 return JNI_VERSION_1_6;
333 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700334
Ian Rogers25e8b912012-09-07 11:31:36 -0700335 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700336 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800337 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700338 }
339
Elliott Hughescdf53122011-08-19 15:46:09 -0700340 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700341 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700342 Runtime* runtime = Runtime::Current();
343 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700344 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700345 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800346 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700347 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700348 StackHandleScope<1> hs(soa.Self());
349 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800350 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700351 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800352 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700353 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700354 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700355 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700356
Ian Rogers62f05122014-03-21 11:21:29 -0700357 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700358 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700359 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700360 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700361 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700362
Ian Rogers62f05122014-03-21 11:21:29 -0700363 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700364 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700365 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700366 ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700367 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700368 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700369 return nullptr;
370 }
Mathieu Chartier0795f232016-09-27 18:43:30 -0700371 ObjPtr<mirror::Field> field = down_cast<mirror::Field*>(obj_field.Decode());
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700372 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700373 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700374
Elliott Hughescdf53122011-08-19 15:46:09 -0700375 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700376 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700377 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700378 ArtMethod* m = soa.DecodeMethod(mid);
Neil Fuller0e844392016-09-08 13:43:31 +0100379 mirror::Executable* method;
Andreas Gampe542451c2016-07-26 09:02:02 -0700380 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
Andreas Gampee01e3642016-07-25 13:06:04 -0700381 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200382 if (m->IsConstructor()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700383 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200384 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700385 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200386 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700387 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700388 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700389
Elliott Hughescdf53122011-08-19 15:46:09 -0700390 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700391 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700392 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700393 ArtField* f = soa.DecodeField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700394 return soa.AddLocalReference<jobject>(
Andreas Gampe542451c2016-07-26 09:02:02 -0700395 mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700396 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700397
Elliott Hughes37f7a402011-08-22 18:56:01 -0700398 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700399 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700400 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700401 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700402 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700403 }
404
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700405 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700406 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700407 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700408 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700409 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700410 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700411
Narayan Kamath1268b742014-07-11 19:15:11 +0100412 // Note: java_class1 should be safely castable to java_class2, and
413 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700414 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700415 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
416 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700417 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700418 ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
419 ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
420 return c2->IsAssignableFrom(c1.Decode()) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700421 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700422
Elliott Hughese84278b2012-03-22 10:06:53 -0700423 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700424 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800425 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700426 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700427 return JNI_TRUE;
428 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700429 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700430 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj);
431 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700432 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700433 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700434 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700435
Elliott Hughes37f7a402011-08-22 18:56:01 -0700436 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700437 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700438 ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800439 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700440 return JNI_ERR;
441 }
Mathieu Chartier0795f232016-09-27 18:43:30 -0700442 soa.Self()->SetException(exception.Decode());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700443 return JNI_OK;
444 }
445
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700446 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700447 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800448 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700449 }
450
451 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700452 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700453 }
454
455 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700456 ScopedObjectAccess soa(env);
457 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700458 }
459
460 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700461 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700462
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700463 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000464 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700465 return;
466 }
467
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000468 StackHandleScope<1> hs(soa.Self());
469 Handle<mirror::Throwable> old_exception(
470 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
471 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800472 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700473 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700474 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
475 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800476 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700477 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700478 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700479 } else {
480 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800481 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000482 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700483 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800484 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700485 }
486 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000487 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700488 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700489
Elliott Hughescdf53122011-08-19 15:46:09 -0700490 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700491 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000492 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700493 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700494 }
495
Ian Rogers25e8b912012-09-07 11:31:36 -0700496 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700497 LOG(FATAL) << "JNI FatalError called: " << msg;
498 }
499
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700500 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700501 // TODO: SOA may not be necessary but I do it to please lock annotations.
502 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700503 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700504 return JNI_ERR;
505 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700506 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700507 return JNI_OK;
508 }
509
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700510 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700511 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700512 ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700513 soa.Env()->PopFrame();
514 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700515 }
516
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700517 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700518 // TODO: SOA may not be necessary but I do it to please lock annotations.
519 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700520 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700521 }
522
Elliott Hughescdf53122011-08-19 15:46:09 -0700523 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700524 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700525 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
526 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj.Decode());
Elliott Hughescdf53122011-08-19 15:46:09 -0700527 }
528
529 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700530 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
531 Thread* self = down_cast<JNIEnvExt*>(env)->self;
532 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700533 }
534
535 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700536 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700537 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
538 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj.Decode());
Elliott Hughescdf53122011-08-19 15:46:09 -0700539 }
540
541 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700542 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
543 Thread* self = down_cast<JNIEnvExt*>(env)->self;
544 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700545 }
546
547 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700548 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700549 ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800550 // Check for null after decoding the object to handle cleared weak globals.
551 if (decoded_obj == nullptr) {
552 return nullptr;
553 }
554 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700555 }
556
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700557 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800558 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700559 return;
560 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700561 // SOA is only necessary to have exclusion between GC root marking and removing.
562 // We don't want to have the GC attempt to mark a null root if we just removed
563 // it. b/22119403
564 ScopedObjectAccess soa(env);
565 auto* ext_env = down_cast<JNIEnvExt*>(env);
566 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700567 // Attempting to delete a local reference that is not in the
568 // topmost local reference frame is a no-op. DeleteLocalRef returns
569 // void and doesn't throw any exceptions, but we should probably
570 // complain about it so the user will notice that things aren't
571 // going quite the way they expect.
572 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
573 << "failed to find entry";
574 }
575 }
576
577 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700578 if (obj1 == obj2) {
579 return JNI_TRUE;
580 } else {
581 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700582 return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2))
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800583 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700584 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700585 }
586
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700587 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700588 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700589 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700590 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800591 if (c == nullptr) {
592 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700593 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800594 if (c->IsStringClass()) {
595 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700596 return soa.AddLocalReference<jobject>(mirror::String::AllocEmptyString<true>(soa.Self(),
597 allocator_type));
Jeff Hao848f70a2014-01-15 13:49:50 -0800598 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700599 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700600 }
601
Ian Rogersbc939662013-08-15 10:26:54 -0700602 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700603 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700604 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700605 CHECK_NON_NULL_ARGUMENT(java_class);
606 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700607 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700608 va_end(args);
609 return result;
610 }
611
Elliott Hughes72025e52011-08-23 17:50:30 -0700612 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700613 CHECK_NON_NULL_ARGUMENT(java_class);
614 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700615 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700616 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
617 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800618 if (c == nullptr) {
619 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700620 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800621 if (c->IsStringClass()) {
622 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100623 jmethodID sf_mid = soa.EncodeMethod(
624 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800625 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
626 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800627 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800628 if (result == nullptr) {
629 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700630 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700631 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700632 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800633 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800634 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700635 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800636 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700637 }
638
Elliott Hughes72025e52011-08-23 17:50:30 -0700639 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700640 CHECK_NON_NULL_ARGUMENT(java_class);
641 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700642 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -0700643 ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
644 soa.Decode<mirror::Class>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800645 if (c == nullptr) {
646 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700647 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800648 if (c->IsStringClass()) {
649 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100650 jmethodID sf_mid = soa.EncodeMethod(
651 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800652 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
653 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800654 mirror::Object* result = c->AllocObject(soa.Self());
655 if (result == nullptr) {
656 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700657 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700658 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700659 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800660 if (soa.Self()->IsExceptionPending()) {
661 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700662 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800663 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700664 }
665
Ian Rogersbc939662013-08-15 10:26:54 -0700666 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700667 CHECK_NON_NULL_ARGUMENT(java_class);
668 CHECK_NON_NULL_ARGUMENT(name);
669 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700670 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700671 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700672 }
673
Ian Rogersbc939662013-08-15 10:26:54 -0700674 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
675 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700676 CHECK_NON_NULL_ARGUMENT(java_class);
677 CHECK_NON_NULL_ARGUMENT(name);
678 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700679 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700680 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700681 }
682
Elliott Hughes72025e52011-08-23 17:50:30 -0700683 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700684 va_list ap;
685 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700686 CHECK_NON_NULL_ARGUMENT(obj);
687 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700688 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700689 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700690 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700691 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700692 }
693
Elliott Hughes72025e52011-08-23 17:50:30 -0700694 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700695 CHECK_NON_NULL_ARGUMENT(obj);
696 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700697 ScopedObjectAccess soa(env);
698 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
699 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700700 }
701
Elliott Hughes72025e52011-08-23 17:50:30 -0700702 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700703 CHECK_NON_NULL_ARGUMENT(obj);
704 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700705 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700706 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700707 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700708 }
709
Elliott Hughes72025e52011-08-23 17:50:30 -0700710 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700711 va_list ap;
712 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700713 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
714 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700715 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700716 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700717 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700718 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700719 }
720
Elliott Hughes72025e52011-08-23 17:50:30 -0700721 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700722 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
723 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700724 ScopedObjectAccess soa(env);
725 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700726 }
727
Elliott Hughes72025e52011-08-23 17:50:30 -0700728 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700729 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
730 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700731 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700732 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700733 }
734
Elliott Hughes72025e52011-08-23 17:50:30 -0700735 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700736 va_list ap;
737 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700738 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
739 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700740 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700741 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700742 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700743 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700744 }
745
Elliott Hughes72025e52011-08-23 17:50:30 -0700746 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700747 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
748 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700749 ScopedObjectAccess soa(env);
750 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700751 }
752
Elliott Hughes72025e52011-08-23 17:50:30 -0700753 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700754 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
755 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700756 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700757 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700758 }
759
Elliott Hughes72025e52011-08-23 17:50:30 -0700760 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700761 va_list ap;
762 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700763 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
764 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700765 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700766 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700767 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700768 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700769 }
770
Elliott Hughes72025e52011-08-23 17:50:30 -0700771 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700772 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
773 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700774 ScopedObjectAccess soa(env);
775 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700776 }
777
Elliott Hughes72025e52011-08-23 17:50:30 -0700778 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700779 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
780 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700781 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700782 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700783 }
784
Elliott Hughes72025e52011-08-23 17:50:30 -0700785 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700786 va_list ap;
787 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700788 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
789 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700790 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700791 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700792 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700793 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700794 }
795
Elliott Hughes72025e52011-08-23 17:50:30 -0700796 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700797 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
798 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700799 ScopedObjectAccess soa(env);
800 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700801 }
802
Elliott Hughes72025e52011-08-23 17:50:30 -0700803 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700804 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
805 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700806 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700807 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700808 }
809
Elliott Hughes72025e52011-08-23 17:50:30 -0700810 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700811 va_list ap;
812 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700813 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
814 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700815 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700816 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700817 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700818 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700819 }
820
Elliott Hughes72025e52011-08-23 17:50:30 -0700821 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700822 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
823 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700824 ScopedObjectAccess soa(env);
825 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700826 }
827
Elliott Hughes72025e52011-08-23 17:50:30 -0700828 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700829 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
830 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700831 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700832 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700833 }
834
Elliott Hughes72025e52011-08-23 17:50:30 -0700835 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700836 va_list ap;
837 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700838 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
839 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700840 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700841 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700842 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700843 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700844 }
845
Elliott Hughes72025e52011-08-23 17:50:30 -0700846 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700847 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
848 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700849 ScopedObjectAccess soa(env);
850 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700851 }
852
Elliott Hughes72025e52011-08-23 17:50:30 -0700853 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700854 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
855 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700856 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700857 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700858 }
859
Elliott Hughes72025e52011-08-23 17:50:30 -0700860 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700861 va_list ap;
862 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700863 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
864 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700865 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700866 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700867 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700868 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700869 }
870
Elliott Hughes72025e52011-08-23 17:50:30 -0700871 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700872 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
873 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700874 ScopedObjectAccess soa(env);
875 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700876 }
877
Elliott Hughes72025e52011-08-23 17:50:30 -0700878 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700879 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
880 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700881 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700882 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700883 }
884
Elliott Hughes72025e52011-08-23 17:50:30 -0700885 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700886 va_list ap;
887 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700888 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
889 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700890 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700891 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700892 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700893 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700894 }
895
Elliott Hughes72025e52011-08-23 17:50:30 -0700896 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700897 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
898 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700899 ScopedObjectAccess soa(env);
900 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700901 }
902
Elliott Hughes72025e52011-08-23 17:50:30 -0700903 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700904 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
905 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700906 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700907 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700908 }
909
Elliott Hughes72025e52011-08-23 17:50:30 -0700910 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700911 va_list ap;
912 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700913 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
914 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700915 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700916 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700917 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700918 }
919
Elliott Hughes72025e52011-08-23 17:50:30 -0700920 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700921 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
922 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700923 ScopedObjectAccess soa(env);
924 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700925 }
926
Elliott Hughes72025e52011-08-23 17:50:30 -0700927 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700928 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
929 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700930 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700931 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700932 }
933
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700934 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700935 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700936 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700937 CHECK_NON_NULL_ARGUMENT(obj);
938 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700939 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700940 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
941 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700942 va_end(ap);
943 return local_result;
944 }
945
Ian Rogersbc939662013-08-15 10:26:54 -0700946 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
947 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700948 CHECK_NON_NULL_ARGUMENT(obj);
949 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700950 ScopedObjectAccess soa(env);
951 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
952 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700953 }
954
Ian Rogersbc939662013-08-15 10:26:54 -0700955 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
956 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700957 CHECK_NON_NULL_ARGUMENT(obj);
958 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700959 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700960 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700961 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700962 }
963
Ian Rogersbc939662013-08-15 10:26:54 -0700964 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
965 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700966 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700967 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700968 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
969 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700970 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700971 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700972 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700973 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700974 }
975
Ian Rogersbc939662013-08-15 10:26:54 -0700976 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
977 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700978 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
979 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700980 ScopedObjectAccess soa(env);
981 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700982 }
983
Ian Rogersbc939662013-08-15 10:26:54 -0700984 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
985 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700986 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
987 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700988 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700989 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700990 }
991
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700992 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700993 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700994 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700995 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
996 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700997 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700998 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700999 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001000 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001001 }
1002
Ian Rogersbc939662013-08-15 10:26:54 -07001003 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1004 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001005 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1006 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001007 ScopedObjectAccess soa(env);
1008 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001009 }
1010
Ian Rogersbc939662013-08-15 10:26:54 -07001011 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1012 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001013 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1014 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001015 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001016 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001017 }
1018
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001019 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001020 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001021 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001022 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1023 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001024 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001025 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001026 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001027 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001028 }
1029
Ian Rogersbc939662013-08-15 10:26:54 -07001030 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1031 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001032 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1033 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001034 ScopedObjectAccess soa(env);
1035 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001036 }
1037
Ian Rogersbc939662013-08-15 10:26:54 -07001038 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1039 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001040 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1041 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001042 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001043 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001044 }
1045
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001046 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001047 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001048 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001049 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1050 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001051 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001052 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001053 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001054 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001055 }
1056
Ian Rogersbc939662013-08-15 10:26:54 -07001057 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1058 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001059 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1060 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001061 ScopedObjectAccess soa(env);
1062 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001063 }
1064
Ian Rogersbc939662013-08-15 10:26:54 -07001065 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1066 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001067 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1068 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001069 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001070 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001071 }
1072
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001073 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001074 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001075 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001076 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1077 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001078 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001079 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001080 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001081 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001082 }
1083
Ian Rogersbc939662013-08-15 10:26:54 -07001084 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1085 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001086 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1087 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001088 ScopedObjectAccess soa(env);
1089 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001090 }
1091
Ian Rogersbc939662013-08-15 10:26:54 -07001092 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1093 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001094 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1095 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001096 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001097 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001098 }
1099
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001100 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001101 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001102 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001103 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1104 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001105 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001106 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001107 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001108 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001109 }
1110
Ian Rogersbc939662013-08-15 10:26:54 -07001111 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1112 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001113 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1114 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001115 ScopedObjectAccess soa(env);
1116 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001117 }
1118
Ian Rogersbc939662013-08-15 10:26:54 -07001119 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1120 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001121 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1122 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001123 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001124 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001125 }
1126
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001127 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001128 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001129 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001130 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1131 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001132 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001133 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001134 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001135 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001136 }
1137
Ian Rogersbc939662013-08-15 10:26:54 -07001138 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1139 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001140 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1141 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001142 ScopedObjectAccess soa(env);
1143 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001144 }
1145
Ian Rogersbc939662013-08-15 10:26:54 -07001146 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1147 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001148 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1149 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001150 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001151 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001152 }
1153
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001154 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001155 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001156 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001157 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1158 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001159 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001160 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001161 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001162 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001163 }
1164
Ian Rogersbc939662013-08-15 10:26:54 -07001165 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1166 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001167 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1168 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001169 ScopedObjectAccess soa(env);
1170 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001171 }
1172
Ian Rogersbc939662013-08-15 10:26:54 -07001173 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1174 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001175 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1176 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001177 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001178 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001179 }
1180
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001181 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001182 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001183 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001184 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1185 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001186 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001187 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001188 va_end(ap);
1189 }
1190
Brian Carlstromea46f952013-07-30 01:26:50 -07001191 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1192 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001193 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1194 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001195 ScopedObjectAccess soa(env);
1196 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001197 }
1198
Ian Rogersbc939662013-08-15 10:26:54 -07001199 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1200 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001201 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1202 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001203 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001204 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001205 }
1206
Ian Rogersbc939662013-08-15 10:26:54 -07001207 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001208 CHECK_NON_NULL_ARGUMENT(java_class);
1209 CHECK_NON_NULL_ARGUMENT(name);
1210 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001211 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001212 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001213 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001214
Ian Rogersbc939662013-08-15 10:26:54 -07001215 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1216 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001217 CHECK_NON_NULL_ARGUMENT(java_class);
1218 CHECK_NON_NULL_ARGUMENT(name);
1219 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001220 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001221 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001222 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001223
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001224 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001225 CHECK_NON_NULL_ARGUMENT(obj);
1226 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001227 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001228 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001229 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001230 return soa.AddLocalReference<jobject>(f->GetObject(o.Decode()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001231 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001232
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001233 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001234 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001235 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001236 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001237 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001238 }
1239
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001240 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001241 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1242 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001243 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001244 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
1245 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001246 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001247 f->SetObject<false>(o.Decode(), v.Decode());
Elliott Hughescdf53122011-08-19 15:46:09 -07001248 }
1249
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001250 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001251 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001252 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001253 ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001254 ArtField* f = soa.DecodeField(fid);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001255 f->SetObject<false>(f->GetDeclaringClass(), v.Decode());
Elliott Hughescdf53122011-08-19 15:46:09 -07001256 }
1257
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001258#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001259 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1260 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001261 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001262 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001263 ArtField* f = soa.DecodeField(fid); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001264 return f->Get ##fn (o.Decode())
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001265
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001266#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001267 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001268 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001269 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001270 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001271
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001272#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001273 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1274 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001275 ScopedObjectAccess soa(env); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001276 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001277 ArtField* f = soa.DecodeField(fid); \
Mathieu Chartier0795f232016-09-27 18:43:30 -07001278 f->Set ##fn <false>(o.Decode(), value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001279
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001280#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001281 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001282 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001283 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001284 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001285
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001286 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001287 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001288 }
1289
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001290 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001291 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001292 }
1293
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001294 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001295 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001296 }
1297
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001298 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001299 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001300 }
1301
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001302 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001303 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001304 }
1305
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001306 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001307 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001308 }
1309
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001310 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001311 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001312 }
1313
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001314 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001315 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001316 }
1317
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001318 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001319 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001320 }
1321
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001322 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001323 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001324 }
1325
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001326 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001327 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001328 }
1329
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001330 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001331 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001332 }
1333
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001334 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001335 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001336 }
1337
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001338 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001339 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001340 }
1341
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001342 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001343 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001344 }
1345
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001346 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001347 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001348 }
1349
1350 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001351 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001352 }
1353
1354 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001355 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001356 }
1357
1358 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001359 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001360 }
1361
1362 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001363 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001364 }
1365
1366 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001367 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001368 }
1369
1370 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001371 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001372 }
1373
1374 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001375 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001376 }
1377
1378 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001379 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001380 }
1381
1382 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001383 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001384 }
1385
1386 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001387 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001388 }
1389
1390 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001391 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001392 }
1393
1394 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001395 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001396 }
1397
1398 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001399 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001400 }
1401
1402 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001403 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001404 }
1405
1406 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001407 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001408 }
1409
1410 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001411 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001412 }
1413
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001414 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001415 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001416 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001417 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001418 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001419 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001420 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001421 va_end(ap);
1422 return local_result;
1423 }
1424
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001425 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001426 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001427 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001428 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001429 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001430 }
1431
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001432 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001433 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001434 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001435 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001436 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001437 }
1438
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001439 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001440 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001441 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001442 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001443 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001444 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001445 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001446 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001447 }
1448
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001449 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001450 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001451 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001452 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001453 }
1454
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001455 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001456 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001457 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001458 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001459 }
1460
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001461 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001462 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001463 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001464 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001465 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001466 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001467 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001468 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001469 }
1470
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001471 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001472 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001473 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001474 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001475 }
1476
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001477 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001478 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001479 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001480 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001481 }
1482
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001483 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001484 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001485 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001486 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001487 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001488 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001489 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001490 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001491 }
1492
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001493 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001494 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001495 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001496 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001497 }
1498
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001499 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001500 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001501 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001502 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001503 }
1504
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001505 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001506 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001507 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001508 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001509 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001510 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001511 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001512 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001513 }
1514
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001515 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001516 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001517 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001518 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001519 }
1520
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001521 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001522 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001523 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001524 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001525 }
1526
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001527 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001528 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001529 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001530 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001531 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001532 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001533 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001534 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001535 }
1536
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001537 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001538 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001539 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001540 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001541 }
1542
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001543 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001544 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001545 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001546 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001547 }
1548
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001549 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001550 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001551 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001552 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001553 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001554 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001555 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001556 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001557 }
1558
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001559 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001560 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001561 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001562 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001563 }
1564
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001565 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001566 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001567 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001568 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001569 }
1570
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001571 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001572 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001573 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001574 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001575 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001576 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001577 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001578 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001579 }
1580
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001581 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001582 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001583 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001584 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001585 }
1586
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001587 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001588 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001589 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001590 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001591 }
1592
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001593 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001594 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001595 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001596 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001597 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001598 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001599 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001600 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001601 }
1602
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001603 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001604 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001605 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001606 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001607 }
1608
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001609 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001610 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001611 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001612 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001613 }
1614
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001615 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001616 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001617 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001618 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001619 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001620 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001621 va_end(ap);
1622 }
1623
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001624 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001625 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001626 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001627 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001628 }
1629
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001630 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001631 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001632 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001633 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001634 }
1635
Elliott Hughes814e4032011-08-23 12:07:56 -07001636 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001637 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001638 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001639 return nullptr;
1640 }
1641 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001642 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001643 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001644 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001645 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001646 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001647 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001648 }
1649
1650 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001651 if (utf == nullptr) {
1652 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001653 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001654 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001655 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001656 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001657 }
1658
Elliott Hughes814e4032011-08-23 12:07:56 -07001659 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001660 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001661 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001662 return soa.Decode<mirror::String>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001663 }
1664
1665 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001666 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001667 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001668 return soa.Decode<mirror::String>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001669 }
1670
Ian Rogersbc939662013-08-15 10:26:54 -07001671 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1672 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001673 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001674 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001675 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001676 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001677 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001678 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001679 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001680 if (s->IsCompressed()) {
1681 for (int i = 0; i < length; ++i) {
1682 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1683 }
1684 } else {
1685 const jchar* chars = static_cast<jchar*>(s->GetValue());
1686 memcpy(buf, chars + start, length * sizeof(jchar));
1687 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001688 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001689 }
1690
Ian Rogersbc939662013-08-15 10:26:54 -07001691 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1692 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001693 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001694 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001695 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001696 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001697 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001698 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001699 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001700 if (s->IsCompressed()) {
1701 for (int i = 0; i < length; ++i) {
1702 buf[i] = s->CharAt(start+i);
1703 }
1704 } else {
1705 const jchar* chars = s->GetValue();
1706 size_t bytes = CountUtf8Bytes(chars + start, length);
1707 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1708 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001709 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001710 }
1711
Elliott Hughes75770752011-08-24 17:52:38 -07001712 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001713 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001714 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001715 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001716 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001717 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001718 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001719 if (s->IsCompressed()) {
1720 int32_t length = s->GetLength();
1721 for (int i = 0; i < length; ++i) {
1722 chars[i] = s->CharAt(i);
1723 }
1724 } else {
1725 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1726 }
Fred Shih56890e22014-06-02 11:11:52 -07001727 if (is_copy != nullptr) {
1728 *is_copy = JNI_TRUE;
1729 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001730 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001731 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001732 if (is_copy != nullptr) {
1733 *is_copy = JNI_FALSE;
1734 }
1735 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001736 }
1737
Mathieu Chartier590fee92013-09-13 13:46:47 -07001738 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001739 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001740 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001741 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001742 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001743 delete[] chars;
1744 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001745 }
1746
Elliott Hughes75770752011-08-24 17:52:38 -07001747 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001748 CHECK_NON_NULL_ARGUMENT(java_string);
1749 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001750 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001751 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001752 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001753 StackHandleScope<1> hs(soa.Self());
Mathieu Chartier0795f232016-09-27 18:43:30 -07001754 HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001755 if (!kUseReadBarrier) {
1756 heap->IncrementDisableMovingGC(soa.Self());
1757 } else {
1758 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1759 // to occur thanks to the to-space invariant.
1760 heap->IncrementDisableThreadFlip(soa.Self());
1761 }
Fred Shih56890e22014-06-02 11:11:52 -07001762 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001763 if (s->IsCompressed()) {
1764 if (is_copy != nullptr) {
1765 *is_copy = JNI_TRUE;
1766 }
1767 int32_t length = s->GetLength();
1768 jchar* chars = new jchar[length];
1769 for (int i = 0; i < length; ++i) {
1770 chars[i] = s->CharAt(i);
1771 }
1772 return chars;
1773 } else {
1774 if (is_copy != nullptr) {
1775 *is_copy = JNI_FALSE;
1776 }
1777 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001778 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001779 }
1780
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001781 static void ReleaseStringCritical(JNIEnv* env,
1782 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001783 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001784 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1785 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001786 gc::Heap* heap = Runtime::Current()->GetHeap();
Mathieu Chartier0795f232016-09-27 18:43:30 -07001787 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001788 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001789 if (!kUseReadBarrier) {
1790 heap->DecrementDisableMovingGC(soa.Self());
1791 } else {
1792 heap->DecrementDisableThreadFlip(soa.Self());
1793 }
Fred Shih56890e22014-06-02 11:11:52 -07001794 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001795 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1796 delete[] chars;
1797 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001798 }
1799
Elliott Hughes75770752011-08-24 17:52:38 -07001800 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001801 if (java_string == nullptr) {
1802 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001803 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001804 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001805 *is_copy = JNI_TRUE;
1806 }
Ian Rogersef28b142012-11-30 14:22:18 -08001807 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001808 ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001809 size_t byte_count = s->GetUtfLength();
1810 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001811 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001812 if (s->IsCompressed()) {
1813 for (size_t i = 0; i < byte_count; ++i) {
1814 bytes[i] = s->CharAt(i);
1815 }
1816 } else {
1817 const uint16_t* chars = s->GetValue();
1818 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1819 }
Elliott Hughes75770752011-08-24 17:52:38 -07001820 bytes[byte_count] = '\0';
1821 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001822 }
1823
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001824 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001825 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001826 }
1827
Elliott Hughesbd935992011-08-22 11:59:34 -07001828 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001829 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001830 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001831 ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001832 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001833 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1834 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001835 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001836 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001837 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001838 }
1839
Elliott Hughes814e4032011-08-23 12:07:56 -07001840 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001841 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001842 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001843 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1844 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001845 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001846 }
1847
Ian Rogersbc939662013-08-15 10:26:54 -07001848 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1849 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001850 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001851 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001852 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1853 soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
1854 ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value);
1855 array->Set<false>(index, value.Decode());
Elliott Hughescdf53122011-08-19 15:46:09 -07001856 }
1857
1858 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001859 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001860 }
1861
1862 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001863 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001864 }
1865
1866 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001867 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001868 }
1869
1870 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001871 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001872 }
1873
1874 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001875 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001876 }
1877
1878 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001879 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001880 }
1881
1882 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001883 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001884 }
1885
Ian Rogers1d99e452014-01-02 17:36:41 -08001886 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1887 jobject initial_element) {
1888 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001889 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001890 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001891 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001892 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001893
1894 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001895 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001896 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001897 {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001898 mirror::Class* element_class = soa.Decode<mirror::Class>(element_jclass).Decode();
Ian Rogers1d99e452014-01-02 17:36:41 -08001899 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001900 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1901 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001902 return nullptr;
1903 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001904 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001905 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001906 if (UNLIKELY(array_class == nullptr)) {
1907 return nullptr;
1908 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001909 }
1910
Elliott Hughes75770752011-08-24 17:52:38 -07001911 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001912 mirror::ObjectArray<mirror::Object>* result =
1913 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001914 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001915 ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001916 if (initial_object != nullptr) {
1917 mirror::Class* element_class = result->GetClass()->GetComponentType();
1918 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001919 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1920 "element type of '%s'",
1921 PrettyDescriptor(initial_object->GetClass()).c_str(),
1922 PrettyDescriptor(element_class).c_str());
1923 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001924 } else {
1925 for (jsize i = 0; i < length; ++i) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001926 result->SetWithoutChecks<false>(i, initial_object.Decode());
Ian Rogers1d99e452014-01-02 17:36:41 -08001927 }
1928 }
Elliott Hughes75770752011-08-24 17:52:38 -07001929 }
1930 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001931 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001932 }
1933
1934 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001935 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001936 }
1937
Ian Rogersa15e67d2012-02-28 13:51:55 -08001938 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001939 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001940 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001941 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001942 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001943 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1944 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001945 return nullptr;
1946 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001947 gc::Heap* heap = Runtime::Current()->GetHeap();
1948 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001949 if (!kUseReadBarrier) {
1950 heap->IncrementDisableMovingGC(soa.Self());
1951 } else {
1952 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1953 // to occur thanks to the to-space invariant.
1954 heap->IncrementDisableThreadFlip(soa.Self());
1955 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001956 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartier0795f232016-09-27 18:43:30 -07001957 array = soa.Decode<mirror::Array>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001958 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001959 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001960 *is_copy = JNI_FALSE;
1961 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001962 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001963 }
1964
Ian Rogers2d10b202014-05-12 19:15:18 -07001965 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1966 jint mode) {
1967 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1968 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001969 ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001970 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001971 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1972 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001973 return;
1974 }
1975 const size_t component_size = array->GetClass()->GetComponentSize();
Mathieu Chartier0795f232016-09-27 18:43:30 -07001976 ReleasePrimitiveArray(soa, array.Decode(), component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001977 }
1978
Elliott Hughes75770752011-08-24 17:52:38 -07001979 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001980 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001981 }
1982
Elliott Hughes75770752011-08-24 17:52:38 -07001983 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001984 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001985 }
1986
Elliott Hughes75770752011-08-24 17:52:38 -07001987 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001988 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001989 }
1990
Elliott Hughes75770752011-08-24 17:52:38 -07001991 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001992 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001993 }
1994
Elliott Hughes75770752011-08-24 17:52:38 -07001995 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001996 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001997 }
1998
Elliott Hughes75770752011-08-24 17:52:38 -07001999 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002000 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002001 }
2002
Elliott Hughes75770752011-08-24 17:52:38 -07002003 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002004 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002005 }
2006
Elliott Hughes75770752011-08-24 17:52:38 -07002007 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002008 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002009 }
2010
Mathieu Chartier590fee92013-09-13 13:46:47 -07002011 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2012 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002013 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2014 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002015 }
2016
Mathieu Chartier590fee92013-09-13 13:46:47 -07002017 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002018 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002019 }
2020
Mathieu Chartier590fee92013-09-13 13:46:47 -07002021 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002022 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002023 }
2024
Mathieu Chartier590fee92013-09-13 13:46:47 -07002025 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2026 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002027 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002028 }
2029
Mathieu Chartier590fee92013-09-13 13:46:47 -07002030 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2031 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002032 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002033 }
2034
Mathieu Chartier590fee92013-09-13 13:46:47 -07002035 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002036 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002037 }
2038
Mathieu Chartier590fee92013-09-13 13:46:47 -07002039 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002040 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002041 }
2042
Mathieu Chartier590fee92013-09-13 13:46:47 -07002043 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2044 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002045 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002046 }
2047
Ian Rogersbc939662013-08-15 10:26:54 -07002048 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2049 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002050 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002051 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002052 }
2053
Ian Rogersbc939662013-08-15 10:26:54 -07002054 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2055 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002056 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002057 }
2058
Ian Rogersbc939662013-08-15 10:26:54 -07002059 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2060 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002061 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002062 }
2063
Ian Rogersbc939662013-08-15 10:26:54 -07002064 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2065 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002066 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002067 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002068 }
2069
Ian Rogersbc939662013-08-15 10:26:54 -07002070 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2071 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002072 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002073 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002074 }
2075
Ian Rogersbc939662013-08-15 10:26:54 -07002076 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2077 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002078 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002079 }
2080
Ian Rogersbc939662013-08-15 10:26:54 -07002081 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2082 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002083 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002084 }
2085
Ian Rogersbc939662013-08-15 10:26:54 -07002086 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2087 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002088 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002089 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002090 }
2091
Ian Rogersbc939662013-08-15 10:26:54 -07002092 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2093 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002094 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002095 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002096 }
2097
Ian Rogersbc939662013-08-15 10:26:54 -07002098 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2099 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002100 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002101 }
2102
Ian Rogersbc939662013-08-15 10:26:54 -07002103 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2104 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002105 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002106 }
2107
Ian Rogersbc939662013-08-15 10:26:54 -07002108 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2109 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002110 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002111 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002112 }
2113
Ian Rogersbc939662013-08-15 10:26:54 -07002114 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2115 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002116 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002117 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002118 }
2119
Ian Rogersbc939662013-08-15 10:26:54 -07002120 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2121 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002122 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002123 }
2124
Ian Rogersbc939662013-08-15 10:26:54 -07002125 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2126 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002127 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002128 }
2129
Ian Rogersbc939662013-08-15 10:26:54 -07002130 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2131 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002132 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002133 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002134 }
2135
Ian Rogersbc939662013-08-15 10:26:54 -07002136 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2137 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002138 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2139 }
2140
Ian Rogersbc939662013-08-15 10:26:54 -07002141 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2142 jint method_count, bool return_errors) {
2143 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002144 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2145 method_count);
2146 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002147 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002148 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002149 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002150 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002151 if (UNLIKELY(method_count == 0)) {
2152 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2153 << PrettyDescriptor(c);
2154 return JNI_OK;
2155 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002156 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002157 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002158 const char* name = methods[i].name;
2159 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002160 const void* fnPtr = methods[i].fnPtr;
2161 if (UNLIKELY(name == nullptr)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002162 ReportInvalidJNINativeMethod(soa, c.Decode(), "method name", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002163 return JNI_ERR;
2164 } else if (UNLIKELY(sig == nullptr)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002165 ReportInvalidJNINativeMethod(soa, c.Decode(), "method signature", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002166 return JNI_ERR;
2167 } else if (UNLIKELY(fnPtr == nullptr)) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002168 ReportInvalidJNINativeMethod(soa, c.Decode(), "native function", i, return_errors);
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002169 return JNI_ERR;
2170 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002171 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002172 // Notes about fast JNI calls:
2173 //
2174 // On a normal JNI call, the calling thread usually transitions
2175 // from the kRunnable state to the kNative state. But if the
2176 // called native function needs to access any Java object, it
2177 // will have to transition back to the kRunnable state.
2178 //
2179 // There is a cost to this double transition. For a JNI call
2180 // that should be quick, this cost may dominate the call cost.
2181 //
2182 // On a fast JNI call, the calling thread avoids this double
2183 // transition by not transitioning from kRunnable to kNative and
2184 // stays in the kRunnable state.
2185 //
2186 // There are risks to using a fast JNI call because it can delay
2187 // a response to a thread suspension request which is typically
2188 // used for a GC root scanning, etc. If a fast JNI call takes a
2189 // long time, it could cause longer thread suspension latency
2190 // and GC pauses.
2191 //
2192 // Thus, fast JNI should be used with care. It should be used
2193 // for a JNI call that takes a short amount of time (eg. no
2194 // long-running loop) and does not block (eg. no locks, I/O,
2195 // etc.)
2196 //
2197 // A '!' prefix in the signature in the JNINativeMethod
2198 // indicates that it's a fast JNI call and the runtime omits the
2199 // thread state transition from kRunnable to kNative at the
2200 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002201 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002202 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002203 ++sig;
2204 }
2205
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002206 // Note: the right order is to try to find the method locally
2207 // first, either as a direct or a virtual method. Then move to
2208 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002209 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002210 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
Mathieu Chartier0795f232016-09-27 18:43:30 -07002211 for (ObjPtr<mirror::Class> current_class = c;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002212 current_class != nullptr;
2213 current_class = current_class->GetSuperClass()) {
2214 // Search first only comparing methods which are native.
Mathieu Chartier0795f232016-09-27 18:43:30 -07002215 m = FindMethod<true>(current_class.Decode(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002216 if (m != nullptr) {
2217 break;
2218 }
2219
2220 // Search again comparing to all methods, to find non-native methods that match.
Mathieu Chartier0795f232016-09-27 18:43:30 -07002221 m = FindMethod<false>(current_class.Decode(), name, sig);
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002222 if (m != nullptr) {
2223 break;
2224 }
2225
2226 if (warn_on_going_to_parent) {
2227 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2228 << "This is slow, consider changing your RegisterNatives calls.";
2229 warn_on_going_to_parent = false;
2230 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002231 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002232
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002233 if (m == nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002234 c->DumpClass(
2235 LOG_STREAM(return_errors
2236 ? ::android::base::ERROR
2237 : ::android::base::FATAL_WITHOUT_ABORT),
2238 mirror::Class::kDumpClassFullDetail);
2239 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2240 << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002241 << PrettyDescriptor(c) << "." << name << sig << " in "
2242 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier0795f232016-09-27 18:43:30 -07002243 ThrowNoSuchMethodError(soa, c.Decode(), name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002244 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002245 } else if (!m->IsNative()) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002246 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2247 << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002248 << PrettyDescriptor(c) << "." << name << sig
2249 << " as native";
Mathieu Chartier0795f232016-09-27 18:43:30 -07002250 ThrowNoSuchMethodError(soa, c.Decode(), name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002251 return JNI_ERR;
2252 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002253
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002254 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002255
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002256 is_fast = is_fast || m->IsFastNative(); // Merge with @FastNative state.
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002257 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002258 }
2259 return JNI_OK;
2260 }
2261
Elliott Hughes5174fe62011-08-23 15:12:35 -07002262 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002263 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002264 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002265 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002266
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002267 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002268
Ian Rogers2d10b202014-05-12 19:15:18 -07002269 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002270 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002271 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002272 if (m.IsNative()) {
2273 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002274 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002275 }
2276 }
2277
Ian Rogers2d10b202014-05-12 19:15:18 -07002278 if (unregistered_count == 0) {
2279 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2280 << PrettyDescriptor(c) << "' that contains no native methods";
2281 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002282 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002283 }
2284
Ian Rogers719d1a32014-03-06 12:13:39 -08002285 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002286 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002287 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002288 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002289 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002290 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002291 return JNI_ERR;
2292 }
Mathieu Chartier0795f232016-09-27 18:43:30 -07002293 soa.Env()->monitors.Add(o.Decode());
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002294 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002295 }
2296
Ian Rogers719d1a32014-03-06 12:13:39 -08002297 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002298 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002299 ScopedObjectAccess soa(env);
Mathieu Chartier0795f232016-09-27 18:43:30 -07002300 ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002301 o->MonitorExit(soa.Self());
2302 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002303 return JNI_ERR;
2304 }
Mathieu Chartier0795f232016-09-27 18:43:30 -07002305 soa.Env()->monitors.Remove(o.Decode());
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002306 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002307 }
2308
2309 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002310 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002311 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002312 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002313 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002314 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002315 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002316 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002317 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002318 }
2319
Elliott Hughescdf53122011-08-19 15:46:09 -07002320 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002321 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002322 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2323 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002324 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002325 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002326 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002327 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2328 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002329 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002330 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002331
Brian Carlstrom85a93362014-06-25 09:30:52 -07002332 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002333 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002334 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2335 "buffer capacity greater than maximum jint: %" PRId64,
2336 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002337 return nullptr;
2338 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002339 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002340 jint capacity_arg = static_cast<jint>(capacity);
2341
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002342 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2343 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002344 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002345 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002346 }
2347
Elliott Hughesb465ab02011-08-24 11:21:21 -07002348 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002349 return reinterpret_cast<void*>(env->GetLongField(
2350 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002351 }
2352
Elliott Hughesb465ab02011-08-24 11:21:21 -07002353 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002354 return static_cast<jlong>(env->GetIntField(
2355 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002356 }
2357
Andreas Gampea8763072014-12-20 00:08:35 -08002358 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2359 if (java_object == nullptr) {
2360 return JNIInvalidRefType;
2361 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002362
2363 // Do we definitely know what kind of reference this is?
2364 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2365 IndirectRefKind kind = GetIndirectRefKind(ref);
2366 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002367 case kLocal:
2368 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002369 case kGlobal:
2370 return JNIGlobalRefType;
2371 case kWeakGlobal:
2372 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002373 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002374 // Assume value is in a handle scope.
2375 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002376 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002377 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002378 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002379 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002380
2381 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002382 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2383 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002384 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002385 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002386 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002387 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2388 return JNI_ERR;
2389 }
2390 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002391 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002392 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2393 if (!okay) {
2394 soa.Self()->ThrowOutOfMemoryError(caller);
2395 }
2396 return okay ? JNI_OK : JNI_ERR;
2397 }
2398
2399 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002400 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002401 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002402 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002403 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002404 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002405 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002406 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002407 return soa.AddLocalReference<JniT>(result);
2408 }
2409
Ian Rogers2d10b202014-05-12 19:15:18 -07002410 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2411 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2412 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002413 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07002414 ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002415 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002416 soa.Vm()->JniAbortF(fn_name,
2417 "attempt to %s %s primitive array elements with an object of type %s",
2418 operation,
2419 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2420 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002421 return nullptr;
2422 }
2423 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
Mathieu Chartier0795f232016-09-27 18:43:30 -07002424 return array.Decode();
Ian Rogers2d10b202014-05-12 19:15:18 -07002425 }
2426
2427 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2428 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2429 CHECK_NON_NULL_ARGUMENT(java_array);
2430 ScopedObjectAccess soa(env);
2431 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2432 "GetArrayElements",
2433 "get");
2434 if (UNLIKELY(array == nullptr)) {
2435 return nullptr;
2436 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002437 // Only make a copy if necessary.
2438 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2439 if (is_copy != nullptr) {
2440 *is_copy = JNI_TRUE;
2441 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002442 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002443 size_t size = array->GetLength() * component_size;
2444 void* data = new uint64_t[RoundUp(size, 8) / 8];
2445 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002446 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002447 } else {
2448 if (is_copy != nullptr) {
2449 *is_copy = JNI_FALSE;
2450 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002451 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002452 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002453 }
2454
Ian Rogers2d10b202014-05-12 19:15:18 -07002455 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002456 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002457 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002458 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002459 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2460 "ReleaseArrayElements",
2461 "release");
2462 if (array == nullptr) {
2463 return;
2464 }
2465 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2466 }
2467
2468 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2469 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002470 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002471 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002472 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002473 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002474 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002475 if (is_copy) {
2476 // Sanity check: If elements is not the same as the java array's data, it better not be a
2477 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2478 // copies we make?
2479 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002480 soa.Vm()->JniAbortF("ReleaseArrayElements",
2481 "invalid element pointer %p, array elements are %p",
2482 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002483 return;
2484 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002485 if (mode != JNI_ABORT) {
2486 memcpy(array_data, elements, bytes);
2487 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2488 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2489 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002490 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002491 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002492 }
2493 if (mode != JNI_COMMIT) {
2494 if (is_copy) {
2495 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002496 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002497 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002498 if (!kUseReadBarrier) {
2499 heap->DecrementDisableMovingGC(soa.Self());
2500 } else {
2501 heap->DecrementDisableThreadFlip(soa.Self());
2502 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002503 }
2504 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002505 }
2506
Ian Rogers2d10b202014-05-12 19:15:18 -07002507 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2508 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2509 jsize start, jsize length, ElementT* buf) {
2510 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2511 ScopedObjectAccess soa(env);
2512 ArtArrayT* array =
2513 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2514 "GetPrimitiveArrayRegion",
2515 "get region of");
2516 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002517 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002518 ThrowAIOOBE(soa, array, start, length, "src");
2519 } else {
2520 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2521 ElementT* data = array->GetData();
2522 memcpy(buf, data + start, length * sizeof(ElementT));
2523 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002524 }
2525 }
2526
Ian Rogers2d10b202014-05-12 19:15:18 -07002527 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2528 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2529 jsize start, jsize length, const ElementT* buf) {
2530 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2531 ScopedObjectAccess soa(env);
2532 ArtArrayT* array =
2533 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2534 "SetPrimitiveArrayRegion",
2535 "set region of");
2536 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002537 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002538 ThrowAIOOBE(soa, array, start, length, "dst");
2539 } else {
2540 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2541 ElementT* data = array->GetData();
2542 memcpy(data + start, buf, length * sizeof(ElementT));
2543 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002544 }
2545 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002546};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002547
Elliott Hughes88c5c352012-03-15 18:49:48 -07002548const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002549 nullptr, // reserved0.
2550 nullptr, // reserved1.
2551 nullptr, // reserved2.
2552 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002553 JNI::GetVersion,
2554 JNI::DefineClass,
2555 JNI::FindClass,
2556 JNI::FromReflectedMethod,
2557 JNI::FromReflectedField,
2558 JNI::ToReflectedMethod,
2559 JNI::GetSuperclass,
2560 JNI::IsAssignableFrom,
2561 JNI::ToReflectedField,
2562 JNI::Throw,
2563 JNI::ThrowNew,
2564 JNI::ExceptionOccurred,
2565 JNI::ExceptionDescribe,
2566 JNI::ExceptionClear,
2567 JNI::FatalError,
2568 JNI::PushLocalFrame,
2569 JNI::PopLocalFrame,
2570 JNI::NewGlobalRef,
2571 JNI::DeleteGlobalRef,
2572 JNI::DeleteLocalRef,
2573 JNI::IsSameObject,
2574 JNI::NewLocalRef,
2575 JNI::EnsureLocalCapacity,
2576 JNI::AllocObject,
2577 JNI::NewObject,
2578 JNI::NewObjectV,
2579 JNI::NewObjectA,
2580 JNI::GetObjectClass,
2581 JNI::IsInstanceOf,
2582 JNI::GetMethodID,
2583 JNI::CallObjectMethod,
2584 JNI::CallObjectMethodV,
2585 JNI::CallObjectMethodA,
2586 JNI::CallBooleanMethod,
2587 JNI::CallBooleanMethodV,
2588 JNI::CallBooleanMethodA,
2589 JNI::CallByteMethod,
2590 JNI::CallByteMethodV,
2591 JNI::CallByteMethodA,
2592 JNI::CallCharMethod,
2593 JNI::CallCharMethodV,
2594 JNI::CallCharMethodA,
2595 JNI::CallShortMethod,
2596 JNI::CallShortMethodV,
2597 JNI::CallShortMethodA,
2598 JNI::CallIntMethod,
2599 JNI::CallIntMethodV,
2600 JNI::CallIntMethodA,
2601 JNI::CallLongMethod,
2602 JNI::CallLongMethodV,
2603 JNI::CallLongMethodA,
2604 JNI::CallFloatMethod,
2605 JNI::CallFloatMethodV,
2606 JNI::CallFloatMethodA,
2607 JNI::CallDoubleMethod,
2608 JNI::CallDoubleMethodV,
2609 JNI::CallDoubleMethodA,
2610 JNI::CallVoidMethod,
2611 JNI::CallVoidMethodV,
2612 JNI::CallVoidMethodA,
2613 JNI::CallNonvirtualObjectMethod,
2614 JNI::CallNonvirtualObjectMethodV,
2615 JNI::CallNonvirtualObjectMethodA,
2616 JNI::CallNonvirtualBooleanMethod,
2617 JNI::CallNonvirtualBooleanMethodV,
2618 JNI::CallNonvirtualBooleanMethodA,
2619 JNI::CallNonvirtualByteMethod,
2620 JNI::CallNonvirtualByteMethodV,
2621 JNI::CallNonvirtualByteMethodA,
2622 JNI::CallNonvirtualCharMethod,
2623 JNI::CallNonvirtualCharMethodV,
2624 JNI::CallNonvirtualCharMethodA,
2625 JNI::CallNonvirtualShortMethod,
2626 JNI::CallNonvirtualShortMethodV,
2627 JNI::CallNonvirtualShortMethodA,
2628 JNI::CallNonvirtualIntMethod,
2629 JNI::CallNonvirtualIntMethodV,
2630 JNI::CallNonvirtualIntMethodA,
2631 JNI::CallNonvirtualLongMethod,
2632 JNI::CallNonvirtualLongMethodV,
2633 JNI::CallNonvirtualLongMethodA,
2634 JNI::CallNonvirtualFloatMethod,
2635 JNI::CallNonvirtualFloatMethodV,
2636 JNI::CallNonvirtualFloatMethodA,
2637 JNI::CallNonvirtualDoubleMethod,
2638 JNI::CallNonvirtualDoubleMethodV,
2639 JNI::CallNonvirtualDoubleMethodA,
2640 JNI::CallNonvirtualVoidMethod,
2641 JNI::CallNonvirtualVoidMethodV,
2642 JNI::CallNonvirtualVoidMethodA,
2643 JNI::GetFieldID,
2644 JNI::GetObjectField,
2645 JNI::GetBooleanField,
2646 JNI::GetByteField,
2647 JNI::GetCharField,
2648 JNI::GetShortField,
2649 JNI::GetIntField,
2650 JNI::GetLongField,
2651 JNI::GetFloatField,
2652 JNI::GetDoubleField,
2653 JNI::SetObjectField,
2654 JNI::SetBooleanField,
2655 JNI::SetByteField,
2656 JNI::SetCharField,
2657 JNI::SetShortField,
2658 JNI::SetIntField,
2659 JNI::SetLongField,
2660 JNI::SetFloatField,
2661 JNI::SetDoubleField,
2662 JNI::GetStaticMethodID,
2663 JNI::CallStaticObjectMethod,
2664 JNI::CallStaticObjectMethodV,
2665 JNI::CallStaticObjectMethodA,
2666 JNI::CallStaticBooleanMethod,
2667 JNI::CallStaticBooleanMethodV,
2668 JNI::CallStaticBooleanMethodA,
2669 JNI::CallStaticByteMethod,
2670 JNI::CallStaticByteMethodV,
2671 JNI::CallStaticByteMethodA,
2672 JNI::CallStaticCharMethod,
2673 JNI::CallStaticCharMethodV,
2674 JNI::CallStaticCharMethodA,
2675 JNI::CallStaticShortMethod,
2676 JNI::CallStaticShortMethodV,
2677 JNI::CallStaticShortMethodA,
2678 JNI::CallStaticIntMethod,
2679 JNI::CallStaticIntMethodV,
2680 JNI::CallStaticIntMethodA,
2681 JNI::CallStaticLongMethod,
2682 JNI::CallStaticLongMethodV,
2683 JNI::CallStaticLongMethodA,
2684 JNI::CallStaticFloatMethod,
2685 JNI::CallStaticFloatMethodV,
2686 JNI::CallStaticFloatMethodA,
2687 JNI::CallStaticDoubleMethod,
2688 JNI::CallStaticDoubleMethodV,
2689 JNI::CallStaticDoubleMethodA,
2690 JNI::CallStaticVoidMethod,
2691 JNI::CallStaticVoidMethodV,
2692 JNI::CallStaticVoidMethodA,
2693 JNI::GetStaticFieldID,
2694 JNI::GetStaticObjectField,
2695 JNI::GetStaticBooleanField,
2696 JNI::GetStaticByteField,
2697 JNI::GetStaticCharField,
2698 JNI::GetStaticShortField,
2699 JNI::GetStaticIntField,
2700 JNI::GetStaticLongField,
2701 JNI::GetStaticFloatField,
2702 JNI::GetStaticDoubleField,
2703 JNI::SetStaticObjectField,
2704 JNI::SetStaticBooleanField,
2705 JNI::SetStaticByteField,
2706 JNI::SetStaticCharField,
2707 JNI::SetStaticShortField,
2708 JNI::SetStaticIntField,
2709 JNI::SetStaticLongField,
2710 JNI::SetStaticFloatField,
2711 JNI::SetStaticDoubleField,
2712 JNI::NewString,
2713 JNI::GetStringLength,
2714 JNI::GetStringChars,
2715 JNI::ReleaseStringChars,
2716 JNI::NewStringUTF,
2717 JNI::GetStringUTFLength,
2718 JNI::GetStringUTFChars,
2719 JNI::ReleaseStringUTFChars,
2720 JNI::GetArrayLength,
2721 JNI::NewObjectArray,
2722 JNI::GetObjectArrayElement,
2723 JNI::SetObjectArrayElement,
2724 JNI::NewBooleanArray,
2725 JNI::NewByteArray,
2726 JNI::NewCharArray,
2727 JNI::NewShortArray,
2728 JNI::NewIntArray,
2729 JNI::NewLongArray,
2730 JNI::NewFloatArray,
2731 JNI::NewDoubleArray,
2732 JNI::GetBooleanArrayElements,
2733 JNI::GetByteArrayElements,
2734 JNI::GetCharArrayElements,
2735 JNI::GetShortArrayElements,
2736 JNI::GetIntArrayElements,
2737 JNI::GetLongArrayElements,
2738 JNI::GetFloatArrayElements,
2739 JNI::GetDoubleArrayElements,
2740 JNI::ReleaseBooleanArrayElements,
2741 JNI::ReleaseByteArrayElements,
2742 JNI::ReleaseCharArrayElements,
2743 JNI::ReleaseShortArrayElements,
2744 JNI::ReleaseIntArrayElements,
2745 JNI::ReleaseLongArrayElements,
2746 JNI::ReleaseFloatArrayElements,
2747 JNI::ReleaseDoubleArrayElements,
2748 JNI::GetBooleanArrayRegion,
2749 JNI::GetByteArrayRegion,
2750 JNI::GetCharArrayRegion,
2751 JNI::GetShortArrayRegion,
2752 JNI::GetIntArrayRegion,
2753 JNI::GetLongArrayRegion,
2754 JNI::GetFloatArrayRegion,
2755 JNI::GetDoubleArrayRegion,
2756 JNI::SetBooleanArrayRegion,
2757 JNI::SetByteArrayRegion,
2758 JNI::SetCharArrayRegion,
2759 JNI::SetShortArrayRegion,
2760 JNI::SetIntArrayRegion,
2761 JNI::SetLongArrayRegion,
2762 JNI::SetFloatArrayRegion,
2763 JNI::SetDoubleArrayRegion,
2764 JNI::RegisterNatives,
2765 JNI::UnregisterNatives,
2766 JNI::MonitorEnter,
2767 JNI::MonitorExit,
2768 JNI::GetJavaVM,
2769 JNI::GetStringRegion,
2770 JNI::GetStringUTFRegion,
2771 JNI::GetPrimitiveArrayCritical,
2772 JNI::ReleasePrimitiveArrayCritical,
2773 JNI::GetStringCritical,
2774 JNI::ReleaseStringCritical,
2775 JNI::NewWeakGlobalRef,
2776 JNI::DeleteWeakGlobalRef,
2777 JNI::ExceptionCheck,
2778 JNI::NewDirectByteBuffer,
2779 JNI::GetDirectBufferAddress,
2780 JNI::GetDirectBufferCapacity,
2781 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002782};
2783
Ian Rogers68d8b422014-07-17 11:09:10 -07002784const JNINativeInterface* GetJniNativeInterface() {
2785 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002786}
2787
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002788void (*gJniSleepForeverStub[])() = {
2789 nullptr, // reserved0.
2790 nullptr, // reserved1.
2791 nullptr, // reserved2.
2792 nullptr, // reserved3.
2793 SleepForever,
2794 SleepForever,
2795 SleepForever,
2796 SleepForever,
2797 SleepForever,
2798 SleepForever,
2799 SleepForever,
2800 SleepForever,
2801 SleepForever,
2802 SleepForever,
2803 SleepForever,
2804 SleepForever,
2805 SleepForever,
2806 SleepForever,
2807 SleepForever,
2808 SleepForever,
2809 SleepForever,
2810 SleepForever,
2811 SleepForever,
2812 SleepForever,
2813 SleepForever,
2814 SleepForever,
2815 SleepForever,
2816 SleepForever,
2817 SleepForever,
2818 SleepForever,
2819 SleepForever,
2820 SleepForever,
2821 SleepForever,
2822 SleepForever,
2823 SleepForever,
2824 SleepForever,
2825 SleepForever,
2826 SleepForever,
2827 SleepForever,
2828 SleepForever,
2829 SleepForever,
2830 SleepForever,
2831 SleepForever,
2832 SleepForever,
2833 SleepForever,
2834 SleepForever,
2835 SleepForever,
2836 SleepForever,
2837 SleepForever,
2838 SleepForever,
2839 SleepForever,
2840 SleepForever,
2841 SleepForever,
2842 SleepForever,
2843 SleepForever,
2844 SleepForever,
2845 SleepForever,
2846 SleepForever,
2847 SleepForever,
2848 SleepForever,
2849 SleepForever,
2850 SleepForever,
2851 SleepForever,
2852 SleepForever,
2853 SleepForever,
2854 SleepForever,
2855 SleepForever,
2856 SleepForever,
2857 SleepForever,
2858 SleepForever,
2859 SleepForever,
2860 SleepForever,
2861 SleepForever,
2862 SleepForever,
2863 SleepForever,
2864 SleepForever,
2865 SleepForever,
2866 SleepForever,
2867 SleepForever,
2868 SleepForever,
2869 SleepForever,
2870 SleepForever,
2871 SleepForever,
2872 SleepForever,
2873 SleepForever,
2874 SleepForever,
2875 SleepForever,
2876 SleepForever,
2877 SleepForever,
2878 SleepForever,
2879 SleepForever,
2880 SleepForever,
2881 SleepForever,
2882 SleepForever,
2883 SleepForever,
2884 SleepForever,
2885 SleepForever,
2886 SleepForever,
2887 SleepForever,
2888 SleepForever,
2889 SleepForever,
2890 SleepForever,
2891 SleepForever,
2892 SleepForever,
2893 SleepForever,
2894 SleepForever,
2895 SleepForever,
2896 SleepForever,
2897 SleepForever,
2898 SleepForever,
2899 SleepForever,
2900 SleepForever,
2901 SleepForever,
2902 SleepForever,
2903 SleepForever,
2904 SleepForever,
2905 SleepForever,
2906 SleepForever,
2907 SleepForever,
2908 SleepForever,
2909 SleepForever,
2910 SleepForever,
2911 SleepForever,
2912 SleepForever,
2913 SleepForever,
2914 SleepForever,
2915 SleepForever,
2916 SleepForever,
2917 SleepForever,
2918 SleepForever,
2919 SleepForever,
2920 SleepForever,
2921 SleepForever,
2922 SleepForever,
2923 SleepForever,
2924 SleepForever,
2925 SleepForever,
2926 SleepForever,
2927 SleepForever,
2928 SleepForever,
2929 SleepForever,
2930 SleepForever,
2931 SleepForever,
2932 SleepForever,
2933 SleepForever,
2934 SleepForever,
2935 SleepForever,
2936 SleepForever,
2937 SleepForever,
2938 SleepForever,
2939 SleepForever,
2940 SleepForever,
2941 SleepForever,
2942 SleepForever,
2943 SleepForever,
2944 SleepForever,
2945 SleepForever,
2946 SleepForever,
2947 SleepForever,
2948 SleepForever,
2949 SleepForever,
2950 SleepForever,
2951 SleepForever,
2952 SleepForever,
2953 SleepForever,
2954 SleepForever,
2955 SleepForever,
2956 SleepForever,
2957 SleepForever,
2958 SleepForever,
2959 SleepForever,
2960 SleepForever,
2961 SleepForever,
2962 SleepForever,
2963 SleepForever,
2964 SleepForever,
2965 SleepForever,
2966 SleepForever,
2967 SleepForever,
2968 SleepForever,
2969 SleepForever,
2970 SleepForever,
2971 SleepForever,
2972 SleepForever,
2973 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};
3023
3024const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3025 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3026}
3027
Elliott Hughesc8fece32013-01-02 11:27:23 -08003028void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003029 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003030 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003031 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003032 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3033 }
3034 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3035}
3036
Ian Rogersdf20fe02011-07-20 20:34:16 -07003037} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003038
3039std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3040 switch (rhs) {
3041 case JNIInvalidRefType:
3042 os << "JNIInvalidRefType";
3043 return os;
3044 case JNILocalRefType:
3045 os << "JNILocalRefType";
3046 return os;
3047 case JNIGlobalRefType:
3048 os << "JNIGlobalRefType";
3049 return os;
3050 case JNIWeakGlobalRefType:
3051 os << "JNIWeakGlobalRefType";
3052 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003053 default:
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07003054 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Ian Rogersc7dd2952014-10-21 23:31:19 -07003055 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003056 }
3057}