blob: 330027962b3c45bb13babba9a22dc8175c1b7de0 [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>
Elliott Hughes0af55432011-08-17 18:37:28 -070022#include <utility>
23#include <vector>
Carl Shapiro2ed144c2011-07-26 16:52:08 -070024
Mathieu Chartier590fee92013-09-13 13:46:47 -070025#include "atomic_integer.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080026#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080027#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080028#include "base/stl_util.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080029#include "base/stringpiece.h"
Elliott Hughes40ef99e2011-08-11 17:44:34 -070030#include "class_linker.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070031#include "dex_file-inl.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070032#include "gc/accounting/card_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070033#include "interpreter/interpreter.h"
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070034#include "invoke_arg_array_builder.h"
Carl Shapiroea4dca82011-08-01 13:45:38 -070035#include "jni.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070036#include "mirror/art_field-inl.h"
37#include "mirror/art_method-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038#include "mirror/class-inl.h"
39#include "mirror/class_loader.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080040#include "mirror/object-inl.h"
41#include "mirror/object_array-inl.h"
42#include "mirror/throwable.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080043#include "object_utils.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070044#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070045#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070046#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070047#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070048#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049#include "utf.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070050#include "UniquePtr.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070051#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070052
Brian Carlstromea46f952013-07-30 01:26:50 -070053using ::art::mirror::ArtField;
54using ::art::mirror::ArtMethod;
Brian Carlstrom3e3d5912013-07-18 00:19:45 -070055using ::art::mirror::Array;
56using ::art::mirror::BooleanArray;
57using ::art::mirror::ByteArray;
58using ::art::mirror::CharArray;
59using ::art::mirror::Class;
60using ::art::mirror::ClassLoader;
61using ::art::mirror::DoubleArray;
Brian Carlstrom3e3d5912013-07-18 00:19:45 -070062using ::art::mirror::FloatArray;
63using ::art::mirror::IntArray;
64using ::art::mirror::LongArray;
65using ::art::mirror::Object;
66using ::art::mirror::ObjectArray;
67using ::art::mirror::ShortArray;
68using ::art::mirror::String;
69using ::art::mirror::Throwable;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080070
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070071namespace art {
72
Brian Carlstrom7934ac22013-07-26 10:54:15 -070073static const size_t kMonitorsInitial = 32; // Arbitrary.
74static const size_t kMonitorsMax = 4096; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070075
Brian Carlstrom7934ac22013-07-26 10:54:15 -070076static const size_t kLocalsInitial = 64; // Arbitrary.
77static const size_t kLocalsMax = 512; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070078
Brian Carlstrom7934ac22013-07-26 10:54:15 -070079static const size_t kPinTableInitial = 16; // Arbitrary.
80static const size_t kPinTableMax = 1024; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070081
Brian Carlstrom7934ac22013-07-26 10:54:15 -070082static size_t gGlobalsInitial = 512; // Arbitrary.
83static size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
Elliott Hughes2ced6a52011-10-16 18:44:48 -070084
Brian Carlstrom7934ac22013-07-26 10:54:15 -070085static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
86static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
Ian Rogersdf20fe02011-07-20 20:34:16 -070087
Ian Rogers00f7d0e2012-07-19 15:28:27 -070088static jweak AddWeakGlobalReference(ScopedObjectAccess& soa, Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -070089 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -070090 return soa.Vm()->AddWeakGlobalReference(soa.Self(), obj);
Elliott Hughescdf53122011-08-19 15:46:09 -070091}
92
Jeff Hao19c5d372013-03-15 14:33:43 -070093static bool IsBadJniVersion(int version) {
94 // We don't support JNI_VERSION_1_1. These are the only other valid versions.
95 return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
96}
97
Brian Carlstromea46f952013-07-30 01:26:50 -070098static void CheckMethodArguments(ArtMethod* m, uint32_t* args)
Ian Rogersb726dcb2012-09-05 08:57:23 -070099 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesb264f082012-04-06 17:10:10 -0700100 MethodHelper mh(m);
Ian Rogers50b35e22012-10-04 10:09:15 -0700101 const DexFile::TypeList* params = mh.GetParameterTypeList();
102 if (params == NULL) {
103 return; // No arguments so nothing to check.
104 }
Jeff Hao5d917302013-02-27 17:57:33 -0800105 uint32_t offset = 0;
Ian Rogers50b35e22012-10-04 10:09:15 -0700106 uint32_t num_params = params->Size();
Elliott Hughesb264f082012-04-06 17:10:10 -0700107 size_t error_count = 0;
Jeff Hao5d917302013-02-27 17:57:33 -0800108 if (!m->IsStatic()) {
109 offset = 1;
110 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700111 for (uint32_t i = 0; i < num_params; i++) {
112 uint16_t type_idx = params->GetTypeItem(i).type_idx_;
113 Class* param_type = mh.GetClassFromTypeIdx(type_idx);
114 if (param_type == NULL) {
115 Thread* self = Thread::Current();
116 CHECK(self->IsExceptionPending());
117 LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
118 << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
Ian Rogers62d6c772013-02-27 08:32:07 -0800119 << self->GetException(NULL)->Dump();
Ian Rogers50b35e22012-10-04 10:09:15 -0700120 self->ClearException();
121 ++error_count;
122 } else if (!param_type->IsPrimitive()) {
123 // TODO: check primitives are in range.
Jeff Hao5d917302013-02-27 17:57:33 -0800124 Object* argument = reinterpret_cast<Object*>(args[i + offset]);
Ian Rogers50b35e22012-10-04 10:09:15 -0700125 if (argument != NULL && !argument->InstanceOf(param_type)) {
Elliott Hughesb264f082012-04-06 17:10:10 -0700126 LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
127 << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m);
128 ++error_count;
129 }
Jeff Hao5d917302013-02-27 17:57:33 -0800130 } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) {
131 offset++;
Elliott Hughesb264f082012-04-06 17:10:10 -0700132 }
133 }
134 if (error_count > 0) {
135 // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort
136 // with an argument.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700137 JniAbortF(NULL, "bad arguments passed to %s (see above for details)", PrettyMethod(m).c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -0700138 }
139}
Elliott Hughesb264f082012-04-06 17:10:10 -0700140
Brian Carlstromea46f952013-07-30 01:26:50 -0700141void InvokeWithArgArray(const ScopedObjectAccess& soa, ArtMethod* method,
Jeff Hao6474d192013-03-26 14:08:09 -0700142 ArgArray* arg_array, JValue* result, char result_type)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700143 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Jeff Hao3dd9f762013-07-08 13:09:25 -0700144 uint32_t* args = arg_array->GetArray();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700145 if (UNLIKELY(soa.Env()->check_jni)) {
Jeff Hao3dd9f762013-07-08 13:09:25 -0700146 CheckMethodArguments(method, args);
Elliott Hughes4cacde82012-04-11 18:32:27 -0700147 }
Sebastien Hertz7d658cf2013-07-09 10:56:11 +0200148 method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700149}
150
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700151static JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj,
152 jmethodID mid, va_list args)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700153 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700154 ArtMethod* method = soa.DecodeMethod(mid);
Jeff Hao7a549462013-03-18 19:04:24 -0700155 Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700156 MethodHelper mh(method);
Jeff Hao5d917302013-02-27 17:57:33 -0800157 JValue result;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700158 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
Jeff Hao5d917302013-02-27 17:57:33 -0800159 arg_array.BuildArgArray(soa, receiver, args);
Jeff Hao6474d192013-03-26 14:08:09 -0700160 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
161 return result;
Elliott Hughes72025e52011-08-23 17:50:30 -0700162}
163
Brian Carlstromea46f952013-07-30 01:26:50 -0700164static ArtMethod* FindVirtualMethod(Object* receiver, ArtMethod* method)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700165 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom30b94452011-08-25 21:35:26 -0700166 return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method);
Elliott Hughes72025e52011-08-23 17:50:30 -0700167}
168
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700169static JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess& soa,
170 jobject obj, jmethodID mid, jvalue* args)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700171 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700172 Object* receiver = soa.Decode<Object*>(obj);
Brian Carlstromea46f952013-07-30 01:26:50 -0700173 ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700174 MethodHelper mh(method);
Jeff Hao5d917302013-02-27 17:57:33 -0800175 JValue result;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700176 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
Jeff Hao5d917302013-02-27 17:57:33 -0800177 arg_array.BuildArgArray(soa, receiver, args);
Jeff Hao6474d192013-03-26 14:08:09 -0700178 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
179 return result;
Elliott Hughes72025e52011-08-23 17:50:30 -0700180}
181
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700182static JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess& soa,
183 jobject obj, jmethodID mid, va_list args)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700184 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700185 Object* receiver = soa.Decode<Object*>(obj);
Brian Carlstromea46f952013-07-30 01:26:50 -0700186 ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700187 MethodHelper mh(method);
Jeff Hao5d917302013-02-27 17:57:33 -0800188 JValue result;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700189 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
Jeff Hao5d917302013-02-27 17:57:33 -0800190 arg_array.BuildArgArray(soa, receiver, args);
Jeff Hao6474d192013-03-26 14:08:09 -0700191 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
192 return result;
Carl Shapiroea4dca82011-08-01 13:45:38 -0700193}
194
Elliott Hughes6b436852011-08-12 10:16:44 -0700195// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
196// separated with slashes but aren't wrapped with "L;" like regular descriptors
197// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
198// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
199// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -0700200static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -0700201 std::string result;
202 // Add the missing "L;" if necessary.
203 if (name[0] == '[') {
204 result = name;
205 } else {
206 result += 'L';
207 result += name;
208 result += ';';
209 }
210 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -0700211 if (result.find('.') != std::string::npos) {
212 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
213 << "\"" << name << "\"";
214 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -0700215 }
216 return result;
217}
218
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700219static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, Class* c,
220 const char* name, const char* sig, const char* kind)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700221 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800222 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
223 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
224 "no %s method \"%s.%s%s\"",
225 kind, ClassHelper(c).GetDescriptor(), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -0700226}
227
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800228static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
229 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
230 if (LIKELY(klass->IsInitialized())) {
231 return klass;
232 }
233 SirtRef<mirror::Class> sirt_klass(self, klass);
234 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true)) {
235 return nullptr;
236 }
237 return sirt_klass.get();
238}
239
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700240static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
241 const char* name, const char* sig, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700242 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800243 Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(jni_class));
244 if (c == nullptr) {
245 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700246 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700247
Brian Carlstromea46f952013-07-30 01:26:50 -0700248 ArtMethod* method = NULL;
Elliott Hughescdf53122011-08-19 15:46:09 -0700249 if (is_static) {
250 method = c->FindDirectMethod(name, sig);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700251 } else {
Elliott Hughescdf53122011-08-19 15:46:09 -0700252 method = c->FindVirtualMethod(name, sig);
253 if (method == NULL) {
254 // No virtual method matching the signature. Search declared
255 // private methods and constructors.
256 method = c->FindDeclaredDirectMethod(name, sig);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700257 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700258 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700259
Elliott Hughescdf53122011-08-19 15:46:09 -0700260 if (method == NULL || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700261 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -0700262 return NULL;
263 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700264
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700265 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700266}
267
Ian Rogersef28b142012-11-30 14:22:18 -0800268static ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700269 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700270 ArtMethod* method = soa.Self()->GetCurrentMethod(NULL);
Brian Carlstromce888532013-10-10 00:32:58 -0700271 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
272 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogersef28b142012-11-30 14:22:18 -0800273 return soa.Self()->GetClassLoaderOverride();
Brian Carlstrom00fae582011-10-28 01:16:28 -0700274 }
Brian Carlstromce888532013-10-10 00:32:58 -0700275 // If we have a method, use its ClassLoader for context.
276 if (method != NULL) {
277 return method->GetDeclaringClass()->GetClassLoader();
278 }
279 // We don't have a method, so try to use the system ClassLoader.
280 ClassLoader* class_loader = soa.Decode<ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
281 if (class_loader != NULL) {
282 return class_loader;
283 }
284 // See if the override ClassLoader is set for gtests.
285 class_loader = soa.Self()->GetClassLoaderOverride();
286 if (class_loader != NULL) {
287 // If so, CommonTest should have set UseCompileTimeClassPath.
288 CHECK(Runtime::Current()->UseCompileTimeClassPath());
289 return class_loader;
290 }
291 // Use the BOOTCLASSPATH.
292 return NULL;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700293}
294
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700295static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
296 const char* sig, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700297 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800298 Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(jni_class));
299 if (c == nullptr) {
300 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700301 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700302
Brian Carlstromea46f952013-07-30 01:26:50 -0700303 ArtField* field = NULL;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700304 Class* field_type;
305 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
306 if (sig[1] != '\0') {
Mathieu Chartier590fee92013-09-13 13:46:47 -0700307 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), GetClassLoader(soa));
308 field_type = class_linker->FindClass(sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700309 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700310 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700311 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700312 if (field_type == NULL) {
313 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700314 DCHECK(soa.Self()->IsExceptionPending());
Ian Rogers62d6c772013-02-27 08:32:07 -0800315 ThrowLocation throw_location;
Brian Carlstromea46f952013-07-30 01:26:50 -0700316 SirtRef<Throwable> cause(soa.Self(), soa.Self()->GetException(&throw_location));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700317 soa.Self()->ClearException();
Ian Rogers62d6c772013-02-27 08:32:07 -0800318 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
319 "no type \"%s\" found and so no field \"%s\" could be found in class "
320 "\"%s\" or its superclasses", sig, name,
321 ClassHelper(c).GetDescriptor());
322 soa.Self()->GetException(NULL)->SetCause(cause.get());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700323 return NULL;
324 }
325 if (is_static) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800326 field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700327 } else {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800328 field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700329 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700330 if (field == NULL) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800331 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
332 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
333 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
334 sig, name, ClassHelper(c).GetDescriptor());
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700335 return NULL;
336 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700337 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700338}
339
Mathieu Chartier423d2a32013-09-12 17:33:56 -0700340static void PinPrimitiveArray(const ScopedObjectAccess& soa, Array* array)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700341 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700342 JavaVMExt* vm = soa.Vm();
Ian Rogers50b35e22012-10-04 10:09:15 -0700343 MutexLock mu(soa.Self(), vm->pins_lock);
Elliott Hughes75770752011-08-24 17:52:38 -0700344 vm->pin_table.Add(array);
345}
346
Mathieu Chartier423d2a32013-09-12 17:33:56 -0700347static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, Array* array)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700348 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700349 JavaVMExt* vm = soa.Vm();
Ian Rogers50b35e22012-10-04 10:09:15 -0700350 MutexLock mu(soa.Self(), vm->pins_lock);
Elliott Hughes75770752011-08-24 17:52:38 -0700351 vm->pin_table.Remove(array);
352}
353
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700354static void ThrowAIOOBE(ScopedObjectAccess& soa, Array* array, jsize start,
355 jsize length, const char* identifier)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700356 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700357 std::string type(PrettyTypeOf(array));
Ian Rogers62d6c772013-02-27 08:32:07 -0800358 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
359 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;",
360 "%s offset=%d length=%d %s.length=%d",
361 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700362}
Ian Rogers0571d352011-11-03 19:51:38 -0700363
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700364static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
365 jsize array_length)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700366 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800367 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
368 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
369 "offset=%d length=%d string.length()=%d", start, length,
370 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700371}
Elliott Hughes814e4032011-08-23 12:07:56 -0700372
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700373int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700374 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700375 // Turn the const char* into a java.lang.String.
376 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
377 if (msg != NULL && s.get() == NULL) {
378 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700379 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700380
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700381 // Choose an appropriate constructor and set up the arguments.
382 jvalue args[2];
383 const char* signature;
384 if (msg == NULL && cause == NULL) {
385 signature = "()V";
386 } else if (msg != NULL && cause == NULL) {
387 signature = "(Ljava/lang/String;)V";
388 args[0].l = s.get();
389 } else if (msg == NULL && cause != NULL) {
390 signature = "(Ljava/lang/Throwable;)V";
391 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700392 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700393 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
394 args[0].l = s.get();
395 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700396 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700397 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
398 if (mid == NULL) {
Ian Rogersef28b142012-11-30 14:22:18 -0800399 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700400 LOG(ERROR) << "No <init>" << signature << " in "
401 << PrettyClass(soa.Decode<Class*>(exception_class));
402 return JNI_ERR;
403 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700404
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700405 ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
406 if (exception.get() == NULL) {
407 return JNI_ERR;
408 }
Ian Rogersef28b142012-11-30 14:22:18 -0800409 ScopedObjectAccess soa(env);
Ian Rogers62d6c772013-02-27 08:32:07 -0800410 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
411 soa.Self()->SetException(throw_location, soa.Decode<Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700412 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700413}
414
Elliott Hughes462c9442012-03-23 18:47:50 -0700415static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
Elliott Hughes75770752011-08-24 17:52:38 -0700416 if (vm == NULL || p_env == NULL) {
417 return JNI_ERR;
418 }
419
Elliott Hughes462c9442012-03-23 18:47:50 -0700420 // Return immediately if we're already attached.
Elliott Hughescac6cc72011-11-03 20:31:21 -0700421 Thread* self = Thread::Current();
422 if (self != NULL) {
423 *p_env = self->GetJniEnv();
424 return JNI_OK;
425 }
426
427 Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime;
428
429 // No threads allowed in zygote mode.
430 if (runtime->IsZygote()) {
431 LOG(ERROR) << "Attempt to attach a thread in the zygote";
432 return JNI_ERR;
433 }
434
Elliott Hughes462c9442012-03-23 18:47:50 -0700435 JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
436 const char* thread_name = NULL;
Ian Rogers365c1022012-06-22 15:05:28 -0700437 jobject thread_group = NULL;
Elliott Hughes462c9442012-03-23 18:47:50 -0700438 if (args != NULL) {
Elliott Hughes83a25322013-03-14 11:18:53 -0700439 if (IsBadJniVersion(args->version)) {
440 LOG(ERROR) << "Bad JNI version passed to "
441 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
442 << args->version;
443 return JNI_EVERSION;
Brian Carlstrom86922152013-03-12 00:59:36 -0700444 }
Elliott Hughes462c9442012-03-23 18:47:50 -0700445 thread_name = args->name;
Ian Rogers365c1022012-06-22 15:05:28 -0700446 thread_group = args->group;
Elliott Hughes75770752011-08-24 17:52:38 -0700447 }
Elliott Hughes75770752011-08-24 17:52:38 -0700448
Mathieu Chartier664bebf2012-11-12 16:54:11 -0800449 if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700450 *p_env = NULL;
451 return JNI_ERR;
452 } else {
453 *p_env = Thread::Current()->GetJniEnv();
454 return JNI_OK;
455 }
Elliott Hughes75770752011-08-24 17:52:38 -0700456}
457
Elliott Hughes79082e32011-08-25 12:07:32 -0700458class SharedLibrary {
459 public:
460 SharedLibrary(const std::string& path, void* handle, Object* class_loader)
461 : path_(path),
462 handle_(handle),
Shih-wei Liao31384c52011-09-06 15:27:45 -0700463 class_loader_(class_loader),
Elliott Hughes8daa0922011-09-11 13:46:25 -0700464 jni_on_load_lock_("JNI_OnLoad lock"),
Ian Rogersc604d732012-10-14 16:09:54 -0700465 jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700466 jni_on_load_thread_id_(Thread::Current()->GetThreadId()),
Elliott Hughes79082e32011-08-25 12:07:32 -0700467 jni_on_load_result_(kPending) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700468 }
469
Elliott Hughes79082e32011-08-25 12:07:32 -0700470 Object* GetClassLoader() {
471 return class_loader_;
472 }
473
474 std::string GetPath() {
475 return path_;
476 }
477
478 /*
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700479 * Check the result of an earlier call to JNI_OnLoad on this library.
480 * If the call has not yet finished in another thread, wait for it.
Elliott Hughes79082e32011-08-25 12:07:32 -0700481 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700482 bool CheckOnLoadResult()
483 LOCKS_EXCLUDED(jni_on_load_lock_)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700484 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700485 Thread* self = Thread::Current();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700486 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
487 bool okay;
488 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700489 MutexLock mu(self, jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700490
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700491 if (jni_on_load_thread_id_ == self->GetThreadId()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700492 // Check this so we don't end up waiting for ourselves. We need to return "true" so the
493 // caller can continue.
494 LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
495 okay = true;
496 } else {
497 while (jni_on_load_result_ == kPending) {
498 VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
Ian Rogersc604d732012-10-14 16:09:54 -0700499 jni_on_load_cond_.Wait(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700500 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700501
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700502 okay = (jni_on_load_result_ == kOkay);
503 VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
504 << (okay ? "succeeded" : "failed") << "]";
505 }
506 }
507 self->TransitionFromSuspendedToRunnable();
Elliott Hughes79082e32011-08-25 12:07:32 -0700508 return okay;
509 }
510
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700511 void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
Ian Rogersc604d732012-10-14 16:09:54 -0700512 Thread* self = Thread::Current();
513 MutexLock mu(self, jni_on_load_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700514
Elliott Hughes79082e32011-08-25 12:07:32 -0700515 jni_on_load_result_ = result ? kOkay : kFailed;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700516 jni_on_load_thread_id_ = 0;
Elliott Hughes79082e32011-08-25 12:07:32 -0700517
518 // Broadcast a wakeup to anybody sleeping on the condition variable.
Ian Rogersc604d732012-10-14 16:09:54 -0700519 jni_on_load_cond_.Broadcast(self);
Elliott Hughes79082e32011-08-25 12:07:32 -0700520 }
521
522 void* FindSymbol(const std::string& symbol_name) {
523 return dlsym(handle_, symbol_name.c_str());
524 }
525
526 private:
527 enum JNI_OnLoadState {
528 kPending,
529 kFailed,
530 kOkay,
531 };
532
533 // Path to library "/system/lib/libjni.so".
534 std::string path_;
535
536 // The void* returned by dlopen(3).
537 void* handle_;
538
539 // The ClassLoader this library is associated with.
540 Object* class_loader_;
541
542 // Guards remaining items.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700543 Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Elliott Hughes79082e32011-08-25 12:07:32 -0700544 // Wait for JNI_OnLoad in other thread.
Ian Rogersc604d732012-10-14 16:09:54 -0700545 ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700546 // Recursive invocation guard.
Elliott Hughesf8349362012-06-18 15:00:06 -0700547 uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700548 // Result of earlier JNI_OnLoad call.
Elliott Hughesf8349362012-06-18 15:00:06 -0700549 JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700550};
551
Elliott Hughes79082e32011-08-25 12:07:32 -0700552// This exists mainly to keep implementation details out of the header file.
553class Libraries {
554 public:
555 Libraries() {
556 }
557
558 ~Libraries() {
Elliott Hughesc31664f2011-09-29 15:58:28 -0700559 STLDeleteValues(&libraries_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700560 }
561
Elliott Hughesae80b492012-04-24 10:43:17 -0700562 void Dump(std::ostream& os) const {
563 bool first = true;
Mathieu Chartier02e25112013-08-14 16:14:24 -0700564 for (const auto& library : libraries_) {
Elliott Hughesae80b492012-04-24 10:43:17 -0700565 if (!first) {
566 os << ' ';
567 }
568 first = false;
Mathieu Chartier02e25112013-08-14 16:14:24 -0700569 os << library.first;
Elliott Hughesae80b492012-04-24 10:43:17 -0700570 }
571 }
572
573 size_t size() const {
574 return libraries_.size();
575 }
576
Elliott Hughes79082e32011-08-25 12:07:32 -0700577 SharedLibrary* Get(const std::string& path) {
Mathieu Chartier02e25112013-08-14 16:14:24 -0700578 auto it = libraries_.find(path);
Ian Rogers712462a2012-04-12 16:32:29 -0700579 return (it == libraries_.end()) ? NULL : it->second;
Elliott Hughes79082e32011-08-25 12:07:32 -0700580 }
581
582 void Put(const std::string& path, SharedLibrary* library) {
Elliott Hughesa0e18062012-04-13 15:59:59 -0700583 libraries_.Put(path, library);
Elliott Hughes79082e32011-08-25 12:07:32 -0700584 }
585
586 // See section 11.3 "Linking Native Methods" of the JNI spec.
Brian Carlstromea46f952013-07-30 01:26:50 -0700587 void* FindNativeMethod(const ArtMethod* m, std::string& detail)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700588 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700589 std::string jni_short_name(JniShortName(m));
590 std::string jni_long_name(JniLongName(m));
Elliott Hughes4b093bf2011-08-25 13:34:29 -0700591 const ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
Mathieu Chartier02e25112013-08-14 16:14:24 -0700592 for (const auto& lib : libraries_) {
593 SharedLibrary* library = lib.second;
Elliott Hughes79082e32011-08-25 12:07:32 -0700594 if (library->GetClassLoader() != declaring_class_loader) {
595 // We only search libraries loaded by the appropriate ClassLoader.
596 continue;
597 }
598 // Try the short name then the long name...
599 void* fn = library->FindSymbol(jni_short_name);
600 if (fn == NULL) {
601 fn = library->FindSymbol(jni_long_name);
602 }
603 if (fn != NULL) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800604 VLOG(jni) << "[Found native code for " << PrettyMethod(m)
605 << " in \"" << library->GetPath() << "\"]";
Elliott Hughes79082e32011-08-25 12:07:32 -0700606 return fn;
607 }
608 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700609 detail += "No implementation found for ";
Elliott Hughesa2501992011-08-26 19:39:54 -0700610 detail += PrettyMethod(m);
Brian Carlstrom92827a52011-10-10 15:50:01 -0700611 detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
Elliott Hughes79082e32011-08-25 12:07:32 -0700612 LOG(ERROR) << detail;
Elliott Hughes79082e32011-08-25 12:07:32 -0700613 return NULL;
614 }
615
616 private:
Elliott Hughesa0e18062012-04-13 15:59:59 -0700617 SafeMap<std::string, SharedLibrary*> libraries_;
Elliott Hughes79082e32011-08-25 12:07:32 -0700618};
619
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700620JValue InvokeWithJValues(const ScopedObjectAccess& soa, jobject obj, jmethodID mid,
621 jvalue* args) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700622 ArtMethod* method = soa.DecodeMethod(mid);
Jeff Hao7a549462013-03-18 19:04:24 -0700623 Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700624 MethodHelper mh(method);
Jeff Hao5d917302013-02-27 17:57:33 -0800625 JValue result;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700626 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
Jeff Hao5d917302013-02-27 17:57:33 -0800627 arg_array.BuildArgArray(soa, receiver, args);
Jeff Hao6474d192013-03-26 14:08:09 -0700628 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
629 return result;
Elliott Hughesd07986f2011-12-06 18:27:45 -0800630}
631
Ian Rogersbc939662013-08-15 10:26:54 -0700632#define CHECK_NON_NULL_ARGUMENT(fn, value) \
633 if (UNLIKELY(value == NULL)) { \
634 JniAbortF(#fn, #value " == null"); \
635 }
636
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700637#define CHECK_NON_NULL_MEMCPY_ARGUMENT(fn, length, value) \
638 if (UNLIKELY(length != 0 && value == NULL)) { \
639 JniAbortF(#fn, #value " == null"); \
640 }
641
Elliott Hughescdf53122011-08-19 15:46:09 -0700642class JNI {
643 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700644 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700645 return JNI_VERSION_1_6;
646 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700647
Ian Rogers25e8b912012-09-07 11:31:36 -0700648 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700649 LOG(WARNING) << "JNI DefineClass is not supported";
Elliott Hughesf2682d52011-08-15 16:37:04 -0700650 return NULL;
651 }
652
Elliott Hughescdf53122011-08-19 15:46:09 -0700653 static jclass FindClass(JNIEnv* env, const char* name) {
Ian Rogersbc939662013-08-15 10:26:54 -0700654 CHECK_NON_NULL_ARGUMENT(FindClass, name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700655 Runtime* runtime = Runtime::Current();
656 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700657 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700658 ScopedObjectAccess soa(env);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700659 Class* c = NULL;
660 if (runtime->IsStarted()) {
Mathieu Chartier590fee92013-09-13 13:46:47 -0700661 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), GetClassLoader(soa));
662 c = class_linker->FindClass(descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700663 } else {
Elliott Hughesc3b77c72011-12-15 20:56:48 -0800664 c = class_linker->FindSystemClass(descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700665 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700666 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700667 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700668
Elliott Hughescdf53122011-08-19 15:46:09 -0700669 static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
Ian Rogersbc939662013-08-15 10:26:54 -0700670 CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, java_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700671 ScopedObjectAccess soa(env);
Brian Carlstromea46f952013-07-30 01:26:50 -0700672 jobject art_method = env->GetObjectField(java_method,
673 WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
674 ArtMethod* method = soa.Decode<ArtMethod*>(art_method);
675 DCHECK(method != NULL);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700676 return soa.EncodeMethod(method);
Elliott Hughesf2682d52011-08-15 16:37:04 -0700677 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700678
Elliott Hughescdf53122011-08-19 15:46:09 -0700679 static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) {
Ian Rogersbc939662013-08-15 10:26:54 -0700680 CHECK_NON_NULL_ARGUMENT(FromReflectedField, java_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700681 ScopedObjectAccess soa(env);
Brian Carlstromea46f952013-07-30 01:26:50 -0700682 jobject art_field = env->GetObjectField(java_field,
683 WellKnownClasses::java_lang_reflect_Field_artField);
684 ArtField* field = soa.Decode<ArtField*>(art_field);
685 DCHECK(field != NULL);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700686 return soa.EncodeField(field);
Elliott Hughescdf53122011-08-19 15:46:09 -0700687 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700688
Elliott Hughescdf53122011-08-19 15:46:09 -0700689 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Ian Rogersbc939662013-08-15 10:26:54 -0700690 CHECK_NON_NULL_ARGUMENT(ToReflectedMethod, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700691 ScopedObjectAccess soa(env);
Brian Carlstromea46f952013-07-30 01:26:50 -0700692 ArtMethod* m = soa.DecodeMethod(mid);
693 jobject art_method = soa.AddLocalReference<jobject>(m);
694 jobject reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
695 if (env->ExceptionCheck()) {
696 return NULL;
697 }
698 SetObjectField(env,
699 reflect_method,
700 WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod,
701 art_method);
702 return reflect_method;
Elliott Hughescdf53122011-08-19 15:46:09 -0700703 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700704
Elliott Hughescdf53122011-08-19 15:46:09 -0700705 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Ian Rogersbc939662013-08-15 10:26:54 -0700706 CHECK_NON_NULL_ARGUMENT(ToReflectedField, fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700707 ScopedObjectAccess soa(env);
Brian Carlstromea46f952013-07-30 01:26:50 -0700708 ArtField* f = soa.DecodeField(fid);
709 jobject art_field = soa.AddLocalReference<jobject>(f);
710 jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
711 if (env->ExceptionCheck()) {
712 return NULL;
713 }
714 SetObjectField(env,
715 reflect_field,
716 WellKnownClasses::java_lang_reflect_Field_artField,
717 art_field);
718 return reflect_field;
Elliott Hughescdf53122011-08-19 15:46:09 -0700719 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700720
Elliott Hughes37f7a402011-08-22 18:56:01 -0700721 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Ian Rogersbc939662013-08-15 10:26:54 -0700722 CHECK_NON_NULL_ARGUMENT(GetObjectClass, java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700723 ScopedObjectAccess soa(env);
724 Object* o = soa.Decode<Object*>(java_object);
725 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700726 }
727
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700728 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Ian Rogersbc939662013-08-15 10:26:54 -0700729 CHECK_NON_NULL_ARGUMENT(GetSuperclass, java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700730 ScopedObjectAccess soa(env);
731 Class* c = soa.Decode<Class*>(java_class);
732 return soa.AddLocalReference<jclass>(c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700733 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700734
Elliott Hughes37f7a402011-08-22 18:56:01 -0700735 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogersbc939662013-08-15 10:26:54 -0700736 CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class1);
737 CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class2);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700738 ScopedObjectAccess soa(env);
739 Class* c1 = soa.Decode<Class*>(java_class1);
740 Class* c2 = soa.Decode<Class*>(java_class2);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700741 return c1->IsAssignableFrom(c2) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700742 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700743
Elliott Hughese84278b2012-03-22 10:06:53 -0700744 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogersbc939662013-08-15 10:26:54 -0700745 CHECK_NON_NULL_ARGUMENT(IsInstanceOf, java_class);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700746 if (jobj == NULL) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700747 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700748 return JNI_TRUE;
749 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700750 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700751 Object* obj = soa.Decode<Object*>(jobj);
752 Class* c = soa.Decode<Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700753 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700754 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700755 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700756
Elliott Hughes37f7a402011-08-22 18:56:01 -0700757 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700758 ScopedObjectAccess soa(env);
759 Throwable* exception = soa.Decode<Throwable*>(java_exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700760 if (exception == NULL) {
761 return JNI_ERR;
762 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800763 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
764 soa.Self()->SetException(throw_location, exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700765 return JNI_OK;
766 }
767
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700768 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogersbc939662013-08-15 10:26:54 -0700769 CHECK_NON_NULL_ARGUMENT(ThrowNew, c);
Elliott Hughesa4f94742012-05-29 16:28:38 -0700770 return ThrowNewException(env, c, msg, NULL);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700771 }
772
773 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700774 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700775 }
776
777 static void ExceptionClear(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700778 static_cast<JNIEnvExt*>(env)->self->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700779 }
780
781 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700782 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700783
Brian Carlstromea46f952013-07-30 01:26:50 -0700784 SirtRef<Object> old_throw_this_object(soa.Self(), NULL);
785 SirtRef<ArtMethod> old_throw_method(soa.Self(), NULL);
786 SirtRef<Throwable> old_exception(soa.Self(), NULL);
Ian Rogers62d6c772013-02-27 08:32:07 -0800787 uint32_t old_throw_dex_pc;
788 {
789 ThrowLocation old_throw_location;
Brian Carlstromea46f952013-07-30 01:26:50 -0700790 Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
Ian Rogers62d6c772013-02-27 08:32:07 -0800791 old_throw_this_object.reset(old_throw_location.GetThis());
792 old_throw_method.reset(old_throw_location.GetMethod());
793 old_exception.reset(old_exception_obj);
794 old_throw_dex_pc = old_throw_location.GetDexPc();
795 soa.Self()->ClearException();
796 }
797 ScopedLocalRef<jthrowable> exception(env, soa.AddLocalReference<jthrowable>(old_exception.get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700798 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
799 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
800 if (mid == NULL) {
801 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Ian Rogers62d6c772013-02-27 08:32:07 -0800802 << PrettyTypeOf(old_exception.get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700803 } else {
804 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800805 if (soa.Self()->IsExceptionPending()) {
806 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(NULL))
Elliott Hughes72025e52011-08-23 17:50:30 -0700807 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800808 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700809 }
810 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800811 ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(),
812 old_throw_dex_pc);
Elliott Hughes72025e52011-08-23 17:50:30 -0700813
Ian Rogers62d6c772013-02-27 08:32:07 -0800814 soa.Self()->SetException(gc_safe_throw_location, old_exception.get());
Elliott Hughescdf53122011-08-19 15:46:09 -0700815 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700816
Elliott Hughescdf53122011-08-19 15:46:09 -0700817 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700818 ScopedObjectAccess soa(env);
Ian Rogers62d6c772013-02-27 08:32:07 -0800819 Object* exception = soa.Self()->GetException(NULL);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700820 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700821 }
822
Ian Rogers25e8b912012-09-07 11:31:36 -0700823 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700824 LOG(FATAL) << "JNI FatalError called: " << msg;
825 }
826
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700827 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Ian Rogersef28b142012-11-30 14:22:18 -0800828 if (EnsureLocalCapacity(env, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700829 return JNI_ERR;
830 }
Ian Rogersef28b142012-11-30 14:22:18 -0800831 static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700832 return JNI_OK;
833 }
834
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700835 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700836 ScopedObjectAccess soa(env);
837 Object* survivor = soa.Decode<Object*>(java_survivor);
838 soa.Env()->PopFrame();
839 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700840 }
841
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700842 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Ian Rogersef28b142012-11-30 14:22:18 -0800843 return EnsureLocalCapacity(env, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700844 }
845
Elliott Hughescdf53122011-08-19 15:46:09 -0700846 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700847 if (obj == NULL) {
848 return NULL;
849 }
Ian Rogers25e8b912012-09-07 11:31:36 -0700850 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700851 JavaVMExt* vm = soa.Vm();
Elliott Hughescdf53122011-08-19 15:46:09 -0700852 IndirectReferenceTable& globals = vm->globals;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700853 Object* decoded_obj = soa.Decode<Object*>(obj);
Ian Rogersb8a0b942013-08-20 18:09:52 -0700854 WriterMutexLock mu(soa.Self(), vm->globals_lock);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700855 IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700856 return reinterpret_cast<jobject>(ref);
857 }
858
859 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700860 if (obj == NULL) {
861 return;
862 }
Ian Rogersef28b142012-11-30 14:22:18 -0800863 JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughescdf53122011-08-19 15:46:09 -0700864 IndirectReferenceTable& globals = vm->globals;
Ian Rogersef28b142012-11-30 14:22:18 -0800865 Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
Ian Rogersb8a0b942013-08-20 18:09:52 -0700866 WriterMutexLock mu(self, vm->globals_lock);
Elliott Hughescdf53122011-08-19 15:46:09 -0700867
868 if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
869 LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
870 << "failed to find entry";
871 }
872 }
873
874 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700875 ScopedObjectAccess soa(env);
876 return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj));
Elliott Hughescdf53122011-08-19 15:46:09 -0700877 }
878
879 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -0700880 if (obj != nullptr) {
881 ScopedObjectAccess soa(env);
882 soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700883 }
884 }
885
886 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700887 if (obj == NULL) {
888 return NULL;
889 }
Ian Rogers25e8b912012-09-07 11:31:36 -0700890 ScopedObjectAccess soa(env);
Elliott Hughes9dcd45c2013-07-29 14:40:52 -0700891 return soa.AddLocalReference<jobject>(soa.Decode<Object*>(obj));
Elliott Hughescdf53122011-08-19 15:46:09 -0700892 }
893
894 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700895 if (obj == NULL) {
896 return;
897 }
Ian Rogersef28b142012-11-30 14:22:18 -0800898 IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
Elliott Hughescdf53122011-08-19 15:46:09 -0700899
Ian Rogersef28b142012-11-30 14:22:18 -0800900 uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
Elliott Hughescdf53122011-08-19 15:46:09 -0700901 if (!locals.Remove(cookie, obj)) {
902 // Attempting to delete a local reference that is not in the
903 // topmost local reference frame is a no-op. DeleteLocalRef returns
904 // void and doesn't throw any exceptions, but we should probably
905 // complain about it so the user will notice that things aren't
906 // going quite the way they expect.
907 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
908 << "failed to find entry";
909 }
910 }
911
912 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700913 if (obj1 == obj2) {
914 return JNI_TRUE;
915 } else {
916 ScopedObjectAccess soa(env);
917 return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2)) ? JNI_TRUE : JNI_FALSE;
918 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700919 }
920
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700921 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Ian Rogersbc939662013-08-15 10:26:54 -0700922 CHECK_NON_NULL_ARGUMENT(AllocObject, java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700923 ScopedObjectAccess soa(env);
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800924 Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class));
925 if (c == nullptr) {
926 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700927 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700928 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700929 }
930
Ian Rogersbc939662013-08-15 10:26:54 -0700931 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700932 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700933 va_start(args, mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700934 CHECK_NON_NULL_ARGUMENT(NewObject, java_class);
935 CHECK_NON_NULL_ARGUMENT(NewObject, mid);
936 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700937 va_end(args);
938 return result;
939 }
940
Elliott Hughes72025e52011-08-23 17:50:30 -0700941 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -0700942 CHECK_NON_NULL_ARGUMENT(NewObjectV, java_class);
943 CHECK_NON_NULL_ARGUMENT(NewObjectV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700944 ScopedObjectAccess soa(env);
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800945 Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class));
946 if (c == nullptr) {
947 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700948 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700949 Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800950 if (result == nullptr) {
951 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700952 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700953 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700954 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700955 if (!soa.Self()->IsExceptionPending()) {
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700956 return local_result;
957 } else {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800958 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700959 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700960 }
961
Elliott Hughes72025e52011-08-23 17:50:30 -0700962 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -0700963 CHECK_NON_NULL_ARGUMENT(NewObjectA, java_class);
964 CHECK_NON_NULL_ARGUMENT(NewObjectA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700965 ScopedObjectAccess soa(env);
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800966 Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class));
967 if (c == nullptr) {
968 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700969 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700970 Object* result = c->AllocObject(soa.Self());
Elliott Hughes30646832011-10-13 16:59:46 -0700971 if (result == NULL) {
972 return NULL;
973 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700974 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700975 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700976 if (!soa.Self()->IsExceptionPending()) {
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700977 return local_result;
978 } else {
979 return NULL;
980 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700981 }
982
Ian Rogersbc939662013-08-15 10:26:54 -0700983 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
984 CHECK_NON_NULL_ARGUMENT(GetMethodID, java_class);
985 CHECK_NON_NULL_ARGUMENT(GetMethodID, name);
986 CHECK_NON_NULL_ARGUMENT(GetMethodID, sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700987 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700988 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700989 }
990
Ian Rogersbc939662013-08-15 10:26:54 -0700991 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
992 const char* sig) {
993 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, java_class);
994 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, name);
995 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700996 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700997 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700998 }
999
Elliott Hughes72025e52011-08-23 17:50:30 -07001000 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001001 va_list ap;
1002 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001003 CHECK_NON_NULL_ARGUMENT(CallObjectMethod, obj);
1004 CHECK_NON_NULL_ARGUMENT(CallObjectMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001005 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001006 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001007 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001008 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001009 }
1010
Elliott Hughes72025e52011-08-23 17:50:30 -07001011 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001012 CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, obj);
1013 CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001014 ScopedObjectAccess soa(env);
1015 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
1016 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001017 }
1018
Elliott Hughes72025e52011-08-23 17:50:30 -07001019 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001020 CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, obj);
1021 CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001022 ScopedObjectAccess soa(env);
1023 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
1024 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001025 }
1026
Elliott Hughes72025e52011-08-23 17:50:30 -07001027 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001028 va_list ap;
1029 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001030 CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, obj);
1031 CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001032 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001033 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001034 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001035 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001036 }
1037
Elliott Hughes72025e52011-08-23 17:50:30 -07001038 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001039 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, obj);
1040 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001041 ScopedObjectAccess soa(env);
1042 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001043 }
1044
Elliott Hughes72025e52011-08-23 17:50:30 -07001045 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001046 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, obj);
1047 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001048 ScopedObjectAccess soa(env);
1049 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001050 }
1051
Elliott Hughes72025e52011-08-23 17:50:30 -07001052 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001053 va_list ap;
1054 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001055 CHECK_NON_NULL_ARGUMENT(CallByteMethod, obj);
1056 CHECK_NON_NULL_ARGUMENT(CallByteMethod, mid);
1057 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001058 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001059 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001060 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001061 }
1062
Elliott Hughes72025e52011-08-23 17:50:30 -07001063 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001064 CHECK_NON_NULL_ARGUMENT(CallByteMethodV, obj);
1065 CHECK_NON_NULL_ARGUMENT(CallByteMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001066 ScopedObjectAccess soa(env);
1067 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001068 }
1069
Elliott Hughes72025e52011-08-23 17:50:30 -07001070 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001071 CHECK_NON_NULL_ARGUMENT(CallByteMethodA, obj);
1072 CHECK_NON_NULL_ARGUMENT(CallByteMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001073 ScopedObjectAccess soa(env);
1074 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001075 }
1076
Elliott Hughes72025e52011-08-23 17:50:30 -07001077 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001078 va_list ap;
1079 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001080 CHECK_NON_NULL_ARGUMENT(CallCharMethod, obj);
1081 CHECK_NON_NULL_ARGUMENT(CallCharMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001082 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001083 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001084 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001085 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001086 }
1087
Elliott Hughes72025e52011-08-23 17:50:30 -07001088 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001089 CHECK_NON_NULL_ARGUMENT(CallCharMethodV, obj);
1090 CHECK_NON_NULL_ARGUMENT(CallCharMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001091 ScopedObjectAccess soa(env);
1092 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001093 }
1094
Elliott Hughes72025e52011-08-23 17:50:30 -07001095 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001096 CHECK_NON_NULL_ARGUMENT(CallCharMethodA, obj);
1097 CHECK_NON_NULL_ARGUMENT(CallCharMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001098 ScopedObjectAccess soa(env);
1099 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001100 }
1101
Elliott Hughes72025e52011-08-23 17:50:30 -07001102 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001103 va_list ap;
1104 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001105 CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, obj);
1106 CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001107 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001108 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001109 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001110 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001111 }
1112
Elliott Hughes72025e52011-08-23 17:50:30 -07001113 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001114 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, obj);
1115 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001116 ScopedObjectAccess soa(env);
1117 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001118 }
1119
Elliott Hughes72025e52011-08-23 17:50:30 -07001120 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001121 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, obj);
1122 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001123 ScopedObjectAccess soa(env);
1124 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001125 }
1126
Elliott Hughes72025e52011-08-23 17:50:30 -07001127 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001128 va_list ap;
1129 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001130 CHECK_NON_NULL_ARGUMENT(CallFloatMethod, obj);
1131 CHECK_NON_NULL_ARGUMENT(CallFloatMethod, mid);
1132 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001133 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001134 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001135 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001136 }
1137
Elliott Hughes72025e52011-08-23 17:50:30 -07001138 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001139 CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, obj);
1140 CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001141 ScopedObjectAccess soa(env);
1142 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001143 }
1144
Elliott Hughes72025e52011-08-23 17:50:30 -07001145 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001146 CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, obj);
1147 CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001148 ScopedObjectAccess soa(env);
1149 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001150 }
1151
Elliott Hughes72025e52011-08-23 17:50:30 -07001152 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001153 va_list ap;
1154 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001155 CHECK_NON_NULL_ARGUMENT(CallIntMethod, obj);
1156 CHECK_NON_NULL_ARGUMENT(CallIntMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001157 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001158 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001159 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001160 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001161 }
1162
Elliott Hughes72025e52011-08-23 17:50:30 -07001163 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001164 CHECK_NON_NULL_ARGUMENT(CallIntMethodV, obj);
1165 CHECK_NON_NULL_ARGUMENT(CallIntMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001166 ScopedObjectAccess soa(env);
1167 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001168 }
1169
Elliott Hughes72025e52011-08-23 17:50:30 -07001170 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001171 CHECK_NON_NULL_ARGUMENT(CallIntMethodA, obj);
1172 CHECK_NON_NULL_ARGUMENT(CallIntMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001173 ScopedObjectAccess soa(env);
1174 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001175 }
1176
Elliott Hughes72025e52011-08-23 17:50:30 -07001177 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001178 va_list ap;
1179 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001180 CHECK_NON_NULL_ARGUMENT(CallLongMethod, obj);
1181 CHECK_NON_NULL_ARGUMENT(CallLongMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001182 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001183 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001184 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001185 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001186 }
1187
Elliott Hughes72025e52011-08-23 17:50:30 -07001188 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001189 CHECK_NON_NULL_ARGUMENT(CallLongMethodV, obj);
1190 CHECK_NON_NULL_ARGUMENT(CallLongMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001191 ScopedObjectAccess soa(env);
1192 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001193 }
1194
Elliott Hughes72025e52011-08-23 17:50:30 -07001195 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001196 CHECK_NON_NULL_ARGUMENT(CallLongMethodA, obj);
1197 CHECK_NON_NULL_ARGUMENT(CallLongMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001198 ScopedObjectAccess soa(env);
1199 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001200 }
1201
Elliott Hughes72025e52011-08-23 17:50:30 -07001202 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001203 va_list ap;
1204 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001205 CHECK_NON_NULL_ARGUMENT(CallShortMethod, obj);
1206 CHECK_NON_NULL_ARGUMENT(CallShortMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001207 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001208 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001209 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001210 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001211 }
1212
Elliott Hughes72025e52011-08-23 17:50:30 -07001213 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001214 CHECK_NON_NULL_ARGUMENT(CallShortMethodV, obj);
1215 CHECK_NON_NULL_ARGUMENT(CallShortMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001216 ScopedObjectAccess soa(env);
1217 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001218 }
1219
Elliott Hughes72025e52011-08-23 17:50:30 -07001220 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001221 CHECK_NON_NULL_ARGUMENT(CallShortMethodA, obj);
1222 CHECK_NON_NULL_ARGUMENT(CallShortMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001223 ScopedObjectAccess soa(env);
1224 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001225 }
1226
Elliott Hughes72025e52011-08-23 17:50:30 -07001227 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001228 va_list ap;
1229 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001230 CHECK_NON_NULL_ARGUMENT(CallVoidMethod, obj);
1231 CHECK_NON_NULL_ARGUMENT(CallVoidMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001232 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -07001233 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -07001234 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001235 }
1236
Elliott Hughes72025e52011-08-23 17:50:30 -07001237 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001238 CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, obj);
1239 CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001240 ScopedObjectAccess soa(env);
1241 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001242 }
1243
Elliott Hughes72025e52011-08-23 17:50:30 -07001244 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001245 CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, obj);
1246 CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001247 ScopedObjectAccess soa(env);
1248 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001249 }
1250
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001251 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001252 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001253 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001254 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, obj);
1255 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001256 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001257 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1258 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001259 va_end(ap);
1260 return local_result;
1261 }
1262
Ian Rogersbc939662013-08-15 10:26:54 -07001263 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1264 va_list args) {
1265 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, obj);
1266 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001267 ScopedObjectAccess soa(env);
1268 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1269 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001270 }
1271
Ian Rogersbc939662013-08-15 10:26:54 -07001272 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1273 jvalue* args) {
1274 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, obj);
1275 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001276 ScopedObjectAccess soa(env);
1277 JValue result(InvokeWithJValues(soa, obj, mid, args));
1278 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001279 }
1280
Ian Rogersbc939662013-08-15 10:26:54 -07001281 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1282 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001283 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001284 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001285 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, obj);
1286 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001287 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001288 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001289 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001290 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001291 }
1292
Ian Rogersbc939662013-08-15 10:26:54 -07001293 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1294 va_list args) {
1295 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, obj);
1296 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001297 ScopedObjectAccess soa(env);
1298 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001299 }
1300
Ian Rogersbc939662013-08-15 10:26:54 -07001301 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1302 jvalue* args) {
1303 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, obj);
1304 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001305 ScopedObjectAccess soa(env);
1306 return InvokeWithJValues(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001307 }
1308
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001309 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001310 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001311 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001312 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, obj);
1313 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001314 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001315 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001316 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001317 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001318 }
1319
Ian Rogersbc939662013-08-15 10:26:54 -07001320 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1321 va_list args) {
1322 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, obj);
1323 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001324 ScopedObjectAccess soa(env);
1325 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001326 }
1327
Ian Rogersbc939662013-08-15 10:26:54 -07001328 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1329 jvalue* args) {
1330 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, obj);
1331 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001332 ScopedObjectAccess soa(env);
1333 return InvokeWithJValues(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001334 }
1335
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001336 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001337 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001338 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001339 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, obj);
1340 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, mid);
1341 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001342 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001343 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001344 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001345 }
1346
Ian Rogersbc939662013-08-15 10:26:54 -07001347 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1348 va_list args) {
1349 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, obj);
1350 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001351 ScopedObjectAccess soa(env);
1352 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001353 }
1354
Ian Rogersbc939662013-08-15 10:26:54 -07001355 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1356 jvalue* args) {
1357 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, obj);
1358 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001359 ScopedObjectAccess soa(env);
1360 return InvokeWithJValues(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001361 }
1362
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001363 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001364 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001365 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001366 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, obj);
1367 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001368 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001369 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001370 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001371 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001372 }
1373
Ian Rogersbc939662013-08-15 10:26:54 -07001374 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1375 va_list args) {
1376 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, obj);
1377 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001378 ScopedObjectAccess soa(env);
1379 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001380 }
1381
Ian Rogersbc939662013-08-15 10:26:54 -07001382 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1383 jvalue* args) {
1384 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, obj);
1385 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001386 ScopedObjectAccess soa(env);
1387 return InvokeWithJValues(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001388 }
1389
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001390 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001391 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001392 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001393 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, obj);
1394 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001395 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001396 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001397 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001398 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001399 }
1400
Ian Rogersbc939662013-08-15 10:26:54 -07001401 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1402 va_list args) {
1403 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, obj);
1404 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001405 ScopedObjectAccess soa(env);
1406 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001407 }
1408
Ian Rogersbc939662013-08-15 10:26:54 -07001409 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1410 jvalue* args) {
1411 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, obj);
1412 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001413 ScopedObjectAccess soa(env);
1414 return InvokeWithJValues(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001415 }
1416
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001417 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001418 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001419 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001420 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, obj);
1421 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001422 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001423 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001424 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001425 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 }
1427
Ian Rogersbc939662013-08-15 10:26:54 -07001428 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1429 va_list args) {
1430 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, obj);
1431 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001432 ScopedObjectAccess soa(env);
1433 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001434 }
1435
Ian Rogersbc939662013-08-15 10:26:54 -07001436 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1437 jvalue* args) {
1438 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, obj);
1439 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001440 ScopedObjectAccess soa(env);
1441 return InvokeWithJValues(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001442 }
1443
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001444 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001445 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001446 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001447 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, obj);
1448 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001449 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001450 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001451 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001452 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001453 }
1454
Ian Rogersbc939662013-08-15 10:26:54 -07001455 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1456 va_list args) {
1457 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, obj);
1458 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001459 ScopedObjectAccess soa(env);
1460 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001461 }
1462
Ian Rogersbc939662013-08-15 10:26:54 -07001463 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1464 jvalue* args) {
1465 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, obj);
1466 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001467 ScopedObjectAccess soa(env);
1468 return InvokeWithJValues(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001469 }
1470
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001471 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001472 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001473 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001474 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, obj);
1475 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001476 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001477 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001478 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001479 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 }
1481
Ian Rogersbc939662013-08-15 10:26:54 -07001482 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1483 va_list args) {
1484 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, obj);
1485 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001486 ScopedObjectAccess soa(env);
1487 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001488 }
1489
Ian Rogersbc939662013-08-15 10:26:54 -07001490 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1491 jvalue* args) {
1492 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, obj);
1493 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001494 ScopedObjectAccess soa(env);
1495 return InvokeWithJValues(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001496 }
1497
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001498 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001499 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001500 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001501 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, obj);
1502 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001503 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001504 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001505 va_end(ap);
1506 }
1507
Brian Carlstromea46f952013-07-30 01:26:50 -07001508 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1509 va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001510 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, obj);
1511 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001512 ScopedObjectAccess soa(env);
1513 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001514 }
1515
Ian Rogersbc939662013-08-15 10:26:54 -07001516 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1517 jvalue* args) {
1518 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, obj);
1519 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001520 ScopedObjectAccess soa(env);
1521 InvokeWithJValues(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001522 }
1523
Ian Rogersbc939662013-08-15 10:26:54 -07001524 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1525 CHECK_NON_NULL_ARGUMENT(GetFieldID, java_class);
1526 CHECK_NON_NULL_ARGUMENT(GetFieldID, name);
1527 CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001528 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001529 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001530 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001531
Ian Rogersbc939662013-08-15 10:26:54 -07001532 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1533 const char* sig) {
1534 CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, java_class);
1535 CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, name);
1536 CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001537 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001538 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001539 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001540
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001541 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001542 CHECK_NON_NULL_ARGUMENT(GetObjectField, obj);
1543 CHECK_NON_NULL_ARGUMENT(GetObjectField, fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001544 ScopedObjectAccess soa(env);
1545 Object* o = soa.Decode<Object*>(obj);
Brian Carlstromea46f952013-07-30 01:26:50 -07001546 ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001547 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001548 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001549
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001550 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001551 CHECK_NON_NULL_ARGUMENT(GetStaticObjectField, fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001552 ScopedObjectAccess soa(env);
Brian Carlstromea46f952013-07-30 01:26:50 -07001553 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001554 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001555 }
1556
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001557 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogersbc939662013-08-15 10:26:54 -07001558 CHECK_NON_NULL_ARGUMENT(SetObjectField, java_object);
1559 CHECK_NON_NULL_ARGUMENT(SetObjectField, fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001560 ScopedObjectAccess soa(env);
1561 Object* o = soa.Decode<Object*>(java_object);
1562 Object* v = soa.Decode<Object*>(java_value);
Brian Carlstromea46f952013-07-30 01:26:50 -07001563 ArtField* f = soa.DecodeField(fid);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001564 f->SetObject(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001565 }
1566
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001567 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogersbc939662013-08-15 10:26:54 -07001568 CHECK_NON_NULL_ARGUMENT(SetStaticObjectField, fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001569 ScopedObjectAccess soa(env);
1570 Object* v = soa.Decode<Object*>(java_value);
Brian Carlstromea46f952013-07-30 01:26:50 -07001571 ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001572 f->SetObject(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001573 }
1574
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001575#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogersbc939662013-08-15 10:26:54 -07001576 CHECK_NON_NULL_ARGUMENT(Get #fn Field, instance); \
1577 CHECK_NON_NULL_ARGUMENT(Get #fn Field, fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001578 ScopedObjectAccess soa(env); \
1579 Object* o = soa.Decode<Object*>(instance); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001580 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001581 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001582
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001583#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogersbc939662013-08-15 10:26:54 -07001584 CHECK_NON_NULL_ARGUMENT(GetStatic #fn Field, fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001585 ScopedObjectAccess soa(env); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001586 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001587 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001588
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001589#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogersbc939662013-08-15 10:26:54 -07001590 CHECK_NON_NULL_ARGUMENT(Set #fn Field, instance); \
1591 CHECK_NON_NULL_ARGUMENT(Set #fn Field, fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001592 ScopedObjectAccess soa(env); \
1593 Object* o = soa.Decode<Object*>(instance); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001594 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001595 f->Set ##fn(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001596
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001597#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogersbc939662013-08-15 10:26:54 -07001598 CHECK_NON_NULL_ARGUMENT(SetStatic #fn Field, fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001599 ScopedObjectAccess soa(env); \
Brian Carlstromea46f952013-07-30 01:26:50 -07001600 ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001601 f->Set ##fn(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001602
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001603 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001604 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001605 }
1606
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001607 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001608 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001609 }
1610
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001611 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001612 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001613 }
1614
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001615 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001616 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001617 }
1618
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001619 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001620 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001621 }
1622
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001623 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001624 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001625 }
1626
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001627 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001628 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001629 }
1630
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001631 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001632 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001633 }
1634
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001635 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001636 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001637 }
1638
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001639 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001640 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001641 }
1642
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001643 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001644 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001645 }
1646
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001647 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001648 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001649 }
1650
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001651 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001652 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001653 }
1654
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001655 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001656 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001657 }
1658
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001659 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001660 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001661 }
1662
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001663 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001664 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001665 }
1666
1667 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001668 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001669 }
1670
1671 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001672 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001673 }
1674
1675 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001676 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001677 }
1678
1679 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001680 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001681 }
1682
1683 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001684 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001685 }
1686
1687 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001688 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001689 }
1690
1691 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001692 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001693 }
1694
1695 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001696 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001697 }
1698
1699 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001700 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001701 }
1702
1703 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001704 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001705 }
1706
1707 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001708 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001709 }
1710
1711 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001712 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001713 }
1714
1715 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001716 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001717 }
1718
1719 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001720 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001721 }
1722
1723 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001724 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001725 }
1726
1727 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001728 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001729 }
1730
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001731 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001732 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001733 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001734 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001735 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001736 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1737 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001738 va_end(ap);
1739 return local_result;
1740 }
1741
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001742 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001743 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001744 ScopedObjectAccess soa(env);
1745 JValue result(InvokeWithVarArgs(soa, NULL, mid, args));
1746 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001747 }
1748
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001749 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001750 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001751 ScopedObjectAccess soa(env);
1752 JValue result(InvokeWithJValues(soa, NULL, mid, args));
1753 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001754 }
1755
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001756 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001757 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001758 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001759 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001760 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001761 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001762 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001763 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001764 }
1765
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001766 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001767 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001768 ScopedObjectAccess soa(env);
1769 return InvokeWithVarArgs(soa, NULL, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001770 }
1771
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001772 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001773 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001774 ScopedObjectAccess soa(env);
1775 return InvokeWithJValues(soa, NULL, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001776 }
1777
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001778 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001779 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001780 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001781 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001782 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001783 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001784 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001785 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001786 }
1787
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001788 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001789 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001790 ScopedObjectAccess soa(env);
1791 return InvokeWithVarArgs(soa, NULL, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001792 }
1793
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001794 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001795 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001796 ScopedObjectAccess soa(env);
1797 return InvokeWithJValues(soa, NULL, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001798 }
1799
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001800 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001801 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001802 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001803 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001804 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001805 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001806 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001807 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001808 }
1809
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001810 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001811 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001812 ScopedObjectAccess soa(env);
1813 return InvokeWithVarArgs(soa, NULL, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001814 }
1815
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001816 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001817 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001818 ScopedObjectAccess soa(env);
1819 return InvokeWithJValues(soa, NULL, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001820 }
1821
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001822 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001823 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001824 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001825 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001826 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001827 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001828 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001829 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001830 }
1831
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001832 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001833 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001834 ScopedObjectAccess soa(env);
1835 return InvokeWithVarArgs(soa, NULL, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001836 }
1837
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001838 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001839 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001840 ScopedObjectAccess soa(env);
1841 return InvokeWithJValues(soa, NULL, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001842 }
1843
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001844 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001845 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001846 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001847 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001848 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001849 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001850 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001851 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001852 }
1853
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001854 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001855 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001856 ScopedObjectAccess soa(env);
1857 return InvokeWithVarArgs(soa, NULL, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001858 }
1859
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001860 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001861 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001862 ScopedObjectAccess soa(env);
1863 return InvokeWithJValues(soa, NULL, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001864 }
1865
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001866 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001867 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001868 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001869 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001870 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001871 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001872 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001873 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001874 }
1875
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001876 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001877 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001878 ScopedObjectAccess soa(env);
1879 return InvokeWithVarArgs(soa, NULL, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001880 }
1881
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001882 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001883 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001884 ScopedObjectAccess soa(env);
1885 return InvokeWithJValues(soa, NULL, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001886 }
1887
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001888 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001889 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001890 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001891 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001892 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001893 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001894 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001895 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001896 }
1897
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001898 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001899 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001900 ScopedObjectAccess soa(env);
1901 return InvokeWithVarArgs(soa, NULL, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001902 }
1903
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001904 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001905 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001906 ScopedObjectAccess soa(env);
1907 return InvokeWithJValues(soa, NULL, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001908 }
1909
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001910 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001911 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001912 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001913 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001914 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001915 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001916 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001917 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001918 }
1919
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001920 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001921 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001922 ScopedObjectAccess soa(env);
1923 return InvokeWithVarArgs(soa, NULL, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001924 }
1925
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001926 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001927 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001928 ScopedObjectAccess soa(env);
1929 return InvokeWithJValues(soa, NULL, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001930 }
1931
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001932 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001933 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001934 va_start(ap, mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001935 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethod, mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001936 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001937 InvokeWithVarArgs(soa, NULL, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001938 va_end(ap);
1939 }
1940
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001941 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001942 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodV, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001943 ScopedObjectAccess soa(env);
1944 InvokeWithVarArgs(soa, NULL, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001945 }
1946
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001947 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogersbc939662013-08-15 10:26:54 -07001948 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodA, mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001949 ScopedObjectAccess soa(env);
1950 InvokeWithJValues(soa, NULL, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001951 }
1952
Elliott Hughes814e4032011-08-23 12:07:56 -07001953 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogersbc939662013-08-15 10:26:54 -07001954 if (UNLIKELY(chars == NULL && char_count > 0)) { \
1955 JniAbortF("NewString", "char == null && char_count > 0"); \
1956 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001957 ScopedObjectAccess soa(env);
Ian Rogers50b35e22012-10-04 10:09:15 -07001958 String* result = String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001959 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001960 }
1961
1962 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001963 if (utf == NULL) {
1964 return NULL;
1965 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001966 ScopedObjectAccess soa(env);
Ian Rogers50b35e22012-10-04 10:09:15 -07001967 String* result = String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001968 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001969 }
1970
Elliott Hughes814e4032011-08-23 12:07:56 -07001971 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogersbc939662013-08-15 10:26:54 -07001972 CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001973 ScopedObjectAccess soa(env);
1974 return soa.Decode<String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001975 }
1976
1977 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogersbc939662013-08-15 10:26:54 -07001978 CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001979 ScopedObjectAccess soa(env);
1980 return soa.Decode<String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001981 }
1982
Ian Rogersbc939662013-08-15 10:26:54 -07001983 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1984 jchar* buf) {
1985 CHECK_NON_NULL_ARGUMENT(GetStringRegion, java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001986 ScopedObjectAccess soa(env);
1987 String* s = soa.Decode<String*>(java_string);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001988 if (start < 0 || length < 0 || start + length > s->GetLength()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001989 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001990 } else {
Ian Rogers4ffdc6b2013-08-21 16:55:13 -07001991 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001992 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1993 memcpy(buf, chars + start, length * sizeof(jchar));
1994 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001995 }
1996
Ian Rogersbc939662013-08-15 10:26:54 -07001997 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1998 char* buf) {
1999 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002000 ScopedObjectAccess soa(env);
2001 String* s = soa.Decode<String*>(java_string);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002002 if (start < 0 || length < 0 || start + length > s->GetLength()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002003 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07002004 } else {
Ian Rogers4ffdc6b2013-08-21 16:55:13 -07002005 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringUTFRegion, length, buf);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002006 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
2007 ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
2008 }
Elliott Hughes814e4032011-08-23 12:07:56 -07002009 }
2010
Elliott Hughes75770752011-08-24 17:52:38 -07002011 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002012 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002013 ScopedObjectAccess soa(env);
2014 String* s = soa.Decode<String*>(java_string);
Mathieu Chartier423d2a32013-09-12 17:33:56 -07002015 CharArray* chars = s->GetCharArray();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002016 PinPrimitiveArray(soa, chars);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002017 if (is_copy != nullptr) {
2018 *is_copy = JNI_TRUE;
Elliott Hughes75770752011-08-24 17:52:38 -07002019 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002020 int32_t char_count = s->GetLength();
2021 int32_t offset = s->GetOffset();
2022 jchar* bytes = new jchar[char_count + 1];
2023 for (int32_t i = 0; i < char_count; i++) {
2024 bytes[i] = chars->Get(i + offset);
2025 }
2026 bytes[char_count] = '\0';
2027 return bytes;
Elliott Hughes814e4032011-08-23 12:07:56 -07002028 }
2029
Mathieu Chartier590fee92013-09-13 13:46:47 -07002030 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogersbc939662013-08-15 10:26:54 -07002031 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002032 delete[] chars;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002033 ScopedObjectAccess soa(env);
2034 UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray());
Elliott Hughescdf53122011-08-19 15:46:09 -07002035 }
2036
Elliott Hughes75770752011-08-24 17:52:38 -07002037 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Elliott Hughes75770752011-08-24 17:52:38 -07002038 return GetStringChars(env, java_string, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002039 }
2040
Elliott Hughes75770752011-08-24 17:52:38 -07002041 static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07002042 return ReleaseStringChars(env, java_string, chars);
Elliott Hughescdf53122011-08-19 15:46:09 -07002043 }
2044
Elliott Hughes75770752011-08-24 17:52:38 -07002045 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Elliott Hughes75770752011-08-24 17:52:38 -07002046 if (java_string == NULL) {
2047 return NULL;
2048 }
2049 if (is_copy != NULL) {
2050 *is_copy = JNI_TRUE;
2051 }
Ian Rogersef28b142012-11-30 14:22:18 -08002052 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002053 String* s = soa.Decode<String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07002054 size_t byte_count = s->GetUtfLength();
2055 char* bytes = new char[byte_count + 1];
Brian Carlstrom7934ac22013-07-26 10:54:15 -07002056 CHECK(bytes != NULL); // bionic aborts anyway.
Elliott Hughes75770752011-08-24 17:52:38 -07002057 const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
2058 ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
2059 bytes[byte_count] = '\0';
2060 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002061 }
2062
Elliott Hughes75770752011-08-24 17:52:38 -07002063 static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07002064 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002065 }
2066
Elliott Hughesbd935992011-08-22 11:59:34 -07002067 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogersbc939662013-08-15 10:26:54 -07002068 CHECK_NON_NULL_ARGUMENT(GetArrayLength, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002069 ScopedObjectAccess soa(env);
2070 Object* obj = soa.Decode<Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07002071 if (UNLIKELY(!obj->IsArrayInstance())) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002072 JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
2073 }
Elliott Hughesbd935992011-08-22 11:59:34 -07002074 Array* array = obj->AsArray();
2075 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07002076 }
2077
Elliott Hughes814e4032011-08-23 12:07:56 -07002078 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Ian Rogersbc939662013-08-15 10:26:54 -07002079 CHECK_NON_NULL_ARGUMENT(GetObjectArrayElement, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002080 ScopedObjectAccess soa(env);
2081 ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
2082 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07002083 }
2084
Ian Rogersbc939662013-08-15 10:26:54 -07002085 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2086 jobject java_value) {
2087 CHECK_NON_NULL_ARGUMENT(SetObjectArrayElement, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002088 ScopedObjectAccess soa(env);
2089 ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
2090 Object* value = soa.Decode<Object*>(java_value);
Elliott Hughescdf53122011-08-19 15:46:09 -07002091 array->Set(index, value);
2092 }
2093
2094 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002095 ScopedObjectAccess soa(env);
2096 return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002097 }
2098
2099 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002100 ScopedObjectAccess soa(env);
2101 return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002102 }
2103
2104 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002105 ScopedObjectAccess soa(env);
2106 return NewPrimitiveArray<jcharArray, CharArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002107 }
2108
2109 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002110 ScopedObjectAccess soa(env);
2111 return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002112 }
2113
2114 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002115 ScopedObjectAccess soa(env);
2116 return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002117 }
2118
2119 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002120 ScopedObjectAccess soa(env);
2121 return NewPrimitiveArray<jintArray, IntArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002122 }
2123
2124 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002125 ScopedObjectAccess soa(env);
2126 return NewPrimitiveArray<jlongArray, LongArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002127 }
2128
2129 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002130 if (length < 0) {
2131 JniAbortF("NewObjectArray", "negative array length: %d", length);
2132 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002133
2134 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07002135 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002136 Class* element_class = soa.Decode<Class*>(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07002137 std::string descriptor;
2138 descriptor += "[";
Ian Rogers6d4d9fc2011-11-30 16:24:48 -08002139 descriptor += ClassHelper(element_class).GetDescriptor();
Elliott Hughescdf53122011-08-19 15:46:09 -07002140
2141 // Find the class.
Brian Carlstromce888532013-10-10 00:32:58 -07002142 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartier590fee92013-09-13 13:46:47 -07002143 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), element_class->GetClassLoader());
2144 Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
Brian Carlstromce888532013-10-10 00:32:58 -07002145 if (array_class == NULL) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002146 return NULL;
2147 }
2148
Elliott Hughes75770752011-08-24 17:52:38 -07002149 // Allocate and initialize if necessary.
Ian Rogers50b35e22012-10-04 10:09:15 -07002150 ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
Elliott Hughes75770752011-08-24 17:52:38 -07002151 if (initial_element != NULL) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002152 Object* initial_object = soa.Decode<Object*>(initial_element);
Elliott Hughes75770752011-08-24 17:52:38 -07002153 for (jsize i = 0; i < length; ++i) {
2154 result->Set(i, initial_object);
2155 }
2156 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002157 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07002158 }
2159
2160 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002161 ScopedObjectAccess soa(env);
2162 return NewPrimitiveArray<jshortArray, ShortArray>(soa, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002163 }
2164
Ian Rogersa15e67d2012-02-28 13:51:55 -08002165 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002166 CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayCritical, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002167 ScopedObjectAccess soa(env);
2168 Array* array = soa.Decode<Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002169 gc::Heap* heap = Runtime::Current()->GetHeap();
2170 if (heap->IsMovableObject(array)) {
2171 heap->IncrementDisableGC(soa.Self());
2172 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
2173 array = soa.Decode<Array*>(java_array);
2174 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002175 PinPrimitiveArray(soa, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002176 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08002177 *is_copy = JNI_FALSE;
2178 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002179 void* address = array->GetRawData(array->GetClass()->GetComponentSize());;
2180 return address;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002181 }
2182
Mathieu Chartier590fee92013-09-13 13:46:47 -07002183 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* elements, jint mode) {
Ian Rogersbc939662013-08-15 10:26:54 -07002184 CHECK_NON_NULL_ARGUMENT(ReleasePrimitiveArrayCritical, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002185 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002186 }
2187
Elliott Hughes75770752011-08-24 17:52:38 -07002188 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002189 CHECK_NON_NULL_ARGUMENT(GetBooleanArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002190 ScopedObjectAccess soa(env);
2191 return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002192 }
2193
Elliott Hughes75770752011-08-24 17:52:38 -07002194 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002195 CHECK_NON_NULL_ARGUMENT(GetByteArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002196 ScopedObjectAccess soa(env);
2197 return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002198 }
2199
Elliott Hughes75770752011-08-24 17:52:38 -07002200 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002201 CHECK_NON_NULL_ARGUMENT(GetCharArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002202 ScopedObjectAccess soa(env);
2203 return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002204 }
2205
Elliott Hughes75770752011-08-24 17:52:38 -07002206 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002207 CHECK_NON_NULL_ARGUMENT(GetDoubleArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002208 ScopedObjectAccess soa(env);
2209 return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002210 }
2211
Elliott Hughes75770752011-08-24 17:52:38 -07002212 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002213 CHECK_NON_NULL_ARGUMENT(GetFloatArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002214 ScopedObjectAccess soa(env);
2215 return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002216 }
2217
Elliott Hughes75770752011-08-24 17:52:38 -07002218 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002219 CHECK_NON_NULL_ARGUMENT(GetIntArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002220 ScopedObjectAccess soa(env);
2221 return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002222 }
2223
Elliott Hughes75770752011-08-24 17:52:38 -07002224 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002225 CHECK_NON_NULL_ARGUMENT(GetLongArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002226 ScopedObjectAccess soa(env);
2227 return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002228 }
2229
Elliott Hughes75770752011-08-24 17:52:38 -07002230 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogersbc939662013-08-15 10:26:54 -07002231 CHECK_NON_NULL_ARGUMENT(GetShortArrayElements, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002232 ScopedObjectAccess soa(env);
2233 return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002234 }
2235
Mathieu Chartier590fee92013-09-13 13:46:47 -07002236 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2237 jint mode) {
2238 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002239 }
2240
Mathieu Chartier590fee92013-09-13 13:46:47 -07002241 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
2242 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002243 }
2244
Mathieu Chartier590fee92013-09-13 13:46:47 -07002245 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
2246 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002247 }
2248
Mathieu Chartier590fee92013-09-13 13:46:47 -07002249 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2250 jint mode) {
2251 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002252 }
2253
Mathieu Chartier590fee92013-09-13 13:46:47 -07002254 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2255 jint mode) {
2256 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002257 }
2258
Mathieu Chartier590fee92013-09-13 13:46:47 -07002259 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
2260 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002261 }
2262
Mathieu Chartier590fee92013-09-13 13:46:47 -07002263 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
2264 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002265 }
2266
Mathieu Chartier590fee92013-09-13 13:46:47 -07002267 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2268 jint mode) {
2269 ReleasePrimitiveArray(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002270 }
2271
Ian Rogersbc939662013-08-15 10:26:54 -07002272 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2273 jboolean* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002274 ScopedObjectAccess soa(env);
2275 GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002276 }
2277
Ian Rogersbc939662013-08-15 10:26:54 -07002278 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2279 jbyte* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002280 ScopedObjectAccess soa(env);
2281 GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002282 }
2283
Ian Rogersbc939662013-08-15 10:26:54 -07002284 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2285 jchar* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002286 ScopedObjectAccess soa(env);
2287 GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002288 }
2289
Ian Rogersbc939662013-08-15 10:26:54 -07002290 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2291 jdouble* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002292 ScopedObjectAccess soa(env);
2293 GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002294 }
2295
Ian Rogersbc939662013-08-15 10:26:54 -07002296 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2297 jfloat* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002298 ScopedObjectAccess soa(env);
2299 GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002300 }
2301
Ian Rogersbc939662013-08-15 10:26:54 -07002302 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2303 jint* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002304 ScopedObjectAccess soa(env);
2305 GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002306 }
2307
Ian Rogersbc939662013-08-15 10:26:54 -07002308 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2309 jlong* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002310 ScopedObjectAccess soa(env);
2311 GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002312 }
2313
Ian Rogersbc939662013-08-15 10:26:54 -07002314 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2315 jshort* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002316 ScopedObjectAccess soa(env);
2317 GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002318 }
2319
Ian Rogersbc939662013-08-15 10:26:54 -07002320 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2321 const jboolean* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002322 ScopedObjectAccess soa(env);
2323 SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002324 }
2325
Ian Rogersbc939662013-08-15 10:26:54 -07002326 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2327 const jbyte* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002328 ScopedObjectAccess soa(env);
2329 SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002330 }
2331
Ian Rogersbc939662013-08-15 10:26:54 -07002332 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2333 const jchar* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002334 ScopedObjectAccess soa(env);
2335 SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002336 }
2337
Ian Rogersbc939662013-08-15 10:26:54 -07002338 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2339 const jdouble* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002340 ScopedObjectAccess soa(env);
2341 SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002342 }
2343
Ian Rogersbc939662013-08-15 10:26:54 -07002344 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2345 const jfloat* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002346 ScopedObjectAccess soa(env);
2347 SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002348 }
2349
Ian Rogersbc939662013-08-15 10:26:54 -07002350 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2351 const jint* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002352 ScopedObjectAccess soa(env);
2353 SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002354 }
2355
Ian Rogersbc939662013-08-15 10:26:54 -07002356 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2357 const jlong* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002358 ScopedObjectAccess soa(env);
2359 SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002360 }
2361
Ian Rogersbc939662013-08-15 10:26:54 -07002362 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2363 const jshort* buf) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002364 ScopedObjectAccess soa(env);
2365 SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002366 }
2367
Ian Rogersbc939662013-08-15 10:26:54 -07002368 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2369 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002370 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2371 }
2372
Ian Rogersbc939662013-08-15 10:26:54 -07002373 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2374 jint method_count, bool return_errors) {
2375 if (UNLIKELY(method_count < 0)) {
Elliott Hughesaa836f72013-08-20 16:57:23 -07002376 JniAbortF("RegisterNatives", "negative method count: %d", method_count);
Ian Rogersbc939662013-08-15 10:26:54 -07002377 return JNI_ERR; // Not reached.
2378 }
2379 CHECK_NON_NULL_ARGUMENT(RegisterNatives, java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002380 ScopedObjectAccess soa(env);
2381 Class* c = soa.Decode<Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002382 if (UNLIKELY(method_count == 0)) {
2383 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2384 << PrettyDescriptor(c);
2385 return JNI_OK;
2386 }
2387 CHECK_NON_NULL_ARGUMENT(RegisterNatives, methods);
2388 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002389 const char* name = methods[i].name;
2390 const char* sig = methods[i].signature;
Ian Rogers1eb512d2013-10-18 15:42:20 -07002391 bool is_fast = false;
Elliott Hughescdf53122011-08-19 15:46:09 -07002392 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002393 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002394 ++sig;
2395 }
2396
Brian Carlstromea46f952013-07-30 01:26:50 -07002397 ArtMethod* m = c->FindDirectMethod(name, sig);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002398 if (m == NULL) {
2399 m = c->FindVirtualMethod(name, sig);
Elliott Hughescdf53122011-08-19 15:46:09 -07002400 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002401 if (m == NULL) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002402 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002403 << PrettyDescriptor(c) << "." << name << sig;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002404 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002405 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002406 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002407 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002408 << PrettyDescriptor(c) << "." << name << sig
2409 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002410 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002411 return JNI_ERR;
2412 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002413
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002414 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002415
Ian Rogers1eb512d2013-10-18 15:42:20 -07002416 m->RegisterNative(soa.Self(), methods[i].fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002417 }
2418 return JNI_OK;
2419 }
2420
Elliott Hughes5174fe62011-08-23 15:12:35 -07002421 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogersbc939662013-08-15 10:26:54 -07002422 CHECK_NON_NULL_ARGUMENT(UnregisterNatives, java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002423 ScopedObjectAccess soa(env);
2424 Class* c = soa.Decode<Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002425
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002426 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002427
2428 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
Brian Carlstromea46f952013-07-30 01:26:50 -07002429 ArtMethod* m = c->GetDirectMethod(i);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002430 if (m->IsNative()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002431 m->UnregisterNative(soa.Self());
Elliott Hughes5174fe62011-08-23 15:12:35 -07002432 }
2433 }
2434 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
Brian Carlstromea46f952013-07-30 01:26:50 -07002435 ArtMethod* m = c->GetVirtualMethod(i);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002436 if (m->IsNative()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002437 m->UnregisterNative(soa.Self());
Elliott Hughes5174fe62011-08-23 15:12:35 -07002438 }
2439 }
2440
2441 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002442 }
2443
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002444 static jint MonitorEnter(JNIEnv* env, jobject java_object)
2445 EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
Ian Rogersbc939662013-08-15 10:26:54 -07002446 CHECK_NON_NULL_ARGUMENT(MonitorEnter, java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002447 ScopedObjectAccess soa(env);
2448 Object* o = soa.Decode<Object*>(java_object);
2449 o->MonitorEnter(soa.Self());
2450 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002451 return JNI_ERR;
2452 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002453 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002454 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002455 }
2456
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002457 static jint MonitorExit(JNIEnv* env, jobject java_object)
2458 UNLOCK_FUNCTION(monitor_lock_) {
Ian Rogersbc939662013-08-15 10:26:54 -07002459 CHECK_NON_NULL_ARGUMENT(MonitorExit, java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002460 ScopedObjectAccess soa(env);
2461 Object* o = soa.Decode<Object*>(java_object);
2462 o->MonitorExit(soa.Self());
2463 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002464 return JNI_ERR;
2465 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002466 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002467 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002468 }
2469
2470 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogersbc939662013-08-15 10:26:54 -07002471 CHECK_NON_NULL_ARGUMENT(GetJavaVM, vm);
Elliott Hughescdf53122011-08-19 15:46:09 -07002472 Runtime* runtime = Runtime::Current();
2473 if (runtime != NULL) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002474 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002475 } else {
2476 *vm = NULL;
2477 }
2478 return (*vm != NULL) ? JNI_OK : JNI_ERR;
2479 }
2480
Elliott Hughescdf53122011-08-19 15:46:09 -07002481 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002482 if (capacity < 0) {
Ian Rogers62d6c772013-02-27 08:32:07 -08002483 JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %lld", capacity);
Elliott Hughes96a98872012-12-19 14:21:15 -08002484 }
Elliott Hughes11a796e2012-12-19 14:42:57 -08002485 if (address == NULL && capacity != 0) {
Ian Rogers62d6c772013-02-27 08:32:07 -08002486 JniAbortF("NewDirectByteBuffer", "non-zero capacity for NULL pointer: %lld", capacity);
Elliott Hughes96a98872012-12-19 14:21:15 -08002487 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002488
Elliott Hughes96a98872012-12-19 14:21:15 -08002489 // At the moment, the Java side is limited to 32 bits.
Elliott Hughesb465ab02011-08-24 11:21:21 -07002490 CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff);
2491 CHECK_LE(capacity, 0xffffffff);
Elliott Hughesb5681212013-03-29 17:29:22 -07002492 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002493 jint capacity_arg = static_cast<jint>(capacity);
2494
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002495 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2496 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002497 address_arg, capacity_arg);
Ian Rogersef28b142012-11-30 14:22:18 -08002498 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? NULL : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002499 }
2500
Elliott Hughesb465ab02011-08-24 11:21:21 -07002501 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Jeff Hao534f2b62013-07-10 15:29:36 -07002502 return reinterpret_cast<void*>(env->GetLongField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002503 }
2504
Elliott Hughesb465ab02011-08-24 11:21:21 -07002505 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002506 return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002507 }
2508
Elliott Hughesb465ab02011-08-24 11:21:21 -07002509 static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
Ian Rogersbc939662013-08-15 10:26:54 -07002510 CHECK_NON_NULL_ARGUMENT(GetObjectRefType, java_object);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002511
2512 // Do we definitely know what kind of reference this is?
2513 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2514 IndirectRefKind kind = GetIndirectRefKind(ref);
2515 switch (kind) {
2516 case kLocal:
Ian Rogersef28b142012-11-30 14:22:18 -08002517 if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -07002518 return JNILocalRefType;
2519 }
2520 return JNIInvalidRefType;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002521 case kGlobal:
2522 return JNIGlobalRefType;
2523 case kWeakGlobal:
2524 return JNIWeakGlobalRefType;
2525 case kSirtOrInvalid:
2526 // Is it in a stack IRT?
Ian Rogersef28b142012-11-30 14:22:18 -08002527 if (static_cast<JNIEnvExt*>(env)->self->SirtContains(java_object)) {
Elliott Hughesb465ab02011-08-24 11:21:21 -07002528 return JNILocalRefType;
2529 }
2530
Ian Rogersef28b142012-11-30 14:22:18 -08002531 if (!static_cast<JNIEnvExt*>(env)->vm->work_around_app_jni_bugs) {
Elliott Hughesc5bfa8f2011-08-30 14:32:49 -07002532 return JNIInvalidRefType;
2533 }
2534
Elliott Hughesb465ab02011-08-24 11:21:21 -07002535 // If we're handing out direct pointers, check whether it's a direct pointer
2536 // to a local reference.
Ian Rogersef28b142012-11-30 14:22:18 -08002537 {
2538 ScopedObjectAccess soa(env);
2539 if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) {
2540 if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) {
2541 return JNILocalRefType;
2542 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002543 }
2544 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002545 return JNIInvalidRefType;
2546 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002547 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2548 return JNIInvalidRefType;
Elliott Hughescdf53122011-08-19 15:46:09 -07002549 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002550
2551 private:
Ian Rogersef28b142012-11-30 14:22:18 -08002552 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity,
2553 const char* caller) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002554 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002555 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002556 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2557 return JNI_ERR;
2558 }
2559 // TODO: this isn't quite right, since "capacity" includes holes.
Ian Rogersef28b142012-11-30 14:22:18 -08002560 size_t capacity = static_cast<JNIEnvExt*>(env)->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002561 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2562 if (!okay) {
Ian Rogersef28b142012-11-30 14:22:18 -08002563 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002564 soa.Self()->ThrowOutOfMemoryError(caller);
2565 }
2566 return okay ? JNI_OK : JNI_ERR;
2567 }
2568
2569 template<typename JniT, typename ArtT>
2570 static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
Ian Rogersb726dcb2012-09-05 08:57:23 -07002571 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002572 if (length < 0) {
2573 JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2574 }
Ian Rogers50b35e22012-10-04 10:09:15 -07002575 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002576 return soa.AddLocalReference<JniT>(result);
2577 }
2578
2579 template <typename ArrayT, typename CArrayT, typename ArtArrayT>
2580 static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array,
2581 jboolean* is_copy)
Ian Rogersb726dcb2012-09-05 08:57:23 -07002582 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002583 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
2584 PinPrimitiveArray(soa, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002585 // Only make a copy if necessary.
2586 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2587 if (is_copy != nullptr) {
2588 *is_copy = JNI_TRUE;
2589 }
2590 static const size_t component_size = array->GetClass()->GetComponentSize();
2591 size_t size = array->GetLength() * component_size;
2592 void* data = new uint64_t[RoundUp(size, 8) / 8];
2593 memcpy(data, array->GetData(), size);
2594 return reinterpret_cast<CArrayT>(data);
2595 } else {
2596 if (is_copy != nullptr) {
2597 *is_copy = JNI_FALSE;
2598 }
2599 return reinterpret_cast<CArrayT>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002600 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002601 }
2602
Mathieu Chartier590fee92013-09-13 13:46:47 -07002603 template <typename ArrayT, typename ElementT>
2604 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
2605 ScopedObjectAccess soa(env);
2606 Array* array = soa.Decode<Array*>(java_array);
2607 size_t component_size = array->GetClass()->GetComponentSize();
2608 void* array_data = array->GetRawData(component_size);
2609 gc::Heap* heap = Runtime::Current()->GetHeap();
2610 bool is_copy = array_data != reinterpret_cast<void*>(elements);
2611 size_t bytes = array->GetLength() * component_size;
2612 VLOG(heap) << "Release primitive array " << env << " array_data " << array_data
2613 << " elements " << reinterpret_cast<void*>(elements);
2614 if (!is_copy && heap->IsMovableObject(array)) {
2615 heap->DecrementDisableGC(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002616 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002617 // Don't need to copy if we had a direct pointer.
2618 if (mode != JNI_ABORT && is_copy) {
2619 memcpy(array_data, elements, bytes);
2620 }
2621 if (mode != JNI_COMMIT) {
2622 if (is_copy) {
2623 delete[] reinterpret_cast<uint64_t*>(elements);
2624 }
2625 }
2626 // TODO: Do we always unpin primitive array?
2627 UnpinPrimitiveArray(soa, array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002628 }
2629
2630 template <typename JavaArrayT, typename JavaT, typename ArrayT>
2631 static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
2632 jsize start, jsize length, JavaT* buf)
Ian Rogersb726dcb2012-09-05 08:57:23 -07002633 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersbc939662013-08-15 10:26:54 -07002634 CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayRegion, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002635 ArrayT* array = soa.Decode<ArrayT*>(java_array);
2636 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2637 ThrowAIOOBE(soa, array, start, length, "src");
2638 } else {
Ian Rogers4ffdc6b2013-08-21 16:55:13 -07002639 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002640 JavaT* data = array->GetData();
2641 memcpy(buf, data + start, length * sizeof(JavaT));
2642 }
2643 }
2644
2645 template <typename JavaArrayT, typename JavaT, typename ArrayT>
2646 static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
2647 jsize start, jsize length, const JavaT* buf)
Ian Rogersb726dcb2012-09-05 08:57:23 -07002648 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersbc939662013-08-15 10:26:54 -07002649 CHECK_NON_NULL_ARGUMENT(SetPrimitiveArrayRegion, java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002650 ArrayT* array = soa.Decode<ArrayT*>(java_array);
2651 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2652 ThrowAIOOBE(soa, array, start, length, "dst");
2653 } else {
Ian Rogers4ffdc6b2013-08-21 16:55:13 -07002654 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002655 JavaT* data = array->GetData();
2656 memcpy(data + start, buf, length * sizeof(JavaT));
2657 }
2658 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002659};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002660
Elliott Hughes88c5c352012-03-15 18:49:48 -07002661const JNINativeInterface gJniNativeInterface = {
Carl Shapiroea4dca82011-08-01 13:45:38 -07002662 NULL, // reserved0.
2663 NULL, // reserved1.
2664 NULL, // reserved2.
2665 NULL, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002666 JNI::GetVersion,
2667 JNI::DefineClass,
2668 JNI::FindClass,
2669 JNI::FromReflectedMethod,
2670 JNI::FromReflectedField,
2671 JNI::ToReflectedMethod,
2672 JNI::GetSuperclass,
2673 JNI::IsAssignableFrom,
2674 JNI::ToReflectedField,
2675 JNI::Throw,
2676 JNI::ThrowNew,
2677 JNI::ExceptionOccurred,
2678 JNI::ExceptionDescribe,
2679 JNI::ExceptionClear,
2680 JNI::FatalError,
2681 JNI::PushLocalFrame,
2682 JNI::PopLocalFrame,
2683 JNI::NewGlobalRef,
2684 JNI::DeleteGlobalRef,
2685 JNI::DeleteLocalRef,
2686 JNI::IsSameObject,
2687 JNI::NewLocalRef,
2688 JNI::EnsureLocalCapacity,
2689 JNI::AllocObject,
2690 JNI::NewObject,
2691 JNI::NewObjectV,
2692 JNI::NewObjectA,
2693 JNI::GetObjectClass,
2694 JNI::IsInstanceOf,
2695 JNI::GetMethodID,
2696 JNI::CallObjectMethod,
2697 JNI::CallObjectMethodV,
2698 JNI::CallObjectMethodA,
2699 JNI::CallBooleanMethod,
2700 JNI::CallBooleanMethodV,
2701 JNI::CallBooleanMethodA,
2702 JNI::CallByteMethod,
2703 JNI::CallByteMethodV,
2704 JNI::CallByteMethodA,
2705 JNI::CallCharMethod,
2706 JNI::CallCharMethodV,
2707 JNI::CallCharMethodA,
2708 JNI::CallShortMethod,
2709 JNI::CallShortMethodV,
2710 JNI::CallShortMethodA,
2711 JNI::CallIntMethod,
2712 JNI::CallIntMethodV,
2713 JNI::CallIntMethodA,
2714 JNI::CallLongMethod,
2715 JNI::CallLongMethodV,
2716 JNI::CallLongMethodA,
2717 JNI::CallFloatMethod,
2718 JNI::CallFloatMethodV,
2719 JNI::CallFloatMethodA,
2720 JNI::CallDoubleMethod,
2721 JNI::CallDoubleMethodV,
2722 JNI::CallDoubleMethodA,
2723 JNI::CallVoidMethod,
2724 JNI::CallVoidMethodV,
2725 JNI::CallVoidMethodA,
2726 JNI::CallNonvirtualObjectMethod,
2727 JNI::CallNonvirtualObjectMethodV,
2728 JNI::CallNonvirtualObjectMethodA,
2729 JNI::CallNonvirtualBooleanMethod,
2730 JNI::CallNonvirtualBooleanMethodV,
2731 JNI::CallNonvirtualBooleanMethodA,
2732 JNI::CallNonvirtualByteMethod,
2733 JNI::CallNonvirtualByteMethodV,
2734 JNI::CallNonvirtualByteMethodA,
2735 JNI::CallNonvirtualCharMethod,
2736 JNI::CallNonvirtualCharMethodV,
2737 JNI::CallNonvirtualCharMethodA,
2738 JNI::CallNonvirtualShortMethod,
2739 JNI::CallNonvirtualShortMethodV,
2740 JNI::CallNonvirtualShortMethodA,
2741 JNI::CallNonvirtualIntMethod,
2742 JNI::CallNonvirtualIntMethodV,
2743 JNI::CallNonvirtualIntMethodA,
2744 JNI::CallNonvirtualLongMethod,
2745 JNI::CallNonvirtualLongMethodV,
2746 JNI::CallNonvirtualLongMethodA,
2747 JNI::CallNonvirtualFloatMethod,
2748 JNI::CallNonvirtualFloatMethodV,
2749 JNI::CallNonvirtualFloatMethodA,
2750 JNI::CallNonvirtualDoubleMethod,
2751 JNI::CallNonvirtualDoubleMethodV,
2752 JNI::CallNonvirtualDoubleMethodA,
2753 JNI::CallNonvirtualVoidMethod,
2754 JNI::CallNonvirtualVoidMethodV,
2755 JNI::CallNonvirtualVoidMethodA,
2756 JNI::GetFieldID,
2757 JNI::GetObjectField,
2758 JNI::GetBooleanField,
2759 JNI::GetByteField,
2760 JNI::GetCharField,
2761 JNI::GetShortField,
2762 JNI::GetIntField,
2763 JNI::GetLongField,
2764 JNI::GetFloatField,
2765 JNI::GetDoubleField,
2766 JNI::SetObjectField,
2767 JNI::SetBooleanField,
2768 JNI::SetByteField,
2769 JNI::SetCharField,
2770 JNI::SetShortField,
2771 JNI::SetIntField,
2772 JNI::SetLongField,
2773 JNI::SetFloatField,
2774 JNI::SetDoubleField,
2775 JNI::GetStaticMethodID,
2776 JNI::CallStaticObjectMethod,
2777 JNI::CallStaticObjectMethodV,
2778 JNI::CallStaticObjectMethodA,
2779 JNI::CallStaticBooleanMethod,
2780 JNI::CallStaticBooleanMethodV,
2781 JNI::CallStaticBooleanMethodA,
2782 JNI::CallStaticByteMethod,
2783 JNI::CallStaticByteMethodV,
2784 JNI::CallStaticByteMethodA,
2785 JNI::CallStaticCharMethod,
2786 JNI::CallStaticCharMethodV,
2787 JNI::CallStaticCharMethodA,
2788 JNI::CallStaticShortMethod,
2789 JNI::CallStaticShortMethodV,
2790 JNI::CallStaticShortMethodA,
2791 JNI::CallStaticIntMethod,
2792 JNI::CallStaticIntMethodV,
2793 JNI::CallStaticIntMethodA,
2794 JNI::CallStaticLongMethod,
2795 JNI::CallStaticLongMethodV,
2796 JNI::CallStaticLongMethodA,
2797 JNI::CallStaticFloatMethod,
2798 JNI::CallStaticFloatMethodV,
2799 JNI::CallStaticFloatMethodA,
2800 JNI::CallStaticDoubleMethod,
2801 JNI::CallStaticDoubleMethodV,
2802 JNI::CallStaticDoubleMethodA,
2803 JNI::CallStaticVoidMethod,
2804 JNI::CallStaticVoidMethodV,
2805 JNI::CallStaticVoidMethodA,
2806 JNI::GetStaticFieldID,
2807 JNI::GetStaticObjectField,
2808 JNI::GetStaticBooleanField,
2809 JNI::GetStaticByteField,
2810 JNI::GetStaticCharField,
2811 JNI::GetStaticShortField,
2812 JNI::GetStaticIntField,
2813 JNI::GetStaticLongField,
2814 JNI::GetStaticFloatField,
2815 JNI::GetStaticDoubleField,
2816 JNI::SetStaticObjectField,
2817 JNI::SetStaticBooleanField,
2818 JNI::SetStaticByteField,
2819 JNI::SetStaticCharField,
2820 JNI::SetStaticShortField,
2821 JNI::SetStaticIntField,
2822 JNI::SetStaticLongField,
2823 JNI::SetStaticFloatField,
2824 JNI::SetStaticDoubleField,
2825 JNI::NewString,
2826 JNI::GetStringLength,
2827 JNI::GetStringChars,
2828 JNI::ReleaseStringChars,
2829 JNI::NewStringUTF,
2830 JNI::GetStringUTFLength,
2831 JNI::GetStringUTFChars,
2832 JNI::ReleaseStringUTFChars,
2833 JNI::GetArrayLength,
2834 JNI::NewObjectArray,
2835 JNI::GetObjectArrayElement,
2836 JNI::SetObjectArrayElement,
2837 JNI::NewBooleanArray,
2838 JNI::NewByteArray,
2839 JNI::NewCharArray,
2840 JNI::NewShortArray,
2841 JNI::NewIntArray,
2842 JNI::NewLongArray,
2843 JNI::NewFloatArray,
2844 JNI::NewDoubleArray,
2845 JNI::GetBooleanArrayElements,
2846 JNI::GetByteArrayElements,
2847 JNI::GetCharArrayElements,
2848 JNI::GetShortArrayElements,
2849 JNI::GetIntArrayElements,
2850 JNI::GetLongArrayElements,
2851 JNI::GetFloatArrayElements,
2852 JNI::GetDoubleArrayElements,
2853 JNI::ReleaseBooleanArrayElements,
2854 JNI::ReleaseByteArrayElements,
2855 JNI::ReleaseCharArrayElements,
2856 JNI::ReleaseShortArrayElements,
2857 JNI::ReleaseIntArrayElements,
2858 JNI::ReleaseLongArrayElements,
2859 JNI::ReleaseFloatArrayElements,
2860 JNI::ReleaseDoubleArrayElements,
2861 JNI::GetBooleanArrayRegion,
2862 JNI::GetByteArrayRegion,
2863 JNI::GetCharArrayRegion,
2864 JNI::GetShortArrayRegion,
2865 JNI::GetIntArrayRegion,
2866 JNI::GetLongArrayRegion,
2867 JNI::GetFloatArrayRegion,
2868 JNI::GetDoubleArrayRegion,
2869 JNI::SetBooleanArrayRegion,
2870 JNI::SetByteArrayRegion,
2871 JNI::SetCharArrayRegion,
2872 JNI::SetShortArrayRegion,
2873 JNI::SetIntArrayRegion,
2874 JNI::SetLongArrayRegion,
2875 JNI::SetFloatArrayRegion,
2876 JNI::SetDoubleArrayRegion,
2877 JNI::RegisterNatives,
2878 JNI::UnregisterNatives,
2879 JNI::MonitorEnter,
2880 JNI::MonitorExit,
2881 JNI::GetJavaVM,
2882 JNI::GetStringRegion,
2883 JNI::GetStringUTFRegion,
2884 JNI::GetPrimitiveArrayCritical,
2885 JNI::ReleasePrimitiveArrayCritical,
2886 JNI::GetStringCritical,
2887 JNI::ReleaseStringCritical,
2888 JNI::NewWeakGlobalRef,
2889 JNI::DeleteWeakGlobalRef,
2890 JNI::ExceptionCheck,
2891 JNI::NewDirectByteBuffer,
2892 JNI::GetDirectBufferAddress,
2893 JNI::GetDirectBufferCapacity,
2894 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002895};
2896
Elliott Hughes75770752011-08-24 17:52:38 -07002897JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002898 : self(self),
Elliott Hughes75770752011-08-24 17:52:38 -07002899 vm(vm),
Ian Rogers5a7a74a2011-09-26 16:32:29 -07002900 local_ref_cookie(IRT_FIRST_SEGMENT),
2901 locals(kLocalsInitial, kLocalsMax, kLocal),
Elliott Hughes4ffd3132011-10-24 12:06:42 -07002902 check_jni(false),
Elliott Hughesbbd76712011-08-17 10:25:24 -07002903 critical(false),
Ian Rogers5a7a74a2011-09-26 16:32:29 -07002904 monitors("monitors", kMonitorsInitial, kMonitorsMax) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07002905 functions = unchecked_functions = &gJniNativeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07002906 if (vm->check_jni) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07002907 SetCheckJniEnabled(true);
Elliott Hughesa2501992011-08-26 19:39:54 -07002908 }
Ian Rogers5a7a74a2011-09-26 16:32:29 -07002909 // The JniEnv local reference values must be at a consistent offset or else cross-compilation
2910 // errors will ensue.
2911 CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12);
2912 CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16);
Elliott Hughes40ef99e2011-08-11 17:44:34 -07002913}
2914
Elliott Hughesc1674ed2011-08-25 18:09:09 -07002915JNIEnvExt::~JNIEnvExt() {
2916}
2917
Mathieu Chartier590fee92013-09-13 13:46:47 -07002918jobject JNIEnvExt::NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2919 if (obj == nullptr) {
2920 return nullptr;
2921 }
2922 return reinterpret_cast<jobject>(locals.Add(local_ref_cookie, obj));
2923}
2924
2925void JNIEnvExt::DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2926 if (obj != nullptr) {
2927 locals.Remove(local_ref_cookie, reinterpret_cast<IndirectRef>(obj));
2928 }
2929}
Elliott Hughes88c5c352012-03-15 18:49:48 -07002930void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
2931 check_jni = enabled;
2932 functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07002933}
2934
Elliott Hughes73e66f72012-05-09 09:34:45 -07002935void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
2936 locals.Dump(os);
2937 monitors.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07002938}
2939
Elliott Hughes1bac54f2012-03-16 12:48:31 -07002940void JNIEnvExt::PushFrame(int /*capacity*/) {
2941 // TODO: take 'capacity' into account.
Elliott Hughes2ced6a52011-10-16 18:44:48 -07002942 stacked_local_ref_cookies.push_back(local_ref_cookie);
2943 local_ref_cookie = locals.GetSegmentState();
2944}
2945
2946void JNIEnvExt::PopFrame() {
2947 locals.SetSegmentState(local_ref_cookie);
2948 local_ref_cookie = stacked_local_ref_cookies.back();
2949 stacked_local_ref_cookies.pop_back();
2950}
2951
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08002952Offset JNIEnvExt::SegmentStateOffset() {
2953 return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
2954 IndirectReferenceTable::SegmentStateOffset().Int32Value());
2955}
2956
Carl Shapiroea4dca82011-08-01 13:45:38 -07002957// JNI Invocation interface.
2958
Brian Carlstrombddf9762013-05-14 11:35:37 -07002959extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002960 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
Elliott Hughes83a25322013-03-14 11:18:53 -07002961 if (IsBadJniVersion(args->version)) {
2962 LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002963 return JNI_EVERSION;
2964 }
2965 Runtime::Options options;
2966 for (int i = 0; i < args->nOptions; ++i) {
2967 JavaVMOption* option = &args->options[i];
Elliott Hughesf1a5adc2012-02-10 18:09:35 -08002968 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002969 }
2970 bool ignore_unrecognized = args->ignoreUnrecognized;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002971 if (!Runtime::Create(options, ignore_unrecognized)) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002972 return JNI_ERR;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002973 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002974 Runtime* runtime = Runtime::Current();
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07002975 bool started = runtime->Start();
2976 if (!started) {
2977 delete Thread::Current()->GetJniEnv();
2978 delete runtime->GetJavaVM();
2979 LOG(WARNING) << "CreateJavaVM failed";
2980 return JNI_ERR;
2981 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07002982 *p_env = Thread::Current()->GetJniEnv();
2983 *p_vm = runtime->GetJavaVM();
2984 return JNI_OK;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002985}
2986
Elliott Hughesf2682d52011-08-15 16:37:04 -07002987extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002988 Runtime* runtime = Runtime::Current();
2989 if (runtime == NULL) {
Elliott Hughesf2682d52011-08-15 16:37:04 -07002990 *vm_count = 0;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002991 } else {
Elliott Hughesf2682d52011-08-15 16:37:04 -07002992 *vm_count = 1;
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002993 vms[0] = runtime->GetJavaVM();
Carl Shapiro2ed144c2011-07-26 16:52:08 -07002994 }
2995 return JNI_OK;
2996}
2997
2998// Historically unsupported.
Elliott Hughes1bac54f2012-03-16 12:48:31 -07002999extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003000 return JNI_ERR;
3001}
3002
Elliott Hughescdf53122011-08-19 15:46:09 -07003003class JII {
3004 public:
3005 static jint DestroyJavaVM(JavaVM* vm) {
3006 if (vm == NULL) {
3007 return JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07003008 }
Elliott Hughes6a144332012-04-03 13:07:11 -07003009 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
3010 delete raw_vm->runtime;
3011 return JNI_OK;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003012 }
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003013
Elliott Hughescdf53122011-08-19 15:46:09 -07003014 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughes75770752011-08-24 17:52:38 -07003015 return JII_AttachCurrentThread(vm, p_env, thr_args, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07003016 }
3017
3018 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughes75770752011-08-24 17:52:38 -07003019 return JII_AttachCurrentThread(vm, p_env, thr_args, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07003020 }
3021
3022 static jint DetachCurrentThread(JavaVM* vm) {
Brian Carlstrom4d571432012-05-16 00:21:41 -07003023 if (vm == NULL || Thread::Current() == NULL) {
Elliott Hughescdf53122011-08-19 15:46:09 -07003024 return JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07003025 }
Elliott Hughes6a144332012-04-03 13:07:11 -07003026 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
3027 Runtime* runtime = raw_vm->runtime;
3028 runtime->DetachCurrentThread();
3029 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07003030 }
3031
3032 static jint GetEnv(JavaVM* vm, void** env, jint version) {
Elliott Hughes3b7ffa12013-09-06 15:57:08 -07003033 // GetEnv always returns a JNIEnv* for the most current supported JNI version,
3034 // and unlike other calls that take a JNI version doesn't care if you supply
3035 // JNI_VERSION_1_1, which we don't otherwise support.
3036 if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
Elliott Hughes83a25322013-03-14 11:18:53 -07003037 LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
Elliott Hughescdf53122011-08-19 15:46:09 -07003038 return JNI_EVERSION;
3039 }
3040 if (vm == NULL || env == NULL) {
3041 return JNI_ERR;
3042 }
3043 Thread* thread = Thread::Current();
3044 if (thread == NULL) {
3045 *env = NULL;
3046 return JNI_EDETACHED;
3047 }
3048 *env = thread->GetJniEnv();
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003049 return JNI_OK;
3050 }
Elliott Hughescdf53122011-08-19 15:46:09 -07003051};
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003052
Elliott Hughes88c5c352012-03-15 18:49:48 -07003053const JNIInvokeInterface gJniInvokeInterface = {
Carl Shapiroea4dca82011-08-01 13:45:38 -07003054 NULL, // reserved0
3055 NULL, // reserved1
3056 NULL, // reserved2
Elliott Hughescdf53122011-08-19 15:46:09 -07003057 JII::DestroyJavaVM,
3058 JII::AttachCurrentThread,
3059 JII::DetachCurrentThread,
3060 JII::GetEnv,
3061 JII::AttachCurrentThreadAsDaemon
Carl Shapiroea4dca82011-08-01 13:45:38 -07003062};
3063
Elliott Hughesa0957642011-09-02 14:27:33 -07003064JavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options)
Elliott Hughes69f5bc62011-08-24 09:26:14 -07003065 : runtime(runtime),
Elliott Hughesa2501992011-08-26 19:39:54 -07003066 check_jni_abort_hook(NULL),
Elliott Hughesb264f082012-04-06 17:10:10 -07003067 check_jni_abort_hook_data(NULL),
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003068 check_jni(false),
Brian Carlstrom7934ac22013-07-26 10:54:15 -07003069 force_copy(false), // TODO: add a way to enable this
Elliott Hughesa0957642011-09-02 14:27:33 -07003070 trace(options->jni_trace_),
Elliott Hughesc2dc62d2012-01-17 20:06:12 -08003071 work_around_app_jni_bugs(false),
Ian Rogers62d6c772013-02-27 08:32:07 -08003072 pins_lock("JNI pin table lock", kPinTableLock),
Elliott Hughes2ced6a52011-10-16 18:44:48 -07003073 pin_table("pin table", kPinTableInitial, kPinTableMax),
Elliott Hughes8daa0922011-09-11 13:46:25 -07003074 globals_lock("JNI global reference table lock"),
Elliott Hughesbb1e8f02011-10-18 14:14:25 -07003075 globals(gGlobalsInitial, gGlobalsMax, kGlobal),
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003076 libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003077 libraries(new Libraries),
3078 weak_globals_lock_("JNI weak global reference table lock"),
3079 weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
3080 allow_new_weak_globals_(true),
3081 weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07003082 functions = unchecked_functions = &gJniInvokeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003083 if (options->check_jni_) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07003084 SetCheckJniEnabled(true);
Elliott Hughesa2501992011-08-26 19:39:54 -07003085 }
Elliott Hughesf2682d52011-08-15 16:37:04 -07003086}
3087
Elliott Hughesde69d7f2011-08-18 16:49:37 -07003088JavaVMExt::~JavaVMExt() {
Elliott Hughes79082e32011-08-25 12:07:32 -07003089 delete libraries;
Elliott Hughesde69d7f2011-08-18 16:49:37 -07003090}
3091
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003092jweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
3093 if (obj == nullptr) {
3094 return nullptr;
3095 }
3096 MutexLock mu(self, weak_globals_lock_);
3097 while (UNLIKELY(!allow_new_weak_globals_)) {
3098 weak_globals_add_condition_.WaitHoldingLocks(self);
3099 }
3100 IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
3101 return reinterpret_cast<jweak>(ref);
3102}
3103
3104void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
3105 MutexLock mu(self, weak_globals_lock_);
3106 if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
3107 LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
3108 << "failed to find entry";
3109 }
3110}
3111
Elliott Hughes88c5c352012-03-15 18:49:48 -07003112void JavaVMExt::SetCheckJniEnabled(bool enabled) {
3113 check_jni = enabled;
3114 functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003115}
3116
Elliott Hughesae80b492012-04-24 10:43:17 -07003117void JavaVMExt::DumpForSigQuit(std::ostream& os) {
3118 os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
3119 if (force_copy) {
3120 os << " (with forcecopy)";
3121 }
3122 os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
Ian Rogers50b35e22012-10-04 10:09:15 -07003123 Thread* self = Thread::Current();
Elliott Hughesae80b492012-04-24 10:43:17 -07003124 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003125 MutexLock mu(self, pins_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003126 os << "; pins=" << pin_table.Size();
3127 }
3128 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003129 ReaderMutexLock mu(self, globals_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003130 os << "; globals=" << globals.Capacity();
3131 }
3132 {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003133 MutexLock mu(self, weak_globals_lock_);
3134 if (weak_globals_.Capacity() > 0) {
3135 os << " (plus " << weak_globals_.Capacity() << " weak)";
Elliott Hughesae80b492012-04-24 10:43:17 -07003136 }
3137 }
3138 os << '\n';
3139
3140 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003141 MutexLock mu(self, libraries_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003142 os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
3143 }
3144}
3145
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003146void JavaVMExt::DisallowNewWeakGlobals() {
3147 MutexLock mu(Thread::Current(), weak_globals_lock_);
3148 allow_new_weak_globals_ = false;
3149}
3150
3151void JavaVMExt::AllowNewWeakGlobals() {
3152 Thread* self = Thread::Current();
3153 MutexLock mu(self, weak_globals_lock_);
3154 allow_new_weak_globals_ = true;
3155 weak_globals_add_condition_.Broadcast(self);
3156}
3157
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003158mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
3159 MutexLock mu(self, weak_globals_lock_);
3160 while (UNLIKELY(!allow_new_weak_globals_)) {
3161 weak_globals_add_condition_.WaitHoldingLocks(self);
3162 }
3163 return const_cast<mirror::Object*>(weak_globals_.Get(ref));
3164}
3165
Elliott Hughes73e66f72012-05-09 09:34:45 -07003166void JavaVMExt::DumpReferenceTables(std::ostream& os) {
Ian Rogers50b35e22012-10-04 10:09:15 -07003167 Thread* self = Thread::Current();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003168 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003169 ReaderMutexLock mu(self, globals_lock);
Elliott Hughes73e66f72012-05-09 09:34:45 -07003170 globals.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003171 }
3172 {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003173 MutexLock mu(self, weak_globals_lock_);
3174 weak_globals_.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003175 }
3176 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003177 MutexLock mu(self, pins_lock);
Elliott Hughes73e66f72012-05-09 09:34:45 -07003178 pin_table.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003179 }
3180}
3181
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003182bool JavaVMExt::LoadNativeLibrary(const std::string& path, ClassLoader* class_loader,
Ian Rogers1eb512d2013-10-18 15:42:20 -07003183 std::string* detail) {
3184 detail->clear();
Elliott Hughescdf53122011-08-19 15:46:09 -07003185
3186 // See if we've already loaded this library. If we have, and the class loader
3187 // matches, return successfully without doing anything.
Elliott Hughes75770752011-08-24 17:52:38 -07003188 // TODO: for better results we should canonicalize the pathname (or even compare
3189 // inodes). This implementation is fine if everybody is using System.loadLibrary.
Elliott Hughes79082e32011-08-25 12:07:32 -07003190 SharedLibrary* library;
Ian Rogers50b35e22012-10-04 10:09:15 -07003191 Thread* self = Thread::Current();
Elliott Hughes79082e32011-08-25 12:07:32 -07003192 {
3193 // TODO: move the locking (and more of this logic) into Libraries.
Ian Rogers50b35e22012-10-04 10:09:15 -07003194 MutexLock mu(self, libraries_lock);
Elliott Hughes79082e32011-08-25 12:07:32 -07003195 library = libraries->Get(path);
3196 }
Elliott Hughescdf53122011-08-19 15:46:09 -07003197 if (library != NULL) {
3198 if (library->GetClassLoader() != class_loader) {
Elliott Hughes75770752011-08-24 17:52:38 -07003199 // The library will be associated with class_loader. The JNI
3200 // spec says we can't load the same library into more than one
3201 // class loader.
Ian Rogers1eb512d2013-10-18 15:42:20 -07003202 StringAppendF(detail, "Shared library \"%s\" already opened by "
Elliott Hughes75770752011-08-24 17:52:38 -07003203 "ClassLoader %p; can't open in ClassLoader %p",
3204 path.c_str(), library->GetClassLoader(), class_loader);
3205 LOG(WARNING) << detail;
Elliott Hughescdf53122011-08-19 15:46:09 -07003206 return false;
3207 }
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003208 VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
3209 << "ClassLoader " << class_loader << "]";
Elliott Hughes1bac54f2012-03-16 12:48:31 -07003210 if (!library->CheckOnLoadResult()) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003211 StringAppendF(detail, "JNI_OnLoad failed on a previous attempt "
Elliott Hughes75770752011-08-24 17:52:38 -07003212 "to load \"%s\"", path.c_str());
Elliott Hughescdf53122011-08-19 15:46:09 -07003213 return false;
3214 }
3215 return true;
3216 }
3217
3218 // Open the shared library. Because we're using a full path, the system
3219 // doesn't have to search through LD_LIBRARY_PATH. (It may do so to
3220 // resolve this library's dependencies though.)
3221
3222 // Failures here are expected when java.library.path has several entries
3223 // and we have to hunt for the lib.
3224
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003225 // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
3226 // class unloading. Libraries will only be unloaded when the reference count (incremented by
3227 // dlopen) becomes zero from dlclose.
3228
Elliott Hughescdf53122011-08-19 15:46:09 -07003229 // This can execute slowly for a large library on a busy system, so we
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003230 // want to switch from kRunnable while it executes. This allows the GC to ignore us.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003231 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
3232 void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
3233 self->TransitionFromSuspendedToRunnable();
Elliott Hughescdf53122011-08-19 15:46:09 -07003234
Elliott Hughes84b2f142012-09-27 09:16:28 -07003235 VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
Elliott Hughescdf53122011-08-19 15:46:09 -07003236
3237 if (handle == NULL) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003238 *detail = dlerror();
Elliott Hughes84b2f142012-09-27 09:16:28 -07003239 LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail;
Elliott Hughescdf53122011-08-19 15:46:09 -07003240 return false;
3241 }
3242
3243 // Create a new entry.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003244 // TODO: move the locking (and more of this logic) into Libraries.
3245 bool created_library = false;
Elliott Hughescdf53122011-08-19 15:46:09 -07003246 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003247 MutexLock mu(self, libraries_lock);
Elliott Hughes79082e32011-08-25 12:07:32 -07003248 library = libraries->Get(path);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003249 if (library == NULL) { // We won race to get libraries_lock
3250 library = new SharedLibrary(path, handle, class_loader);
3251 libraries->Put(path, library);
3252 created_library = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07003253 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003254 }
3255 if (!created_library) {
3256 LOG(INFO) << "WOW: we lost a race to add shared library: "
3257 << "\"" << path << "\" ClassLoader=" << class_loader;
3258 return library->CheckOnLoadResult();
Elliott Hughescdf53122011-08-19 15:46:09 -07003259 }
Elliott Hughes79082e32011-08-25 12:07:32 -07003260
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003261 VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
Elliott Hughes79082e32011-08-25 12:07:32 -07003262
Elliott Hughes79353722013-08-02 16:52:18 -07003263 bool was_successful = false;
Elliott Hughes79082e32011-08-25 12:07:32 -07003264 void* sym = dlsym(handle, "JNI_OnLoad");
3265 if (sym == NULL) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003266 VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
Elliott Hughes85affca2013-08-02 17:48:52 -07003267 was_successful = true;
Elliott Hughes79082e32011-08-25 12:07:32 -07003268 } else {
3269 // Call JNI_OnLoad. We have to override the current class
3270 // loader, which will always be "null" since the stuff at the
3271 // top of the stack is around Runtime.loadLibrary(). (See
3272 // the comments in the JNI FindClass function.)
3273 typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
3274 JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
Mathieu Chartier590fee92013-09-13 13:46:47 -07003275 SirtRef<ClassLoader> old_class_loader(self, self->GetClassLoaderOverride());
Elliott Hughes79082e32011-08-25 12:07:32 -07003276 self->SetClassLoaderOverride(class_loader);
3277
Elliott Hughesad7c2a32011-08-31 11:58:10 -07003278 int version = 0;
3279 {
Elliott Hughes34e06962012-04-09 13:55:55 -07003280 ScopedThreadStateChange tsc(self, kNative);
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003281 VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
Elliott Hughesad7c2a32011-08-31 11:58:10 -07003282 version = (*jni_on_load)(this, NULL);
Elliott Hughes79082e32011-08-25 12:07:32 -07003283 }
Elliott Hughes79082e32011-08-25 12:07:32 -07003284
Mathieu Chartier590fee92013-09-13 13:46:47 -07003285 self->SetClassLoaderOverride(old_class_loader.get());
Elliott Hughes79082e32011-08-25 12:07:32 -07003286
Elliott Hughes79353722013-08-02 16:52:18 -07003287 if (version == JNI_ERR) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003288 StringAppendF(detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
Elliott Hughes79353722013-08-02 16:52:18 -07003289 } else if (IsBadJniVersion(version)) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003290 StringAppendF(detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
Brian Carlstrom75fe90c2013-06-26 22:26:16 -07003291 path.c_str(), version);
Elliott Hughes79082e32011-08-25 12:07:32 -07003292 // It's unwise to call dlclose() here, but we can mark it
3293 // as bad and ensure that future load attempts will fail.
3294 // We don't know how far JNI_OnLoad got, so there could
3295 // be some partially-initialized stuff accessible through
3296 // newly-registered native method calls. We could try to
3297 // unregister them, but that doesn't seem worthwhile.
Elliott Hughes79353722013-08-02 16:52:18 -07003298 } else {
3299 was_successful = true;
Elliott Hughes79082e32011-08-25 12:07:32 -07003300 }
Elliott Hughes79353722013-08-02 16:52:18 -07003301 VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
Brian Carlstrom75fe90c2013-06-26 22:26:16 -07003302 << " from JNI_OnLoad in \"" << path << "\"]";
Elliott Hughes79082e32011-08-25 12:07:32 -07003303 }
3304
Elliott Hughes79353722013-08-02 16:52:18 -07003305 library->SetResult(was_successful);
3306 return was_successful;
Elliott Hughes79082e32011-08-25 12:07:32 -07003307}
3308
Brian Carlstromea46f952013-07-30 01:26:50 -07003309void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) {
Elliott Hughes79082e32011-08-25 12:07:32 -07003310 CHECK(m->IsNative());
3311
3312 Class* c = m->GetDeclaringClass();
3313
3314 // If this is a static method, it could be called before the class
3315 // has been initialized.
3316 if (m->IsStatic()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -08003317 c = EnsureInitialized(Thread::Current(), c);
3318 if (c == nullptr) {
3319 return nullptr;
Elliott Hughes79082e32011-08-25 12:07:32 -07003320 }
3321 } else {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003322 CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
Elliott Hughes79082e32011-08-25 12:07:32 -07003323 }
3324
Brian Carlstrom16192862011-09-12 17:50:06 -07003325 std::string detail;
3326 void* native_method;
Ian Rogers50b35e22012-10-04 10:09:15 -07003327 Thread* self = Thread::Current();
Brian Carlstrom16192862011-09-12 17:50:06 -07003328 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003329 MutexLock mu(self, libraries_lock);
Brian Carlstrom16192862011-09-12 17:50:06 -07003330 native_method = libraries->FindNativeMethod(m, detail);
3331 }
Ian Rogers62d6c772013-02-27 08:32:07 -08003332 // Throwing can cause libraries_lock to be reacquired.
Brian Carlstrom16192862011-09-12 17:50:06 -07003333 if (native_method == NULL) {
Ian Rogers62d6c772013-02-27 08:32:07 -08003334 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
3335 self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
Brian Carlstrom16192862011-09-12 17:50:06 -07003336 }
3337 return native_method;
Elliott Hughescdf53122011-08-19 15:46:09 -07003338}
3339
Mathieu Chartier6aa3df92013-09-17 15:17:28 -07003340void JavaVMExt::SweepJniWeakGlobals(RootVisitor visitor, void* arg) {
Mathieu Chartier810b1d72013-09-20 14:02:02 -07003341 MutexLock mu(Thread::Current(), weak_globals_lock_);
3342 for (mirror::Object** entry : weak_globals_) {
Mathieu Chartier6aa3df92013-09-17 15:17:28 -07003343 mirror::Object* obj = *entry;
3344 mirror::Object* new_obj = visitor(obj, arg);
3345 if (new_obj == nullptr) {
3346 new_obj = kClearedJniWeakGlobal;
3347 }
3348 *entry = new_obj;
3349 }
3350}
3351
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08003352void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) {
Ian Rogers50b35e22012-10-04 10:09:15 -07003353 Thread* self = Thread::Current();
Elliott Hughes410c0c82011-09-01 17:58:25 -07003354 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003355 ReaderMutexLock mu(self, globals_lock);
Elliott Hughes410c0c82011-09-01 17:58:25 -07003356 globals.VisitRoots(visitor, arg);
3357 }
3358 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003359 MutexLock mu(self, pins_lock);
Elliott Hughes410c0c82011-09-01 17:58:25 -07003360 pin_table.VisitRoots(visitor, arg);
3361 }
3362 // The weak_globals table is visited by the GC itself (because it mutates the table).
3363}
3364
Elliott Hughesc8fece32013-01-02 11:27:23 -08003365void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003366 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003367 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
3368 if (c.get() == NULL) {
3369 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3370 }
3371 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3372}
3373
Ian Rogersdf20fe02011-07-20 20:34:16 -07003374} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003375
3376std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3377 switch (rhs) {
3378 case JNIInvalidRefType:
3379 os << "JNIInvalidRefType";
3380 return os;
3381 case JNILocalRefType:
3382 os << "JNILocalRefType";
3383 return os;
3384 case JNIGlobalRefType:
3385 os << "JNIGlobalRefType";
3386 return os;
3387 case JNIWeakGlobalRefType:
3388 os << "JNIWeakGlobalRefType";
3389 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003390 default:
Shih-wei Liao24782c62012-01-08 12:46:11 -08003391 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003392 return os;
Elliott Hughesb465ab02011-08-24 11:21:21 -07003393 }
3394}