blob: a11f9ab31ffcea33db077dca75a997a8f7b66eaf [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Ian Rogersdf20fe02011-07-20 20:34:16 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "jni_internal.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070018
Elliott Hughes0af55432011-08-17 18:37:28 -070019#include <dlfcn.h>
Elliott Hughes79082e32011-08-25 12:07:32 -070020
21#include <cstdarg>
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Elliott Hughes0af55432011-08-17 18:37:28 -070023#include <utility>
24#include <vector>
Carl Shapiro2ed144c2011-07-26 16:52:08 -070025
Mathieu Chartierc7853442015-03-27 14:35:38 -070026#include "art_field-inl.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070027#include "art_method-inl.h"
Ian Rogersef7d42f2014-01-06 12:55:46 -080028#include "atomic.h"
Mathieu Chartierbad02672014-08-25 13:08:22 -070029#include "base/allocator.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070030#include "base/enums.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080032#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080033#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080034#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070035#include "dex_file-inl.h"
Mathieu Chartierd0004802014-10-15 16:59:47 -070036#include "fault_handler.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070037#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070038#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070039#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070040#include "interpreter/interpreter.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070041#include "jni_env_ext.h"
42#include "java_vm_ext.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043#include "mirror/class-inl.h"
44#include "mirror/class_loader.h"
Hiroshi Yamauchi02d2f292015-04-03 13:35:16 -070045#include "mirror/field-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070046#include "mirror/method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047#include "mirror/object-inl.h"
48#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070049#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080050#include "mirror/throwable.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080051#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070052#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070053#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070054#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070055#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070056#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070057#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080058#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070059#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070060
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070061namespace art {
62
Mathieu Chartier24555ad2014-10-06 13:41:33 -070063// Consider turning this on when there is errors which could be related to JNI array copies such as
64// things not rendering correctly. E.g. b/16858794
65static constexpr bool kWarnJniAbort = false;
66
Elliott Hughes6b436852011-08-12 10:16:44 -070067// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
68// separated with slashes but aren't wrapped with "L;" like regular descriptors
69// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
70// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
71// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -070072static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070073 std::string result;
74 // Add the missing "L;" if necessary.
75 if (name[0] == '[') {
76 result = name;
77 } else {
78 result += 'L';
79 result += name;
80 result += ';';
81 }
82 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070083 if (result.find('.') != std::string::npos) {
84 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
85 << "\"" << name << "\"";
86 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -070087 }
88 return result;
89}
90
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080091static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070092 const char* name, const char* sig, const char* kind)
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 Chartierc528dba2013-11-26 12:00:11 -0800111static mirror::Class* EnsureInitialized(Thread* self, 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800127 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) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700146 ThrowNoSuchMethodError(soa, c, 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800152static 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)) {
Ian Rogers68d8b422014-07-17 11:09:10 -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 Chartiere7e8a5f2014-02-14 16:59:41 -0800164 mirror::ClassLoader* class_loader =
165 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
166 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.
Ian Rogers68d8b422014-07-17 11:09:10 -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(
187 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
188 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800275 << 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);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000285 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
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 Chartierdaaf3262015-03-24 13:30:28 -0700366 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
367 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 }
371 auto* field = static_cast<mirror::Field*>(obj_field);
372 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800401 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800408 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800418 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
419 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100420 return c2->IsAssignableFrom(c1) ? 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800430 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
431 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800438 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
439 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700440 return JNI_ERR;
441 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000442 soa.Self()->SetException(exception);
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 Chartiere7e8a5f2014-02-14 16:59:41 -0800512 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800525 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Ian Rogers68d8b422014-07-17 11:09:10 -0700526 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
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);
Ian Rogers68d8b422014-07-17 11:09:10 -0700537 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
538 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
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 Chartiere7e8a5f2014-02-14 16:59:41 -0800549 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);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800582 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
583 ? 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800590 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 Chartiere7e8a5f2014-02-14 16:59:41 -0800616 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800617 if (c == nullptr) {
618 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700619 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800620 if (c->IsStringClass()) {
621 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100622 jmethodID sf_mid = soa.EncodeMethod(
623 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800624 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
625 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800626 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800627 if (result == nullptr) {
628 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700629 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700630 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700631 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800632 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800633 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700634 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800635 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700636 }
637
Elliott Hughes72025e52011-08-23 17:50:30 -0700638 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700639 CHECK_NON_NULL_ARGUMENT(java_class);
640 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700641 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800642 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800643 if (c == nullptr) {
644 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700645 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800646 if (c->IsStringClass()) {
647 // Replace calls to String.<init> with equivalent StringFactory call.
Nicolas Geoffrayda079bb2016-09-26 17:56:07 +0100648 jmethodID sf_mid = soa.EncodeMethod(
649 WellKnownClasses::StringInitToStringFactory(soa.DecodeMethod(mid)));
Jeff Hao848f70a2014-01-15 13:49:50 -0800650 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
651 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800652 mirror::Object* result = c->AllocObject(soa.Self());
653 if (result == nullptr) {
654 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700655 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700656 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700657 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800658 if (soa.Self()->IsExceptionPending()) {
659 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700660 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800661 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700662 }
663
Ian Rogersbc939662013-08-15 10:26:54 -0700664 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700665 CHECK_NON_NULL_ARGUMENT(java_class);
666 CHECK_NON_NULL_ARGUMENT(name);
667 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700668 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700669 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700670 }
671
Ian Rogersbc939662013-08-15 10:26:54 -0700672 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
673 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700674 CHECK_NON_NULL_ARGUMENT(java_class);
675 CHECK_NON_NULL_ARGUMENT(name);
676 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700677 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700678 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700679 }
680
Elliott Hughes72025e52011-08-23 17:50:30 -0700681 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700682 va_list ap;
683 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700684 CHECK_NON_NULL_ARGUMENT(obj);
685 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700686 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700687 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700688 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700689 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700690 }
691
Elliott Hughes72025e52011-08-23 17:50:30 -0700692 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700693 CHECK_NON_NULL_ARGUMENT(obj);
694 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700695 ScopedObjectAccess soa(env);
696 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
697 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700698 }
699
Elliott Hughes72025e52011-08-23 17:50:30 -0700700 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700701 CHECK_NON_NULL_ARGUMENT(obj);
702 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700703 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700704 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700705 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700706 }
707
Elliott Hughes72025e52011-08-23 17:50:30 -0700708 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700709 va_list ap;
710 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700711 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
712 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700713 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700714 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700715 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700716 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700717 }
718
Elliott Hughes72025e52011-08-23 17:50:30 -0700719 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700720 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
721 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700722 ScopedObjectAccess soa(env);
723 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700724 }
725
Elliott Hughes72025e52011-08-23 17:50:30 -0700726 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700727 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
728 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700729 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700730 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700731 }
732
Elliott Hughes72025e52011-08-23 17:50:30 -0700733 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700734 va_list ap;
735 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700736 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
737 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700738 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700739 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700740 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700741 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700742 }
743
Elliott Hughes72025e52011-08-23 17:50:30 -0700744 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700745 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
746 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700747 ScopedObjectAccess soa(env);
748 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700749 }
750
Elliott Hughes72025e52011-08-23 17:50:30 -0700751 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700752 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
753 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700754 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700755 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700756 }
757
Elliott Hughes72025e52011-08-23 17:50:30 -0700758 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700759 va_list ap;
760 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700761 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
762 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700763 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700764 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700765 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700766 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700767 }
768
Elliott Hughes72025e52011-08-23 17:50:30 -0700769 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700770 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
771 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700772 ScopedObjectAccess soa(env);
773 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700774 }
775
Elliott Hughes72025e52011-08-23 17:50:30 -0700776 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700777 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
778 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700779 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700780 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700781 }
782
Elliott Hughes72025e52011-08-23 17:50:30 -0700783 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700784 va_list ap;
785 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700786 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
787 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700788 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700789 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700790 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700791 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700792 }
793
Elliott Hughes72025e52011-08-23 17:50:30 -0700794 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700795 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
796 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700797 ScopedObjectAccess soa(env);
798 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700799 }
800
Elliott Hughes72025e52011-08-23 17:50:30 -0700801 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700802 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
803 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700804 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700805 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700806 }
807
Elliott Hughes72025e52011-08-23 17:50:30 -0700808 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700809 va_list ap;
810 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700811 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
812 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700813 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700814 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700815 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700816 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700817 }
818
Elliott Hughes72025e52011-08-23 17:50:30 -0700819 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700820 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
821 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700822 ScopedObjectAccess soa(env);
823 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700824 }
825
Elliott Hughes72025e52011-08-23 17:50:30 -0700826 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700827 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
828 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700829 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700830 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700831 }
832
Elliott Hughes72025e52011-08-23 17:50:30 -0700833 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700834 va_list ap;
835 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700836 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
837 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700838 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700839 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700840 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700841 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700842 }
843
Elliott Hughes72025e52011-08-23 17:50:30 -0700844 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700845 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
846 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700847 ScopedObjectAccess soa(env);
848 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700849 }
850
Elliott Hughes72025e52011-08-23 17:50:30 -0700851 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700852 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
853 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700854 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700855 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700856 }
857
Elliott Hughes72025e52011-08-23 17:50:30 -0700858 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700859 va_list ap;
860 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700861 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
862 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700863 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700864 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700865 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700866 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700867 }
868
Elliott Hughes72025e52011-08-23 17:50:30 -0700869 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700870 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
871 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700872 ScopedObjectAccess soa(env);
873 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700874 }
875
Elliott Hughes72025e52011-08-23 17:50:30 -0700876 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700877 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
878 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700879 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700880 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700881 }
882
Elliott Hughes72025e52011-08-23 17:50:30 -0700883 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700884 va_list ap;
885 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700886 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
887 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700888 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700889 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700890 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700891 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700892 }
893
Elliott Hughes72025e52011-08-23 17:50:30 -0700894 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700895 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
896 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700897 ScopedObjectAccess soa(env);
898 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700899 }
900
Elliott Hughes72025e52011-08-23 17:50:30 -0700901 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700902 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
903 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700904 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700905 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700906 }
907
Elliott Hughes72025e52011-08-23 17:50:30 -0700908 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700909 va_list ap;
910 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700911 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
912 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700913 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700914 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700915 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700916 }
917
Elliott Hughes72025e52011-08-23 17:50:30 -0700918 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700919 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
920 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700921 ScopedObjectAccess soa(env);
922 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700923 }
924
Elliott Hughes72025e52011-08-23 17:50:30 -0700925 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700926 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
927 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700928 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700929 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700930 }
931
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700932 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700933 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700934 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700935 CHECK_NON_NULL_ARGUMENT(obj);
936 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700937 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700938 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
939 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700940 va_end(ap);
941 return local_result;
942 }
943
Ian Rogersbc939662013-08-15 10:26:54 -0700944 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
945 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700946 CHECK_NON_NULL_ARGUMENT(obj);
947 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700948 ScopedObjectAccess soa(env);
949 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
950 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700951 }
952
Ian Rogersbc939662013-08-15 10:26:54 -0700953 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
954 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700955 CHECK_NON_NULL_ARGUMENT(obj);
956 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700957 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700958 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700959 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700960 }
961
Ian Rogersbc939662013-08-15 10:26:54 -0700962 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
963 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700964 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700965 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700966 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
967 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700968 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700969 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700970 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700971 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700972 }
973
Ian Rogersbc939662013-08-15 10:26:54 -0700974 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
975 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700976 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
977 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700978 ScopedObjectAccess soa(env);
979 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700980 }
981
Ian Rogersbc939662013-08-15 10:26:54 -0700982 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
983 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700984 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
985 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700986 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700987 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700988 }
989
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700990 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700991 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700992 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700993 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
994 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700995 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700996 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700997 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700998 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700999 }
1000
Ian Rogersbc939662013-08-15 10:26:54 -07001001 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1002 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001003 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1004 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001005 ScopedObjectAccess soa(env);
1006 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001007 }
1008
Ian Rogersbc939662013-08-15 10:26:54 -07001009 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1010 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001011 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1012 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001013 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001014 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001015 }
1016
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001017 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001018 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001019 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001020 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1021 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001022 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001023 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001024 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001025 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001026 }
1027
Ian Rogersbc939662013-08-15 10:26:54 -07001028 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1029 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001030 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1031 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001032 ScopedObjectAccess soa(env);
1033 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001034 }
1035
Ian Rogersbc939662013-08-15 10:26:54 -07001036 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1037 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001038 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1039 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001040 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001041 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001042 }
1043
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001044 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001045 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001046 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001047 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1048 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001049 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001050 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001051 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001052 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001053 }
1054
Ian Rogersbc939662013-08-15 10:26:54 -07001055 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1056 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001057 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1058 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001059 ScopedObjectAccess soa(env);
1060 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001061 }
1062
Ian Rogersbc939662013-08-15 10:26:54 -07001063 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1064 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001065 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1066 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001067 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001068 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001069 }
1070
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001071 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001072 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001073 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001074 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1075 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001076 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001077 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001078 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001079 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001080 }
1081
Ian Rogersbc939662013-08-15 10:26:54 -07001082 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1083 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001084 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1085 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001086 ScopedObjectAccess soa(env);
1087 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001088 }
1089
Ian Rogersbc939662013-08-15 10:26:54 -07001090 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1091 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001092 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1093 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001094 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001095 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001096 }
1097
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001098 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001099 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001100 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001101 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1102 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001103 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001104 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001105 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001106 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001107 }
1108
Ian Rogersbc939662013-08-15 10:26:54 -07001109 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1110 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001111 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1112 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001113 ScopedObjectAccess soa(env);
1114 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001115 }
1116
Ian Rogersbc939662013-08-15 10:26:54 -07001117 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1118 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001119 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1120 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001121 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001122 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001123 }
1124
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001125 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001126 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001127 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001128 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1129 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001130 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001131 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001132 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001133 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001134 }
1135
Ian Rogersbc939662013-08-15 10:26:54 -07001136 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1137 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001138 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1139 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001140 ScopedObjectAccess soa(env);
1141 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001142 }
1143
Ian Rogersbc939662013-08-15 10:26:54 -07001144 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1145 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001146 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1147 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001148 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001149 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001150 }
1151
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001152 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001153 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001154 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001155 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1156 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001157 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001158 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001159 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001160 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001161 }
1162
Ian Rogersbc939662013-08-15 10:26:54 -07001163 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1164 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001165 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1166 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001167 ScopedObjectAccess soa(env);
1168 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001169 }
1170
Ian Rogersbc939662013-08-15 10:26:54 -07001171 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1172 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001173 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1174 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001175 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001176 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001177 }
1178
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001179 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001180 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001181 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001182 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1183 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001184 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001185 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001186 va_end(ap);
1187 }
1188
Brian Carlstromea46f952013-07-30 01:26:50 -07001189 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1190 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001191 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1192 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001193 ScopedObjectAccess soa(env);
1194 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001195 }
1196
Ian Rogersbc939662013-08-15 10:26:54 -07001197 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1198 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001199 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1200 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001201 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001202 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001203 }
1204
Ian Rogersbc939662013-08-15 10:26:54 -07001205 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001206 CHECK_NON_NULL_ARGUMENT(java_class);
1207 CHECK_NON_NULL_ARGUMENT(name);
1208 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001209 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001210 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001211 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001212
Ian Rogersbc939662013-08-15 10:26:54 -07001213 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1214 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001215 CHECK_NON_NULL_ARGUMENT(java_class);
1216 CHECK_NON_NULL_ARGUMENT(name);
1217 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001218 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001219 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001220 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001221
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001222 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001223 CHECK_NON_NULL_ARGUMENT(obj);
1224 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001225 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001226 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001227 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001228 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001229 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001230
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001231 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001232 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001233 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001234 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001235 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001236 }
1237
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001238 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001239 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1240 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001241 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001242 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1243 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001244 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001245 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001246 }
1247
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001248 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001249 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001250 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001251 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001252 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001253 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001254 }
1255
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001256#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001257 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1258 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001259 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001260 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001261 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001262 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001263
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001264#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001265 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001266 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001267 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001268 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001269
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001270#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001271 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1272 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001273 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001274 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001275 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001276 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001277
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001278#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001279 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001280 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001281 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001282 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001283
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001284 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001285 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001286 }
1287
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001288 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001289 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001290 }
1291
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001292 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001293 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001294 }
1295
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001296 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001297 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001298 }
1299
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001300 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001301 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001302 }
1303
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001304 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001305 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001306 }
1307
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001308 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001309 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001310 }
1311
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001312 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001313 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001314 }
1315
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001316 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001317 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001318 }
1319
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001320 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001321 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001322 }
1323
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001324 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001325 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001326 }
1327
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001328 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001329 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001330 }
1331
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001332 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001333 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001334 }
1335
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001336 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001337 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001338 }
1339
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001340 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001341 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001342 }
1343
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001344 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001345 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001346 }
1347
1348 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001349 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001350 }
1351
1352 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001353 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001354 }
1355
1356 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001357 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001358 }
1359
1360 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001361 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001362 }
1363
1364 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001365 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001366 }
1367
1368 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001369 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001370 }
1371
1372 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001373 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001374 }
1375
1376 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001377 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001378 }
1379
1380 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001381 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001382 }
1383
1384 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001385 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001386 }
1387
1388 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001389 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001390 }
1391
1392 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001393 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001394 }
1395
1396 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001397 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001398 }
1399
1400 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001401 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001402 }
1403
1404 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001405 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001406 }
1407
1408 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001409 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001410 }
1411
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001412 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001413 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001414 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001415 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001416 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001417 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001418 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001419 va_end(ap);
1420 return local_result;
1421 }
1422
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001423 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001424 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001425 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001426 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001427 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001428 }
1429
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001430 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001431 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001432 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001433 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001434 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001435 }
1436
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001437 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001438 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001439 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001440 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001441 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001442 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001443 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001444 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001445 }
1446
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001447 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001448 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001449 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001450 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001451 }
1452
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001453 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001454 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001455 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001456 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001457 }
1458
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001459 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001460 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001461 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001462 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001463 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001464 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001465 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001466 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001467 }
1468
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001469 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001470 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001471 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001472 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001473 }
1474
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001475 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001476 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001477 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001478 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001479 }
1480
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001481 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001482 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001483 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001484 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001485 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001486 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001487 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001488 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001489 }
1490
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001491 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001492 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001493 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001494 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001495 }
1496
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001497 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001498 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001499 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001500 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001501 }
1502
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001503 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001504 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001505 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001506 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001507 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001508 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001509 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001510 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001511 }
1512
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001513 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001514 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001515 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001516 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001517 }
1518
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001519 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001520 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001521 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001522 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001523 }
1524
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001525 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001526 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001527 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001528 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001529 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001530 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001531 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001532 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001533 }
1534
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001535 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001536 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001537 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001538 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001539 }
1540
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001541 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001542 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001543 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001544 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001545 }
1546
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001547 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001548 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001549 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001550 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001551 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001552 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001553 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001554 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001555 }
1556
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001557 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001558 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001559 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001560 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001561 }
1562
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001563 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001564 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001565 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001566 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001567 }
1568
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001569 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001570 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001571 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001572 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001573 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001574 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001575 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001576 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001577 }
1578
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001579 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001580 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001581 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001582 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001583 }
1584
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001585 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001586 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001587 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001588 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001589 }
1590
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001591 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001592 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001593 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001594 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001595 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001596 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001597 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001598 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001599 }
1600
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001601 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001602 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001603 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001604 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001605 }
1606
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001607 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001608 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001609 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001610 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001611 }
1612
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001613 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001614 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001615 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001616 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001617 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001618 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001619 va_end(ap);
1620 }
1621
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001622 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001623 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001624 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001625 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001626 }
1627
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001628 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001629 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001630 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001631 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001632 }
1633
Elliott Hughes814e4032011-08-23 12:07:56 -07001634 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001635 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001636 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001637 return nullptr;
1638 }
1639 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001640 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001641 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001642 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001643 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001644 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001645 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001646 }
1647
1648 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001649 if (utf == nullptr) {
1650 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001651 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001652 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001653 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001654 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001655 }
1656
Elliott Hughes814e4032011-08-23 12:07:56 -07001657 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001658 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001659 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001660 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001661 }
1662
1663 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001664 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001665 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001666 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001667 }
1668
Ian Rogersbc939662013-08-15 10:26:54 -07001669 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1670 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001671 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001672 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001673 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001674 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001675 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001676 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001677 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001678 if (s->IsCompressed()) {
1679 for (int i = 0; i < length; ++i) {
1680 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1681 }
1682 } else {
1683 const jchar* chars = static_cast<jchar*>(s->GetValue());
1684 memcpy(buf, chars + start, length * sizeof(jchar));
1685 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001686 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001687 }
1688
Ian Rogersbc939662013-08-15 10:26:54 -07001689 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1690 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001691 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001692 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001693 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001694 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001695 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001696 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001697 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001698 if (s->IsCompressed()) {
1699 for (int i = 0; i < length; ++i) {
1700 buf[i] = s->CharAt(start+i);
1701 }
1702 } else {
1703 const jchar* chars = s->GetValue();
1704 size_t bytes = CountUtf8Bytes(chars + start, length);
1705 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1706 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001707 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001708 }
1709
Elliott Hughes75770752011-08-24 17:52:38 -07001710 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001711 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001712 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001713 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001714 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001715 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001716 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001717 if (s->IsCompressed()) {
1718 int32_t length = s->GetLength();
1719 for (int i = 0; i < length; ++i) {
1720 chars[i] = s->CharAt(i);
1721 }
1722 } else {
1723 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1724 }
Fred Shih56890e22014-06-02 11:11:52 -07001725 if (is_copy != nullptr) {
1726 *is_copy = JNI_TRUE;
1727 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001728 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001729 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001730 if (is_copy != nullptr) {
1731 *is_copy = JNI_FALSE;
1732 }
1733 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001734 }
1735
Mathieu Chartier590fee92013-09-13 13:46:47 -07001736 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001737 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001738 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001739 mirror::String* s = soa.Decode<mirror::String*>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001740 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001741 delete[] chars;
1742 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001743 }
1744
Elliott Hughes75770752011-08-24 17:52:38 -07001745 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001746 CHECK_NON_NULL_ARGUMENT(java_string);
1747 ScopedObjectAccess soa(env);
1748 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001749 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001750 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001751 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001752 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001753 if (!kUseReadBarrier) {
1754 heap->IncrementDisableMovingGC(soa.Self());
1755 } else {
1756 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1757 // to occur thanks to the to-space invariant.
1758 heap->IncrementDisableThreadFlip(soa.Self());
1759 }
Fred Shih56890e22014-06-02 11:11:52 -07001760 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001761 if (s->IsCompressed()) {
1762 if (is_copy != nullptr) {
1763 *is_copy = JNI_TRUE;
1764 }
1765 int32_t length = s->GetLength();
1766 jchar* chars = new jchar[length];
1767 for (int i = 0; i < length; ++i) {
1768 chars[i] = s->CharAt(i);
1769 }
1770 return chars;
1771 } else {
1772 if (is_copy != nullptr) {
1773 *is_copy = JNI_FALSE;
1774 }
1775 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001776 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001777 }
1778
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001779 static void ReleaseStringCritical(JNIEnv* env,
1780 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001781 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001782 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1783 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001784 gc::Heap* heap = Runtime::Current()->GetHeap();
1785 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001786 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001787 if (!kUseReadBarrier) {
1788 heap->DecrementDisableMovingGC(soa.Self());
1789 } else {
1790 heap->DecrementDisableThreadFlip(soa.Self());
1791 }
Fred Shih56890e22014-06-02 11:11:52 -07001792 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001793 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1794 delete[] chars;
1795 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001796 }
1797
Elliott Hughes75770752011-08-24 17:52:38 -07001798 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001799 if (java_string == nullptr) {
1800 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001801 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001802 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001803 *is_copy = JNI_TRUE;
1804 }
Ian Rogersef28b142012-11-30 14:22:18 -08001805 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001806 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001807 size_t byte_count = s->GetUtfLength();
1808 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001809 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001810 if (s->IsCompressed()) {
1811 for (size_t i = 0; i < byte_count; ++i) {
1812 bytes[i] = s->CharAt(i);
1813 }
1814 } else {
1815 const uint16_t* chars = s->GetValue();
1816 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1817 }
Elliott Hughes75770752011-08-24 17:52:38 -07001818 bytes[byte_count] = '\0';
1819 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001820 }
1821
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001822 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001823 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001824 }
1825
Elliott Hughesbd935992011-08-22 11:59:34 -07001826 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001827 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001828 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001829 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001830 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001831 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1832 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001833 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001834 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001835 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001836 }
1837
Elliott Hughes814e4032011-08-23 12:07:56 -07001838 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001839 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001840 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001841 mirror::ObjectArray<mirror::Object>* array =
1842 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001843 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001844 }
1845
Ian Rogersbc939662013-08-15 10:26:54 -07001846 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1847 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001848 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001849 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001850 mirror::ObjectArray<mirror::Object>* array =
1851 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1852 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001853 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001854 }
1855
1856 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001857 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001858 }
1859
1860 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001861 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001862 }
1863
1864 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001865 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001866 }
1867
1868 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001869 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001870 }
1871
1872 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001873 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001874 }
1875
1876 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001877 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001878 }
1879
1880 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001881 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001882 }
1883
Ian Rogers1d99e452014-01-02 17:36:41 -08001884 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1885 jobject initial_element) {
1886 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001887 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001888 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001889 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001890 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001891
1892 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001893 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001894 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001895 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001896 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001897 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001898 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1899 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001900 return nullptr;
1901 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001902 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001903 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001904 if (UNLIKELY(array_class == nullptr)) {
1905 return nullptr;
1906 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001907 }
1908
Elliott Hughes75770752011-08-24 17:52:38 -07001909 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001910 mirror::ObjectArray<mirror::Object>* result =
1911 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001912 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001913 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001914 if (initial_object != nullptr) {
1915 mirror::Class* element_class = result->GetClass()->GetComponentType();
1916 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001917 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1918 "element type of '%s'",
1919 PrettyDescriptor(initial_object->GetClass()).c_str(),
1920 PrettyDescriptor(element_class).c_str());
1921 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001922 } else {
1923 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001924 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001925 }
1926 }
Elliott Hughes75770752011-08-24 17:52:38 -07001927 }
1928 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001929 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001930 }
1931
1932 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001933 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001934 }
1935
Ian Rogersa15e67d2012-02-28 13:51:55 -08001936 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001937 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001938 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001939 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001940 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001941 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1942 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001943 return nullptr;
1944 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001945 gc::Heap* heap = Runtime::Current()->GetHeap();
1946 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001947 if (!kUseReadBarrier) {
1948 heap->IncrementDisableMovingGC(soa.Self());
1949 } else {
1950 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1951 // to occur thanks to the to-space invariant.
1952 heap->IncrementDisableThreadFlip(soa.Self());
1953 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001954 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001955 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001956 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001957 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001958 *is_copy = JNI_FALSE;
1959 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001960 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001961 }
1962
Ian Rogers2d10b202014-05-12 19:15:18 -07001963 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1964 jint mode) {
1965 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1966 ScopedObjectAccess soa(env);
1967 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1968 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001969 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1970 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001971 return;
1972 }
1973 const size_t component_size = array->GetClass()->GetComponentSize();
1974 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001975 }
1976
Elliott Hughes75770752011-08-24 17:52:38 -07001977 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001978 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001979 }
1980
Elliott Hughes75770752011-08-24 17:52:38 -07001981 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001982 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001983 }
1984
Elliott Hughes75770752011-08-24 17:52:38 -07001985 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001986 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001987 }
1988
Elliott Hughes75770752011-08-24 17:52:38 -07001989 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001990 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001991 }
1992
Elliott Hughes75770752011-08-24 17:52:38 -07001993 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001994 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001995 }
1996
Elliott Hughes75770752011-08-24 17:52:38 -07001997 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001998 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001999 }
2000
Elliott Hughes75770752011-08-24 17:52:38 -07002001 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002002 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002003 }
2004
Elliott Hughes75770752011-08-24 17:52:38 -07002005 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002006 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002007 }
2008
Mathieu Chartier590fee92013-09-13 13:46:47 -07002009 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2010 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002011 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2012 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002013 }
2014
Mathieu Chartier590fee92013-09-13 13:46:47 -07002015 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002016 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002017 }
2018
Mathieu Chartier590fee92013-09-13 13:46:47 -07002019 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002020 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002021 }
2022
Mathieu Chartier590fee92013-09-13 13:46:47 -07002023 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2024 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002025 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002026 }
2027
Mathieu Chartier590fee92013-09-13 13:46:47 -07002028 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2029 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002030 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002031 }
2032
Mathieu Chartier590fee92013-09-13 13:46:47 -07002033 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002034 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002035 }
2036
Mathieu Chartier590fee92013-09-13 13:46:47 -07002037 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002038 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002039 }
2040
Mathieu Chartier590fee92013-09-13 13:46:47 -07002041 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2042 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002043 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002044 }
2045
Ian Rogersbc939662013-08-15 10:26:54 -07002046 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2047 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002048 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002049 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002050 }
2051
Ian Rogersbc939662013-08-15 10:26:54 -07002052 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2053 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002054 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002055 }
2056
Ian Rogersbc939662013-08-15 10:26:54 -07002057 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2058 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002059 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002060 }
2061
Ian Rogersbc939662013-08-15 10:26:54 -07002062 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2063 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002064 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002065 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002066 }
2067
Ian Rogersbc939662013-08-15 10:26:54 -07002068 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2069 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002070 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002071 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002072 }
2073
Ian Rogersbc939662013-08-15 10:26:54 -07002074 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2075 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002076 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002077 }
2078
Ian Rogersbc939662013-08-15 10:26:54 -07002079 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2080 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002081 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002082 }
2083
Ian Rogersbc939662013-08-15 10:26:54 -07002084 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2085 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002086 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002087 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002088 }
2089
Ian Rogersbc939662013-08-15 10:26:54 -07002090 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2091 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002092 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002093 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002094 }
2095
Ian Rogersbc939662013-08-15 10:26:54 -07002096 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2097 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002098 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002099 }
2100
Ian Rogersbc939662013-08-15 10:26:54 -07002101 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2102 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002103 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002104 }
2105
Ian Rogersbc939662013-08-15 10:26:54 -07002106 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2107 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002108 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002109 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002110 }
2111
Ian Rogersbc939662013-08-15 10:26:54 -07002112 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2113 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002114 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002115 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002116 }
2117
Ian Rogersbc939662013-08-15 10:26:54 -07002118 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2119 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002120 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002121 }
2122
Ian Rogersbc939662013-08-15 10:26:54 -07002123 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2124 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002125 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002126 }
2127
Ian Rogersbc939662013-08-15 10:26:54 -07002128 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2129 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002130 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002131 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002132 }
2133
Ian Rogersbc939662013-08-15 10:26:54 -07002134 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2135 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002136 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2137 }
2138
Ian Rogersbc939662013-08-15 10:26:54 -07002139 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2140 jint method_count, bool return_errors) {
2141 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002142 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2143 method_count);
2144 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002145 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002146 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002147 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002148 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002149 if (UNLIKELY(method_count == 0)) {
2150 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2151 << PrettyDescriptor(c);
2152 return JNI_OK;
2153 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002154 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002155 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002156 const char* name = methods[i].name;
2157 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002158 const void* fnPtr = methods[i].fnPtr;
2159 if (UNLIKELY(name == nullptr)) {
2160 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2161 return JNI_ERR;
2162 } else if (UNLIKELY(sig == nullptr)) {
2163 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2164 return JNI_ERR;
2165 } else if (UNLIKELY(fnPtr == nullptr)) {
2166 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2167 return JNI_ERR;
2168 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002169 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002170 // Notes about fast JNI calls:
2171 //
2172 // On a normal JNI call, the calling thread usually transitions
2173 // from the kRunnable state to the kNative state. But if the
2174 // called native function needs to access any Java object, it
2175 // will have to transition back to the kRunnable state.
2176 //
2177 // There is a cost to this double transition. For a JNI call
2178 // that should be quick, this cost may dominate the call cost.
2179 //
2180 // On a fast JNI call, the calling thread avoids this double
2181 // transition by not transitioning from kRunnable to kNative and
2182 // stays in the kRunnable state.
2183 //
2184 // There are risks to using a fast JNI call because it can delay
2185 // a response to a thread suspension request which is typically
2186 // used for a GC root scanning, etc. If a fast JNI call takes a
2187 // long time, it could cause longer thread suspension latency
2188 // and GC pauses.
2189 //
2190 // Thus, fast JNI should be used with care. It should be used
2191 // for a JNI call that takes a short amount of time (eg. no
2192 // long-running loop) and does not block (eg. no locks, I/O,
2193 // etc.)
2194 //
2195 // A '!' prefix in the signature in the JNINativeMethod
2196 // indicates that it's a fast JNI call and the runtime omits the
2197 // thread state transition from kRunnable to kNative at the
2198 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002199 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002200 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002201 ++sig;
2202 }
2203
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002204 // Note: the right order is to try to find the method locally
2205 // first, either as a direct or a virtual method. Then move to
2206 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002207 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002208 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2209 for (mirror::Class* current_class = c;
2210 current_class != nullptr;
2211 current_class = current_class->GetSuperClass()) {
2212 // Search first only comparing methods which are native.
2213 m = FindMethod<true>(current_class, name, sig);
2214 if (m != nullptr) {
2215 break;
2216 }
2217
2218 // Search again comparing to all methods, to find non-native methods that match.
2219 m = FindMethod<false>(current_class, name, sig);
2220 if (m != nullptr) {
2221 break;
2222 }
2223
2224 if (warn_on_going_to_parent) {
2225 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2226 << "This is slow, consider changing your RegisterNatives calls.";
2227 warn_on_going_to_parent = false;
2228 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002229 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002230
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002231 if (m == nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002232 c->DumpClass(
2233 LOG_STREAM(return_errors
2234 ? ::android::base::ERROR
2235 : ::android::base::FATAL_WITHOUT_ABORT),
2236 mirror::Class::kDumpClassFullDetail);
2237 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2238 << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002239 << PrettyDescriptor(c) << "." << name << sig << " in "
2240 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002241 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002242 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002243 } else if (!m->IsNative()) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002244 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2245 << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002246 << PrettyDescriptor(c) << "." << name << sig
2247 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002248 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002249 return JNI_ERR;
2250 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002251
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002252 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002253
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002254 is_fast = is_fast || m->IsFastNative(); // Merge with @FastNative state.
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002255 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002256 }
2257 return JNI_OK;
2258 }
2259
Elliott Hughes5174fe62011-08-23 15:12:35 -07002260 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002261 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002262 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002263 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002264
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002265 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002266
Ian Rogers2d10b202014-05-12 19:15:18 -07002267 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002268 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002269 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002270 if (m.IsNative()) {
2271 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002272 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002273 }
2274 }
2275
Ian Rogers2d10b202014-05-12 19:15:18 -07002276 if (unregistered_count == 0) {
2277 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2278 << PrettyDescriptor(c) << "' that contains no native methods";
2279 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002280 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002281 }
2282
Ian Rogers719d1a32014-03-06 12:13:39 -08002283 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002284 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002285 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002286 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2287 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002288 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002289 return JNI_ERR;
2290 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002291 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002292 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002293 }
2294
Ian Rogers719d1a32014-03-06 12:13:39 -08002295 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002296 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002297 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002298 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002299 o->MonitorExit(soa.Self());
2300 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002301 return JNI_ERR;
2302 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002303 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002304 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002305 }
2306
2307 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002308 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002309 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002310 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002311 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002312 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002313 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002314 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002315 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002316 }
2317
Elliott Hughescdf53122011-08-19 15:46:09 -07002318 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002319 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002320 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2321 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002322 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002323 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002324 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002325 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2326 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002327 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002328 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002329
Brian Carlstrom85a93362014-06-25 09:30:52 -07002330 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002331 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002332 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2333 "buffer capacity greater than maximum jint: %" PRId64,
2334 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002335 return nullptr;
2336 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002337 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002338 jint capacity_arg = static_cast<jint>(capacity);
2339
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002340 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2341 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002342 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002343 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002344 }
2345
Elliott Hughesb465ab02011-08-24 11:21:21 -07002346 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002347 return reinterpret_cast<void*>(env->GetLongField(
2348 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002349 }
2350
Elliott Hughesb465ab02011-08-24 11:21:21 -07002351 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002352 return static_cast<jlong>(env->GetIntField(
2353 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002354 }
2355
Andreas Gampea8763072014-12-20 00:08:35 -08002356 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2357 if (java_object == nullptr) {
2358 return JNIInvalidRefType;
2359 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002360
2361 // Do we definitely know what kind of reference this is?
2362 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2363 IndirectRefKind kind = GetIndirectRefKind(ref);
2364 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002365 case kLocal:
2366 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002367 case kGlobal:
2368 return JNIGlobalRefType;
2369 case kWeakGlobal:
2370 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002371 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002372 // Assume value is in a handle scope.
2373 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002374 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002375 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002376 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002377 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002378
2379 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002380 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2381 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002382 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002383 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002384 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002385 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2386 return JNI_ERR;
2387 }
2388 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002389 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002390 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2391 if (!okay) {
2392 soa.Self()->ThrowOutOfMemoryError(caller);
2393 }
2394 return okay ? JNI_OK : JNI_ERR;
2395 }
2396
2397 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002398 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002399 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002400 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002401 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002402 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002403 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002404 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002405 return soa.AddLocalReference<JniT>(result);
2406 }
2407
Ian Rogers2d10b202014-05-12 19:15:18 -07002408 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2409 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2410 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002411 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002412 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002413 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002414 soa.Vm()->JniAbortF(fn_name,
2415 "attempt to %s %s primitive array elements with an object of type %s",
2416 operation,
2417 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2418 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002419 return nullptr;
2420 }
2421 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2422 return array;
2423 }
2424
2425 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2426 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2427 CHECK_NON_NULL_ARGUMENT(java_array);
2428 ScopedObjectAccess soa(env);
2429 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2430 "GetArrayElements",
2431 "get");
2432 if (UNLIKELY(array == nullptr)) {
2433 return nullptr;
2434 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002435 // Only make a copy if necessary.
2436 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2437 if (is_copy != nullptr) {
2438 *is_copy = JNI_TRUE;
2439 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002440 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002441 size_t size = array->GetLength() * component_size;
2442 void* data = new uint64_t[RoundUp(size, 8) / 8];
2443 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002444 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002445 } else {
2446 if (is_copy != nullptr) {
2447 *is_copy = JNI_FALSE;
2448 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002449 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002450 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002451 }
2452
Ian Rogers2d10b202014-05-12 19:15:18 -07002453 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002454 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002455 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002456 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002457 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2458 "ReleaseArrayElements",
2459 "release");
2460 if (array == nullptr) {
2461 return;
2462 }
2463 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2464 }
2465
2466 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2467 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002468 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002469 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002470 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002471 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002472 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002473 if (is_copy) {
2474 // Sanity check: If elements is not the same as the java array's data, it better not be a
2475 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2476 // copies we make?
2477 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002478 soa.Vm()->JniAbortF("ReleaseArrayElements",
2479 "invalid element pointer %p, array elements are %p",
2480 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002481 return;
2482 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002483 if (mode != JNI_ABORT) {
2484 memcpy(array_data, elements, bytes);
2485 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2486 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2487 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002488 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002489 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002490 }
2491 if (mode != JNI_COMMIT) {
2492 if (is_copy) {
2493 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002494 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002495 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002496 if (!kUseReadBarrier) {
2497 heap->DecrementDisableMovingGC(soa.Self());
2498 } else {
2499 heap->DecrementDisableThreadFlip(soa.Self());
2500 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002501 }
2502 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002503 }
2504
Ian Rogers2d10b202014-05-12 19:15:18 -07002505 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2506 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2507 jsize start, jsize length, ElementT* buf) {
2508 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2509 ScopedObjectAccess soa(env);
2510 ArtArrayT* array =
2511 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2512 "GetPrimitiveArrayRegion",
2513 "get region of");
2514 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002515 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002516 ThrowAIOOBE(soa, array, start, length, "src");
2517 } else {
2518 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2519 ElementT* data = array->GetData();
2520 memcpy(buf, data + start, length * sizeof(ElementT));
2521 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002522 }
2523 }
2524
Ian Rogers2d10b202014-05-12 19:15:18 -07002525 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2526 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2527 jsize start, jsize length, const ElementT* buf) {
2528 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2529 ScopedObjectAccess soa(env);
2530 ArtArrayT* array =
2531 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2532 "SetPrimitiveArrayRegion",
2533 "set region of");
2534 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002535 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002536 ThrowAIOOBE(soa, array, start, length, "dst");
2537 } else {
2538 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2539 ElementT* data = array->GetData();
2540 memcpy(data + start, buf, length * sizeof(ElementT));
2541 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002542 }
2543 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002544};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002545
Elliott Hughes88c5c352012-03-15 18:49:48 -07002546const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002547 nullptr, // reserved0.
2548 nullptr, // reserved1.
2549 nullptr, // reserved2.
2550 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002551 JNI::GetVersion,
2552 JNI::DefineClass,
2553 JNI::FindClass,
2554 JNI::FromReflectedMethod,
2555 JNI::FromReflectedField,
2556 JNI::ToReflectedMethod,
2557 JNI::GetSuperclass,
2558 JNI::IsAssignableFrom,
2559 JNI::ToReflectedField,
2560 JNI::Throw,
2561 JNI::ThrowNew,
2562 JNI::ExceptionOccurred,
2563 JNI::ExceptionDescribe,
2564 JNI::ExceptionClear,
2565 JNI::FatalError,
2566 JNI::PushLocalFrame,
2567 JNI::PopLocalFrame,
2568 JNI::NewGlobalRef,
2569 JNI::DeleteGlobalRef,
2570 JNI::DeleteLocalRef,
2571 JNI::IsSameObject,
2572 JNI::NewLocalRef,
2573 JNI::EnsureLocalCapacity,
2574 JNI::AllocObject,
2575 JNI::NewObject,
2576 JNI::NewObjectV,
2577 JNI::NewObjectA,
2578 JNI::GetObjectClass,
2579 JNI::IsInstanceOf,
2580 JNI::GetMethodID,
2581 JNI::CallObjectMethod,
2582 JNI::CallObjectMethodV,
2583 JNI::CallObjectMethodA,
2584 JNI::CallBooleanMethod,
2585 JNI::CallBooleanMethodV,
2586 JNI::CallBooleanMethodA,
2587 JNI::CallByteMethod,
2588 JNI::CallByteMethodV,
2589 JNI::CallByteMethodA,
2590 JNI::CallCharMethod,
2591 JNI::CallCharMethodV,
2592 JNI::CallCharMethodA,
2593 JNI::CallShortMethod,
2594 JNI::CallShortMethodV,
2595 JNI::CallShortMethodA,
2596 JNI::CallIntMethod,
2597 JNI::CallIntMethodV,
2598 JNI::CallIntMethodA,
2599 JNI::CallLongMethod,
2600 JNI::CallLongMethodV,
2601 JNI::CallLongMethodA,
2602 JNI::CallFloatMethod,
2603 JNI::CallFloatMethodV,
2604 JNI::CallFloatMethodA,
2605 JNI::CallDoubleMethod,
2606 JNI::CallDoubleMethodV,
2607 JNI::CallDoubleMethodA,
2608 JNI::CallVoidMethod,
2609 JNI::CallVoidMethodV,
2610 JNI::CallVoidMethodA,
2611 JNI::CallNonvirtualObjectMethod,
2612 JNI::CallNonvirtualObjectMethodV,
2613 JNI::CallNonvirtualObjectMethodA,
2614 JNI::CallNonvirtualBooleanMethod,
2615 JNI::CallNonvirtualBooleanMethodV,
2616 JNI::CallNonvirtualBooleanMethodA,
2617 JNI::CallNonvirtualByteMethod,
2618 JNI::CallNonvirtualByteMethodV,
2619 JNI::CallNonvirtualByteMethodA,
2620 JNI::CallNonvirtualCharMethod,
2621 JNI::CallNonvirtualCharMethodV,
2622 JNI::CallNonvirtualCharMethodA,
2623 JNI::CallNonvirtualShortMethod,
2624 JNI::CallNonvirtualShortMethodV,
2625 JNI::CallNonvirtualShortMethodA,
2626 JNI::CallNonvirtualIntMethod,
2627 JNI::CallNonvirtualIntMethodV,
2628 JNI::CallNonvirtualIntMethodA,
2629 JNI::CallNonvirtualLongMethod,
2630 JNI::CallNonvirtualLongMethodV,
2631 JNI::CallNonvirtualLongMethodA,
2632 JNI::CallNonvirtualFloatMethod,
2633 JNI::CallNonvirtualFloatMethodV,
2634 JNI::CallNonvirtualFloatMethodA,
2635 JNI::CallNonvirtualDoubleMethod,
2636 JNI::CallNonvirtualDoubleMethodV,
2637 JNI::CallNonvirtualDoubleMethodA,
2638 JNI::CallNonvirtualVoidMethod,
2639 JNI::CallNonvirtualVoidMethodV,
2640 JNI::CallNonvirtualVoidMethodA,
2641 JNI::GetFieldID,
2642 JNI::GetObjectField,
2643 JNI::GetBooleanField,
2644 JNI::GetByteField,
2645 JNI::GetCharField,
2646 JNI::GetShortField,
2647 JNI::GetIntField,
2648 JNI::GetLongField,
2649 JNI::GetFloatField,
2650 JNI::GetDoubleField,
2651 JNI::SetObjectField,
2652 JNI::SetBooleanField,
2653 JNI::SetByteField,
2654 JNI::SetCharField,
2655 JNI::SetShortField,
2656 JNI::SetIntField,
2657 JNI::SetLongField,
2658 JNI::SetFloatField,
2659 JNI::SetDoubleField,
2660 JNI::GetStaticMethodID,
2661 JNI::CallStaticObjectMethod,
2662 JNI::CallStaticObjectMethodV,
2663 JNI::CallStaticObjectMethodA,
2664 JNI::CallStaticBooleanMethod,
2665 JNI::CallStaticBooleanMethodV,
2666 JNI::CallStaticBooleanMethodA,
2667 JNI::CallStaticByteMethod,
2668 JNI::CallStaticByteMethodV,
2669 JNI::CallStaticByteMethodA,
2670 JNI::CallStaticCharMethod,
2671 JNI::CallStaticCharMethodV,
2672 JNI::CallStaticCharMethodA,
2673 JNI::CallStaticShortMethod,
2674 JNI::CallStaticShortMethodV,
2675 JNI::CallStaticShortMethodA,
2676 JNI::CallStaticIntMethod,
2677 JNI::CallStaticIntMethodV,
2678 JNI::CallStaticIntMethodA,
2679 JNI::CallStaticLongMethod,
2680 JNI::CallStaticLongMethodV,
2681 JNI::CallStaticLongMethodA,
2682 JNI::CallStaticFloatMethod,
2683 JNI::CallStaticFloatMethodV,
2684 JNI::CallStaticFloatMethodA,
2685 JNI::CallStaticDoubleMethod,
2686 JNI::CallStaticDoubleMethodV,
2687 JNI::CallStaticDoubleMethodA,
2688 JNI::CallStaticVoidMethod,
2689 JNI::CallStaticVoidMethodV,
2690 JNI::CallStaticVoidMethodA,
2691 JNI::GetStaticFieldID,
2692 JNI::GetStaticObjectField,
2693 JNI::GetStaticBooleanField,
2694 JNI::GetStaticByteField,
2695 JNI::GetStaticCharField,
2696 JNI::GetStaticShortField,
2697 JNI::GetStaticIntField,
2698 JNI::GetStaticLongField,
2699 JNI::GetStaticFloatField,
2700 JNI::GetStaticDoubleField,
2701 JNI::SetStaticObjectField,
2702 JNI::SetStaticBooleanField,
2703 JNI::SetStaticByteField,
2704 JNI::SetStaticCharField,
2705 JNI::SetStaticShortField,
2706 JNI::SetStaticIntField,
2707 JNI::SetStaticLongField,
2708 JNI::SetStaticFloatField,
2709 JNI::SetStaticDoubleField,
2710 JNI::NewString,
2711 JNI::GetStringLength,
2712 JNI::GetStringChars,
2713 JNI::ReleaseStringChars,
2714 JNI::NewStringUTF,
2715 JNI::GetStringUTFLength,
2716 JNI::GetStringUTFChars,
2717 JNI::ReleaseStringUTFChars,
2718 JNI::GetArrayLength,
2719 JNI::NewObjectArray,
2720 JNI::GetObjectArrayElement,
2721 JNI::SetObjectArrayElement,
2722 JNI::NewBooleanArray,
2723 JNI::NewByteArray,
2724 JNI::NewCharArray,
2725 JNI::NewShortArray,
2726 JNI::NewIntArray,
2727 JNI::NewLongArray,
2728 JNI::NewFloatArray,
2729 JNI::NewDoubleArray,
2730 JNI::GetBooleanArrayElements,
2731 JNI::GetByteArrayElements,
2732 JNI::GetCharArrayElements,
2733 JNI::GetShortArrayElements,
2734 JNI::GetIntArrayElements,
2735 JNI::GetLongArrayElements,
2736 JNI::GetFloatArrayElements,
2737 JNI::GetDoubleArrayElements,
2738 JNI::ReleaseBooleanArrayElements,
2739 JNI::ReleaseByteArrayElements,
2740 JNI::ReleaseCharArrayElements,
2741 JNI::ReleaseShortArrayElements,
2742 JNI::ReleaseIntArrayElements,
2743 JNI::ReleaseLongArrayElements,
2744 JNI::ReleaseFloatArrayElements,
2745 JNI::ReleaseDoubleArrayElements,
2746 JNI::GetBooleanArrayRegion,
2747 JNI::GetByteArrayRegion,
2748 JNI::GetCharArrayRegion,
2749 JNI::GetShortArrayRegion,
2750 JNI::GetIntArrayRegion,
2751 JNI::GetLongArrayRegion,
2752 JNI::GetFloatArrayRegion,
2753 JNI::GetDoubleArrayRegion,
2754 JNI::SetBooleanArrayRegion,
2755 JNI::SetByteArrayRegion,
2756 JNI::SetCharArrayRegion,
2757 JNI::SetShortArrayRegion,
2758 JNI::SetIntArrayRegion,
2759 JNI::SetLongArrayRegion,
2760 JNI::SetFloatArrayRegion,
2761 JNI::SetDoubleArrayRegion,
2762 JNI::RegisterNatives,
2763 JNI::UnregisterNatives,
2764 JNI::MonitorEnter,
2765 JNI::MonitorExit,
2766 JNI::GetJavaVM,
2767 JNI::GetStringRegion,
2768 JNI::GetStringUTFRegion,
2769 JNI::GetPrimitiveArrayCritical,
2770 JNI::ReleasePrimitiveArrayCritical,
2771 JNI::GetStringCritical,
2772 JNI::ReleaseStringCritical,
2773 JNI::NewWeakGlobalRef,
2774 JNI::DeleteWeakGlobalRef,
2775 JNI::ExceptionCheck,
2776 JNI::NewDirectByteBuffer,
2777 JNI::GetDirectBufferAddress,
2778 JNI::GetDirectBufferCapacity,
2779 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002780};
2781
Ian Rogers68d8b422014-07-17 11:09:10 -07002782const JNINativeInterface* GetJniNativeInterface() {
2783 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002784}
2785
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002786void (*gJniSleepForeverStub[])() = {
2787 nullptr, // reserved0.
2788 nullptr, // reserved1.
2789 nullptr, // reserved2.
2790 nullptr, // reserved3.
2791 SleepForever,
2792 SleepForever,
2793 SleepForever,
2794 SleepForever,
2795 SleepForever,
2796 SleepForever,
2797 SleepForever,
2798 SleepForever,
2799 SleepForever,
2800 SleepForever,
2801 SleepForever,
2802 SleepForever,
2803 SleepForever,
2804 SleepForever,
2805 SleepForever,
2806 SleepForever,
2807 SleepForever,
2808 SleepForever,
2809 SleepForever,
2810 SleepForever,
2811 SleepForever,
2812 SleepForever,
2813 SleepForever,
2814 SleepForever,
2815 SleepForever,
2816 SleepForever,
2817 SleepForever,
2818 SleepForever,
2819 SleepForever,
2820 SleepForever,
2821 SleepForever,
2822 SleepForever,
2823 SleepForever,
2824 SleepForever,
2825 SleepForever,
2826 SleepForever,
2827 SleepForever,
2828 SleepForever,
2829 SleepForever,
2830 SleepForever,
2831 SleepForever,
2832 SleepForever,
2833 SleepForever,
2834 SleepForever,
2835 SleepForever,
2836 SleepForever,
2837 SleepForever,
2838 SleepForever,
2839 SleepForever,
2840 SleepForever,
2841 SleepForever,
2842 SleepForever,
2843 SleepForever,
2844 SleepForever,
2845 SleepForever,
2846 SleepForever,
2847 SleepForever,
2848 SleepForever,
2849 SleepForever,
2850 SleepForever,
2851 SleepForever,
2852 SleepForever,
2853 SleepForever,
2854 SleepForever,
2855 SleepForever,
2856 SleepForever,
2857 SleepForever,
2858 SleepForever,
2859 SleepForever,
2860 SleepForever,
2861 SleepForever,
2862 SleepForever,
2863 SleepForever,
2864 SleepForever,
2865 SleepForever,
2866 SleepForever,
2867 SleepForever,
2868 SleepForever,
2869 SleepForever,
2870 SleepForever,
2871 SleepForever,
2872 SleepForever,
2873 SleepForever,
2874 SleepForever,
2875 SleepForever,
2876 SleepForever,
2877 SleepForever,
2878 SleepForever,
2879 SleepForever,
2880 SleepForever,
2881 SleepForever,
2882 SleepForever,
2883 SleepForever,
2884 SleepForever,
2885 SleepForever,
2886 SleepForever,
2887 SleepForever,
2888 SleepForever,
2889 SleepForever,
2890 SleepForever,
2891 SleepForever,
2892 SleepForever,
2893 SleepForever,
2894 SleepForever,
2895 SleepForever,
2896 SleepForever,
2897 SleepForever,
2898 SleepForever,
2899 SleepForever,
2900 SleepForever,
2901 SleepForever,
2902 SleepForever,
2903 SleepForever,
2904 SleepForever,
2905 SleepForever,
2906 SleepForever,
2907 SleepForever,
2908 SleepForever,
2909 SleepForever,
2910 SleepForever,
2911 SleepForever,
2912 SleepForever,
2913 SleepForever,
2914 SleepForever,
2915 SleepForever,
2916 SleepForever,
2917 SleepForever,
2918 SleepForever,
2919 SleepForever,
2920 SleepForever,
2921 SleepForever,
2922 SleepForever,
2923 SleepForever,
2924 SleepForever,
2925 SleepForever,
2926 SleepForever,
2927 SleepForever,
2928 SleepForever,
2929 SleepForever,
2930 SleepForever,
2931 SleepForever,
2932 SleepForever,
2933 SleepForever,
2934 SleepForever,
2935 SleepForever,
2936 SleepForever,
2937 SleepForever,
2938 SleepForever,
2939 SleepForever,
2940 SleepForever,
2941 SleepForever,
2942 SleepForever,
2943 SleepForever,
2944 SleepForever,
2945 SleepForever,
2946 SleepForever,
2947 SleepForever,
2948 SleepForever,
2949 SleepForever,
2950 SleepForever,
2951 SleepForever,
2952 SleepForever,
2953 SleepForever,
2954 SleepForever,
2955 SleepForever,
2956 SleepForever,
2957 SleepForever,
2958 SleepForever,
2959 SleepForever,
2960 SleepForever,
2961 SleepForever,
2962 SleepForever,
2963 SleepForever,
2964 SleepForever,
2965 SleepForever,
2966 SleepForever,
2967 SleepForever,
2968 SleepForever,
2969 SleepForever,
2970 SleepForever,
2971 SleepForever,
2972 SleepForever,
2973 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};
3021
3022const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3023 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3024}
3025
Elliott Hughesc8fece32013-01-02 11:27:23 -08003026void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003027 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003028 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003029 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003030 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3031 }
3032 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3033}
3034
Ian Rogersdf20fe02011-07-20 20:34:16 -07003035} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003036
3037std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3038 switch (rhs) {
3039 case JNIInvalidRefType:
3040 os << "JNIInvalidRefType";
3041 return os;
3042 case JNILocalRefType:
3043 os << "JNILocalRefType";
3044 return os;
3045 case JNIGlobalRefType:
3046 os << "JNIGlobalRefType";
3047 return os;
3048 case JNIWeakGlobalRefType:
3049 os << "JNIWeakGlobalRefType";
3050 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003051 default:
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07003052 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Ian Rogersc7dd2952014-10-21 23:31:19 -07003053 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003054 }
3055}