blob: d9cb1c66a4c81f76bb3e848c1fdacf7f5b45d557 [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_) {
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200103 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
104 << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
105 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000106 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200107 "%s is null at index %d", kind, idx);
108}
109
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800110static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700111 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800112 if (LIKELY(klass->IsInitialized())) {
113 return klass;
114 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700115 StackHandleScope<1> hs(self);
116 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700117 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800118 return nullptr;
119 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700120 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800121}
122
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700123static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
124 const char* name, const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700125 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800126 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800127 if (c == nullptr) {
128 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700129 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700130 ArtMethod* method = nullptr;
131 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700132 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700133 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700134 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700135 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700136 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700137 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800138 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700139 // No virtual method matching the signature. Search declared
140 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700141 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700142 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700143 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800144 if (method == nullptr || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700145 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800146 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700147 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700148 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700149}
150
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800151static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700152 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700153 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700154 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
155 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700156 return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700157 }
Brian Carlstromce888532013-10-10 00:32:58 -0700158 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800159 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700160 return method->GetDeclaringClass()->GetClassLoader();
161 }
162 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800163 mirror::ClassLoader* class_loader =
164 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
165 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700166 return class_loader;
167 }
168 // See if the override ClassLoader is set for gtests.
Ian Rogers68d8b422014-07-17 11:09:10 -0700169 class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800170 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700171 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
172 // image.
173 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700174 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700175 return class_loader;
176 }
177 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800178 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700179}
180
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700181static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
182 const char* sig, bool is_static)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700183 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700184 StackHandleScope<2> hs(soa.Self());
185 Handle<mirror::Class> c(
186 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
187 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800188 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700189 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700190 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800191 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700192 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
193 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700194 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800195 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700196 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700197 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700198 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800199 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700200 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700201 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800202 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000203 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700204 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700205 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000206 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800207 "no type \"%s\" found and so no field \"%s\" "
208 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700209 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000210 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800211 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700212 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700213 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700214 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700215 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700216 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700217 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700218 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700219 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800220 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000221 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800222 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700223 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800224 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700225 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700226 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700227}
228
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800229static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700230 jsize length, const char* identifier)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700231 REQUIRES_SHARED(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700232 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000233 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800234 "%s offset=%d length=%d %s.length=%d",
235 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700236}
Ian Rogers0571d352011-11-03 19:51:38 -0700237
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700238static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
239 jsize array_length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700240 REQUIRES_SHARED(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000241 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800242 "offset=%d length=%d string.length()=%d", start, length,
243 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700244}
Elliott Hughes814e4032011-08-23 12:07:56 -0700245
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700246int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700247 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700248 // Turn the const char* into a java.lang.String.
249 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800250 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700251 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700252 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700253
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700254 // Choose an appropriate constructor and set up the arguments.
255 jvalue args[2];
256 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800257 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700258 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800259 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700260 signature = "(Ljava/lang/String;)V";
261 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800262 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700263 signature = "(Ljava/lang/Throwable;)V";
264 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700265 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
267 args[0].l = s.get();
268 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700269 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700270 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800271 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800272 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700273 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800274 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700275 return JNI_ERR;
276 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700277
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800278 ScopedLocalRef<jthrowable> exception(
279 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
280 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 return JNI_ERR;
282 }
Ian Rogersef28b142012-11-30 14:22:18 -0800283 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000284 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700285 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700286}
287
Ian Rogers68d8b422014-07-17 11:09:10 -0700288static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
289 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700290}
291
Ian Rogers2d10b202014-05-12 19:15:18 -0700292#define CHECK_NON_NULL_ARGUMENT(value) \
293 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700294
Ian Rogers2d10b202014-05-12 19:15:18 -0700295#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
296 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
297
298#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
299 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
300
301#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
302 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
303
304#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700305 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700306 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700307 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700308 }
309
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700310#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700311 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700312 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700313 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700314 }
315
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700316template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700317static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700318 REQUIRES_SHARED(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700319 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800320 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700321 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
322 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700323 }
324 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700325 return nullptr;
326}
327
Elliott Hughescdf53122011-08-19 15:46:09 -0700328class JNI {
329 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700330 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700331 return JNI_VERSION_1_6;
332 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700333
Ian Rogers25e8b912012-09-07 11:31:36 -0700334 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700335 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800336 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700337 }
338
Elliott Hughescdf53122011-08-19 15:46:09 -0700339 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700340 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700341 Runtime* runtime = Runtime::Current();
342 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700343 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700344 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800345 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700346 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700347 StackHandleScope<1> hs(soa.Self());
348 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800349 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700350 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800351 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700352 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700353 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700354 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700355
Ian Rogers62f05122014-03-21 11:21:29 -0700356 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700357 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700358 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700359 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700360 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700361
Ian Rogers62f05122014-03-21 11:21:29 -0700362 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700363 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700364 ScopedObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700365 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
366 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700367 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700368 return nullptr;
369 }
370 auto* field = static_cast<mirror::Field*>(obj_field);
371 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700372 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700373
Elliott Hughescdf53122011-08-19 15:46:09 -0700374 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700375 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700376 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700377 ArtMethod* m = soa.DecodeMethod(mid);
Neil Fuller0e844392016-09-08 13:43:31 +0100378 mirror::Executable* method;
Andreas Gampe542451c2016-07-26 09:02:02 -0700379 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
Andreas Gampee01e3642016-07-25 13:06:04 -0700380 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200381 if (m->IsConstructor()) {
Andreas Gampe542451c2016-07-26 09:02:02 -0700382 method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200383 } else {
Andreas Gampe542451c2016-07-26 09:02:02 -0700384 method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200385 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700386 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700387 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700388
Elliott Hughescdf53122011-08-19 15:46:09 -0700389 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700390 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700391 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700392 ArtField* f = soa.DecodeField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700393 return soa.AddLocalReference<jobject>(
Andreas Gampe542451c2016-07-26 09:02:02 -0700394 mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700395 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700396
Elliott Hughes37f7a402011-08-22 18:56:01 -0700397 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700398 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700399 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800400 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700401 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700402 }
403
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700404 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700405 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700406 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800407 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700408 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700409 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700410
Narayan Kamath1268b742014-07-11 19:15:11 +0100411 // Note: java_class1 should be safely castable to java_class2, and
412 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700413 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700414 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
415 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700416 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800417 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
418 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100419 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700420 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700421
Elliott Hughese84278b2012-03-22 10:06:53 -0700422 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700423 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800424 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700425 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700426 return JNI_TRUE;
427 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700428 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800429 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
430 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700431 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700432 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700433 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700434
Elliott Hughes37f7a402011-08-22 18:56:01 -0700435 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700436 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800437 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
438 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700439 return JNI_ERR;
440 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000441 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700442 return JNI_OK;
443 }
444
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700445 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700446 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800447 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700448 }
449
450 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700451 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700452 }
453
454 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700455 ScopedObjectAccess soa(env);
456 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700457 }
458
459 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700460 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700461
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700462 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000463 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700464 return;
465 }
466
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000467 StackHandleScope<1> hs(soa.Self());
468 Handle<mirror::Throwable> old_exception(
469 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
470 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800471 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700472 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700473 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
474 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800475 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700476 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700477 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700478 } else {
479 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800480 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000481 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700482 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800483 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700484 }
485 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000486 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700487 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700488
Elliott Hughescdf53122011-08-19 15:46:09 -0700489 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700490 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000491 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700492 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700493 }
494
Ian Rogers25e8b912012-09-07 11:31:36 -0700495 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700496 LOG(FATAL) << "JNI FatalError called: " << msg;
497 }
498
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700499 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700500 // TODO: SOA may not be necessary but I do it to please lock annotations.
501 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700502 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700503 return JNI_ERR;
504 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700505 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700506 return JNI_OK;
507 }
508
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700509 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700510 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800511 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700512 soa.Env()->PopFrame();
513 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700514 }
515
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700516 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700517 // TODO: SOA may not be necessary but I do it to please lock annotations.
518 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700519 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700520 }
521
Elliott Hughescdf53122011-08-19 15:46:09 -0700522 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700523 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800524 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Ian Rogers68d8b422014-07-17 11:09:10 -0700525 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700526 }
527
528 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700529 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
530 Thread* self = down_cast<JNIEnvExt*>(env)->self;
531 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700532 }
533
534 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700535 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700536 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
537 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700538 }
539
540 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700541 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
542 Thread* self = down_cast<JNIEnvExt*>(env)->self;
543 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700544 }
545
546 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700547 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800548 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800549 // Check for null after decoding the object to handle cleared weak globals.
550 if (decoded_obj == nullptr) {
551 return nullptr;
552 }
553 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700554 }
555
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700556 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800557 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700558 return;
559 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700560 // SOA is only necessary to have exclusion between GC root marking and removing.
561 // We don't want to have the GC attempt to mark a null root if we just removed
562 // it. b/22119403
563 ScopedObjectAccess soa(env);
564 auto* ext_env = down_cast<JNIEnvExt*>(env);
565 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700566 // Attempting to delete a local reference that is not in the
567 // topmost local reference frame is a no-op. DeleteLocalRef returns
568 // void and doesn't throw any exceptions, but we should probably
569 // complain about it so the user will notice that things aren't
570 // going quite the way they expect.
571 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
572 << "failed to find entry";
573 }
574 }
575
576 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700577 if (obj1 == obj2) {
578 return JNI_TRUE;
579 } else {
580 ScopedObjectAccess soa(env);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800581 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
582 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700583 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700584 }
585
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700586 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700587 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700588 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800589 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800590 if (c == nullptr) {
591 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700592 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800593 if (c->IsStringClass()) {
594 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700595 return soa.AddLocalReference<jobject>(mirror::String::AllocEmptyString<true>(soa.Self(),
596 allocator_type));
Jeff Hao848f70a2014-01-15 13:49:50 -0800597 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700598 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700599 }
600
Ian Rogersbc939662013-08-15 10:26:54 -0700601 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700602 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700603 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700604 CHECK_NON_NULL_ARGUMENT(java_class);
605 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700606 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700607 va_end(args);
608 return result;
609 }
610
Elliott Hughes72025e52011-08-23 17:50:30 -0700611 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700612 CHECK_NON_NULL_ARGUMENT(java_class);
613 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700614 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800615 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800616 if (c == nullptr) {
617 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700618 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800619 if (c->IsStringClass()) {
620 // Replace calls to String.<init> with equivalent StringFactory call.
621 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
622 return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
623 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800624 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800625 if (result == nullptr) {
626 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700627 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700628 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700629 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800630 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800631 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700632 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800633 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700634 }
635
Elliott Hughes72025e52011-08-23 17:50:30 -0700636 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700637 CHECK_NON_NULL_ARGUMENT(java_class);
638 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700639 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800640 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800641 if (c == nullptr) {
642 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700643 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800644 if (c->IsStringClass()) {
645 // Replace calls to String.<init> with equivalent StringFactory call.
646 jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
647 return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
648 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800649 mirror::Object* result = c->AllocObject(soa.Self());
650 if (result == nullptr) {
651 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700652 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700653 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700654 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800655 if (soa.Self()->IsExceptionPending()) {
656 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700657 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800658 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700659 }
660
Ian Rogersbc939662013-08-15 10:26:54 -0700661 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700662 CHECK_NON_NULL_ARGUMENT(java_class);
663 CHECK_NON_NULL_ARGUMENT(name);
664 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700665 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700666 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700667 }
668
Ian Rogersbc939662013-08-15 10:26:54 -0700669 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
670 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700671 CHECK_NON_NULL_ARGUMENT(java_class);
672 CHECK_NON_NULL_ARGUMENT(name);
673 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700674 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700675 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700676 }
677
Elliott Hughes72025e52011-08-23 17:50:30 -0700678 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700679 va_list ap;
680 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700681 CHECK_NON_NULL_ARGUMENT(obj);
682 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700683 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700684 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700685 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700686 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700687 }
688
Elliott Hughes72025e52011-08-23 17:50:30 -0700689 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700690 CHECK_NON_NULL_ARGUMENT(obj);
691 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700692 ScopedObjectAccess soa(env);
693 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
694 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700695 }
696
Elliott Hughes72025e52011-08-23 17:50:30 -0700697 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700698 CHECK_NON_NULL_ARGUMENT(obj);
699 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700700 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700701 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700702 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700703 }
704
Elliott Hughes72025e52011-08-23 17:50:30 -0700705 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700706 va_list ap;
707 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700708 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
709 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700710 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700711 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700712 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700713 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700714 }
715
Elliott Hughes72025e52011-08-23 17:50:30 -0700716 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700717 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
718 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700719 ScopedObjectAccess soa(env);
720 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700721 }
722
Elliott Hughes72025e52011-08-23 17:50:30 -0700723 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700724 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
725 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700726 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700727 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700728 }
729
Elliott Hughes72025e52011-08-23 17:50:30 -0700730 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700731 va_list ap;
732 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700733 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700735 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700736 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700737 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700738 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700739 }
740
Elliott Hughes72025e52011-08-23 17:50:30 -0700741 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700742 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
743 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700744 ScopedObjectAccess soa(env);
745 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700746 }
747
Elliott Hughes72025e52011-08-23 17:50:30 -0700748 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700749 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
750 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700751 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700752 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700753 }
754
Elliott Hughes72025e52011-08-23 17:50:30 -0700755 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700756 va_list ap;
757 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700758 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
759 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700760 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700761 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700762 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700763 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700764 }
765
Elliott Hughes72025e52011-08-23 17:50:30 -0700766 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700767 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
768 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700769 ScopedObjectAccess soa(env);
770 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700771 }
772
Elliott Hughes72025e52011-08-23 17:50:30 -0700773 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700774 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
775 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700776 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700777 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -0700778 }
779
Elliott Hughes72025e52011-08-23 17:50:30 -0700780 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700781 va_list ap;
782 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700783 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700785 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700786 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700787 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700788 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700789 }
790
Elliott Hughes72025e52011-08-23 17:50:30 -0700791 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700792 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
793 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700794 ScopedObjectAccess soa(env);
795 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700796 }
797
Elliott Hughes72025e52011-08-23 17:50:30 -0700798 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700799 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
800 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700801 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700802 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -0700803 }
804
Elliott Hughes72025e52011-08-23 17:50:30 -0700805 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700806 va_list ap;
807 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700808 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
809 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700810 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700811 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700812 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700813 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700814 }
815
Elliott Hughes72025e52011-08-23 17:50:30 -0700816 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700817 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
818 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700819 ScopedObjectAccess soa(env);
820 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700821 }
822
Elliott Hughes72025e52011-08-23 17:50:30 -0700823 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700824 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
825 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700826 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700827 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -0700828 }
829
Elliott Hughes72025e52011-08-23 17:50:30 -0700830 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700831 va_list ap;
832 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700833 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
834 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700835 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700836 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700837 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700838 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700839 }
840
Elliott Hughes72025e52011-08-23 17:50:30 -0700841 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700842 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
843 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700844 ScopedObjectAccess soa(env);
845 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700846 }
847
Elliott Hughes72025e52011-08-23 17:50:30 -0700848 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700849 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
850 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700851 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700852 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -0700853 }
854
Elliott Hughes72025e52011-08-23 17:50:30 -0700855 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700856 va_list ap;
857 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700858 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
859 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700860 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700861 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700862 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700863 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700864 }
865
Elliott Hughes72025e52011-08-23 17:50:30 -0700866 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700867 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
868 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700869 ScopedObjectAccess soa(env);
870 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700871 }
872
Elliott Hughes72025e52011-08-23 17:50:30 -0700873 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700874 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
875 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700876 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700877 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700878 }
879
Elliott Hughes72025e52011-08-23 17:50:30 -0700880 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700881 va_list ap;
882 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700883 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
884 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700885 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700886 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700887 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700888 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700889 }
890
Elliott Hughes72025e52011-08-23 17:50:30 -0700891 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700892 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
893 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700894 ScopedObjectAccess soa(env);
895 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700896 }
897
Elliott Hughes72025e52011-08-23 17:50:30 -0700898 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700899 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
900 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700901 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700902 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -0700903 }
904
Elliott Hughes72025e52011-08-23 17:50:30 -0700905 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700906 va_list ap;
907 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700908 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
909 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700910 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -0700911 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -0700912 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -0700913 }
914
Elliott Hughes72025e52011-08-23 17:50:30 -0700915 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700916 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
917 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700918 ScopedObjectAccess soa(env);
919 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700920 }
921
Elliott Hughes72025e52011-08-23 17:50:30 -0700922 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700923 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
924 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700925 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700926 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700927 }
928
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700929 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700930 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700931 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700932 CHECK_NON_NULL_ARGUMENT(obj);
933 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700934 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700935 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
936 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700937 va_end(ap);
938 return local_result;
939 }
940
Ian Rogersbc939662013-08-15 10:26:54 -0700941 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
942 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700943 CHECK_NON_NULL_ARGUMENT(obj);
944 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700945 ScopedObjectAccess soa(env);
946 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
947 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700948 }
949
Ian Rogersbc939662013-08-15 10:26:54 -0700950 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
951 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700952 CHECK_NON_NULL_ARGUMENT(obj);
953 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700954 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700955 JValue result(InvokeWithJValues(soa, obj, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700956 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700957 }
958
Ian Rogersbc939662013-08-15 10:26:54 -0700959 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
960 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700961 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700962 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700963 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
964 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700965 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700966 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700967 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700968 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700969 }
970
Ian Rogersbc939662013-08-15 10:26:54 -0700971 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
972 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700973 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
974 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700975 ScopedObjectAccess soa(env);
976 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700977 }
978
Ian Rogersbc939662013-08-15 10:26:54 -0700979 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
980 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700981 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
982 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700983 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -0700984 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -0700985 }
986
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700987 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700988 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -0700989 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700990 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
991 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700992 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700993 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -0700994 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -0700995 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -0700996 }
997
Ian Rogersbc939662013-08-15 10:26:54 -0700998 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
999 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001000 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1001 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001002 ScopedObjectAccess soa(env);
1003 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001004 }
1005
Ian Rogersbc939662013-08-15 10:26:54 -07001006 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1007 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001008 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1009 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001010 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001011 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001012 }
1013
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001014 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001015 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001016 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001017 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1018 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001019 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001020 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001021 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001022 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001023 }
1024
Ian Rogersbc939662013-08-15 10:26:54 -07001025 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1026 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001027 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1028 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001029 ScopedObjectAccess soa(env);
1030 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001031 }
1032
Ian Rogersbc939662013-08-15 10:26:54 -07001033 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1034 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001035 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1036 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001037 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001038 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001039 }
1040
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001041 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001042 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001043 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001044 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1045 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001046 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001047 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001048 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001049 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001050 }
1051
Ian Rogersbc939662013-08-15 10:26:54 -07001052 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1053 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001054 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1055 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001056 ScopedObjectAccess soa(env);
1057 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001058 }
1059
Ian Rogersbc939662013-08-15 10:26:54 -07001060 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1061 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001062 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1063 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001064 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001065 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001066 }
1067
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001068 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001069 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001070 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001071 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1072 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001073 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001074 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001075 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001076 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001077 }
1078
Ian Rogersbc939662013-08-15 10:26:54 -07001079 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1080 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001081 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1082 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001083 ScopedObjectAccess soa(env);
1084 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001085 }
1086
Ian Rogersbc939662013-08-15 10:26:54 -07001087 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1088 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001089 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1090 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001091 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001092 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001093 }
1094
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001095 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001096 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001097 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001098 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1099 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001100 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001101 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001102 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001103 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001104 }
1105
Ian Rogersbc939662013-08-15 10:26:54 -07001106 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1107 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001108 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1109 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001110 ScopedObjectAccess soa(env);
1111 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001112 }
1113
Ian Rogersbc939662013-08-15 10:26:54 -07001114 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1115 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001116 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1117 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001118 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001119 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001120 }
1121
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001122 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001123 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001124 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001125 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1126 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001127 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001128 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001129 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001130 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001131 }
1132
Ian Rogersbc939662013-08-15 10:26:54 -07001133 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1134 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001135 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1136 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001137 ScopedObjectAccess soa(env);
1138 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001139 }
1140
Ian Rogersbc939662013-08-15 10:26:54 -07001141 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1142 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001143 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1144 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001145 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001146 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001147 }
1148
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001149 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001150 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001151 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001152 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1153 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001154 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001155 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001156 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001157 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001158 }
1159
Ian Rogersbc939662013-08-15 10:26:54 -07001160 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1161 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001162 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1163 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001164 ScopedObjectAccess soa(env);
1165 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001166 }
1167
Ian Rogersbc939662013-08-15 10:26:54 -07001168 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1169 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001170 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1171 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001172 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001173 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001174 }
1175
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001176 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001177 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001178 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001179 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1180 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001181 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001182 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001183 va_end(ap);
1184 }
1185
Brian Carlstromea46f952013-07-30 01:26:50 -07001186 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1187 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001188 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1189 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001190 ScopedObjectAccess soa(env);
1191 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001192 }
1193
Ian Rogersbc939662013-08-15 10:26:54 -07001194 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1195 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001196 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1197 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001198 ScopedObjectAccess soa(env);
Jeff Hao39b6c242015-05-19 20:30:23 -07001199 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001200 }
1201
Ian Rogersbc939662013-08-15 10:26:54 -07001202 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001203 CHECK_NON_NULL_ARGUMENT(java_class);
1204 CHECK_NON_NULL_ARGUMENT(name);
1205 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001206 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001207 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001208 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001209
Ian Rogersbc939662013-08-15 10:26:54 -07001210 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1211 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001212 CHECK_NON_NULL_ARGUMENT(java_class);
1213 CHECK_NON_NULL_ARGUMENT(name);
1214 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001215 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001216 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001217 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001218
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001219 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001220 CHECK_NON_NULL_ARGUMENT(obj);
1221 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001222 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001223 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001224 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001225 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001226 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001227
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001228 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001229 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001230 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001231 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001232 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001233 }
1234
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001235 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001236 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1237 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001238 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001239 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1240 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001241 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001242 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001243 }
1244
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001245 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001246 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001247 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001248 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
Mathieu Chartierc7853442015-03-27 14:35:38 -07001249 ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001250 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001251 }
1252
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001253#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001254 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1255 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001256 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001257 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001258 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001259 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001260
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001261#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001262 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001263 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001264 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001265 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001266
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001267#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001268 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1269 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001270 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001271 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001272 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001273 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001274
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001275#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001276 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001277 ScopedObjectAccess soa(env); \
Mathieu Chartierc7853442015-03-27 14:35:38 -07001278 ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001279 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001280
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001281 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001282 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001283 }
1284
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001285 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001286 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001287 }
1288
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001289 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001290 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001291 }
1292
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001293 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001294 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001295 }
1296
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001297 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001298 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001299 }
1300
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001301 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001302 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001303 }
1304
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001305 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001306 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001307 }
1308
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001309 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001310 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001311 }
1312
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001313 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001314 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001315 }
1316
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001317 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001318 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001319 }
1320
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001321 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001322 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001323 }
1324
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001325 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001326 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001327 }
1328
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001329 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001330 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001331 }
1332
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001333 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001334 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001335 }
1336
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001337 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001338 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001339 }
1340
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001341 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001342 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001343 }
1344
1345 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001346 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001347 }
1348
1349 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001350 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001351 }
1352
1353 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001354 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001355 }
1356
1357 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001358 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001359 }
1360
1361 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001362 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001363 }
1364
1365 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001366 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001367 }
1368
1369 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001370 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001371 }
1372
1373 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001374 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001375 }
1376
1377 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001378 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001379 }
1380
1381 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001382 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001383 }
1384
1385 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001386 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001387 }
1388
1389 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001390 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001391 }
1392
1393 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001394 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001395 }
1396
1397 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001398 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001399 }
1400
1401 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001402 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001403 }
1404
1405 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001406 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001407 }
1408
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001409 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001410 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001411 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001412 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001413 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001414 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001415 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001416 va_end(ap);
1417 return local_result;
1418 }
1419
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001420 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001421 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001422 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001423 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001424 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001425 }
1426
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001427 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001428 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001429 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001430 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001431 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001432 }
1433
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001434 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001435 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001436 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001437 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001438 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001439 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001440 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001441 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001442 }
1443
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001444 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001445 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001446 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001447 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001448 }
1449
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001450 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001451 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001452 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001453 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001454 }
1455
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001456 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001457 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001458 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001459 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001460 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001461 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001462 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001463 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001464 }
1465
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001466 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001467 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001468 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001469 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001470 }
1471
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001472 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001473 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001474 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001475 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001476 }
1477
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001478 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001479 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001480 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001481 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001482 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001483 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001484 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001485 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001486 }
1487
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001488 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001489 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001490 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001491 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001492 }
1493
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001494 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001495 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001496 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001497 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001498 }
1499
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001500 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001501 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001502 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001503 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001504 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001505 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001506 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001507 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001508 }
1509
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001510 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001511 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001512 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001513 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001514 }
1515
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001516 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001517 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001518 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001519 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001520 }
1521
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001522 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001523 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001524 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001525 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001526 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001527 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001528 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001529 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001530 }
1531
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001532 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001533 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001534 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001535 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001536 }
1537
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001538 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001539 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001540 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001541 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001542 }
1543
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001544 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001545 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001546 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001547 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001548 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001549 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001550 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001551 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001552 }
1553
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001554 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001555 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001556 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001557 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001558 }
1559
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001560 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001561 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001562 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001563 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001564 }
1565
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001566 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001567 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001568 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001569 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001570 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001571 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001572 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001573 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001574 }
1575
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001576 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001577 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001578 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001579 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001580 }
1581
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001582 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001583 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001584 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001585 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001586 }
1587
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001588 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001589 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001590 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001591 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001592 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001593 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001594 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001595 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001596 }
1597
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001598 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001599 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001600 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001601 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001602 }
1603
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001604 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001605 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001606 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001607 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001608 }
1609
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001610 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001611 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001612 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001613 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001614 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001615 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001616 va_end(ap);
1617 }
1618
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001619 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001620 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001621 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001622 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001623 }
1624
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001625 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001626 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001627 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001628 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001629 }
1630
Elliott Hughes814e4032011-08-23 12:07:56 -07001631 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001632 if (UNLIKELY(char_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001633 JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
Ian Rogers1d99e452014-01-02 17:36:41 -08001634 return nullptr;
1635 }
1636 if (UNLIKELY(chars == nullptr && char_count > 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001637 JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
Ian Rogers1d99e452014-01-02 17:36:41 -08001638 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001639 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001640 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001641 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001642 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001643 }
1644
1645 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001646 if (utf == nullptr) {
1647 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001648 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001649 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001650 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001651 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001652 }
1653
Elliott Hughes814e4032011-08-23 12:07:56 -07001654 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001655 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001656 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001657 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001658 }
1659
1660 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001661 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001662 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001663 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001664 }
1665
Ian Rogersbc939662013-08-15 10:26:54 -07001666 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1667 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001668 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001669 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001670 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001671 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001672 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001673 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001674 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001675 if (s->IsCompressed()) {
1676 for (int i = 0; i < length; ++i) {
1677 buf[i] = static_cast<jchar>(s->CharAt(start+i));
1678 }
1679 } else {
1680 const jchar* chars = static_cast<jchar*>(s->GetValue());
1681 memcpy(buf, chars + start, length * sizeof(jchar));
1682 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001683 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001684 }
1685
Ian Rogersbc939662013-08-15 10:26:54 -07001686 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1687 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001688 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001689 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001690 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001691 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001692 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001693 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001694 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001695 if (s->IsCompressed()) {
1696 for (int i = 0; i < length; ++i) {
1697 buf[i] = s->CharAt(start+i);
1698 }
1699 } else {
1700 const jchar* chars = s->GetValue();
1701 size_t bytes = CountUtf8Bytes(chars + start, length);
1702 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
1703 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07001704 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001705 }
1706
Elliott Hughes75770752011-08-24 17:52:38 -07001707 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001708 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001709 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001710 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001711 gc::Heap* heap = Runtime::Current()->GetHeap();
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001712 if (heap->IsMovableObject(s) || s->IsCompressed()) {
Jeff Hao848f70a2014-01-15 13:49:50 -08001713 jchar* chars = new jchar[s->GetLength()];
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001714 if (s->IsCompressed()) {
1715 int32_t length = s->GetLength();
1716 for (int i = 0; i < length; ++i) {
1717 chars[i] = s->CharAt(i);
1718 }
1719 } else {
1720 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1721 }
Fred Shih56890e22014-06-02 11:11:52 -07001722 if (is_copy != nullptr) {
1723 *is_copy = JNI_TRUE;
1724 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001725 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001726 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001727 if (is_copy != nullptr) {
1728 *is_copy = JNI_FALSE;
1729 }
1730 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001731 }
1732
Mathieu Chartier590fee92013-09-13 13:46:47 -07001733 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001734 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001735 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001736 mirror::String* s = soa.Decode<mirror::String*>(java_string);
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001737 if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
Fred Shih56890e22014-06-02 11:11:52 -07001738 delete[] chars;
1739 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001740 }
1741
Elliott Hughes75770752011-08-24 17:52:38 -07001742 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001743 CHECK_NON_NULL_ARGUMENT(java_string);
1744 ScopedObjectAccess soa(env);
1745 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001746 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001747 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001748 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001749 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001750 if (!kUseReadBarrier) {
1751 heap->IncrementDisableMovingGC(soa.Self());
1752 } else {
1753 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1754 // to occur thanks to the to-space invariant.
1755 heap->IncrementDisableThreadFlip(soa.Self());
1756 }
Fred Shih56890e22014-06-02 11:11:52 -07001757 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001758 if (s->IsCompressed()) {
1759 if (is_copy != nullptr) {
1760 *is_copy = JNI_TRUE;
1761 }
1762 int32_t length = s->GetLength();
1763 jchar* chars = new jchar[length];
1764 for (int i = 0; i < length; ++i) {
1765 chars[i] = s->CharAt(i);
1766 }
1767 return chars;
1768 } else {
1769 if (is_copy != nullptr) {
1770 *is_copy = JNI_FALSE;
1771 }
1772 return static_cast<jchar*>(s->GetValue());
Fred Shih56890e22014-06-02 11:11:52 -07001773 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001774 }
1775
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001776 static void ReleaseStringCritical(JNIEnv* env,
1777 jstring java_string,
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001778 const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07001779 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1780 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001781 gc::Heap* heap = Runtime::Current()->GetHeap();
1782 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001783 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001784 if (!kUseReadBarrier) {
1785 heap->DecrementDisableMovingGC(soa.Self());
1786 } else {
1787 heap->DecrementDisableThreadFlip(soa.Self());
1788 }
Fred Shih56890e22014-06-02 11:11:52 -07001789 }
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001790 if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
1791 delete[] chars;
1792 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001793 }
1794
Elliott Hughes75770752011-08-24 17:52:38 -07001795 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001796 if (java_string == nullptr) {
1797 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001798 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001799 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001800 *is_copy = JNI_TRUE;
1801 }
Ian Rogersef28b142012-11-30 14:22:18 -08001802 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001803 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001804 size_t byte_count = s->GetUtfLength();
1805 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001806 CHECK(bytes != nullptr); // bionic aborts anyway.
jessicahandojo3aaa37b2016-07-29 14:46:37 -07001807 if (s->IsCompressed()) {
1808 for (size_t i = 0; i < byte_count; ++i) {
1809 bytes[i] = s->CharAt(i);
1810 }
1811 } else {
1812 const uint16_t* chars = s->GetValue();
1813 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
1814 }
Elliott Hughes75770752011-08-24 17:52:38 -07001815 bytes[byte_count] = '\0';
1816 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001817 }
1818
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001819 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001820 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001821 }
1822
Elliott Hughesbd935992011-08-22 11:59:34 -07001823 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001824 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001825 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001826 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001827 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001828 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1829 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001830 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001831 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001832 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001833 }
1834
Elliott Hughes814e4032011-08-23 12:07:56 -07001835 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001836 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001837 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001838 mirror::ObjectArray<mirror::Object>* array =
1839 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001840 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001841 }
1842
Ian Rogersbc939662013-08-15 10:26:54 -07001843 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1844 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001845 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001846 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001847 mirror::ObjectArray<mirror::Object>* array =
1848 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1849 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001850 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001851 }
1852
1853 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001854 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001855 }
1856
1857 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001858 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001859 }
1860
1861 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001862 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001863 }
1864
1865 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001866 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001867 }
1868
1869 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001870 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001871 }
1872
1873 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001874 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001875 }
1876
1877 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001878 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001879 }
1880
Ian Rogers1d99e452014-01-02 17:36:41 -08001881 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1882 jobject initial_element) {
1883 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001884 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001885 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001886 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001887 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001888
1889 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001890 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001891 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001892 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001893 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001894 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001895 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1896 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001897 return nullptr;
1898 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001899 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001900 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001901 if (UNLIKELY(array_class == nullptr)) {
1902 return nullptr;
1903 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001904 }
1905
Elliott Hughes75770752011-08-24 17:52:38 -07001906 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001907 mirror::ObjectArray<mirror::Object>* result =
1908 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001909 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001910 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001911 if (initial_object != nullptr) {
1912 mirror::Class* element_class = result->GetClass()->GetComponentType();
1913 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001914 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1915 "element type of '%s'",
1916 PrettyDescriptor(initial_object->GetClass()).c_str(),
1917 PrettyDescriptor(element_class).c_str());
1918 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001919 } else {
1920 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001921 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001922 }
1923 }
Elliott Hughes75770752011-08-24 17:52:38 -07001924 }
1925 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001926 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001927 }
1928
1929 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001930 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001931 }
1932
Ian Rogersa15e67d2012-02-28 13:51:55 -08001933 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001934 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001935 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001936 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001937 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001938 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1939 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001940 return nullptr;
1941 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001942 gc::Heap* heap = Runtime::Current()->GetHeap();
1943 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001944 if (!kUseReadBarrier) {
1945 heap->IncrementDisableMovingGC(soa.Self());
1946 } else {
1947 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1948 // to occur thanks to the to-space invariant.
1949 heap->IncrementDisableThreadFlip(soa.Self());
1950 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001951 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001952 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001953 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001954 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001955 *is_copy = JNI_FALSE;
1956 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001957 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001958 }
1959
Ian Rogers2d10b202014-05-12 19:15:18 -07001960 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1961 jint mode) {
1962 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1963 ScopedObjectAccess soa(env);
1964 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1965 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001966 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1967 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001968 return;
1969 }
1970 const size_t component_size = array->GetClass()->GetComponentSize();
1971 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001972 }
1973
Elliott Hughes75770752011-08-24 17:52:38 -07001974 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001975 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001976 }
1977
Elliott Hughes75770752011-08-24 17:52:38 -07001978 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001979 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001980 }
1981
Elliott Hughes75770752011-08-24 17:52:38 -07001982 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001983 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001984 }
1985
Elliott Hughes75770752011-08-24 17:52:38 -07001986 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001987 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001988 }
1989
Elliott Hughes75770752011-08-24 17:52:38 -07001990 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001991 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001992 }
1993
Elliott Hughes75770752011-08-24 17:52:38 -07001994 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001995 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001996 }
1997
Elliott Hughes75770752011-08-24 17:52:38 -07001998 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001999 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002000 }
2001
Elliott Hughes75770752011-08-24 17:52:38 -07002002 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002003 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002004 }
2005
Mathieu Chartier590fee92013-09-13 13:46:47 -07002006 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2007 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002008 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2009 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002010 }
2011
Mathieu Chartier590fee92013-09-13 13:46:47 -07002012 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002013 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002014 }
2015
Mathieu Chartier590fee92013-09-13 13:46:47 -07002016 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002017 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002018 }
2019
Mathieu Chartier590fee92013-09-13 13:46:47 -07002020 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2021 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002022 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002023 }
2024
Mathieu Chartier590fee92013-09-13 13:46:47 -07002025 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2026 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002027 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002028 }
2029
Mathieu Chartier590fee92013-09-13 13:46:47 -07002030 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002031 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002032 }
2033
Mathieu Chartier590fee92013-09-13 13:46:47 -07002034 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002035 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002036 }
2037
Mathieu Chartier590fee92013-09-13 13:46:47 -07002038 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2039 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002040 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002041 }
2042
Ian Rogersbc939662013-08-15 10:26:54 -07002043 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2044 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002045 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002046 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002047 }
2048
Ian Rogersbc939662013-08-15 10:26:54 -07002049 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2050 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002051 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002052 }
2053
Ian Rogersbc939662013-08-15 10:26:54 -07002054 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2055 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002056 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002057 }
2058
Ian Rogersbc939662013-08-15 10:26:54 -07002059 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2060 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002061 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002062 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002063 }
2064
Ian Rogersbc939662013-08-15 10:26:54 -07002065 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2066 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002067 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002068 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002069 }
2070
Ian Rogersbc939662013-08-15 10:26:54 -07002071 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2072 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002073 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002074 }
2075
Ian Rogersbc939662013-08-15 10:26:54 -07002076 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2077 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002078 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002079 }
2080
Ian Rogersbc939662013-08-15 10:26:54 -07002081 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2082 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002083 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002084 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002085 }
2086
Ian Rogersbc939662013-08-15 10:26:54 -07002087 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2088 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002089 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002090 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002091 }
2092
Ian Rogersbc939662013-08-15 10:26:54 -07002093 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2094 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002095 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002096 }
2097
Ian Rogersbc939662013-08-15 10:26:54 -07002098 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2099 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002100 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002101 }
2102
Ian Rogersbc939662013-08-15 10:26:54 -07002103 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2104 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002105 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002106 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002107 }
2108
Ian Rogersbc939662013-08-15 10:26:54 -07002109 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2110 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002111 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002112 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002113 }
2114
Ian Rogersbc939662013-08-15 10:26:54 -07002115 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2116 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002117 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002118 }
2119
Ian Rogersbc939662013-08-15 10:26:54 -07002120 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2121 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002122 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002123 }
2124
Ian Rogersbc939662013-08-15 10:26:54 -07002125 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2126 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002127 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002128 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002129 }
2130
Ian Rogersbc939662013-08-15 10:26:54 -07002131 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2132 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002133 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2134 }
2135
Ian Rogersbc939662013-08-15 10:26:54 -07002136 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2137 jint method_count, bool return_errors) {
2138 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002139 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2140 method_count);
2141 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002142 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002143 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002144 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002145 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002146 if (UNLIKELY(method_count == 0)) {
2147 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2148 << PrettyDescriptor(c);
2149 return JNI_OK;
2150 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002151 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002152 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002153 const char* name = methods[i].name;
2154 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002155 const void* fnPtr = methods[i].fnPtr;
2156 if (UNLIKELY(name == nullptr)) {
2157 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2158 return JNI_ERR;
2159 } else if (UNLIKELY(sig == nullptr)) {
2160 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2161 return JNI_ERR;
2162 } else if (UNLIKELY(fnPtr == nullptr)) {
2163 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2164 return JNI_ERR;
2165 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002166 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002167 // Notes about fast JNI calls:
2168 //
2169 // On a normal JNI call, the calling thread usually transitions
2170 // from the kRunnable state to the kNative state. But if the
2171 // called native function needs to access any Java object, it
2172 // will have to transition back to the kRunnable state.
2173 //
2174 // There is a cost to this double transition. For a JNI call
2175 // that should be quick, this cost may dominate the call cost.
2176 //
2177 // On a fast JNI call, the calling thread avoids this double
2178 // transition by not transitioning from kRunnable to kNative and
2179 // stays in the kRunnable state.
2180 //
2181 // There are risks to using a fast JNI call because it can delay
2182 // a response to a thread suspension request which is typically
2183 // used for a GC root scanning, etc. If a fast JNI call takes a
2184 // long time, it could cause longer thread suspension latency
2185 // and GC pauses.
2186 //
2187 // Thus, fast JNI should be used with care. It should be used
2188 // for a JNI call that takes a short amount of time (eg. no
2189 // long-running loop) and does not block (eg. no locks, I/O,
2190 // etc.)
2191 //
2192 // A '!' prefix in the signature in the JNINativeMethod
2193 // indicates that it's a fast JNI call and the runtime omits the
2194 // thread state transition from kRunnable to kNative at the
2195 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002196 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002197 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002198 ++sig;
2199 }
2200
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002201 // Note: the right order is to try to find the method locally
2202 // first, either as a direct or a virtual method. Then move to
2203 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002204 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002205 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2206 for (mirror::Class* current_class = c;
2207 current_class != nullptr;
2208 current_class = current_class->GetSuperClass()) {
2209 // Search first only comparing methods which are native.
2210 m = FindMethod<true>(current_class, name, sig);
2211 if (m != nullptr) {
2212 break;
2213 }
2214
2215 // Search again comparing to all methods, to find non-native methods that match.
2216 m = FindMethod<false>(current_class, name, sig);
2217 if (m != nullptr) {
2218 break;
2219 }
2220
2221 if (warn_on_going_to_parent) {
2222 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2223 << "This is slow, consider changing your RegisterNatives calls.";
2224 warn_on_going_to_parent = false;
2225 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002226 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002227
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002228 if (m == nullptr) {
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002229 LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002230 << PrettyDescriptor(c) << "." << name << sig << " in "
2231 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002232 // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2233 // out of scope after the DumpClass is done executing.
2234 c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002235 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002236 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002237 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002238 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002239 << PrettyDescriptor(c) << "." << name << sig
2240 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002241 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002242 return JNI_ERR;
2243 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002244
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002245 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002246
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002247 is_fast = is_fast || m->IsFastNative(); // Merge with @FastNative state.
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002248 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002249 }
2250 return JNI_OK;
2251 }
2252
Elliott Hughes5174fe62011-08-23 15:12:35 -07002253 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002254 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002255 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002256 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002257
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002258 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002259
Ian Rogers2d10b202014-05-12 19:15:18 -07002260 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002261 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002262 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002263 if (m.IsNative()) {
2264 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002265 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002266 }
2267 }
2268
Ian Rogers2d10b202014-05-12 19:15:18 -07002269 if (unregistered_count == 0) {
2270 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2271 << PrettyDescriptor(c) << "' that contains no native methods";
2272 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002273 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002274 }
2275
Ian Rogers719d1a32014-03-06 12:13:39 -08002276 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002277 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002278 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002279 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2280 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002281 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002282 return JNI_ERR;
2283 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002284 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002285 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002286 }
2287
Ian Rogers719d1a32014-03-06 12:13:39 -08002288 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002289 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002290 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002291 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002292 o->MonitorExit(soa.Self());
2293 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002294 return JNI_ERR;
2295 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002296 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002297 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002298 }
2299
2300 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002301 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002302 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002303 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002304 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002305 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002306 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002307 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002308 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002309 }
2310
Elliott Hughescdf53122011-08-19 15:46:09 -07002311 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002312 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002313 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2314 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002315 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002316 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002317 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002318 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2319 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002320 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002321 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002322
Brian Carlstrom85a93362014-06-25 09:30:52 -07002323 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002324 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002325 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2326 "buffer capacity greater than maximum jint: %" PRId64,
2327 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002328 return nullptr;
2329 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002330 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002331 jint capacity_arg = static_cast<jint>(capacity);
2332
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002333 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2334 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002335 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002336 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002337 }
2338
Elliott Hughesb465ab02011-08-24 11:21:21 -07002339 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002340 return reinterpret_cast<void*>(env->GetLongField(
2341 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002342 }
2343
Elliott Hughesb465ab02011-08-24 11:21:21 -07002344 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002345 return static_cast<jlong>(env->GetIntField(
2346 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002347 }
2348
Andreas Gampea8763072014-12-20 00:08:35 -08002349 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2350 if (java_object == nullptr) {
2351 return JNIInvalidRefType;
2352 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002353
2354 // Do we definitely know what kind of reference this is?
2355 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2356 IndirectRefKind kind = GetIndirectRefKind(ref);
2357 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002358 case kLocal:
2359 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002360 case kGlobal:
2361 return JNIGlobalRefType;
2362 case kWeakGlobal:
2363 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002364 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002365 // Assume value is in a handle scope.
2366 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002367 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002368 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002369 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002370 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002371
2372 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002373 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2374 const char* caller)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002375 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002376 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002377 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002378 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2379 return JNI_ERR;
2380 }
2381 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002382 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002383 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2384 if (!okay) {
2385 soa.Self()->ThrowOutOfMemoryError(caller);
2386 }
2387 return okay ? JNI_OK : JNI_ERR;
2388 }
2389
2390 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002391 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002392 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002393 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002394 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002395 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002396 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002397 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002398 return soa.AddLocalReference<JniT>(result);
2399 }
2400
Ian Rogers2d10b202014-05-12 19:15:18 -07002401 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2402 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2403 const char* fn_name, const char* operation)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002404 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002405 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002406 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002407 soa.Vm()->JniAbortF(fn_name,
2408 "attempt to %s %s primitive array elements with an object of type %s",
2409 operation,
2410 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2411 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002412 return nullptr;
2413 }
2414 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2415 return array;
2416 }
2417
2418 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2419 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2420 CHECK_NON_NULL_ARGUMENT(java_array);
2421 ScopedObjectAccess soa(env);
2422 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2423 "GetArrayElements",
2424 "get");
2425 if (UNLIKELY(array == nullptr)) {
2426 return nullptr;
2427 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002428 // Only make a copy if necessary.
2429 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2430 if (is_copy != nullptr) {
2431 *is_copy = JNI_TRUE;
2432 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002433 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002434 size_t size = array->GetLength() * component_size;
2435 void* data = new uint64_t[RoundUp(size, 8) / 8];
2436 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002437 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002438 } else {
2439 if (is_copy != nullptr) {
2440 *is_copy = JNI_FALSE;
2441 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002442 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002443 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002444 }
2445
Ian Rogers2d10b202014-05-12 19:15:18 -07002446 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002447 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002448 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002449 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002450 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2451 "ReleaseArrayElements",
2452 "release");
2453 if (array == nullptr) {
2454 return;
2455 }
2456 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2457 }
2458
2459 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2460 size_t component_size, void* elements, jint mode)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -07002461 REQUIRES_SHARED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002462 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002463 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002464 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002465 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002466 if (is_copy) {
2467 // Sanity check: If elements is not the same as the java array's data, it better not be a
2468 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2469 // copies we make?
2470 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002471 soa.Vm()->JniAbortF("ReleaseArrayElements",
2472 "invalid element pointer %p, array elements are %p",
2473 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002474 return;
2475 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002476 if (mode != JNI_ABORT) {
2477 memcpy(array_data, elements, bytes);
2478 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2479 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2480 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2481 soa.Self()->DumpJavaStack(LOG(WARNING));
2482 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002483 }
2484 if (mode != JNI_COMMIT) {
2485 if (is_copy) {
2486 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002487 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002488 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002489 if (!kUseReadBarrier) {
2490 heap->DecrementDisableMovingGC(soa.Self());
2491 } else {
2492 heap->DecrementDisableThreadFlip(soa.Self());
2493 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002494 }
2495 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002496 }
2497
Ian Rogers2d10b202014-05-12 19:15:18 -07002498 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2499 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2500 jsize start, jsize length, ElementT* buf) {
2501 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2502 ScopedObjectAccess soa(env);
2503 ArtArrayT* array =
2504 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2505 "GetPrimitiveArrayRegion",
2506 "get region of");
2507 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002508 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002509 ThrowAIOOBE(soa, array, start, length, "src");
2510 } else {
2511 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2512 ElementT* data = array->GetData();
2513 memcpy(buf, data + start, length * sizeof(ElementT));
2514 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002515 }
2516 }
2517
Ian Rogers2d10b202014-05-12 19:15:18 -07002518 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2519 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2520 jsize start, jsize length, const ElementT* buf) {
2521 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2522 ScopedObjectAccess soa(env);
2523 ArtArrayT* array =
2524 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2525 "SetPrimitiveArrayRegion",
2526 "set region of");
2527 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002528 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002529 ThrowAIOOBE(soa, array, start, length, "dst");
2530 } else {
2531 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2532 ElementT* data = array->GetData();
2533 memcpy(data + start, buf, length * sizeof(ElementT));
2534 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002535 }
2536 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002537};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002538
Elliott Hughes88c5c352012-03-15 18:49:48 -07002539const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002540 nullptr, // reserved0.
2541 nullptr, // reserved1.
2542 nullptr, // reserved2.
2543 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002544 JNI::GetVersion,
2545 JNI::DefineClass,
2546 JNI::FindClass,
2547 JNI::FromReflectedMethod,
2548 JNI::FromReflectedField,
2549 JNI::ToReflectedMethod,
2550 JNI::GetSuperclass,
2551 JNI::IsAssignableFrom,
2552 JNI::ToReflectedField,
2553 JNI::Throw,
2554 JNI::ThrowNew,
2555 JNI::ExceptionOccurred,
2556 JNI::ExceptionDescribe,
2557 JNI::ExceptionClear,
2558 JNI::FatalError,
2559 JNI::PushLocalFrame,
2560 JNI::PopLocalFrame,
2561 JNI::NewGlobalRef,
2562 JNI::DeleteGlobalRef,
2563 JNI::DeleteLocalRef,
2564 JNI::IsSameObject,
2565 JNI::NewLocalRef,
2566 JNI::EnsureLocalCapacity,
2567 JNI::AllocObject,
2568 JNI::NewObject,
2569 JNI::NewObjectV,
2570 JNI::NewObjectA,
2571 JNI::GetObjectClass,
2572 JNI::IsInstanceOf,
2573 JNI::GetMethodID,
2574 JNI::CallObjectMethod,
2575 JNI::CallObjectMethodV,
2576 JNI::CallObjectMethodA,
2577 JNI::CallBooleanMethod,
2578 JNI::CallBooleanMethodV,
2579 JNI::CallBooleanMethodA,
2580 JNI::CallByteMethod,
2581 JNI::CallByteMethodV,
2582 JNI::CallByteMethodA,
2583 JNI::CallCharMethod,
2584 JNI::CallCharMethodV,
2585 JNI::CallCharMethodA,
2586 JNI::CallShortMethod,
2587 JNI::CallShortMethodV,
2588 JNI::CallShortMethodA,
2589 JNI::CallIntMethod,
2590 JNI::CallIntMethodV,
2591 JNI::CallIntMethodA,
2592 JNI::CallLongMethod,
2593 JNI::CallLongMethodV,
2594 JNI::CallLongMethodA,
2595 JNI::CallFloatMethod,
2596 JNI::CallFloatMethodV,
2597 JNI::CallFloatMethodA,
2598 JNI::CallDoubleMethod,
2599 JNI::CallDoubleMethodV,
2600 JNI::CallDoubleMethodA,
2601 JNI::CallVoidMethod,
2602 JNI::CallVoidMethodV,
2603 JNI::CallVoidMethodA,
2604 JNI::CallNonvirtualObjectMethod,
2605 JNI::CallNonvirtualObjectMethodV,
2606 JNI::CallNonvirtualObjectMethodA,
2607 JNI::CallNonvirtualBooleanMethod,
2608 JNI::CallNonvirtualBooleanMethodV,
2609 JNI::CallNonvirtualBooleanMethodA,
2610 JNI::CallNonvirtualByteMethod,
2611 JNI::CallNonvirtualByteMethodV,
2612 JNI::CallNonvirtualByteMethodA,
2613 JNI::CallNonvirtualCharMethod,
2614 JNI::CallNonvirtualCharMethodV,
2615 JNI::CallNonvirtualCharMethodA,
2616 JNI::CallNonvirtualShortMethod,
2617 JNI::CallNonvirtualShortMethodV,
2618 JNI::CallNonvirtualShortMethodA,
2619 JNI::CallNonvirtualIntMethod,
2620 JNI::CallNonvirtualIntMethodV,
2621 JNI::CallNonvirtualIntMethodA,
2622 JNI::CallNonvirtualLongMethod,
2623 JNI::CallNonvirtualLongMethodV,
2624 JNI::CallNonvirtualLongMethodA,
2625 JNI::CallNonvirtualFloatMethod,
2626 JNI::CallNonvirtualFloatMethodV,
2627 JNI::CallNonvirtualFloatMethodA,
2628 JNI::CallNonvirtualDoubleMethod,
2629 JNI::CallNonvirtualDoubleMethodV,
2630 JNI::CallNonvirtualDoubleMethodA,
2631 JNI::CallNonvirtualVoidMethod,
2632 JNI::CallNonvirtualVoidMethodV,
2633 JNI::CallNonvirtualVoidMethodA,
2634 JNI::GetFieldID,
2635 JNI::GetObjectField,
2636 JNI::GetBooleanField,
2637 JNI::GetByteField,
2638 JNI::GetCharField,
2639 JNI::GetShortField,
2640 JNI::GetIntField,
2641 JNI::GetLongField,
2642 JNI::GetFloatField,
2643 JNI::GetDoubleField,
2644 JNI::SetObjectField,
2645 JNI::SetBooleanField,
2646 JNI::SetByteField,
2647 JNI::SetCharField,
2648 JNI::SetShortField,
2649 JNI::SetIntField,
2650 JNI::SetLongField,
2651 JNI::SetFloatField,
2652 JNI::SetDoubleField,
2653 JNI::GetStaticMethodID,
2654 JNI::CallStaticObjectMethod,
2655 JNI::CallStaticObjectMethodV,
2656 JNI::CallStaticObjectMethodA,
2657 JNI::CallStaticBooleanMethod,
2658 JNI::CallStaticBooleanMethodV,
2659 JNI::CallStaticBooleanMethodA,
2660 JNI::CallStaticByteMethod,
2661 JNI::CallStaticByteMethodV,
2662 JNI::CallStaticByteMethodA,
2663 JNI::CallStaticCharMethod,
2664 JNI::CallStaticCharMethodV,
2665 JNI::CallStaticCharMethodA,
2666 JNI::CallStaticShortMethod,
2667 JNI::CallStaticShortMethodV,
2668 JNI::CallStaticShortMethodA,
2669 JNI::CallStaticIntMethod,
2670 JNI::CallStaticIntMethodV,
2671 JNI::CallStaticIntMethodA,
2672 JNI::CallStaticLongMethod,
2673 JNI::CallStaticLongMethodV,
2674 JNI::CallStaticLongMethodA,
2675 JNI::CallStaticFloatMethod,
2676 JNI::CallStaticFloatMethodV,
2677 JNI::CallStaticFloatMethodA,
2678 JNI::CallStaticDoubleMethod,
2679 JNI::CallStaticDoubleMethodV,
2680 JNI::CallStaticDoubleMethodA,
2681 JNI::CallStaticVoidMethod,
2682 JNI::CallStaticVoidMethodV,
2683 JNI::CallStaticVoidMethodA,
2684 JNI::GetStaticFieldID,
2685 JNI::GetStaticObjectField,
2686 JNI::GetStaticBooleanField,
2687 JNI::GetStaticByteField,
2688 JNI::GetStaticCharField,
2689 JNI::GetStaticShortField,
2690 JNI::GetStaticIntField,
2691 JNI::GetStaticLongField,
2692 JNI::GetStaticFloatField,
2693 JNI::GetStaticDoubleField,
2694 JNI::SetStaticObjectField,
2695 JNI::SetStaticBooleanField,
2696 JNI::SetStaticByteField,
2697 JNI::SetStaticCharField,
2698 JNI::SetStaticShortField,
2699 JNI::SetStaticIntField,
2700 JNI::SetStaticLongField,
2701 JNI::SetStaticFloatField,
2702 JNI::SetStaticDoubleField,
2703 JNI::NewString,
2704 JNI::GetStringLength,
2705 JNI::GetStringChars,
2706 JNI::ReleaseStringChars,
2707 JNI::NewStringUTF,
2708 JNI::GetStringUTFLength,
2709 JNI::GetStringUTFChars,
2710 JNI::ReleaseStringUTFChars,
2711 JNI::GetArrayLength,
2712 JNI::NewObjectArray,
2713 JNI::GetObjectArrayElement,
2714 JNI::SetObjectArrayElement,
2715 JNI::NewBooleanArray,
2716 JNI::NewByteArray,
2717 JNI::NewCharArray,
2718 JNI::NewShortArray,
2719 JNI::NewIntArray,
2720 JNI::NewLongArray,
2721 JNI::NewFloatArray,
2722 JNI::NewDoubleArray,
2723 JNI::GetBooleanArrayElements,
2724 JNI::GetByteArrayElements,
2725 JNI::GetCharArrayElements,
2726 JNI::GetShortArrayElements,
2727 JNI::GetIntArrayElements,
2728 JNI::GetLongArrayElements,
2729 JNI::GetFloatArrayElements,
2730 JNI::GetDoubleArrayElements,
2731 JNI::ReleaseBooleanArrayElements,
2732 JNI::ReleaseByteArrayElements,
2733 JNI::ReleaseCharArrayElements,
2734 JNI::ReleaseShortArrayElements,
2735 JNI::ReleaseIntArrayElements,
2736 JNI::ReleaseLongArrayElements,
2737 JNI::ReleaseFloatArrayElements,
2738 JNI::ReleaseDoubleArrayElements,
2739 JNI::GetBooleanArrayRegion,
2740 JNI::GetByteArrayRegion,
2741 JNI::GetCharArrayRegion,
2742 JNI::GetShortArrayRegion,
2743 JNI::GetIntArrayRegion,
2744 JNI::GetLongArrayRegion,
2745 JNI::GetFloatArrayRegion,
2746 JNI::GetDoubleArrayRegion,
2747 JNI::SetBooleanArrayRegion,
2748 JNI::SetByteArrayRegion,
2749 JNI::SetCharArrayRegion,
2750 JNI::SetShortArrayRegion,
2751 JNI::SetIntArrayRegion,
2752 JNI::SetLongArrayRegion,
2753 JNI::SetFloatArrayRegion,
2754 JNI::SetDoubleArrayRegion,
2755 JNI::RegisterNatives,
2756 JNI::UnregisterNatives,
2757 JNI::MonitorEnter,
2758 JNI::MonitorExit,
2759 JNI::GetJavaVM,
2760 JNI::GetStringRegion,
2761 JNI::GetStringUTFRegion,
2762 JNI::GetPrimitiveArrayCritical,
2763 JNI::ReleasePrimitiveArrayCritical,
2764 JNI::GetStringCritical,
2765 JNI::ReleaseStringCritical,
2766 JNI::NewWeakGlobalRef,
2767 JNI::DeleteWeakGlobalRef,
2768 JNI::ExceptionCheck,
2769 JNI::NewDirectByteBuffer,
2770 JNI::GetDirectBufferAddress,
2771 JNI::GetDirectBufferCapacity,
2772 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002773};
2774
Ian Rogers68d8b422014-07-17 11:09:10 -07002775const JNINativeInterface* GetJniNativeInterface() {
2776 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002777}
2778
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002779void (*gJniSleepForeverStub[])() = {
2780 nullptr, // reserved0.
2781 nullptr, // reserved1.
2782 nullptr, // reserved2.
2783 nullptr, // reserved3.
2784 SleepForever,
2785 SleepForever,
2786 SleepForever,
2787 SleepForever,
2788 SleepForever,
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};
3014
3015const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
3016 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
3017}
3018
Elliott Hughesc8fece32013-01-02 11:27:23 -08003019void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003020 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003021 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003022 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003023 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3024 }
3025 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3026}
3027
Ian Rogersdf20fe02011-07-20 20:34:16 -07003028} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003029
3030std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3031 switch (rhs) {
3032 case JNIInvalidRefType:
3033 os << "JNIInvalidRefType";
3034 return os;
3035 case JNILocalRefType:
3036 os << "JNILocalRefType";
3037 return os;
3038 case JNIGlobalRefType:
3039 os << "JNIGlobalRefType";
3040 return os;
3041 case JNIWeakGlobalRefType:
3042 os << "JNIWeakGlobalRefType";
3043 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003044 default:
Ian Rogersc7dd2952014-10-21 23:31:19 -07003045 LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3046 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003047 }
3048}