blob: 59b2b0709628a3afe142cb4f88c793694c133e65 [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.
622 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
623 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
624 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800625 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800626 if (result == nullptr) {
627 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700628 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700629 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700630 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800631 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800632 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700633 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800634 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700635 }
636
Elliott Hughes72025e52011-08-23 17:50:30 -0700637 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700638 CHECK_NON_NULL_ARGUMENT(java_class);
639 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700640 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800641 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800642 if (c == nullptr) {
643 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700644 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800645 if (c->IsStringClass()) {
646 // Replace calls to String.<init> with equivalent StringFactory call.
647 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
648 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
649 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800650 mirror::Object* result = c->AllocObject(soa.Self());
651 if (result == nullptr) {
652 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700653 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700654 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700655 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800656 if (soa.Self()->IsExceptionPending()) {
657 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700658 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800659 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700660 }
661
Ian Rogersbc939662013-08-15 10:26:54 -0700662 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700663 CHECK_NON_NULL_ARGUMENT(java_class);
664 CHECK_NON_NULL_ARGUMENT(name);
665 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700666 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700667 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700668 }
669
Ian Rogersbc939662013-08-15 10:26:54 -0700670 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
671 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700672 CHECK_NON_NULL_ARGUMENT(java_class);
673 CHECK_NON_NULL_ARGUMENT(name);
674 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700675 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700676 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700677 }
678
Elliott Hughes72025e52011-08-23 17:50:30 -0700679 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700680 va_list ap;
681 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700682 CHECK_NON_NULL_ARGUMENT(obj);
683 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700684 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700685 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700686 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700687 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700688 }
689
Elliott Hughes72025e52011-08-23 17:50:30 -0700690 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700691 CHECK_NON_NULL_ARGUMENT(obj);
692 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700693 ScopedObjectAccess soa(env);
694 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
695 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700696 }
697
Elliott Hughes72025e52011-08-23 17:50:30 -0700698 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700699 CHECK_NON_NULL_ARGUMENT(obj);
700 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700701 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700702 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700703 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700704 }
705
Elliott Hughes72025e52011-08-23 17:50:30 -0700706 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700707 va_list ap;
708 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700709 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
710 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700711 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700712 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700713 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700714 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700715 }
716
Elliott Hughes72025e52011-08-23 17:50:30 -0700717 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700718 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
719 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700720 ScopedObjectAccess soa(env);
721 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700722 }
723
Elliott Hughes72025e52011-08-23 17:50:30 -0700724 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700725 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
726 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700727 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700728 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700729 }
730
Elliott Hughes72025e52011-08-23 17:50:30 -0700731 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700732 va_list ap;
733 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
735 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700736 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700737 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700738 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700739 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700740 }
741
Elliott Hughes72025e52011-08-23 17:50:30 -0700742 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700743 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
744 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700745 ScopedObjectAccess soa(env);
746 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700747 }
748
Elliott Hughes72025e52011-08-23 17:50:30 -0700749 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700750 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
751 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700752 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700753 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700754 }
755
Elliott Hughes72025e52011-08-23 17:50:30 -0700756 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700757 va_list ap;
758 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
760 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700761 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700762 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700763 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700764 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700765 }
766
Elliott Hughes72025e52011-08-23 17:50:30 -0700767 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700768 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
769 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700770 ScopedObjectAccess soa(env);
771 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700772 }
773
Elliott Hughes72025e52011-08-23 17:50:30 -0700774 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700775 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
776 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700777 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700778 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700779 }
780
Elliott Hughes72025e52011-08-23 17:50:30 -0700781 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700782 va_list ap;
783 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
785 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700786 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700787 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700788 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700789 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700790 }
791
Elliott Hughes72025e52011-08-23 17:50:30 -0700792 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700793 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
794 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700795 ScopedObjectAccess soa(env);
796 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700797 }
798
Elliott Hughes72025e52011-08-23 17:50:30 -0700799 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700800 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
801 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700802 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700803 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700804 }
805
Elliott Hughes72025e52011-08-23 17:50:30 -0700806 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700807 va_list ap;
808 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700809 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
810 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700811 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700812 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700813 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700814 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700815 }
816
Elliott Hughes72025e52011-08-23 17:50:30 -0700817 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700818 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
819 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700820 ScopedObjectAccess soa(env);
821 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700822 }
823
Elliott Hughes72025e52011-08-23 17:50:30 -0700824 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
826 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700827 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700828 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700829 }
830
Elliott Hughes72025e52011-08-23 17:50:30 -0700831 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700832 va_list ap;
833 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
835 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700836 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700837 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700838 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700839 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700840 }
841
Elliott Hughes72025e52011-08-23 17:50:30 -0700842 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700843 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
844 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700845 ScopedObjectAccess soa(env);
846 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700847 }
848
Elliott Hughes72025e52011-08-23 17:50:30 -0700849 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700850 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
851 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700852 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700853 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700854 }
855
Elliott Hughes72025e52011-08-23 17:50:30 -0700856 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700857 va_list ap;
858 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700859 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
860 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700861 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700862 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700863 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700864 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700865 }
866
Elliott Hughes72025e52011-08-23 17:50:30 -0700867 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700868 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
869 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700870 ScopedObjectAccess soa(env);
871 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700872 }
873
Elliott Hughes72025e52011-08-23 17:50:30 -0700874 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700875 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
876 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700877 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700878 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700879 }
880
Elliott Hughes72025e52011-08-23 17:50:30 -0700881 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700882 va_list ap;
883 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700884 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
885 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700886 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700887 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700888 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700889 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700890 }
891
Elliott Hughes72025e52011-08-23 17:50:30 -0700892 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700893 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
894 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700895 ScopedObjectAccess soa(env);
896 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700897 }
898
Elliott Hughes72025e52011-08-23 17:50:30 -0700899 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700900 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
901 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700902 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700903 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700904 }
905
Elliott Hughes72025e52011-08-23 17:50:30 -0700906 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700907 va_list ap;
908 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700909 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
910 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700911 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700912 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700913 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700914 }
915
Elliott Hughes72025e52011-08-23 17:50:30 -0700916 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700917 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
918 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700919 ScopedObjectAccess soa(env);
920 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700921 }
922
Elliott Hughes72025e52011-08-23 17:50:30 -0700923 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700924 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
925 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700926 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700927 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700928 }
929
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700930 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700931 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700932 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700933 CHECK_NON_NULL_ARGUMENT(obj);
934 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700935 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700936 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
937 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700938 va_end(ap);
939 return local_result;
940 }
941
Ian Rogersbc939662013-08-15 10:26:54 -0700942 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
943 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700944 CHECK_NON_NULL_ARGUMENT(obj);
945 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700946 ScopedObjectAccess soa(env);
947 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
948 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700949 }
950
Ian Rogersbc939662013-08-15 10:26:54 -0700951 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
952 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700953 CHECK_NON_NULL_ARGUMENT(obj);
954 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700955 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700956 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700957 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700958 }
959
Ian Rogersbc939662013-08-15 10:26:54 -0700960 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
961 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700962 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700963 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700964 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
965 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700966 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700967 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700968 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700969 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700970 }
971
Ian Rogersbc939662013-08-15 10:26:54 -0700972 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
973 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700974 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
975 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700976 ScopedObjectAccess soa(env);
977 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700978 }
979
Ian Rogersbc939662013-08-15 10:26:54 -0700980 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
981 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700982 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
983 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700984 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700985 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700986 }
987
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700988 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700989 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700990 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700991 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
992 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700993 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700994 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700995 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700996 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700997 }
998
Ian Rogersbc939662013-08-15 10:26:54 -0700999 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1000 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001001 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1002 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001003 ScopedObjectAccess soa(env);
1004 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001005 }
1006
Ian Rogersbc939662013-08-15 10:26:54 -07001007 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1008 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001009 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1010 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001011 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001012 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001013 }
1014
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001015 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001016 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001017 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001018 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1019 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001020 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001021 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001022 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001023 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001024 }
1025
Ian Rogersbc939662013-08-15 10:26:54 -07001026 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1027 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001028 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1029 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001030 ScopedObjectAccess soa(env);
1031 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001032 }
1033
Ian Rogersbc939662013-08-15 10:26:54 -07001034 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1035 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001036 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1037 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001038 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001039 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001040 }
1041
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001042 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001043 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001044 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001045 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1046 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001047 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001048 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001049 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001050 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001051 }
1052
Ian Rogersbc939662013-08-15 10:26:54 -07001053 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1054 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001055 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1056 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001057 ScopedObjectAccess soa(env);
1058 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001059 }
1060
Ian Rogersbc939662013-08-15 10:26:54 -07001061 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1062 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001063 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1064 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001065 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001066 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001067 }
1068
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001069 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001070 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001071 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001072 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1073 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001074 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001075 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001076 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001077 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001078 }
1079
Ian Rogersbc939662013-08-15 10:26:54 -07001080 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1081 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001082 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1083 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001084 ScopedObjectAccess soa(env);
1085 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001086 }
1087
Ian Rogersbc939662013-08-15 10:26:54 -07001088 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1089 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001090 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001092 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001093 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001094 }
1095
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001096 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001097 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001098 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001099 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1100 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001101 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001102 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001103 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001104 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001105 }
1106
Ian Rogersbc939662013-08-15 10:26:54 -07001107 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1108 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001109 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1110 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001111 ScopedObjectAccess soa(env);
1112 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001113 }
1114
Ian Rogersbc939662013-08-15 10:26:54 -07001115 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1116 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001117 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1118 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001119 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001120 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001121 }
1122
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001123 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001124 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001125 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001126 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1127 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001128 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001129 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001130 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001131 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001132 }
1133
Ian Rogersbc939662013-08-15 10:26:54 -07001134 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1135 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001136 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1137 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001138 ScopedObjectAccess soa(env);
1139 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001140 }
1141
Ian Rogersbc939662013-08-15 10:26:54 -07001142 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1143 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001144 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1145 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001146 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001147 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001148 }
1149
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001150 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001151 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001152 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001153 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1154 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001155 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001156 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001157 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001158 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001159 }
1160
Ian Rogersbc939662013-08-15 10:26:54 -07001161 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1162 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001163 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1164 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001165 ScopedObjectAccess soa(env);
1166 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001167 }
1168
Ian Rogersbc939662013-08-15 10:26:54 -07001169 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1170 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001171 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1172 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001173 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001174 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001175 }
1176
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001177 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001178 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001179 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001180 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1181 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001182 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001183 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001184 va_end(ap);
1185 }
1186
Brian Carlstromea46f952013-07-30 01:26:50 -07001187 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1188 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001189 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1190 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001191 ScopedObjectAccess soa(env);
1192 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001193 }
1194
Ian Rogersbc939662013-08-15 10:26:54 -07001195 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1196 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001197 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1198 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001199 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001200 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001201 }
1202
Ian Rogersbc939662013-08-15 10:26:54 -07001203 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001204 CHECK_NON_NULL_ARGUMENT(java_class);
1205 CHECK_NON_NULL_ARGUMENT(name);
1206 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001207 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001208 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001209 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001210
Ian Rogersbc939662013-08-15 10:26:54 -07001211 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1212 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001213 CHECK_NON_NULL_ARGUMENT(java_class);
1214 CHECK_NON_NULL_ARGUMENT(name);
1215 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001216 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001217 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001218 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001219
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001220 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001221 CHECK_NON_NULL_ARGUMENT(obj);
1222 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001223 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001224 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001225 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001226 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001227 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001228
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001229 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001230 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001231 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001232 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001233 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001234 }
1235
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001236 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001237 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1238 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001239 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001240 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1241 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001242 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001243 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001244 }
1245
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001246 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001247 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001248 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001249 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001250 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001251 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001252 }
1253
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001254#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001255 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1256 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001257 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001258 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001259 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001260 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001261
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001262#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001263 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001264 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001265 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001266 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001267
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001268#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001269 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1270 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001271 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001272 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001273 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001274 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001275
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001276#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001277 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001278 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001279 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001280 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001281
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001282 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001283 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001284 }
1285
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001286 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001287 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001288 }
1289
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001290 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001291 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001292 }
1293
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001294 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001295 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001296 }
1297
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001298 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001299 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001300 }
1301
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001302 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001303 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001304 }
1305
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001306 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001307 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001308 }
1309
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001310 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001311 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001312 }
1313
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001314 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001315 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001316 }
1317
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001318 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001319 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001320 }
1321
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001322 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001323 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001324 }
1325
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001326 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001327 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001328 }
1329
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001330 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001331 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001332 }
1333
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001334 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001335 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001336 }
1337
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001338 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001339 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001340 }
1341
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001342 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001343 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001344 }
1345
1346 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001347 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001348 }
1349
1350 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001351 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001352 }
1353
1354 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001355 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001356 }
1357
1358 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001359 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001360 }
1361
1362 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001363 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001364 }
1365
1366 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001367 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001368 }
1369
1370 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001371 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001372 }
1373
1374 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001375 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001376 }
1377
1378 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001379 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001380 }
1381
1382 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001383 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001384 }
1385
1386 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001387 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001388 }
1389
1390 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001391 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001392 }
1393
1394 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001395 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001396 }
1397
1398 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001399 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001400 }
1401
1402 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001403 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001404 }
1405
1406 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001407 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001408 }
1409
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001410 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001411 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001412 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001413 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001414 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001415 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001416 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001417 va_end(ap);
1418 return local_result;
1419 }
1420
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001421 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001422 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001423 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001424 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001425 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 }
1427
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001428 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001429 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001430 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001431 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001432 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001433 }
1434
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001435 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001436 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001437 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001438 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001439 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001440 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001441 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001442 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001443 }
1444
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001445 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001446 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001447 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001448 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001449 }
1450
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001451 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001452 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001453 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001454 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001455 }
1456
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001457 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001458 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001459 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001460 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001461 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001462 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001463 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001464 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001465 }
1466
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001467 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001468 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001469 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001470 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001471 }
1472
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001473 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001474 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001475 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001476 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001477 }
1478
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001479 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001481 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001482 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001483 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001484 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001485 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001486 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001487 }
1488
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001489 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001490 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001491 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001492 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001493 }
1494
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001495 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001496 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001497 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001498 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001499 }
1500
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001501 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001502 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001503 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001504 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001505 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001506 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001507 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001508 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001509 }
1510
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001511 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001512 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001513 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001514 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001515 }
1516
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001517 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001518 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001519 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001520 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001521 }
1522
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001523 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001524 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001525 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001526 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001527 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001528 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001529 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001530 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001531 }
1532
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001533 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001534 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001535 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001536 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001537 }
1538
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001539 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001540 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001541 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001542 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001543 }
1544
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001545 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001546 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001547 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001548 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001549 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001550 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001551 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001552 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001553 }
1554
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001555 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001556 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001557 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001558 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001559 }
1560
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001561 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001562 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001563 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001564 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001565 }
1566
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001567 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001568 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001569 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001570 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001571 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001572 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001573 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001574 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001575 }
1576
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001577 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001578 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001579 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001580 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001581 }
1582
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001583 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001584 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001585 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001586 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001587 }
1588
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001589 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001590 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001591 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001592 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001593 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001594 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001595 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001596 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001597 }
1598
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001599 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001600 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001601 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001602 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001603 }
1604
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001605 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001606 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001607 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001608 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001609 }
1610
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001611 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001612 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001613 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001614 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001615 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001616 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001617 va_end(ap);
1618 }
1619
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001620 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001621 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001622 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001623 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001624 }
1625
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001626 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001627 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001628 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001629 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001630 }
1631
Elliott Hughes814e4032011-08-23 12:07:56 -07001632 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001633 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001634 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001635 return nullptr;
1636 }
1637 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001638 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001639 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001640 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001641 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001642 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001643 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001644 }
1645
1646 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001647 if (utf == nullptr) {
1648 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001649 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001650 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001651 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001652 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001653 }
1654
Elliott Hughes814e4032011-08-23 12:07:56 -07001655 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001656 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001657 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001658 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001659 }
1660
1661 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001662 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001663 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001664 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001665 }
1666
Ian Rogersbc939662013-08-15 10:26:54 -07001667 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1668 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001669 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001670 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001671 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001672 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001673 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001674 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001675 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001676 if (s->IsCompressed()) {
1677 for (int i = 0; i < length; ++i) {
1678 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1679 }
1680 } else {
1681 const jchar* chars = static_cast<jchar*>(s->GetValue());
1682 memcpy(buf, chars + start, length * sizeof(jchar));
1683 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001684 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001685 }
1686
Ian Rogersbc939662013-08-15 10:26:54 -07001687 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1688 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001689 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001690 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001691 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001692 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001693 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001694 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001695 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001696 if (s->IsCompressed()) {
1697 for (int i = 0; i < length; ++i) {
1698 buf[i] = s->CharAt(start+i);
1699 }
1700 } else {
1701 const jchar* chars = s->GetValue();
1702 size_t bytes = CountUtf8Bytes(chars + start, length);
1703 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1704 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001705 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001706 }
1707
Elliott Hughes75770752011-08-24 17:52:38 -07001708 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001709 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001710 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001711 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001712 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001713 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001714 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001715 if (s->IsCompressed()) {
1716 int32_t length = s->GetLength();
1717 for (int i = 0; i < length; ++i) {
1718 chars[i] = s->CharAt(i);
1719 }
1720 } else {
1721 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1722 }
Fred Shih56890e22014-06-02 11:11:52 -07001723 if (is_copy != nullptr) {
1724 *is_copy = JNI_TRUE;
1725 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001726 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001727 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001728 if (is_copy != nullptr) {
1729 *is_copy = JNI_FALSE;
1730 }
1731 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001732 }
1733
Mathieu Chartier590fee92013-09-13 13:46:47 -07001734 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001735 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001736 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001737 mirror::String* s = soa.Decode<mirror::String*>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001738 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001739 delete[] chars;
1740 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001741 }
1742
Elliott Hughes75770752011-08-24 17:52:38 -07001743 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001744 CHECK_NON_NULL_ARGUMENT(java_string);
1745 ScopedObjectAccess soa(env);
1746 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001747 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001748 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001749 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001750 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001751 if (!kUseReadBarrier) {
1752 heap->IncrementDisableMovingGC(soa.Self());
1753 } else {
1754 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1755 // to occur thanks to the to-space invariant.
1756 heap->IncrementDisableThreadFlip(soa.Self());
1757 }
Fred Shih56890e22014-06-02 11:11:52 -07001758 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001759 if (s->IsCompressed()) {
1760 if (is_copy != nullptr) {
1761 *is_copy = JNI_TRUE;
1762 }
1763 int32_t length = s->GetLength();
1764 jchar* chars = new jchar[length];
1765 for (int i = 0; i < length; ++i) {
1766 chars[i] = s->CharAt(i);
1767 }
1768 return chars;
1769 } else {
1770 if (is_copy != nullptr) {
1771 *is_copy = JNI_FALSE;
1772 }
1773 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001774 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001775 }
1776
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001777 static void ReleaseStringCritical(JNIEnv* env,
1778 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001779 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001780 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1781 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001782 gc::Heap* heap = Runtime::Current()->GetHeap();
1783 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001784 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001785 if (!kUseReadBarrier) {
1786 heap->DecrementDisableMovingGC(soa.Self());
1787 } else {
1788 heap->DecrementDisableThreadFlip(soa.Self());
1789 }
Fred Shih56890e22014-06-02 11:11:52 -07001790 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001791 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1792 delete[] chars;
1793 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001794 }
1795
Elliott Hughes75770752011-08-24 17:52:38 -07001796 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001797 if (java_string == nullptr) {
1798 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001799 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001800 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001801 *is_copy = JNI_TRUE;
1802 }
Ian Rogersef28b142012-11-30 14:22:18 -08001803 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001804 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001805 size_t byte_count = s->GetUtfLength();
1806 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001807 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001808 if (s->IsCompressed()) {
1809 for (size_t i = 0; i < byte_count; ++i) {
1810 bytes[i] = s->CharAt(i);
1811 }
1812 } else {
1813 const uint16_t* chars = s->GetValue();
1814 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1815 }
Elliott Hughes75770752011-08-24 17:52:38 -07001816 bytes[byte_count] = '\0';
1817 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001818 }
1819
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001820 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001821 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001822 }
1823
Elliott Hughesbd935992011-08-22 11:59:34 -07001824 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001826 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001827 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001828 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001829 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1830 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001831 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001832 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001833 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001834 }
1835
Elliott Hughes814e4032011-08-23 12:07:56 -07001836 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001837 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001838 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001839 mirror::ObjectArray<mirror::Object>* array =
1840 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001841 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001842 }
1843
Ian Rogersbc939662013-08-15 10:26:54 -07001844 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1845 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001846 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001847 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001848 mirror::ObjectArray<mirror::Object>* array =
1849 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1850 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001851 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001852 }
1853
1854 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001855 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001856 }
1857
1858 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001859 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001860 }
1861
1862 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001863 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001864 }
1865
1866 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001867 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001868 }
1869
1870 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001871 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001872 }
1873
1874 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001875 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001876 }
1877
1878 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001879 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001880 }
1881
Ian Rogers1d99e452014-01-02 17:36:41 -08001882 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1883 jobject initial_element) {
1884 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001885 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001886 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001887 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001888 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001889
1890 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001891 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001892 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001893 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001894 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001895 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001896 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1897 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001898 return nullptr;
1899 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001900 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001901 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001902 if (UNLIKELY(array_class == nullptr)) {
1903 return nullptr;
1904 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001905 }
1906
Elliott Hughes75770752011-08-24 17:52:38 -07001907 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001908 mirror::ObjectArray<mirror::Object>* result =
1909 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001910 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001911 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001912 if (initial_object != nullptr) {
1913 mirror::Class* element_class = result->GetClass()->GetComponentType();
1914 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001915 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1916 "element type of '%s'",
1917 PrettyDescriptor(initial_object->GetClass()).c_str(),
1918 PrettyDescriptor(element_class).c_str());
1919 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001920 } else {
1921 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001922 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001923 }
1924 }
Elliott Hughes75770752011-08-24 17:52:38 -07001925 }
1926 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001927 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001928 }
1929
1930 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001931 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001932 }
1933
Ian Rogersa15e67d2012-02-28 13:51:55 -08001934 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001935 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001936 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001937 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001938 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001939 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1940 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001941 return nullptr;
1942 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001943 gc::Heap* heap = Runtime::Current()->GetHeap();
1944 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001945 if (!kUseReadBarrier) {
1946 heap->IncrementDisableMovingGC(soa.Self());
1947 } else {
1948 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1949 // to occur thanks to the to-space invariant.
1950 heap->IncrementDisableThreadFlip(soa.Self());
1951 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001952 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001953 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001954 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001955 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001956 *is_copy = JNI_FALSE;
1957 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001958 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001959 }
1960
Ian Rogers2d10b202014-05-12 19:15:18 -07001961 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1962 jint mode) {
1963 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1964 ScopedObjectAccess soa(env);
1965 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1966 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001967 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1968 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001969 return;
1970 }
1971 const size_t component_size = array->GetClass()->GetComponentSize();
1972 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001973 }
1974
Elliott Hughes75770752011-08-24 17:52:38 -07001975 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001976 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001977 }
1978
Elliott Hughes75770752011-08-24 17:52:38 -07001979 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001980 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001981 }
1982
Elliott Hughes75770752011-08-24 17:52:38 -07001983 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001984 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001985 }
1986
Elliott Hughes75770752011-08-24 17:52:38 -07001987 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001988 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001989 }
1990
Elliott Hughes75770752011-08-24 17:52:38 -07001991 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001992 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001993 }
1994
Elliott Hughes75770752011-08-24 17:52:38 -07001995 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001996 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001997 }
1998
Elliott Hughes75770752011-08-24 17:52:38 -07001999 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002000 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002001 }
2002
Elliott Hughes75770752011-08-24 17:52:38 -07002003 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002004 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002005 }
2006
Mathieu Chartier590fee92013-09-13 13:46:47 -07002007 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2008 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002009 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2010 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002011 }
2012
Mathieu Chartier590fee92013-09-13 13:46:47 -07002013 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002014 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002015 }
2016
Mathieu Chartier590fee92013-09-13 13:46:47 -07002017 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002018 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002019 }
2020
Mathieu Chartier590fee92013-09-13 13:46:47 -07002021 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2022 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002023 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002024 }
2025
Mathieu Chartier590fee92013-09-13 13:46:47 -07002026 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2027 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002028 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002029 }
2030
Mathieu Chartier590fee92013-09-13 13:46:47 -07002031 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002032 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002033 }
2034
Mathieu Chartier590fee92013-09-13 13:46:47 -07002035 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002036 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002037 }
2038
Mathieu Chartier590fee92013-09-13 13:46:47 -07002039 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2040 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002041 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002042 }
2043
Ian Rogersbc939662013-08-15 10:26:54 -07002044 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2045 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002046 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002047 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002048 }
2049
Ian Rogersbc939662013-08-15 10:26:54 -07002050 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2051 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002052 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002053 }
2054
Ian Rogersbc939662013-08-15 10:26:54 -07002055 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2056 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002057 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002058 }
2059
Ian Rogersbc939662013-08-15 10:26:54 -07002060 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2061 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002062 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002063 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002064 }
2065
Ian Rogersbc939662013-08-15 10:26:54 -07002066 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2067 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002068 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002069 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002070 }
2071
Ian Rogersbc939662013-08-15 10:26:54 -07002072 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2073 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002074 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002075 }
2076
Ian Rogersbc939662013-08-15 10:26:54 -07002077 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2078 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002079 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002080 }
2081
Ian Rogersbc939662013-08-15 10:26:54 -07002082 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2083 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002084 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002085 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002086 }
2087
Ian Rogersbc939662013-08-15 10:26:54 -07002088 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2089 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002090 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002091 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002092 }
2093
Ian Rogersbc939662013-08-15 10:26:54 -07002094 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2095 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002096 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002097 }
2098
Ian Rogersbc939662013-08-15 10:26:54 -07002099 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2100 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002101 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002102 }
2103
Ian Rogersbc939662013-08-15 10:26:54 -07002104 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2105 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002106 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002107 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002108 }
2109
Ian Rogersbc939662013-08-15 10:26:54 -07002110 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2111 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002112 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002113 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002114 }
2115
Ian Rogersbc939662013-08-15 10:26:54 -07002116 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2117 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002118 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002119 }
2120
Ian Rogersbc939662013-08-15 10:26:54 -07002121 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2122 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002123 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002124 }
2125
Ian Rogersbc939662013-08-15 10:26:54 -07002126 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2127 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002128 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002129 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002130 }
2131
Ian Rogersbc939662013-08-15 10:26:54 -07002132 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2133 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002134 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2135 }
2136
Ian Rogersbc939662013-08-15 10:26:54 -07002137 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2138 jint method_count, bool return_errors) {
2139 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002140 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2141 method_count);
2142 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002143 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002144 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002145 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002146 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002147 if (UNLIKELY(method_count == 0)) {
2148 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2149 << PrettyDescriptor(c);
2150 return JNI_OK;
2151 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002152 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002153 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002154 const char* name = methods[i].name;
2155 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002156 const void* fnPtr = methods[i].fnPtr;
2157 if (UNLIKELY(name == nullptr)) {
2158 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2159 return JNI_ERR;
2160 } else if (UNLIKELY(sig == nullptr)) {
2161 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2162 return JNI_ERR;
2163 } else if (UNLIKELY(fnPtr == nullptr)) {
2164 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2165 return JNI_ERR;
2166 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002167 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002168 // Notes about fast JNI calls:
2169 //
2170 // On a normal JNI call, the calling thread usually transitions
2171 // from the kRunnable state to the kNative state. But if the
2172 // called native function needs to access any Java object, it
2173 // will have to transition back to the kRunnable state.
2174 //
2175 // There is a cost to this double transition. For a JNI call
2176 // that should be quick, this cost may dominate the call cost.
2177 //
2178 // On a fast JNI call, the calling thread avoids this double
2179 // transition by not transitioning from kRunnable to kNative and
2180 // stays in the kRunnable state.
2181 //
2182 // There are risks to using a fast JNI call because it can delay
2183 // a response to a thread suspension request which is typically
2184 // used for a GC root scanning, etc. If a fast JNI call takes a
2185 // long time, it could cause longer thread suspension latency
2186 // and GC pauses.
2187 //
2188 // Thus, fast JNI should be used with care. It should be used
2189 // for a JNI call that takes a short amount of time (eg. no
2190 // long-running loop) and does not block (eg. no locks, I/O,
2191 // etc.)
2192 //
2193 // A '!' prefix in the signature in the JNINativeMethod
2194 // indicates that it's a fast JNI call and the runtime omits the
2195 // thread state transition from kRunnable to kNative at the
2196 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002197 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002198 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002199 ++sig;
2200 }
2201
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002202 // Note: the right order is to try to find the method locally
2203 // first, either as a direct or a virtual method. Then move to
2204 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002205 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002206 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2207 for (mirror::Class* current_class = c;
2208 current_class != nullptr;
2209 current_class = current_class->GetSuperClass()) {
2210 // Search first only comparing methods which are native.
2211 m = FindMethod<true>(current_class, name, sig);
2212 if (m != nullptr) {
2213 break;
2214 }
2215
2216 // Search again comparing to all methods, to find non-native methods that match.
2217 m = FindMethod<false>(current_class, name, sig);
2218 if (m != nullptr) {
2219 break;
2220 }
2221
2222 if (warn_on_going_to_parent) {
2223 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2224 << "This is slow, consider changing your RegisterNatives calls.";
2225 warn_on_going_to_parent = false;
2226 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002227 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002228
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002229 if (m == nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002230 c->DumpClass(
2231 LOG_STREAM(return_errors
2232 ? ::android::base::ERROR
2233 : ::android::base::FATAL_WITHOUT_ABORT),
2234 mirror::Class::kDumpClassFullDetail);
2235 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2236 << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002237 << PrettyDescriptor(c) << "." << name << sig << " in "
2238 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002239 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002240 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002241 } else if (!m->IsNative()) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002242 LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
2243 << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002244 << PrettyDescriptor(c) << "." << name << sig
2245 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002246 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002247 return JNI_ERR;
2248 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002249
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002250 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002251
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002252 is_fast = is_fast || m->IsFastNative(); // Merge with @FastNative state.
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002253 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002254 }
2255 return JNI_OK;
2256 }
2257
Elliott Hughes5174fe62011-08-23 15:12:35 -07002258 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002259 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002260 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002261 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002262
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002263 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002264
Ian Rogers2d10b202014-05-12 19:15:18 -07002265 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002266 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002267 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002268 if (m.IsNative()) {
2269 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002270 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002271 }
2272 }
2273
Ian Rogers2d10b202014-05-12 19:15:18 -07002274 if (unregistered_count == 0) {
2275 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2276 << PrettyDescriptor(c) << "' that contains no native methods";
2277 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002278 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002279 }
2280
Ian Rogers719d1a32014-03-06 12:13:39 -08002281 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002282 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002283 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002284 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2285 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002286 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002287 return JNI_ERR;
2288 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002289 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002290 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002291 }
2292
Ian Rogers719d1a32014-03-06 12:13:39 -08002293 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002294 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002295 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002296 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002297 o->MonitorExit(soa.Self());
2298 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002299 return JNI_ERR;
2300 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002301 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002302 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002303 }
2304
2305 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002306 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002307 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002308 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002309 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002310 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002311 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002312 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002313 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002314 }
2315
Elliott Hughescdf53122011-08-19 15:46:09 -07002316 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002317 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002318 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2319 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002320 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002321 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002322 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002323 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2324 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002325 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002326 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002327
Brian Carlstrom85a93362014-06-25 09:30:52 -07002328 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002329 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002330 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2331 "buffer capacity greater than maximum jint: %" PRId64,
2332 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002333 return nullptr;
2334 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002335 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002336 jint capacity_arg = static_cast<jint>(capacity);
2337
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002338 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2339 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002340 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002341 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002342 }
2343
Elliott Hughesb465ab02011-08-24 11:21:21 -07002344 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002345 return reinterpret_cast<void*>(env->GetLongField(
2346 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002347 }
2348
Elliott Hughesb465ab02011-08-24 11:21:21 -07002349 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002350 return static_cast<jlong>(env->GetIntField(
2351 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002352 }
2353
Andreas Gampea8763072014-12-20 00:08:35 -08002354 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2355 if (java_object == nullptr) {
2356 return JNIInvalidRefType;
2357 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002358
2359 // Do we definitely know what kind of reference this is?
2360 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2361 IndirectRefKind kind = GetIndirectRefKind(ref);
2362 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002363 case kLocal:
2364 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002365 case kGlobal:
2366 return JNIGlobalRefType;
2367 case kWeakGlobal:
2368 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002369 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002370 // Assume value is in a handle scope.
2371 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002372 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002373 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002374 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002375 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002376
2377 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002378 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2379 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002380 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002381 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002382 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002383 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2384 return JNI_ERR;
2385 }
2386 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002387 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002388 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2389 if (!okay) {
2390 soa.Self()->ThrowOutOfMemoryError(caller);
2391 }
2392 return okay ? JNI_OK : JNI_ERR;
2393 }
2394
2395 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002396 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002397 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002398 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002399 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002400 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002401 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002402 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002403 return soa.AddLocalReference<JniT>(result);
2404 }
2405
Ian Rogers2d10b202014-05-12 19:15:18 -07002406 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2407 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2408 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002409 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002410 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002411 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002412 soa.Vm()->JniAbortF(fn_name,
2413 "attempt to %s %s primitive array elements with an object of type %s",
2414 operation,
2415 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2416 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002417 return nullptr;
2418 }
2419 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2420 return array;
2421 }
2422
2423 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2424 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2425 CHECK_NON_NULL_ARGUMENT(java_array);
2426 ScopedObjectAccess soa(env);
2427 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2428 "GetArrayElements",
2429 "get");
2430 if (UNLIKELY(array == nullptr)) {
2431 return nullptr;
2432 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002433 // Only make a copy if necessary.
2434 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2435 if (is_copy != nullptr) {
2436 *is_copy = JNI_TRUE;
2437 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002438 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002439 size_t size = array->GetLength() * component_size;
2440 void* data = new uint64_t[RoundUp(size, 8) / 8];
2441 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002442 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002443 } else {
2444 if (is_copy != nullptr) {
2445 *is_copy = JNI_FALSE;
2446 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002447 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002448 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002449 }
2450
Ian Rogers2d10b202014-05-12 19:15:18 -07002451 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002452 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002453 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002454 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002455 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2456 "ReleaseArrayElements",
2457 "release");
2458 if (array == nullptr) {
2459 return;
2460 }
2461 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2462 }
2463
2464 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2465 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002466 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002467 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002468 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002469 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002470 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002471 if (is_copy) {
2472 // Sanity check: If elements is not the same as the java array's data, it better not be a
2473 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2474 // copies we make?
2475 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002476 soa.Vm()->JniAbortF("ReleaseArrayElements",
2477 "invalid element pointer %p, array elements are %p",
2478 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002479 return;
2480 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002481 if (mode != JNI_ABORT) {
2482 memcpy(array_data, elements, bytes);
2483 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2484 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2485 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07002486 soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002487 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002488 }
2489 if (mode != JNI_COMMIT) {
2490 if (is_copy) {
2491 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002492 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002493 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002494 if (!kUseReadBarrier) {
2495 heap->DecrementDisableMovingGC(soa.Self());
2496 } else {
2497 heap->DecrementDisableThreadFlip(soa.Self());
2498 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002499 }
2500 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002501 }
2502
Ian Rogers2d10b202014-05-12 19:15:18 -07002503 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2504 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2505 jsize start, jsize length, ElementT* buf) {
2506 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2507 ScopedObjectAccess soa(env);
2508 ArtArrayT* array =
2509 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2510 "GetPrimitiveArrayRegion",
2511 "get region of");
2512 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002513 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002514 ThrowAIOOBE(soa, array, start, length, "src");
2515 } else {
2516 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2517 ElementT* data = array->GetData();
2518 memcpy(buf, data + start, length * sizeof(ElementT));
2519 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002520 }
2521 }
2522
Ian Rogers2d10b202014-05-12 19:15:18 -07002523 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2524 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2525 jsize start, jsize length, const ElementT* buf) {
2526 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2527 ScopedObjectAccess soa(env);
2528 ArtArrayT* array =
2529 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2530 "SetPrimitiveArrayRegion",
2531 "set region of");
2532 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002533 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002534 ThrowAIOOBE(soa, array, start, length, "dst");
2535 } else {
2536 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2537 ElementT* data = array->GetData();
2538 memcpy(data + start, buf, length * sizeof(ElementT));
2539 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002540 }
2541 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002542};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002543
Elliott Hughes88c5c352012-03-15 18:49:48 -07002544const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002545 nullptr, // reserved0.
2546 nullptr, // reserved1.
2547 nullptr, // reserved2.
2548 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002549 JNI::GetVersion,
2550 JNI::DefineClass,
2551 JNI::FindClass,
2552 JNI::FromReflectedMethod,
2553 JNI::FromReflectedField,
2554 JNI::ToReflectedMethod,
2555 JNI::GetSuperclass,
2556 JNI::IsAssignableFrom,
2557 JNI::ToReflectedField,
2558 JNI::Throw,
2559 JNI::ThrowNew,
2560 JNI::ExceptionOccurred,
2561 JNI::ExceptionDescribe,
2562 JNI::ExceptionClear,
2563 JNI::FatalError,
2564 JNI::PushLocalFrame,
2565 JNI::PopLocalFrame,
2566 JNI::NewGlobalRef,
2567 JNI::DeleteGlobalRef,
2568 JNI::DeleteLocalRef,
2569 JNI::IsSameObject,
2570 JNI::NewLocalRef,
2571 JNI::EnsureLocalCapacity,
2572 JNI::AllocObject,
2573 JNI::NewObject,
2574 JNI::NewObjectV,
2575 JNI::NewObjectA,
2576 JNI::GetObjectClass,
2577 JNI::IsInstanceOf,
2578 JNI::GetMethodID,
2579 JNI::CallObjectMethod,
2580 JNI::CallObjectMethodV,
2581 JNI::CallObjectMethodA,
2582 JNI::CallBooleanMethod,
2583 JNI::CallBooleanMethodV,
2584 JNI::CallBooleanMethodA,
2585 JNI::CallByteMethod,
2586 JNI::CallByteMethodV,
2587 JNI::CallByteMethodA,
2588 JNI::CallCharMethod,
2589 JNI::CallCharMethodV,
2590 JNI::CallCharMethodA,
2591 JNI::CallShortMethod,
2592 JNI::CallShortMethodV,
2593 JNI::CallShortMethodA,
2594 JNI::CallIntMethod,
2595 JNI::CallIntMethodV,
2596 JNI::CallIntMethodA,
2597 JNI::CallLongMethod,
2598 JNI::CallLongMethodV,
2599 JNI::CallLongMethodA,
2600 JNI::CallFloatMethod,
2601 JNI::CallFloatMethodV,
2602 JNI::CallFloatMethodA,
2603 JNI::CallDoubleMethod,
2604 JNI::CallDoubleMethodV,
2605 JNI::CallDoubleMethodA,
2606 JNI::CallVoidMethod,
2607 JNI::CallVoidMethodV,
2608 JNI::CallVoidMethodA,
2609 JNI::CallNonvirtualObjectMethod,
2610 JNI::CallNonvirtualObjectMethodV,
2611 JNI::CallNonvirtualObjectMethodA,
2612 JNI::CallNonvirtualBooleanMethod,
2613 JNI::CallNonvirtualBooleanMethodV,
2614 JNI::CallNonvirtualBooleanMethodA,
2615 JNI::CallNonvirtualByteMethod,
2616 JNI::CallNonvirtualByteMethodV,
2617 JNI::CallNonvirtualByteMethodA,
2618 JNI::CallNonvirtualCharMethod,
2619 JNI::CallNonvirtualCharMethodV,
2620 JNI::CallNonvirtualCharMethodA,
2621 JNI::CallNonvirtualShortMethod,
2622 JNI::CallNonvirtualShortMethodV,
2623 JNI::CallNonvirtualShortMethodA,
2624 JNI::CallNonvirtualIntMethod,
2625 JNI::CallNonvirtualIntMethodV,
2626 JNI::CallNonvirtualIntMethodA,
2627 JNI::CallNonvirtualLongMethod,
2628 JNI::CallNonvirtualLongMethodV,
2629 JNI::CallNonvirtualLongMethodA,
2630 JNI::CallNonvirtualFloatMethod,
2631 JNI::CallNonvirtualFloatMethodV,
2632 JNI::CallNonvirtualFloatMethodA,
2633 JNI::CallNonvirtualDoubleMethod,
2634 JNI::CallNonvirtualDoubleMethodV,
2635 JNI::CallNonvirtualDoubleMethodA,
2636 JNI::CallNonvirtualVoidMethod,
2637 JNI::CallNonvirtualVoidMethodV,
2638 JNI::CallNonvirtualVoidMethodA,
2639 JNI::GetFieldID,
2640 JNI::GetObjectField,
2641 JNI::GetBooleanField,
2642 JNI::GetByteField,
2643 JNI::GetCharField,
2644 JNI::GetShortField,
2645 JNI::GetIntField,
2646 JNI::GetLongField,
2647 JNI::GetFloatField,
2648 JNI::GetDoubleField,
2649 JNI::SetObjectField,
2650 JNI::SetBooleanField,
2651 JNI::SetByteField,
2652 JNI::SetCharField,
2653 JNI::SetShortField,
2654 JNI::SetIntField,
2655 JNI::SetLongField,
2656 JNI::SetFloatField,
2657 JNI::SetDoubleField,
2658 JNI::GetStaticMethodID,
2659 JNI::CallStaticObjectMethod,
2660 JNI::CallStaticObjectMethodV,
2661 JNI::CallStaticObjectMethodA,
2662 JNI::CallStaticBooleanMethod,
2663 JNI::CallStaticBooleanMethodV,
2664 JNI::CallStaticBooleanMethodA,
2665 JNI::CallStaticByteMethod,
2666 JNI::CallStaticByteMethodV,
2667 JNI::CallStaticByteMethodA,
2668 JNI::CallStaticCharMethod,
2669 JNI::CallStaticCharMethodV,
2670 JNI::CallStaticCharMethodA,
2671 JNI::CallStaticShortMethod,
2672 JNI::CallStaticShortMethodV,
2673 JNI::CallStaticShortMethodA,
2674 JNI::CallStaticIntMethod,
2675 JNI::CallStaticIntMethodV,
2676 JNI::CallStaticIntMethodA,
2677 JNI::CallStaticLongMethod,
2678 JNI::CallStaticLongMethodV,
2679 JNI::CallStaticLongMethodA,
2680 JNI::CallStaticFloatMethod,
2681 JNI::CallStaticFloatMethodV,
2682 JNI::CallStaticFloatMethodA,
2683 JNI::CallStaticDoubleMethod,
2684 JNI::CallStaticDoubleMethodV,
2685 JNI::CallStaticDoubleMethodA,
2686 JNI::CallStaticVoidMethod,
2687 JNI::CallStaticVoidMethodV,
2688 JNI::CallStaticVoidMethodA,
2689 JNI::GetStaticFieldID,
2690 JNI::GetStaticObjectField,
2691 JNI::GetStaticBooleanField,
2692 JNI::GetStaticByteField,
2693 JNI::GetStaticCharField,
2694 JNI::GetStaticShortField,
2695 JNI::GetStaticIntField,
2696 JNI::GetStaticLongField,
2697 JNI::GetStaticFloatField,
2698 JNI::GetStaticDoubleField,
2699 JNI::SetStaticObjectField,
2700 JNI::SetStaticBooleanField,
2701 JNI::SetStaticByteField,
2702 JNI::SetStaticCharField,
2703 JNI::SetStaticShortField,
2704 JNI::SetStaticIntField,
2705 JNI::SetStaticLongField,
2706 JNI::SetStaticFloatField,
2707 JNI::SetStaticDoubleField,
2708 JNI::NewString,
2709 JNI::GetStringLength,
2710 JNI::GetStringChars,
2711 JNI::ReleaseStringChars,
2712 JNI::NewStringUTF,
2713 JNI::GetStringUTFLength,
2714 JNI::GetStringUTFChars,
2715 JNI::ReleaseStringUTFChars,
2716 JNI::GetArrayLength,
2717 JNI::NewObjectArray,
2718 JNI::GetObjectArrayElement,
2719 JNI::SetObjectArrayElement,
2720 JNI::NewBooleanArray,
2721 JNI::NewByteArray,
2722 JNI::NewCharArray,
2723 JNI::NewShortArray,
2724 JNI::NewIntArray,
2725 JNI::NewLongArray,
2726 JNI::NewFloatArray,
2727 JNI::NewDoubleArray,
2728 JNI::GetBooleanArrayElements,
2729 JNI::GetByteArrayElements,
2730 JNI::GetCharArrayElements,
2731 JNI::GetShortArrayElements,
2732 JNI::GetIntArrayElements,
2733 JNI::GetLongArrayElements,
2734 JNI::GetFloatArrayElements,
2735 JNI::GetDoubleArrayElements,
2736 JNI::ReleaseBooleanArrayElements,
2737 JNI::ReleaseByteArrayElements,
2738 JNI::ReleaseCharArrayElements,
2739 JNI::ReleaseShortArrayElements,
2740 JNI::ReleaseIntArrayElements,
2741 JNI::ReleaseLongArrayElements,
2742 JNI::ReleaseFloatArrayElements,
2743 JNI::ReleaseDoubleArrayElements,
2744 JNI::GetBooleanArrayRegion,
2745 JNI::GetByteArrayRegion,
2746 JNI::GetCharArrayRegion,
2747 JNI::GetShortArrayRegion,
2748 JNI::GetIntArrayRegion,
2749 JNI::GetLongArrayRegion,
2750 JNI::GetFloatArrayRegion,
2751 JNI::GetDoubleArrayRegion,
2752 JNI::SetBooleanArrayRegion,
2753 JNI::SetByteArrayRegion,
2754 JNI::SetCharArrayRegion,
2755 JNI::SetShortArrayRegion,
2756 JNI::SetIntArrayRegion,
2757 JNI::SetLongArrayRegion,
2758 JNI::SetFloatArrayRegion,
2759 JNI::SetDoubleArrayRegion,
2760 JNI::RegisterNatives,
2761 JNI::UnregisterNatives,
2762 JNI::MonitorEnter,
2763 JNI::MonitorExit,
2764 JNI::GetJavaVM,
2765 JNI::GetStringRegion,
2766 JNI::GetStringUTFRegion,
2767 JNI::GetPrimitiveArrayCritical,
2768 JNI::ReleasePrimitiveArrayCritical,
2769 JNI::GetStringCritical,
2770 JNI::ReleaseStringCritical,
2771 JNI::NewWeakGlobalRef,
2772 JNI::DeleteWeakGlobalRef,
2773 JNI::ExceptionCheck,
2774 JNI::NewDirectByteBuffer,
2775 JNI::GetDirectBufferAddress,
2776 JNI::GetDirectBufferCapacity,
2777 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002778};
2779
Ian Rogers68d8b422014-07-17 11:09:10 -07002780const JNINativeInterface* GetJniNativeInterface() {
2781 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002782}
2783
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002784void (*gJniSleepForeverStub[])() = {
2785 nullptr, // reserved0.
2786 nullptr, // reserved1.
2787 nullptr, // reserved2.
2788 nullptr, // reserved3.
2789 SleepForever,
2790 SleepForever,
2791 SleepForever,
2792 SleepForever,
2793 SleepForever,
2794 SleepForever,
2795 SleepForever,
2796 SleepForever,
2797 SleepForever,
2798 SleepForever,
2799 SleepForever,
2800 SleepForever,
2801 SleepForever,
2802 SleepForever,
2803 SleepForever,
2804 SleepForever,
2805 SleepForever,
2806 SleepForever,
2807 SleepForever,
2808 SleepForever,
2809 SleepForever,
2810 SleepForever,
2811 SleepForever,
2812 SleepForever,
2813 SleepForever,
2814 SleepForever,
2815 SleepForever,
2816 SleepForever,
2817 SleepForever,
2818 SleepForever,
2819 SleepForever,
2820 SleepForever,
2821 SleepForever,
2822 SleepForever,
2823 SleepForever,
2824 SleepForever,
2825 SleepForever,
2826 SleepForever,
2827 SleepForever,
2828 SleepForever,
2829 SleepForever,
2830 SleepForever,
2831 SleepForever,
2832 SleepForever,
2833 SleepForever,
2834 SleepForever,
2835 SleepForever,
2836 SleepForever,
2837 SleepForever,
2838 SleepForever,
2839 SleepForever,
2840 SleepForever,
2841 SleepForever,
2842 SleepForever,
2843 SleepForever,
2844 SleepForever,
2845 SleepForever,
2846 SleepForever,
2847 SleepForever,
2848 SleepForever,
2849 SleepForever,
2850 SleepForever,
2851 SleepForever,
2852 SleepForever,
2853 SleepForever,
2854 SleepForever,
2855 SleepForever,
2856 SleepForever,
2857 SleepForever,
2858 SleepForever,
2859 SleepForever,
2860 SleepForever,
2861 SleepForever,
2862 SleepForever,
2863 SleepForever,
2864 SleepForever,
2865 SleepForever,
2866 SleepForever,
2867 SleepForever,
2868 SleepForever,
2869 SleepForever,
2870 SleepForever,
2871 SleepForever,
2872 SleepForever,
2873 SleepForever,
2874 SleepForever,
2875 SleepForever,
2876 SleepForever,
2877 SleepForever,
2878 SleepForever,
2879 SleepForever,
2880 SleepForever,
2881 SleepForever,
2882 SleepForever,
2883 SleepForever,
2884 SleepForever,
2885 SleepForever,
2886 SleepForever,
2887 SleepForever,
2888 SleepForever,
2889 SleepForever,
2890 SleepForever,
2891 SleepForever,
2892 SleepForever,
2893 SleepForever,
2894 SleepForever,
2895 SleepForever,
2896 SleepForever,
2897 SleepForever,
2898 SleepForever,
2899 SleepForever,
2900 SleepForever,
2901 SleepForever,
2902 SleepForever,
2903 SleepForever,
2904 SleepForever,
2905 SleepForever,
2906 SleepForever,
2907 SleepForever,
2908 SleepForever,
2909 SleepForever,
2910 SleepForever,
2911 SleepForever,
2912 SleepForever,
2913 SleepForever,
2914 SleepForever,
2915 SleepForever,
2916 SleepForever,
2917 SleepForever,
2918 SleepForever,
2919 SleepForever,
2920 SleepForever,
2921 SleepForever,
2922 SleepForever,
2923 SleepForever,
2924 SleepForever,
2925 SleepForever,
2926 SleepForever,
2927 SleepForever,
2928 SleepForever,
2929 SleepForever,
2930 SleepForever,
2931 SleepForever,
2932 SleepForever,
2933 SleepForever,
2934 SleepForever,
2935 SleepForever,
2936 SleepForever,
2937 SleepForever,
2938 SleepForever,
2939 SleepForever,
2940 SleepForever,
2941 SleepForever,
2942 SleepForever,
2943 SleepForever,
2944 SleepForever,
2945 SleepForever,
2946 SleepForever,
2947 SleepForever,
2948 SleepForever,
2949 SleepForever,
2950 SleepForever,
2951 SleepForever,
2952 SleepForever,
2953 SleepForever,
2954 SleepForever,
2955 SleepForever,
2956 SleepForever,
2957 SleepForever,
2958 SleepForever,
2959 SleepForever,
2960 SleepForever,
2961 SleepForever,
2962 SleepForever,
2963 SleepForever,
2964 SleepForever,
2965 SleepForever,
2966 SleepForever,
2967 SleepForever,
2968 SleepForever,
2969 SleepForever,
2970 SleepForever,
2971 SleepForever,
2972 SleepForever,
2973 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};
3019
3020const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3021 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3022}
3023
Elliott Hughesc8fece32013-01-02 11:27:23 -08003024void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003025 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003026 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003027 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003028 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3029 }
3030 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3031}
3032
Ian Rogersdf20fe02011-07-20 20:34:16 -07003033} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003034
3035std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3036 switch (rhs) {
3037 case JNIInvalidRefType:
3038 os << "JNIInvalidRefType";
3039 return os;
3040 case JNILocalRefType:
3041 os << "JNILocalRefType";
3042 return os;
3043 case JNIGlobalRefType:
3044 os << "JNIGlobalRefType";
3045 return os;
3046 case JNIWeakGlobalRefType:
3047 os << "JNIWeakGlobalRefType";
3048 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003049 default:
Andreas Gampe3fec9ac2016-09-13 10:47:28 -07003050 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Ian Rogersc7dd2952014-10-21 23:31:19 -07003051 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003052 }
3053}