blob: 6ef399982bd2a63b053df32f65302898eec58821 [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"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080030#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080031#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080032#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080033#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070034#include "dex_file-inl.h"
Mathieu Chartierd0004802014-10-15 16:59:47 -070035#include "fault_handler.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070036#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070037#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070038#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070039#include "interpreter/interpreter.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070040#include "jni_env_ext.h"
41#include "java_vm_ext.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080042#include "mirror/class-inl.h"
43#include "mirror/class_loader.h"
Hiroshi Yamauchi02d2f292015-04-03 13:35:16 -070044#include "mirror/field-inl.h"
Mathieu Chartierfc58af42015-04-16 18:00:39 -070045#include "mirror/method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080046#include "mirror/object-inl.h"
47#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070048#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049#include "mirror/throwable.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080050#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070051#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070052#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070053#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070054#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070055#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070056#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080057#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070058#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070059
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070060namespace art {
61
Mathieu Chartier24555ad2014-10-06 13:41:33 -070062// Consider turning this on when there is errors which could be related to JNI array copies such as
63// things not rendering correctly. E.g. b/16858794
64static constexpr bool kWarnJniAbort = false;
65
Elliott Hughes6b436852011-08-12 10:16:44 -070066// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
67// separated with slashes but aren't wrapped with "L;" like regular descriptors
68// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
69// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
70// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -070071static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070072 std::string result;
73 // Add the missing "L;" if necessary.
74 if (name[0] == '[') {
75 result = name;
76 } else {
77 result += 'L';
78 result += name;
79 result += ';';
80 }
81 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070082 if (result.find('.') != std::string::npos) {
83 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
84 << "\"" << name << "\"";
85 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -070086 }
87 return result;
88}
89
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080090static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070091 const char* name, const char* sig, const char* kind)
Mathieu Chartier90443472015-07-16 20:32:27 -070092 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers1ff3c982014-08-12 02:30:58 -070093 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +000094 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Ian Rogers62d6c772013-02-27 08:32:07 -080095 "no %s method \"%s.%s%s\"",
Ian Rogers1ff3c982014-08-12 02:30:58 -070096 kind, c->GetDescriptor(&temp), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -070097}
98
Sebastien Hertzfa65e842014-07-03 09:39:53 +020099static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
100 const char* kind, jint idx, bool return_errors)
Mathieu Chartier90443472015-07-16 20:32:27 -0700101 SHARED_REQUIRES(Locks::mutator_lock_) {
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200102 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
103 << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
104 << ": " << kind << " is null at index " << idx;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000105 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200106 "%s is null at index %d", kind, idx);
107}
108
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800109static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
Mathieu Chartier90443472015-07-16 20:32:27 -0700110 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800111 if (LIKELY(klass->IsInitialized())) {
112 return klass;
113 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700114 StackHandleScope<1> hs(self);
115 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
Ian Rogers7b078e82014-09-10 14:44:24 -0700116 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800117 return nullptr;
118 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700119 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800120}
121
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700122static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
123 const char* name, const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700124 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800125 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800126 if (c == nullptr) {
127 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700128 }
Mathieu Chartiere401d142015-04-22 13:56:20 -0700129 ArtMethod* method = nullptr;
130 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Elliott Hughescdf53122011-08-19 15:46:09 -0700131 if (is_static) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700132 method = c->FindDirectMethod(name, sig, pointer_size);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700133 } else if (c->IsInterface()) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700134 method = c->FindInterfaceMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700135 } else {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700136 method = c->FindVirtualMethod(name, sig, pointer_size);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800137 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700138 // No virtual method matching the signature. Search declared
139 // private methods and constructors.
Mathieu Chartiere401d142015-04-22 13:56:20 -0700140 method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700141 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700142 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800143 if (method == nullptr || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700144 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800145 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700146 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700147 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700148}
149
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800150static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Mathieu Chartier90443472015-07-16 20:32:27 -0700151 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700152 ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700153 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
154 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700155 return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Brian Carlstrom00fae582011-10-28 01:16:28 -0700156 }
Brian Carlstromce888532013-10-10 00:32:58 -0700157 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800158 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700159 return method->GetDeclaringClass()->GetClassLoader();
160 }
161 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800162 mirror::ClassLoader* class_loader =
163 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
164 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700165 return class_loader;
166 }
167 // See if the override ClassLoader is set for gtests.
Ian Rogers68d8b422014-07-17 11:09:10 -0700168 class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800169 if (class_loader != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700170 // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
171 // image.
172 CHECK(Runtime::Current()->IsAotCompiler());
Andreas Gampe4585f872015-03-27 23:45:15 -0700173 CHECK(!Runtime::Current()->IsCompilingBootImage());
Brian Carlstromce888532013-10-10 00:32:58 -0700174 return class_loader;
175 }
176 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800177 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700178}
179
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700180static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
181 const char* sig, bool is_static)
Mathieu Chartier90443472015-07-16 20:32:27 -0700182 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700183 StackHandleScope<2> hs(soa.Self());
184 Handle<mirror::Class> c(
185 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
186 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800187 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700188 }
Mathieu Chartierc7853442015-03-27 14:35:38 -0700189 ArtField* field = nullptr;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800190 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700191 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
192 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700193 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800194 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700195 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700196 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700197 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800198 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700199 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700200 DCHECK(soa.Self()->IsExceptionPending());
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800201 StackHandleScope<1> hs2(soa.Self());
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000202 Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700203 soa.Self()->ClearException();
Ian Rogers1ff3c982014-08-12 02:30:58 -0700204 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000205 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800206 "no type \"%s\" found and so no field \"%s\" "
207 "could be found in class \"%s\" or its superclasses", sig, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700208 c->GetDescriptor(&temp));
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000209 soa.Self()->GetException()->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800210 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700211 }
Ian Rogers1ff3c982014-08-12 02:30:58 -0700212 std::string temp;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700213 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700214 field = mirror::Class::FindStaticField(soa.Self(), c, name,
Ian Rogers1ff3c982014-08-12 02:30:58 -0700215 field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700216 } else {
Ian Rogers1ff3c982014-08-12 02:30:58 -0700217 field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700218 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800219 if (field == nullptr) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000220 soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800221 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700222 sig, name, c->GetDescriptor(&temp));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800223 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700224 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700225 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700226}
227
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800228static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700229 jsize length, const char* identifier)
Mathieu Chartier90443472015-07-16 20:32:27 -0700230 SHARED_REQUIRES(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700231 std::string type(PrettyTypeOf(array));
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000232 soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800233 "%s offset=%d length=%d %s.length=%d",
234 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700235}
Ian Rogers0571d352011-11-03 19:51:38 -0700236
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700237static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
238 jsize array_length)
Mathieu Chartier90443472015-07-16 20:32:27 -0700239 SHARED_REQUIRES(Locks::mutator_lock_) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000240 soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
Ian Rogers62d6c772013-02-27 08:32:07 -0800241 "offset=%d length=%d string.length()=%d", start, length,
242 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700243}
Elliott Hughes814e4032011-08-23 12:07:56 -0700244
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700245int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Mathieu Chartier90443472015-07-16 20:32:27 -0700246 REQUIRES(!Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247 // Turn the const char* into a java.lang.String.
248 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800249 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700250 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700251 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700252
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700253 // Choose an appropriate constructor and set up the arguments.
254 jvalue args[2];
255 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800256 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700257 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800258 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700259 signature = "(Ljava/lang/String;)V";
260 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800261 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700262 signature = "(Ljava/lang/Throwable;)V";
263 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700264 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700265 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
266 args[0].l = s.get();
267 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700268 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700269 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800270 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800271 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700272 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800273 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700274 return JNI_ERR;
275 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700276
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800277 ScopedLocalRef<jthrowable> exception(
278 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
279 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700280 return JNI_ERR;
281 }
Ian Rogersef28b142012-11-30 14:22:18 -0800282 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000283 soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700284 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700285}
286
Ian Rogers68d8b422014-07-17 11:09:10 -0700287static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
288 return reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughes75770752011-08-24 17:52:38 -0700289}
290
Ian Rogers2d10b202014-05-12 19:15:18 -0700291#define CHECK_NON_NULL_ARGUMENT(value) \
292 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700293
Ian Rogers2d10b202014-05-12 19:15:18 -0700294#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
295 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
296
297#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
298 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
299
300#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
301 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
302
303#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700304 if (UNLIKELY((value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700305 JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700306 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700307 }
308
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700309#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Chih-Hung Hsiehfba39972016-05-11 11:26:48 -0700310 if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
Ian Rogers68d8b422014-07-17 11:09:10 -0700311 JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700312 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700313 }
314
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700315template <bool kNative>
Mathieu Chartiere401d142015-04-22 13:56:20 -0700316static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
Mathieu Chartier90443472015-07-16 20:32:27 -0700317 SHARED_REQUIRES(Locks::mutator_lock_) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700318 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -0800319 for (auto& method : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -0700320 if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
321 return &method;
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700322 }
323 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -0700324 return nullptr;
325}
326
Elliott Hughescdf53122011-08-19 15:46:09 -0700327class JNI {
328 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700329 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700330 return JNI_VERSION_1_6;
331 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700332
Ian Rogers25e8b912012-09-07 11:31:36 -0700333 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700334 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800335 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700336 }
337
Elliott Hughescdf53122011-08-19 15:46:09 -0700338 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700339 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700340 Runtime* runtime = Runtime::Current();
341 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700342 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700343 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800344 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700345 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700346 StackHandleScope<1> hs(soa.Self());
347 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800348 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700349 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800350 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700351 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700352 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700353 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700354
Ian Rogers62f05122014-03-21 11:21:29 -0700355 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700356 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700357 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700358 return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700359 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700360
Ian Rogers62f05122014-03-21 11:21:29 -0700361 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700362 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700363 ScopedObjectAccess soa(env);
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700364 mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
365 if (obj_field->GetClass() != mirror::Field::StaticClass()) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700366 // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
Mathieu Chartierdaaf3262015-03-24 13:30:28 -0700367 return nullptr;
368 }
369 auto* field = static_cast<mirror::Field*>(obj_field);
370 return soa.EncodeField(field->GetArtField());
Elliott Hughescdf53122011-08-19 15:46:09 -0700371 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700372
Elliott Hughescdf53122011-08-19 15:46:09 -0700373 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700374 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700375 ScopedObjectAccess soa(env);
Mathieu Chartiere401d142015-04-22 13:56:20 -0700376 ArtMethod* m = soa.DecodeMethod(mid);
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700377 mirror::AbstractMethod* method;
Andreas Gampee01e3642016-07-25 13:06:04 -0700378 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), sizeof(void*));
379 DCHECK(!Runtime::Current()->IsActiveTransaction());
Sebastien Hertzd3333762014-06-26 14:45:07 +0200380 if (m->IsConstructor()) {
Andreas Gampee01e3642016-07-25 13:06:04 -0700381 method = mirror::Constructor::CreateFromArtMethod<sizeof(void*), false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200382 } else {
Andreas Gampee01e3642016-07-25 13:06:04 -0700383 method = mirror::Method::CreateFromArtMethod<sizeof(void*), false>(soa.Self(), m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200384 }
Mathieu Chartierfc58af42015-04-16 18:00:39 -0700385 return soa.AddLocalReference<jobject>(method);
Elliott Hughescdf53122011-08-19 15:46:09 -0700386 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700387
Elliott Hughescdf53122011-08-19 15:46:09 -0700388 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700389 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700390 ScopedObjectAccess soa(env);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700391 ArtField* f = soa.DecodeField(fid);
Andreas Gampee01e3642016-07-25 13:06:04 -0700392 return soa.AddLocalReference<jobject>(
393 mirror::Field::CreateFromArtField<sizeof(void*)>(soa.Self(), f, true));
Elliott Hughescdf53122011-08-19 15:46:09 -0700394 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700395
Elliott Hughes37f7a402011-08-22 18:56:01 -0700396 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700397 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700398 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800399 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700400 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700401 }
402
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700403 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700404 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700405 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800406 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Brian Carlstrom08ac9222015-05-22 13:43:00 -0700407 return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700408 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700409
Narayan Kamath1268b742014-07-11 19:15:11 +0100410 // Note: java_class1 should be safely castable to java_class2, and
411 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700412 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700413 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
414 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700415 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800416 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
417 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100418 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700419 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700420
Elliott Hughese84278b2012-03-22 10:06:53 -0700421 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700422 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800423 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700424 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700425 return JNI_TRUE;
426 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700427 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800428 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
429 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700430 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700431 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700432 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700433
Elliott Hughes37f7a402011-08-22 18:56:01 -0700434 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700435 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800436 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
437 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700438 return JNI_ERR;
439 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000440 soa.Self()->SetException(exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700441 return JNI_OK;
442 }
443
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700444 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700445 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800446 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700447 }
448
449 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700450 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700451 }
452
453 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700454 ScopedObjectAccess soa(env);
455 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700456 }
457
458 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700459 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700460
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700461 // If we have no exception to describe, pass through.
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000462 if (!soa.Self()->GetException()) {
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700463 return;
464 }
465
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000466 StackHandleScope<1> hs(soa.Self());
467 Handle<mirror::Throwable> old_exception(
468 hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
469 soa.Self()->ClearException();
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800470 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700471 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700472 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
473 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800474 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700475 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700476 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700477 } else {
478 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800479 if (soa.Self()->IsExceptionPending()) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000480 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
Elliott Hughes72025e52011-08-23 17:50:30 -0700481 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800482 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700483 }
484 }
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000485 soa.Self()->SetException(old_exception.Get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700486 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700487
Elliott Hughescdf53122011-08-19 15:46:09 -0700488 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700489 ScopedObjectAccess soa(env);
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000490 mirror::Object* exception = soa.Self()->GetException();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700491 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700492 }
493
Ian Rogers25e8b912012-09-07 11:31:36 -0700494 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700495 LOG(FATAL) << "JNI FatalError called: " << msg;
496 }
497
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700498 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700499 // TODO: SOA may not be necessary but I do it to please lock annotations.
500 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700501 if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700502 return JNI_ERR;
503 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700504 down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700505 return JNI_OK;
506 }
507
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700508 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700509 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800510 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700511 soa.Env()->PopFrame();
512 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700513 }
514
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700515 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700516 // TODO: SOA may not be necessary but I do it to please lock annotations.
517 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700518 return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700519 }
520
Elliott Hughescdf53122011-08-19 15:46:09 -0700521 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700522 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800523 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Ian Rogers68d8b422014-07-17 11:09:10 -0700524 return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700525 }
526
527 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700528 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
529 Thread* self = down_cast<JNIEnvExt*>(env)->self;
530 vm->DeleteGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700531 }
532
533 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700534 ScopedObjectAccess soa(env);
Ian Rogers68d8b422014-07-17 11:09:10 -0700535 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
536 return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700537 }
538
539 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700540 JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
541 Thread* self = down_cast<JNIEnvExt*>(env)->self;
542 vm->DeleteWeakGlobalRef(self, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700543 }
544
545 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700546 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800547 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800548 // Check for null after decoding the object to handle cleared weak globals.
549 if (decoded_obj == nullptr) {
550 return nullptr;
551 }
552 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700553 }
554
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700555 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800556 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700557 return;
558 }
Mathieu Chartierdd06afe2015-06-26 10:47:08 -0700559 // SOA is only necessary to have exclusion between GC root marking and removing.
560 // We don't want to have the GC attempt to mark a null root if we just removed
561 // it. b/22119403
562 ScopedObjectAccess soa(env);
563 auto* ext_env = down_cast<JNIEnvExt*>(env);
564 if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700565 // Attempting to delete a local reference that is not in the
566 // topmost local reference frame is a no-op. DeleteLocalRef returns
567 // void and doesn't throw any exceptions, but we should probably
568 // complain about it so the user will notice that things aren't
569 // going quite the way they expect.
570 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
571 << "failed to find entry";
572 }
573 }
574
575 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700576 if (obj1 == obj2) {
577 return JNI_TRUE;
578 } else {
579 ScopedObjectAccess soa(env);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800580 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
581 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700582 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700583 }
584
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700585 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700586 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700587 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800588 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800589 if (c == nullptr) {
590 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700591 }
Jeff Hao848f70a2014-01-15 13:49:50 -0800592 if (c->IsStringClass()) {
593 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
594 mirror::SetStringCountVisitor visitor(0);
595 return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
596 allocator_type, visitor));
597 }
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);
Jeff Hao848f70a2014-01-15 13:49:50 -08001675 const jchar* chars = s->GetValue();
Elliott Hughesb465ab02011-08-24 11:21:21 -07001676 memcpy(buf, chars + start, length * sizeof(jchar));
1677 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001678 }
1679
Ian Rogersbc939662013-08-15 10:26:54 -07001680 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1681 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001682 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001683 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001684 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Vladimir Marko795e3412015-11-06 16:57:03 +00001685 if (start < 0 || length < 0 || length > s->GetLength() - start) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001686 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001687 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001688 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Jeff Hao848f70a2014-01-15 13:49:50 -08001689 const jchar* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001690 size_t bytes = CountUtf8Bytes(chars + start, length);
1691 ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001692 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001693 }
1694
Elliott Hughes75770752011-08-24 17:52:38 -07001695 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001696 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001697 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001698 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001699 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001700 if (heap->IsMovableObject(s)) {
1701 jchar* chars = new jchar[s->GetLength()];
1702 memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
Fred Shih56890e22014-06-02 11:11:52 -07001703 if (is_copy != nullptr) {
1704 *is_copy = JNI_TRUE;
1705 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001706 return chars;
Elliott Hughes75770752011-08-24 17:52:38 -07001707 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001708 if (is_copy != nullptr) {
1709 *is_copy = JNI_FALSE;
1710 }
1711 return static_cast<jchar*>(s->GetValue());
Elliott Hughes814e4032011-08-23 12:07:56 -07001712 }
1713
Mathieu Chartier590fee92013-09-13 13:46:47 -07001714 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001715 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001716 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001717 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001718 if (chars != s->GetValue()) {
Fred Shih56890e22014-06-02 11:11:52 -07001719 delete[] chars;
1720 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001721 }
1722
Elliott Hughes75770752011-08-24 17:52:38 -07001723 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07001724 CHECK_NON_NULL_ARGUMENT(java_string);
1725 ScopedObjectAccess soa(env);
1726 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Fred Shih56890e22014-06-02 11:11:52 -07001727 gc::Heap* heap = Runtime::Current()->GetHeap();
Jeff Hao848f70a2014-01-15 13:49:50 -08001728 if (heap->IsMovableObject(s)) {
Fred Shih56890e22014-06-02 11:11:52 -07001729 StackHandleScope<1> hs(soa.Self());
Jeff Hao848f70a2014-01-15 13:49:50 -08001730 HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001731 if (!kUseReadBarrier) {
1732 heap->IncrementDisableMovingGC(soa.Self());
1733 } else {
1734 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1735 // to occur thanks to the to-space invariant.
1736 heap->IncrementDisableThreadFlip(soa.Self());
1737 }
Fred Shih56890e22014-06-02 11:11:52 -07001738 }
1739 if (is_copy != nullptr) {
1740 *is_copy = JNI_FALSE;
1741 }
Jeff Hao848f70a2014-01-15 13:49:50 -08001742 return static_cast<jchar*>(s->GetValue());
Elliott Hughescdf53122011-08-19 15:46:09 -07001743 }
1744
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001745 static void ReleaseStringCritical(JNIEnv* env,
1746 jstring java_string,
1747 const jchar* chars ATTRIBUTE_UNUSED) {
Fred Shih56890e22014-06-02 11:11:52 -07001748 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1749 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07001750 gc::Heap* heap = Runtime::Current()->GetHeap();
1751 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Jeff Hao848f70a2014-01-15 13:49:50 -08001752 if (heap->IsMovableObject(s)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001753 if (!kUseReadBarrier) {
1754 heap->DecrementDisableMovingGC(soa.Self());
1755 } else {
1756 heap->DecrementDisableThreadFlip(soa.Self());
1757 }
Fred Shih56890e22014-06-02 11:11:52 -07001758 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001759 }
1760
Elliott Hughes75770752011-08-24 17:52:38 -07001761 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001762 if (java_string == nullptr) {
1763 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07001764 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001765 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07001766 *is_copy = JNI_TRUE;
1767 }
Ian Rogersef28b142012-11-30 14:22:18 -08001768 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001769 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07001770 size_t byte_count = s->GetUtfLength();
1771 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001772 CHECK(bytes != nullptr); // bionic aborts anyway.
Jeff Hao848f70a2014-01-15 13:49:50 -08001773 const uint16_t* chars = s->GetValue();
Bruce Hoult1646d7a2015-10-28 15:06:12 +03001774 ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
Elliott Hughes75770752011-08-24 17:52:38 -07001775 bytes[byte_count] = '\0';
1776 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001777 }
1778
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001779 static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07001780 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07001781 }
1782
Elliott Hughesbd935992011-08-22 11:59:34 -07001783 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001784 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001785 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001786 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07001787 if (UNLIKELY(!obj->IsArrayInstance())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001788 soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1789 return 0;
Elliott Hughes96a98872012-12-19 14:21:15 -08001790 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001791 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07001792 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07001793 }
1794
Elliott Hughes814e4032011-08-23 12:07:56 -07001795 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001796 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001797 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001798 mirror::ObjectArray<mirror::Object>* array =
1799 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001800 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07001801 }
1802
Ian Rogersbc939662013-08-15 10:26:54 -07001803 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1804 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001805 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001806 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001807 mirror::ObjectArray<mirror::Object>* array =
1808 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1809 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001810 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07001811 }
1812
1813 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001814 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001815 }
1816
1817 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001818 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001819 }
1820
1821 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001822 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001823 }
1824
1825 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001826 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001827 }
1828
1829 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001830 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001831 }
1832
1833 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001834 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001835 }
1836
1837 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001838 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001839 }
1840
Ian Rogers1d99e452014-01-02 17:36:41 -08001841 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1842 jobject initial_element) {
1843 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001844 JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001845 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08001846 }
Ian Rogers2d10b202014-05-12 19:15:18 -07001847 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07001848
1849 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07001850 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001851 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08001852 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001853 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08001854 if (UNLIKELY(element_class->IsPrimitive())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001855 soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1856 PrettyDescriptor(element_class).c_str());
Ian Rogers1d99e452014-01-02 17:36:41 -08001857 return nullptr;
1858 }
Ian Rogers1d99e452014-01-02 17:36:41 -08001859 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07001860 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08001861 if (UNLIKELY(array_class == nullptr)) {
1862 return nullptr;
1863 }
Elliott Hughescdf53122011-08-19 15:46:09 -07001864 }
1865
Elliott Hughes75770752011-08-24 17:52:38 -07001866 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001867 mirror::ObjectArray<mirror::Object>* result =
1868 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08001869 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001870 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08001871 if (initial_object != nullptr) {
1872 mirror::Class* element_class = result->GetClass()->GetComponentType();
1873 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001874 soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1875 "element type of '%s'",
1876 PrettyDescriptor(initial_object->GetClass()).c_str(),
1877 PrettyDescriptor(element_class).c_str());
1878 return nullptr;
Ian Rogers1d99e452014-01-02 17:36:41 -08001879 } else {
1880 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001881 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08001882 }
1883 }
Elliott Hughes75770752011-08-24 17:52:38 -07001884 }
1885 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001886 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001887 }
1888
1889 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001890 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07001891 }
1892
Ian Rogersa15e67d2012-02-28 13:51:55 -08001893 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001894 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001895 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001896 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07001897 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001898 soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1899 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001900 return nullptr;
1901 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001902 gc::Heap* heap = Runtime::Current()->GetHeap();
1903 if (heap->IsMovableObject(array)) {
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07001904 if (!kUseReadBarrier) {
1905 heap->IncrementDisableMovingGC(soa.Self());
1906 } else {
1907 // For the CC collector, we only need to wait for the thread flip rather than the whole GC
1908 // to occur thanks to the to-space invariant.
1909 heap->IncrementDisableThreadFlip(soa.Self());
1910 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001911 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001912 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001913 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07001914 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08001915 *is_copy = JNI_FALSE;
1916 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08001917 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001918 }
1919
Ian Rogers2d10b202014-05-12 19:15:18 -07001920 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1921 jint mode) {
1922 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1923 ScopedObjectAccess soa(env);
1924 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1925 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07001926 soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1927 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07001928 return;
1929 }
1930 const size_t component_size = array->GetClass()->GetComponentSize();
1931 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001932 }
1933
Elliott Hughes75770752011-08-24 17:52:38 -07001934 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001935 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001936 }
1937
Elliott Hughes75770752011-08-24 17:52:38 -07001938 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001939 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001940 }
1941
Elliott Hughes75770752011-08-24 17:52:38 -07001942 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001943 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001944 }
1945
Elliott Hughes75770752011-08-24 17:52:38 -07001946 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001947 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001948 }
1949
Elliott Hughes75770752011-08-24 17:52:38 -07001950 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001951 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001952 }
1953
Elliott Hughes75770752011-08-24 17:52:38 -07001954 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001955 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001956 }
1957
Elliott Hughes75770752011-08-24 17:52:38 -07001958 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001959 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001960 }
1961
Elliott Hughes75770752011-08-24 17:52:38 -07001962 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001963 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07001964 }
1965
Mathieu Chartier590fee92013-09-13 13:46:47 -07001966 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1967 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001968 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
1969 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001970 }
1971
Mathieu Chartier590fee92013-09-13 13:46:47 -07001972 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001973 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001974 }
1975
Mathieu Chartier590fee92013-09-13 13:46:47 -07001976 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001977 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001978 }
1979
Mathieu Chartier590fee92013-09-13 13:46:47 -07001980 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1981 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001982 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001983 }
1984
Mathieu Chartier590fee92013-09-13 13:46:47 -07001985 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1986 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001987 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001988 }
1989
Mathieu Chartier590fee92013-09-13 13:46:47 -07001990 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001991 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001992 }
1993
Mathieu Chartier590fee92013-09-13 13:46:47 -07001994 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001995 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07001996 }
1997
Mathieu Chartier590fee92013-09-13 13:46:47 -07001998 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
1999 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002000 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002001 }
2002
Ian Rogersbc939662013-08-15 10:26:54 -07002003 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2004 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002005 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002006 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002007 }
2008
Ian Rogersbc939662013-08-15 10:26:54 -07002009 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2010 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002011 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002012 }
2013
Ian Rogersbc939662013-08-15 10:26:54 -07002014 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2015 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002016 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002017 }
2018
Ian Rogersbc939662013-08-15 10:26:54 -07002019 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2020 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002021 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002022 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002023 }
2024
Ian Rogersbc939662013-08-15 10:26:54 -07002025 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2026 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002027 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002028 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002029 }
2030
Ian Rogersbc939662013-08-15 10:26:54 -07002031 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2032 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002033 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002034 }
2035
Ian Rogersbc939662013-08-15 10:26:54 -07002036 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2037 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002038 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002039 }
2040
Ian Rogersbc939662013-08-15 10:26:54 -07002041 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2042 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002043 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002044 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002045 }
2046
Ian Rogersbc939662013-08-15 10:26:54 -07002047 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2048 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002049 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002050 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002051 }
2052
Ian Rogersbc939662013-08-15 10:26:54 -07002053 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2054 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002055 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002056 }
2057
Ian Rogersbc939662013-08-15 10:26:54 -07002058 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2059 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002060 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002061 }
2062
Ian Rogersbc939662013-08-15 10:26:54 -07002063 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2064 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002065 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002066 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002067 }
2068
Ian Rogersbc939662013-08-15 10:26:54 -07002069 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2070 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002071 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002072 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002073 }
2074
Ian Rogersbc939662013-08-15 10:26:54 -07002075 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2076 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002077 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002078 }
2079
Ian Rogersbc939662013-08-15 10:26:54 -07002080 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2081 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002082 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002083 }
2084
Ian Rogersbc939662013-08-15 10:26:54 -07002085 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2086 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002087 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002088 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002089 }
2090
Ian Rogersbc939662013-08-15 10:26:54 -07002091 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2092 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002093 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2094 }
2095
Ian Rogersbc939662013-08-15 10:26:54 -07002096 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2097 jint method_count, bool return_errors) {
2098 if (UNLIKELY(method_count < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002099 JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2100 method_count);
2101 return JNI_ERR; // Not reached except in unit tests.
Ian Rogersbc939662013-08-15 10:26:54 -07002102 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002103 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002104 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002105 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002106 if (UNLIKELY(method_count == 0)) {
2107 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2108 << PrettyDescriptor(c);
2109 return JNI_OK;
2110 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002111 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002112 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002113 const char* name = methods[i].name;
2114 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002115 const void* fnPtr = methods[i].fnPtr;
2116 if (UNLIKELY(name == nullptr)) {
2117 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2118 return JNI_ERR;
2119 } else if (UNLIKELY(sig == nullptr)) {
2120 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2121 return JNI_ERR;
2122 } else if (UNLIKELY(fnPtr == nullptr)) {
2123 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2124 return JNI_ERR;
2125 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002126 bool is_fast = false;
Hiroshi Yamauchi36bce582015-05-12 12:16:10 -07002127 // Notes about fast JNI calls:
2128 //
2129 // On a normal JNI call, the calling thread usually transitions
2130 // from the kRunnable state to the kNative state. But if the
2131 // called native function needs to access any Java object, it
2132 // will have to transition back to the kRunnable state.
2133 //
2134 // There is a cost to this double transition. For a JNI call
2135 // that should be quick, this cost may dominate the call cost.
2136 //
2137 // On a fast JNI call, the calling thread avoids this double
2138 // transition by not transitioning from kRunnable to kNative and
2139 // stays in the kRunnable state.
2140 //
2141 // There are risks to using a fast JNI call because it can delay
2142 // a response to a thread suspension request which is typically
2143 // used for a GC root scanning, etc. If a fast JNI call takes a
2144 // long time, it could cause longer thread suspension latency
2145 // and GC pauses.
2146 //
2147 // Thus, fast JNI should be used with care. It should be used
2148 // for a JNI call that takes a short amount of time (eg. no
2149 // long-running loop) and does not block (eg. no locks, I/O,
2150 // etc.)
2151 //
2152 // A '!' prefix in the signature in the JNINativeMethod
2153 // indicates that it's a fast JNI call and the runtime omits the
2154 // thread state transition from kRunnable to kNative at the
2155 // entry.
Elliott Hughescdf53122011-08-19 15:46:09 -07002156 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002157 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002158 ++sig;
2159 }
2160
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002161 // Note: the right order is to try to find the method locally
2162 // first, either as a direct or a virtual method. Then move to
2163 // the parent.
Mathieu Chartiere401d142015-04-22 13:56:20 -07002164 ArtMethod* m = nullptr;
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002165 bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2166 for (mirror::Class* current_class = c;
2167 current_class != nullptr;
2168 current_class = current_class->GetSuperClass()) {
2169 // Search first only comparing methods which are native.
2170 m = FindMethod<true>(current_class, name, sig);
2171 if (m != nullptr) {
2172 break;
2173 }
2174
2175 // Search again comparing to all methods, to find non-native methods that match.
2176 m = FindMethod<false>(current_class, name, sig);
2177 if (m != nullptr) {
2178 break;
2179 }
2180
2181 if (warn_on_going_to_parent) {
2182 LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2183 << "This is slow, consider changing your RegisterNatives calls.";
2184 warn_on_going_to_parent = false;
2185 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002186 }
Andreas Gampe3f1dc562015-05-18 15:52:22 -07002187
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002188 if (m == nullptr) {
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002189 LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002190 << PrettyDescriptor(c) << "." << name << sig << " in "
2191 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Mathieu Chartier5c02d6c2015-05-04 10:18:24 -07002192 // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2193 // out of scope after the DumpClass is done executing.
2194 c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002195 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002196 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002197 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002198 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002199 << PrettyDescriptor(c) << "." << name << sig
2200 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002201 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002202 return JNI_ERR;
2203 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002204
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002205 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002206
Ian Rogers6f3dbba2014-10-14 17:41:57 -07002207 m->RegisterNative(fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002208 }
2209 return JNI_OK;
2210 }
2211
Elliott Hughes5174fe62011-08-23 15:12:35 -07002212 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002213 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002214 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002215 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002216
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002217 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002218
Ian Rogers2d10b202014-05-12 19:15:18 -07002219 size_t unregistered_count = 0;
Mathieu Chartiere401d142015-04-22 13:56:20 -07002220 auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Alex Lighte64300b2015-12-15 15:02:47 -08002221 for (auto& m : c->GetMethods(pointer_size)) {
Mathieu Chartiere401d142015-04-22 13:56:20 -07002222 if (m.IsNative()) {
2223 m.UnregisterNative();
Ian Rogers2d10b202014-05-12 19:15:18 -07002224 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002225 }
2226 }
2227
Ian Rogers2d10b202014-05-12 19:15:18 -07002228 if (unregistered_count == 0) {
2229 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2230 << PrettyDescriptor(c) << "' that contains no native methods";
2231 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002232 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002233 }
2234
Ian Rogers719d1a32014-03-06 12:13:39 -08002235 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002236 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002237 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002238 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2239 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002240 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002241 return JNI_ERR;
2242 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002243 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002244 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002245 }
2246
Ian Rogers719d1a32014-03-06 12:13:39 -08002247 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002248 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002249 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002250 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002251 o->MonitorExit(soa.Self());
2252 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002253 return JNI_ERR;
2254 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002255 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002256 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002257 }
2258
2259 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002260 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002261 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002262 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002263 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002264 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002265 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002266 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002267 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002268 }
2269
Elliott Hughescdf53122011-08-19 15:46:09 -07002270 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002271 if (capacity < 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002272 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2273 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002274 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002275 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002276 if (address == nullptr && capacity != 0) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002277 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2278 "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002279 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002280 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002281
Brian Carlstrom85a93362014-06-25 09:30:52 -07002282 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002283 if (capacity > INT_MAX) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002284 JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2285 "buffer capacity greater than maximum jint: %" PRId64,
2286 capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002287 return nullptr;
2288 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002289 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002290 jint capacity_arg = static_cast<jint>(capacity);
2291
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002292 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2293 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002294 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002295 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002296 }
2297
Elliott Hughesb465ab02011-08-24 11:21:21 -07002298 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002299 return reinterpret_cast<void*>(env->GetLongField(
2300 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002301 }
2302
Elliott Hughesb465ab02011-08-24 11:21:21 -07002303 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002304 return static_cast<jlong>(env->GetIntField(
2305 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002306 }
2307
Andreas Gampea8763072014-12-20 00:08:35 -08002308 static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2309 if (java_object == nullptr) {
2310 return JNIInvalidRefType;
2311 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002312
2313 // Do we definitely know what kind of reference this is?
2314 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2315 IndirectRefKind kind = GetIndirectRefKind(ref);
2316 switch (kind) {
Ian Rogersc0542af2014-09-03 16:16:56 -07002317 case kLocal:
2318 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002319 case kGlobal:
2320 return JNIGlobalRefType;
2321 case kWeakGlobal:
2322 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002323 case kHandleScopeOrInvalid:
Ian Rogersc0542af2014-09-03 16:16:56 -07002324 // Assume value is in a handle scope.
2325 return JNILocalRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002326 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002327 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
Andreas Gampea8763072014-12-20 00:08:35 -08002328 UNREACHABLE();
Elliott Hughescdf53122011-08-19 15:46:09 -07002329 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002330
2331 private:
Ian Rogers68d8b422014-07-17 11:09:10 -07002332 static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2333 const char* caller)
Mathieu Chartier90443472015-07-16 20:32:27 -07002334 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002335 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002336 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002337 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2338 return JNI_ERR;
2339 }
2340 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002341 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002342 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2343 if (!okay) {
2344 soa.Self()->ThrowOutOfMemoryError(caller);
2345 }
2346 return okay ? JNI_OK : JNI_ERR;
2347 }
2348
2349 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002350 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002351 ScopedObjectAccess soa(env);
Ian Rogers1d99e452014-01-02 17:36:41 -08002352 if (UNLIKELY(length < 0)) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002353 soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002354 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002355 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002356 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002357 return soa.AddLocalReference<JniT>(result);
2358 }
2359
Ian Rogers2d10b202014-05-12 19:15:18 -07002360 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2361 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2362 const char* fn_name, const char* operation)
Mathieu Chartier90443472015-07-16 20:32:27 -07002363 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002364 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002365 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002366 soa.Vm()->JniAbortF(fn_name,
2367 "attempt to %s %s primitive array elements with an object of type %s",
2368 operation,
2369 PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2370 PrettyDescriptor(array->GetClass()).c_str());
Ian Rogers2d10b202014-05-12 19:15:18 -07002371 return nullptr;
2372 }
2373 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2374 return array;
2375 }
2376
2377 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2378 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2379 CHECK_NON_NULL_ARGUMENT(java_array);
2380 ScopedObjectAccess soa(env);
2381 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2382 "GetArrayElements",
2383 "get");
2384 if (UNLIKELY(array == nullptr)) {
2385 return nullptr;
2386 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002387 // Only make a copy if necessary.
2388 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2389 if (is_copy != nullptr) {
2390 *is_copy = JNI_TRUE;
2391 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002392 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002393 size_t size = array->GetLength() * component_size;
2394 void* data = new uint64_t[RoundUp(size, 8) / 8];
2395 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002396 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002397 } else {
2398 if (is_copy != nullptr) {
2399 *is_copy = JNI_FALSE;
2400 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002401 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002402 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002403 }
2404
Ian Rogers2d10b202014-05-12 19:15:18 -07002405 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002406 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002407 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002408 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002409 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2410 "ReleaseArrayElements",
2411 "release");
2412 if (array == nullptr) {
2413 return;
2414 }
2415 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2416 }
2417
2418 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2419 size_t component_size, void* elements, jint mode)
Mathieu Chartier90443472015-07-16 20:32:27 -07002420 SHARED_REQUIRES(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002421 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002422 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002423 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002424 size_t bytes = array->GetLength() * component_size;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002425 if (is_copy) {
2426 // Sanity check: If elements is not the same as the java array's data, it better not be a
2427 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2428 // copies we make?
2429 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
Ian Rogers68d8b422014-07-17 11:09:10 -07002430 soa.Vm()->JniAbortF("ReleaseArrayElements",
2431 "invalid element pointer %p, array elements are %p",
2432 reinterpret_cast<void*>(elements), array_data);
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002433 return;
2434 }
Mathieu Chartier24555ad2014-10-06 13:41:33 -07002435 if (mode != JNI_ABORT) {
2436 memcpy(array_data, elements, bytes);
2437 } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2438 // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2439 LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2440 soa.Self()->DumpJavaStack(LOG(WARNING));
2441 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002442 }
2443 if (mode != JNI_COMMIT) {
2444 if (is_copy) {
2445 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002446 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002447 // Non copy to a movable object must means that we had disabled the moving GC.
Hiroshi Yamauchi76f55b02015-08-21 16:10:39 -07002448 if (!kUseReadBarrier) {
2449 heap->DecrementDisableMovingGC(soa.Self());
2450 } else {
2451 heap->DecrementDisableThreadFlip(soa.Self());
2452 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002453 }
2454 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002455 }
2456
Ian Rogers2d10b202014-05-12 19:15:18 -07002457 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2458 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2459 jsize start, jsize length, ElementT* buf) {
2460 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2461 ScopedObjectAccess soa(env);
2462 ArtArrayT* array =
2463 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2464 "GetPrimitiveArrayRegion",
2465 "get region of");
2466 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002467 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002468 ThrowAIOOBE(soa, array, start, length, "src");
2469 } else {
2470 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2471 ElementT* data = array->GetData();
2472 memcpy(buf, data + start, length * sizeof(ElementT));
2473 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002474 }
2475 }
2476
Ian Rogers2d10b202014-05-12 19:15:18 -07002477 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2478 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2479 jsize start, jsize length, const ElementT* buf) {
2480 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2481 ScopedObjectAccess soa(env);
2482 ArtArrayT* array =
2483 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2484 "SetPrimitiveArrayRegion",
2485 "set region of");
2486 if (array != nullptr) {
Vladimir Marko795e3412015-11-06 16:57:03 +00002487 if (start < 0 || length < 0 || length > array->GetLength() - start) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002488 ThrowAIOOBE(soa, array, start, length, "dst");
2489 } else {
2490 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2491 ElementT* data = array->GetData();
2492 memcpy(data + start, buf, length * sizeof(ElementT));
2493 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002494 }
2495 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002496};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002497
Elliott Hughes88c5c352012-03-15 18:49:48 -07002498const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002499 nullptr, // reserved0.
2500 nullptr, // reserved1.
2501 nullptr, // reserved2.
2502 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002503 JNI::GetVersion,
2504 JNI::DefineClass,
2505 JNI::FindClass,
2506 JNI::FromReflectedMethod,
2507 JNI::FromReflectedField,
2508 JNI::ToReflectedMethod,
2509 JNI::GetSuperclass,
2510 JNI::IsAssignableFrom,
2511 JNI::ToReflectedField,
2512 JNI::Throw,
2513 JNI::ThrowNew,
2514 JNI::ExceptionOccurred,
2515 JNI::ExceptionDescribe,
2516 JNI::ExceptionClear,
2517 JNI::FatalError,
2518 JNI::PushLocalFrame,
2519 JNI::PopLocalFrame,
2520 JNI::NewGlobalRef,
2521 JNI::DeleteGlobalRef,
2522 JNI::DeleteLocalRef,
2523 JNI::IsSameObject,
2524 JNI::NewLocalRef,
2525 JNI::EnsureLocalCapacity,
2526 JNI::AllocObject,
2527 JNI::NewObject,
2528 JNI::NewObjectV,
2529 JNI::NewObjectA,
2530 JNI::GetObjectClass,
2531 JNI::IsInstanceOf,
2532 JNI::GetMethodID,
2533 JNI::CallObjectMethod,
2534 JNI::CallObjectMethodV,
2535 JNI::CallObjectMethodA,
2536 JNI::CallBooleanMethod,
2537 JNI::CallBooleanMethodV,
2538 JNI::CallBooleanMethodA,
2539 JNI::CallByteMethod,
2540 JNI::CallByteMethodV,
2541 JNI::CallByteMethodA,
2542 JNI::CallCharMethod,
2543 JNI::CallCharMethodV,
2544 JNI::CallCharMethodA,
2545 JNI::CallShortMethod,
2546 JNI::CallShortMethodV,
2547 JNI::CallShortMethodA,
2548 JNI::CallIntMethod,
2549 JNI::CallIntMethodV,
2550 JNI::CallIntMethodA,
2551 JNI::CallLongMethod,
2552 JNI::CallLongMethodV,
2553 JNI::CallLongMethodA,
2554 JNI::CallFloatMethod,
2555 JNI::CallFloatMethodV,
2556 JNI::CallFloatMethodA,
2557 JNI::CallDoubleMethod,
2558 JNI::CallDoubleMethodV,
2559 JNI::CallDoubleMethodA,
2560 JNI::CallVoidMethod,
2561 JNI::CallVoidMethodV,
2562 JNI::CallVoidMethodA,
2563 JNI::CallNonvirtualObjectMethod,
2564 JNI::CallNonvirtualObjectMethodV,
2565 JNI::CallNonvirtualObjectMethodA,
2566 JNI::CallNonvirtualBooleanMethod,
2567 JNI::CallNonvirtualBooleanMethodV,
2568 JNI::CallNonvirtualBooleanMethodA,
2569 JNI::CallNonvirtualByteMethod,
2570 JNI::CallNonvirtualByteMethodV,
2571 JNI::CallNonvirtualByteMethodA,
2572 JNI::CallNonvirtualCharMethod,
2573 JNI::CallNonvirtualCharMethodV,
2574 JNI::CallNonvirtualCharMethodA,
2575 JNI::CallNonvirtualShortMethod,
2576 JNI::CallNonvirtualShortMethodV,
2577 JNI::CallNonvirtualShortMethodA,
2578 JNI::CallNonvirtualIntMethod,
2579 JNI::CallNonvirtualIntMethodV,
2580 JNI::CallNonvirtualIntMethodA,
2581 JNI::CallNonvirtualLongMethod,
2582 JNI::CallNonvirtualLongMethodV,
2583 JNI::CallNonvirtualLongMethodA,
2584 JNI::CallNonvirtualFloatMethod,
2585 JNI::CallNonvirtualFloatMethodV,
2586 JNI::CallNonvirtualFloatMethodA,
2587 JNI::CallNonvirtualDoubleMethod,
2588 JNI::CallNonvirtualDoubleMethodV,
2589 JNI::CallNonvirtualDoubleMethodA,
2590 JNI::CallNonvirtualVoidMethod,
2591 JNI::CallNonvirtualVoidMethodV,
2592 JNI::CallNonvirtualVoidMethodA,
2593 JNI::GetFieldID,
2594 JNI::GetObjectField,
2595 JNI::GetBooleanField,
2596 JNI::GetByteField,
2597 JNI::GetCharField,
2598 JNI::GetShortField,
2599 JNI::GetIntField,
2600 JNI::GetLongField,
2601 JNI::GetFloatField,
2602 JNI::GetDoubleField,
2603 JNI::SetObjectField,
2604 JNI::SetBooleanField,
2605 JNI::SetByteField,
2606 JNI::SetCharField,
2607 JNI::SetShortField,
2608 JNI::SetIntField,
2609 JNI::SetLongField,
2610 JNI::SetFloatField,
2611 JNI::SetDoubleField,
2612 JNI::GetStaticMethodID,
2613 JNI::CallStaticObjectMethod,
2614 JNI::CallStaticObjectMethodV,
2615 JNI::CallStaticObjectMethodA,
2616 JNI::CallStaticBooleanMethod,
2617 JNI::CallStaticBooleanMethodV,
2618 JNI::CallStaticBooleanMethodA,
2619 JNI::CallStaticByteMethod,
2620 JNI::CallStaticByteMethodV,
2621 JNI::CallStaticByteMethodA,
2622 JNI::CallStaticCharMethod,
2623 JNI::CallStaticCharMethodV,
2624 JNI::CallStaticCharMethodA,
2625 JNI::CallStaticShortMethod,
2626 JNI::CallStaticShortMethodV,
2627 JNI::CallStaticShortMethodA,
2628 JNI::CallStaticIntMethod,
2629 JNI::CallStaticIntMethodV,
2630 JNI::CallStaticIntMethodA,
2631 JNI::CallStaticLongMethod,
2632 JNI::CallStaticLongMethodV,
2633 JNI::CallStaticLongMethodA,
2634 JNI::CallStaticFloatMethod,
2635 JNI::CallStaticFloatMethodV,
2636 JNI::CallStaticFloatMethodA,
2637 JNI::CallStaticDoubleMethod,
2638 JNI::CallStaticDoubleMethodV,
2639 JNI::CallStaticDoubleMethodA,
2640 JNI::CallStaticVoidMethod,
2641 JNI::CallStaticVoidMethodV,
2642 JNI::CallStaticVoidMethodA,
2643 JNI::GetStaticFieldID,
2644 JNI::GetStaticObjectField,
2645 JNI::GetStaticBooleanField,
2646 JNI::GetStaticByteField,
2647 JNI::GetStaticCharField,
2648 JNI::GetStaticShortField,
2649 JNI::GetStaticIntField,
2650 JNI::GetStaticLongField,
2651 JNI::GetStaticFloatField,
2652 JNI::GetStaticDoubleField,
2653 JNI::SetStaticObjectField,
2654 JNI::SetStaticBooleanField,
2655 JNI::SetStaticByteField,
2656 JNI::SetStaticCharField,
2657 JNI::SetStaticShortField,
2658 JNI::SetStaticIntField,
2659 JNI::SetStaticLongField,
2660 JNI::SetStaticFloatField,
2661 JNI::SetStaticDoubleField,
2662 JNI::NewString,
2663 JNI::GetStringLength,
2664 JNI::GetStringChars,
2665 JNI::ReleaseStringChars,
2666 JNI::NewStringUTF,
2667 JNI::GetStringUTFLength,
2668 JNI::GetStringUTFChars,
2669 JNI::ReleaseStringUTFChars,
2670 JNI::GetArrayLength,
2671 JNI::NewObjectArray,
2672 JNI::GetObjectArrayElement,
2673 JNI::SetObjectArrayElement,
2674 JNI::NewBooleanArray,
2675 JNI::NewByteArray,
2676 JNI::NewCharArray,
2677 JNI::NewShortArray,
2678 JNI::NewIntArray,
2679 JNI::NewLongArray,
2680 JNI::NewFloatArray,
2681 JNI::NewDoubleArray,
2682 JNI::GetBooleanArrayElements,
2683 JNI::GetByteArrayElements,
2684 JNI::GetCharArrayElements,
2685 JNI::GetShortArrayElements,
2686 JNI::GetIntArrayElements,
2687 JNI::GetLongArrayElements,
2688 JNI::GetFloatArrayElements,
2689 JNI::GetDoubleArrayElements,
2690 JNI::ReleaseBooleanArrayElements,
2691 JNI::ReleaseByteArrayElements,
2692 JNI::ReleaseCharArrayElements,
2693 JNI::ReleaseShortArrayElements,
2694 JNI::ReleaseIntArrayElements,
2695 JNI::ReleaseLongArrayElements,
2696 JNI::ReleaseFloatArrayElements,
2697 JNI::ReleaseDoubleArrayElements,
2698 JNI::GetBooleanArrayRegion,
2699 JNI::GetByteArrayRegion,
2700 JNI::GetCharArrayRegion,
2701 JNI::GetShortArrayRegion,
2702 JNI::GetIntArrayRegion,
2703 JNI::GetLongArrayRegion,
2704 JNI::GetFloatArrayRegion,
2705 JNI::GetDoubleArrayRegion,
2706 JNI::SetBooleanArrayRegion,
2707 JNI::SetByteArrayRegion,
2708 JNI::SetCharArrayRegion,
2709 JNI::SetShortArrayRegion,
2710 JNI::SetIntArrayRegion,
2711 JNI::SetLongArrayRegion,
2712 JNI::SetFloatArrayRegion,
2713 JNI::SetDoubleArrayRegion,
2714 JNI::RegisterNatives,
2715 JNI::UnregisterNatives,
2716 JNI::MonitorEnter,
2717 JNI::MonitorExit,
2718 JNI::GetJavaVM,
2719 JNI::GetStringRegion,
2720 JNI::GetStringUTFRegion,
2721 JNI::GetPrimitiveArrayCritical,
2722 JNI::ReleasePrimitiveArrayCritical,
2723 JNI::GetStringCritical,
2724 JNI::ReleaseStringCritical,
2725 JNI::NewWeakGlobalRef,
2726 JNI::DeleteWeakGlobalRef,
2727 JNI::ExceptionCheck,
2728 JNI::NewDirectByteBuffer,
2729 JNI::GetDirectBufferAddress,
2730 JNI::GetDirectBufferCapacity,
2731 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002732};
2733
Ian Rogers68d8b422014-07-17 11:09:10 -07002734const JNINativeInterface* GetJniNativeInterface() {
2735 return &gJniNativeInterface;
Elliott Hughes410c0c82011-09-01 17:58:25 -07002736}
2737
Mathieu Chartier4d87df62016-01-07 15:14:19 -08002738void (*gJniSleepForeverStub[])() = {
2739 nullptr, // reserved0.
2740 nullptr, // reserved1.
2741 nullptr, // reserved2.
2742 nullptr, // reserved3.
2743 SleepForever,
2744 SleepForever,
2745 SleepForever,
2746 SleepForever,
2747 SleepForever,
2748 SleepForever,
2749 SleepForever,
2750 SleepForever,
2751 SleepForever,
2752 SleepForever,
2753 SleepForever,
2754 SleepForever,
2755 SleepForever,
2756 SleepForever,
2757 SleepForever,
2758 SleepForever,
2759 SleepForever,
2760 SleepForever,
2761 SleepForever,
2762 SleepForever,
2763 SleepForever,
2764 SleepForever,
2765 SleepForever,
2766 SleepForever,
2767 SleepForever,
2768 SleepForever,
2769 SleepForever,
2770 SleepForever,
2771 SleepForever,
2772 SleepForever,
2773 SleepForever,
2774 SleepForever,
2775 SleepForever,
2776 SleepForever,
2777 SleepForever,
2778 SleepForever,
2779 SleepForever,
2780 SleepForever,
2781 SleepForever,
2782 SleepForever,
2783 SleepForever,
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};
2973
2974const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
2975 return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
2976}
2977
Elliott Hughesc8fece32013-01-02 11:27:23 -08002978void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07002979 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002980 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002981 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002982 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2983 }
2984 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2985}
2986
Ian Rogersdf20fe02011-07-20 20:34:16 -07002987} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07002988
2989std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2990 switch (rhs) {
2991 case JNIInvalidRefType:
2992 os << "JNIInvalidRefType";
2993 return os;
2994 case JNILocalRefType:
2995 os << "JNILocalRefType";
2996 return os;
2997 case JNIGlobalRefType:
2998 os << "JNIGlobalRefType";
2999 return os;
3000 case JNIWeakGlobalRefType:
3001 os << "JNIWeakGlobalRefType";
3002 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003003 default:
Ian Rogersc7dd2952014-10-21 23:31:19 -07003004 LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3005 UNREACHABLE();
Elliott Hughesb465ab02011-08-24 11:21:21 -07003006 }
3007}