jni_internal.cc revision 85affca81271f573c75c32316aa6faa8e52448b1
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "jni_internal.h" 182ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 190af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h> 2079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 2179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes#include <cstdarg> 220af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <utility> 230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <vector> 242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2507ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 2676b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h" 271aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 28e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h" 2940ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes#include "class_linker.h" 304f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h" 323dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao#include "interpreter/interpreter.h" 332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#include "invoke_arg_array_builder.h" 34ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro#include "jni.h" 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/field-inl.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h" 426d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 432ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "runtime.h" 44a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 4500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 46a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "ScopedLocalRef.h" 472ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "thread.h" 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utf.h" 49a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "UniquePtr.h" 50eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h" 51df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 523e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::AbstractMethod; 533e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Array; 543e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::BooleanArray; 553e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ByteArray; 563e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::CharArray; 573e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Class; 583e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ClassLoader; 593e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::DoubleArray; 603e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Field; 613e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::FloatArray; 623e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::IntArray; 633e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::LongArray; 643e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Object; 653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ObjectArray; 663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ShortArray; 673e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::String; 683e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Throwable; 692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 70bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesnamespace art { 71bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes 727934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsInitial = 32; // Arbitrary. 737934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsMax = 4096; // Arbitrary sanity check. 742ced6a534157d5d963693346904389c19775d2daElliott Hughes 757934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsInitial = 64; // Arbitrary. 767934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsMax = 512; // Arbitrary sanity check. 772ced6a534157d5d963693346904389c19775d2daElliott Hughes 787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kPinTableInitial = 16; // Arbitrary. 797934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kPinTableMax = 1024; // Arbitrary sanity check. 802ced6a534157d5d963693346904389c19775d2daElliott Hughes 817934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsInitial = 512; // Arbitrary. 827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 832ced6a534157d5d963693346904389c19775d2daElliott Hughes 847934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsInitial = 16; // Arbitrary. 857934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 86df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 8700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jweak AddWeakGlobalReference(ScopedObjectAccess& soa, Object* obj) 88b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 8945619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers if (obj == NULL) { 9045619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers return NULL; 91d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes } 9200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 9345619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers IndirectReferenceTable& weak_globals = vm->weak_globals; 9450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->weak_globals_lock); 9545619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers IndirectRef ref = weak_globals.Add(IRT_FIRST_SEGMENT, obj); 9645619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers return reinterpret_cast<jweak>(ref); 9745619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers} 9845619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers 9919c5d3786894af707d8079231105bca1b7dcd096Jeff Haostatic bool IsBadJniVersion(int version) { 10019c5d3786894af707d8079231105bca1b7dcd096Jeff Hao // We don't support JNI_VERSION_1_1. These are the only other valid versions. 10119c5d3786894af707d8079231105bca1b7dcd096Jeff Hao return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6; 10219c5d3786894af707d8079231105bca1b7dcd096Jeff Hao} 10319c5d3786894af707d8079231105bca1b7dcd096Jeff Hao 1045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Haostatic void CheckMethodArguments(AbstractMethod* m, uint32_t* args) 105b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 106b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes MethodHelper mh(m); 10750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers const DexFile::TypeList* params = mh.GetParameterTypeList(); 10850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (params == NULL) { 10950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers return; // No arguments so nothing to check. 11050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers } 1115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint32_t offset = 0; 11250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers uint32_t num_params = params->Size(); 113b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes size_t error_count = 0; 1145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao if (!m->IsStatic()) { 1155d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao offset = 1; 1165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 11750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers for (uint32_t i = 0; i < num_params; i++) { 11850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers uint16_t type_idx = params->GetTypeItem(i).type_idx_; 11950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Class* param_type = mh.GetClassFromTypeIdx(type_idx); 12050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (param_type == NULL) { 12150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 12250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers CHECK(self->IsExceptionPending()); 12350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " 12450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n" 12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << self->GetException(NULL)->Dump(); 12650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers self->ClearException(); 12750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ++error_count; 12850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers } else if (!param_type->IsPrimitive()) { 12950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers // TODO: check primitives are in range. 1305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* argument = reinterpret_cast<Object*>(args[i + offset]); 13150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (argument != NULL && !argument->InstanceOf(param_type)) { 132b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of " 133b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m); 134b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes ++error_count; 135b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 1365d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) { 1375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao offset++; 138b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 139b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 140b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes if (error_count > 0) { 141b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort 142b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes // with an argument. 1433f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes JniAbortF(NULL, "bad arguments passed to %s (see above for details)", PrettyMethod(m).c_str()); 144b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 145b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes} 146b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 1475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Haovoid InvokeWithArgArray(const ScopedObjectAccess& soa, AbstractMethod* method, 1486474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao ArgArray* arg_array, JValue* result, char result_type) 149b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1503dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao uint32_t* args = arg_array->GetArray(); 15100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (UNLIKELY(soa.Env()->check_jni)) { 1523dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao CheckMethodArguments(method, args); 1533dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } 1547d658cf06827d409d76686da1cd2b6acb5977885Sebastien Hertz method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type); 1559b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 1569b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 15700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj, 15800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jmethodID mid, va_list args) 159b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16066f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = soa.DecodeMethod(mid); 1617a549467e332398229724058c07d998d0acfb0bbJeff Hao Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj); 1622fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1642fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1655d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1666474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1676474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 16872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 16972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 17066f19258f9728d4ffe026074d8fd429d639802faMathieu Chartierstatic AbstractMethod* FindVirtualMethod(Object* receiver, AbstractMethod* method) 171b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 17230b944557a969a9aea2098ce9bbcce05db9b1f22Brian Carlstrom return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method); 17372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 17472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 17500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess& soa, 17600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject obj, jmethodID mid, jvalue* args) 177b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 17800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* receiver = soa.Decode<Object*>(obj); 17966f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 1802fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1815d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1835d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1846474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1856474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 18672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 18772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 18800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess& soa, 18900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject obj, jmethodID mid, va_list args) 190b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 19100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* receiver = soa.Decode<Object*>(obj); 19266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 1932fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1945d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1952fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1965d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1976474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1986474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 199ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 200ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2016b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're 2026b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// separated with slashes but aren't wrapped with "L;" like regular descriptors 2036b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an 2046b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// exception; there the "L;" must be present ("[La/b/C;"). Historically we've 2056b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// supported names with dots too (such as "a.b.C"). 2060571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string NormalizeJniClassDescriptor(const char* name) { 2076b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes std::string result; 2086b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes // Add the missing "L;" if necessary. 2096b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes if (name[0] == '[') { 2106b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result = name; 2116b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } else { 2126b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += 'L'; 2136b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += name; 2146b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += ';'; 2156b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } 2166b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes // Rewrite '.' as '/' for backwards compatibility. 217a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes if (result.find('.') != std::string::npos) { 218a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes LOG(WARNING) << "Call to JNI FindClass with dots in name: " 219a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes << "\"" << name << "\""; 220a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes std::replace(result.begin(), result.end(), '.', '/'); 2216b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } 2226b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes return result; 2236b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes} 2246b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes 22500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowNoSuchMethodError(ScopedObjectAccess& soa, Class* c, 22600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* name, const char* sig, const char* kind) 227b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 22962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;", 23062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no %s method \"%s.%s%s\"", 23162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers kind, ClassHelper(c).GetDescriptor(), name, sig); 23214134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes} 23314134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes 23400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class, 23500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* name, const char* sig, bool is_static) 236b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 23700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(jni_class); 2380045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 239f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes return NULL; 240cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 241ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 24266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = NULL; 243cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (is_static) { 244cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindDirectMethod(name, sig); 245cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } else { 246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindVirtualMethod(name, sig); 247cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (method == NULL) { 248cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // No virtual method matching the signature. Search declared 249cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // private methods and constructors. 250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindDeclaredDirectMethod(name, sig); 251cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 252cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 253ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 254cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (method == NULL || method->IsStatic() != is_static) { 25500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static"); 256cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 258ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeMethod(method); 260ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 262ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogersstatic ClassLoader* GetClassLoader(const ScopedObjectAccess& soa) 263b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 26462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers AbstractMethod* method = soa.Self()->GetCurrentMethod(NULL); 265ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (method == NULL || 266ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) { 267ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return soa.Self()->GetClassLoaderOverride(); 26800fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 26900fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom return method->GetDeclaringClass()->GetClassLoader(); 27000fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom} 27100fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom 27200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name, 27300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* sig, bool is_static) 274b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 27500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(jni_class); 2760045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 277f4c21c9f6440c3980c47a297519f758796dbc039Elliott Hughes return NULL; 278cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 279ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 280cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes Field* field = NULL; 2810cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* field_type; 2820cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 2830cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers if (sig[1] != '\0') { 284ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ClassLoader* cl = GetClassLoader(soa); 2850cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers field_type = class_linker->FindClass(sig, cl); 2860cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } else { 2870cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers field_type = class_linker->FindPrimitiveClass(*sig); 2880cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 2890cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers if (field_type == NULL) { 2900cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // Failed to find type from the signature of the field. 29100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DCHECK(soa.Self()->IsExceptionPending()); 29262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location; 29362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Throwable> cause(soa.Self(), soa.Self()->GetException(&throw_location)); 29400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 29562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", 29662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no type \"%s\" found and so no field \"%s\" could be found in class " 29762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "\"%s\" or its superclasses", sig, name, 29862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ClassHelper(c).GetDescriptor()); 29962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->GetException(NULL)->SetCause(cause.get()); 3000cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return NULL; 3010cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 302cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (is_static) { 3036d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor()); 3044dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } else { 3056d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor()); 3064dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 307cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (field == NULL) { 30862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 30962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", 31062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no \"%s\" field \"%s\" in class \"%s\" or its superclasses", 31162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers sig, name, ClassHelper(c).GetDescriptor()); 312cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 313cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 31400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeField(field); 315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 316ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 31700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void PinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array) 318b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 31900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 32050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->pins_lock); 3217577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm->pin_table.Add(array); 3227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 3237577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 32400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void UnpinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array) 325b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 32600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 32750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->pins_lock); 3287577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm->pin_table.Remove(array); 3297577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 3307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 33100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowAIOOBE(ScopedObjectAccess& soa, Array* array, jsize start, 33200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize length, const char* identifier) 333b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 33454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes std::string type(PrettyTypeOf(array)); 33562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 33662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;", 33762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "%s offset=%d length=%d %s.length=%d", 33862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers type.c_str(), start, length, identifier, array->GetLength()); 339814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes} 3400571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 34100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length, 34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize array_length) 343b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 34562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;", 34662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "offset=%d length=%d string.length()=%d", start, length, 34762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers array_length); 348b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes} 349814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 35000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersint ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause) 351b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 35200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Turn the const char* into a java.lang.String. 35300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg)); 35400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (msg != NULL && s.get() == NULL) { 35500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 356814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 357814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 35800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Choose an appropriate constructor and set up the arguments. 35900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jvalue args[2]; 36000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* signature; 36100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (msg == NULL && cause == NULL) { 36200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "()V"; 36300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else if (msg != NULL && cause == NULL) { 36400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/String;)V"; 36500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = s.get(); 36600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else if (msg == NULL && cause != NULL) { 36700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/Throwable;)V"; 36800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = cause; 369814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } else { 37000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V"; 37100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = s.get(); 37200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[1].l = cause; 37300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 37400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jmethodID mid = env->GetMethodID(exception_class, "<init>", signature); 37500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (mid == NULL) { 376ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 37700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(ERROR) << "No <init>" << signature << " in " 37800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers << PrettyClass(soa.Decode<Class*>(exception_class)); 37900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 380814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 381a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 38200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args))); 38300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (exception.get() == NULL) { 38400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 386ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 38762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 38862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(throw_location, soa.Decode<Throwable*>(exception.get())); 38900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_OK; 390a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes} 391a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 392462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughesstatic jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) { 3937577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (vm == NULL || p_env == NULL) { 3947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JNI_ERR; 3957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 3967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 397462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Return immediately if we're already attached. 398cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes Thread* self = Thread::Current(); 399cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes if (self != NULL) { 400cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes *p_env = self->GetJniEnv(); 401cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes return JNI_OK; 402cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes } 403cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 404cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime; 405cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 406cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // No threads allowed in zygote mode. 407cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes if (runtime->IsZygote()) { 408cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes LOG(ERROR) << "Attempt to attach a thread in the zygote"; 409cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes return JNI_ERR; 410cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes } 411cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 412462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args); 413462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes const char* thread_name = NULL; 414365c10235438607541fa2259a5fec48061b90bd8Ian Rogers jobject thread_group = NULL; 415462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes if (args != NULL) { 41683a25328c595975097cf3948451088cbfc64fc09Elliott Hughes if (IsBadJniVersion(args->version)) { 41783a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to " 41883a25328c595975097cf3948451088cbfc64fc09Elliott Hughes << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": " 41983a25328c595975097cf3948451088cbfc64fc09Elliott Hughes << args->version; 42083a25328c595975097cf3948451088cbfc64fc09Elliott Hughes return JNI_EVERSION; 4218692215f793cbf8be9c3d25a705074ca877e09b8Brian Carlstrom } 422462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes thread_name = args->name; 423365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group = args->group; 4247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 4257577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 426664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) { 427120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers *p_env = NULL; 428120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return JNI_ERR; 429120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } else { 430120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers *p_env = Thread::Current()->GetJniEnv(); 431120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return JNI_OK; 432120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 4337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 4347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 43579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass SharedLibrary { 43679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public: 43779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary(const std::string& path, void* handle, Object* class_loader) 43879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes : path_(path), 43979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes handle_(handle), 44031384c59bb4b387f29f2b6d4d3db886c29b81170Shih-wei Liao class_loader_(class_loader), 4418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes jni_on_load_lock_("JNI_OnLoad lock"), 442c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_), 443dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes jni_on_load_thread_id_(Thread::Current()->GetThinLockId()), 44479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes jni_on_load_result_(kPending) { 44579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 44679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 44779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Object* GetClassLoader() { 44879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return class_loader_; 44979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 45079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 45179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string GetPath() { 45279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return path_; 45379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 45479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 45579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes /* 4561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes * Check the result of an earlier call to JNI_OnLoad on this library. 4571bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes * If the call has not yet finished in another thread, wait for it. 45879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes */ 45900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool CheckOnLoadResult() 46000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(jni_on_load_lock_) 461b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 46279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Thread* self = Thread::Current(); 46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad); 46400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool okay; 46500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 46650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, jni_on_load_lock_); 46700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 46800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (jni_on_load_thread_id_ == self->GetThinLockId()) { 46900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Check this so we don't end up waiting for ourselves. We need to return "true" so the 47000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // caller can continue. 47100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\""; 47200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers okay = true; 47300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 47400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers while (jni_on_load_result_ == kPending) { 47500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]"; 476c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_.Wait(self); 47700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 47879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 47900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers okay = (jni_on_load_result_ == kOkay); 48000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" " 48100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers << (okay ? "succeeded" : "failed") << "]"; 48200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 48379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 48400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 48579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return okay; 48679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 48779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 48800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) { 489c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers Thread* self = Thread::Current(); 490c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers MutexLock mu(self, jni_on_load_lock_); 491f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes 49279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes jni_on_load_result_ = result ? kOkay : kFailed; 493dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes jni_on_load_thread_id_ = 0; 49479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 49579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Broadcast a wakeup to anybody sleeping on the condition variable. 496c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_.Broadcast(self); 49779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 49879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 49979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* FindSymbol(const std::string& symbol_name) { 50079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return dlsym(handle_, symbol_name.c_str()); 50179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 50279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 50379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private: 50479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes enum JNI_OnLoadState { 50579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kPending, 50679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kFailed, 50779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kOkay, 50879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes }; 50979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Path to library "/system/lib/libjni.so". 51179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string path_; 51279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // The void* returned by dlopen(3). 51479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* handle_; 51579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // The ClassLoader this library is associated with. 51779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Object* class_loader_; 51879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Guards remaining items. 52000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 52179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Wait for JNI_OnLoad in other thread. 522c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_); 52379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Recursive invocation guard. 524f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_); 52579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Result of earlier JNI_OnLoad call. 526f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_); 52779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes}; 52879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 52979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes// This exists mainly to keep implementation details out of the header file. 53079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass Libraries { 53179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public: 53279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Libraries() { 53379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 53479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 53579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes ~Libraries() { 536c31664f3d82e6cd68275a529a8a73f067a52e8beElliott Hughes STLDeleteValues(&libraries_); 53779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 53879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 539ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes void Dump(std::ostream& os) const { 540ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes bool first = true; 541ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes for (It it = libraries_.begin(); it != libraries_.end(); ++it) { 542ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes if (!first) { 543ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << ' '; 544ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 545ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes first = false; 546ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << it->first; 547ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 548ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 549ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 550ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes size_t size() const { 551ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes return libraries_.size(); 552ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 553ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 55479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary* Get(const std::string& path) { 555712462a887a1bd31ab49d06c4e63ab8b7191b37dIan Rogers It it = libraries_.find(path); 556712462a887a1bd31ab49d06c4e63ab8b7191b37dIan Rogers return (it == libraries_.end()) ? NULL : it->second; 55779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 55879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 55979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void Put(const std::string& path, SharedLibrary* library) { 560a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes libraries_.Put(path, library); 56179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 56279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 56379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // See section 11.3 "Linking Native Methods" of the JNI spec. 56466f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier void* FindNativeMethod(const AbstractMethod* m, std::string& detail) 565b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 56679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string jni_short_name(JniShortName(m)); 56779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string jni_long_name(JniLongName(m)); 5684b093bfcbddd0e8f708da87f333cc98bc9f233e1Elliott Hughes const ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader(); 56979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes for (It it = libraries_.begin(); it != libraries_.end(); ++it) { 57079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary* library = it->second; 57179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (library->GetClassLoader() != declaring_class_loader) { 57279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // We only search libraries loaded by the appropriate ClassLoader. 57379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes continue; 57479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 57579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Try the short name then the long name... 57679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* fn = library->FindSymbol(jni_short_name); 57779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (fn == NULL) { 57879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes fn = library->FindSymbol(jni_long_name); 57979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 58079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (fn != NULL) { 5814dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Found native code for " << PrettyMethod(m) 5824dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes << " in \"" << library->GetPath() << "\"]"; 58379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return fn; 58479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 58579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 58679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes detail += "No implementation found for "; 587a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes detail += PrettyMethod(m); 58892827a5fc2598589b3717269cc09c33b8c53f30bBrian Carlstrom detail += " (tried " + jni_short_name + " and " + jni_long_name + ")"; 58979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes LOG(ERROR) << detail; 59079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return NULL; 59179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 59279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 59379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private: 5947934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom typedef SafeMap<std::string, SharedLibrary*>::const_iterator It; // TODO: C++0x auto 59579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 596a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<std::string, SharedLibrary*> libraries_; 59779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes}; 59879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 59900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersJValue InvokeWithJValues(const ScopedObjectAccess& soa, jobject obj, jmethodID mid, 60000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jvalue* args) { 60166f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = soa.DecodeMethod(mid); 6027a549467e332398229724058c07d998d0acfb0bbJeff Hao Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj); 6032fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 6045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 6052fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 6065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 6076474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 6086474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 609d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes} 610d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes 611cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JNI { 612cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public: 61325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static jint GetVersion(JNIEnv*) { 614cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_VERSION_1_6; 615cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 616cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 61725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) { 618cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI DefineClass is not supported"; 61918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes return NULL; 62018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 62118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 622cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jclass FindClass(JNIEnv* env, const char* name) { 62300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 6245fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Runtime* runtime = Runtime::Current(); 6255fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes ClassLinker* class_linker = runtime->GetClassLinker(); 626cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes std::string descriptor(NormalizeJniClassDescriptor(name)); 6275fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Class* c = NULL; 6285fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes if (runtime->IsStarted()) { 629ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ClassLoader* cl = GetClassLoader(soa); 630c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes c = class_linker->FindClass(descriptor.c_str(), cl); 6315fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes } else { 632c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes c = class_linker->FindSystemClass(descriptor.c_str()); 6335fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes } 63400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c); 635cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 636ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 637cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) { 63800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 63966f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = soa.Decode<AbstractMethod*>(java_method); 64000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeMethod(method); 64118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 64218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 643cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) { 64400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 64500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* field = soa.Decode<Field*>(java_field); 64600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeField(field); 647cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 64818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 649cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) { 65000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 65166f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* method = soa.DecodeMethod(mid); 65200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(method); 65318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 654ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 655cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) { 65600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 65700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* field = soa.DecodeField(fid); 65800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(field); 659cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 660cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 66137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jclass GetObjectClass(JNIEnv* env, jobject java_object) { 66200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 66300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 66400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(o->GetClass()); 66537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 66637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 667885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jclass GetSuperclass(JNIEnv* env, jclass java_class) { 66800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 66900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 67000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c->GetSuperClass()); 67118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 67218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 67337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) { 67400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 67500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c1 = soa.Decode<Class*>(java_class1); 67600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c2 = soa.Decode<Class*>(java_class2); 67737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return c1->IsAssignableFrom(c2) ? JNI_TRUE : JNI_FALSE; 678cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 67918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 680e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) { 68100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 68296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (java_class == NULL) { 68396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("IsInstanceOf", "null class (second argument)"); 68496a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 68537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes if (jobj == NULL) { 6865d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom // Note: JNI is different from regular Java instanceof in this respect 68737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_TRUE; 68837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } else { 68900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* obj = soa.Decode<Object*>(jobj); 69000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 691e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE; 69237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 69337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 69437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 69537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jint Throw(JNIEnv* env, jthrowable java_exception) { 69600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 69700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Throwable* exception = soa.Decode<Throwable*>(java_exception); 69837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes if (exception == NULL) { 69937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_ERR; 70037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 70162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 70262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(throw_location, exception); 70337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_OK; 70437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 70537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 706e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) { 707a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes return ThrowNewException(env, c, msg, NULL); 70837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 70937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 71037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jboolean ExceptionCheck(JNIEnv* env) { 711120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE; 71237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 71337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 71437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static void ExceptionClear(JNIEnv* env) { 715120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers static_cast<JNIEnvExt*>(env)->self->ClearException(); 71618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 71718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 71837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static void ExceptionDescribe(JNIEnv* env) { 71900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 72072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 72162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Object> old_throw_this_object(soa.Self(), NULL); 72262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::AbstractMethod> old_throw_method(soa.Self(), NULL); 72362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SirtRef<mirror::Throwable> old_exception(soa.Self(), NULL); 72462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t old_throw_dex_pc; 72562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers { 72662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation old_throw_location; 72762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location); 72862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_this_object.reset(old_throw_location.GetThis()); 72962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_method.reset(old_throw_location.GetMethod()); 73062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_exception.reset(old_exception_obj); 73162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc = old_throw_location.GetDexPc(); 73262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 73362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 73462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ScopedLocalRef<jthrowable> exception(env, soa.AddLocalReference<jthrowable>(old_exception.get())); 73572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get())); 73672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V"); 73772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes if (mid == NULL) { 73872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes LOG(WARNING) << "JNI WARNING: no printStackTrace()V in " 73962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << PrettyTypeOf(old_exception.get()); 74072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } else { 74172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes env->CallVoidMethod(exception.get(), mid); 74262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (soa.Self()->IsExceptionPending()) { 74362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(NULL)) 74472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes << " thrown while calling printStackTrace"; 74562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 74672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 74772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 74862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(), 74962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc); 75072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 75162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(gc_safe_throw_location, old_exception.get()); 752cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 75318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jthrowable ExceptionOccurred(JNIEnv* env) { 75500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 75662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Object* exception = soa.Self()->GetException(NULL); 75700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jthrowable>(exception); 75818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 75918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 76025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static void FatalError(JNIEnv*, const char* msg) { 761cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(FATAL) << "JNI FatalError called: " << msg; 762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 76318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 7642ced6a534157d5d963693346904389c19775d2daElliott Hughes static jint PushLocalFrame(JNIEnv* env, jint capacity) { 765ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (EnsureLocalCapacity(env, capacity, "PushLocalFrame") != JNI_OK) { 7662ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNI_ERR; 7672ced6a534157d5d963693346904389c19775d2daElliott Hughes } 768ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers static_cast<JNIEnvExt*>(env)->PushFrame(capacity); 769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_OK; 770c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes } 771c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes 7722ced6a534157d5d963693346904389c19775d2daElliott Hughes static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) { 77300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 77400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* survivor = soa.Decode<Object*>(java_survivor); 77500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->PopFrame(); 77600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(survivor); 777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 778c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes 7792ced6a534157d5d963693346904389c19775d2daElliott Hughes static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) { 780ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return EnsureLocalCapacity(env, desired_capacity, "EnsureLocalCapacity"); 78172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 78272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject NewGlobalRef(JNIEnv* env, jobject obj) { 784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 785cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 786cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 78725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 78800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes IndirectReferenceTable& globals = vm->globals; 79000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* decoded_obj = soa.Decode<Object*>(obj); 79150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->globals_lock); 79200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj); 793cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return reinterpret_cast<jobject>(ref); 794c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes } 795ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 796cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteGlobalRef(JNIEnv* env, jobject obj) { 797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return; 799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 800ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm; 801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes IndirectReferenceTable& globals = vm->globals; 802ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self; 803ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers MutexLock mu(self, vm->globals_lock); 804ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) { 806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") " 807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes << "failed to find entry"; 808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 810ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) { 81200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 81300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj)); 814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 815ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) { 817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return; 819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 82025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 82100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes IndirectReferenceTable& weak_globals = vm->weak_globals; 82350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->weak_globals_lock); 824ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (!weak_globals.Remove(IRT_FIRST_SEGMENT, obj)) { 826cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") " 827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes << "failed to find entry"; 828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 830ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 831cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject NewLocalRef(JNIEnv* env, jobject obj) { 832cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 83525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 8369dcd45c60c691524bd8ef7d6f65075d9ee3e5554Elliott Hughes return soa.AddLocalReference<jobject>(soa.Decode<Object*>(obj)); 8374dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 838ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 839cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteLocalRef(JNIEnv* env, jobject obj) { 840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return; 842cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 843ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals; 844cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 845ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie; 846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (!locals.Remove(cookie, obj)) { 847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Attempting to delete a local reference that is not in the 848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // topmost local reference frame is a no-op. DeleteLocalRef returns 849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // void and doesn't throw any exceptions, but we should probably 850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // complain about it so the user will notice that things aren't 851cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // going quite the way they expect. 852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") " 853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes << "failed to find entry"; 854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 85583ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) { 85800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 859120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2)) ? JNI_TRUE : JNI_FALSE; 86083ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 862885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject AllocObject(JNIEnv* env, jclass java_class) { 86300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 86400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 8650045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 866885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes return NULL; 867885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 86850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self())); 869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 871e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) { 872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list args; 87372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(args, mid); 874e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes jobject result = NewObjectV(env, c, mid, args); 875cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(args); 876cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return result; 877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 87972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) { 88000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 88100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 8820045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 883885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes return NULL; 884885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 88550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Object* result = c->AllocObject(soa.Self()); 88630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (result == NULL) { 88730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return NULL; 88830646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 88900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result); 89072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args); 89100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!soa.Self()->IsExceptionPending()) { 8925d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return local_result; 8935d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } else { 8945d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return NULL; 8955d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 896cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 89872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) { 89900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 90000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 9010045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 902885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes return NULL; 903885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 90450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Object* result = c->AllocObject(soa.Self()); 90530646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (result == NULL) { 90630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return NULL; 90730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 90800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobjectArray>(result); 90972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args); 91000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!soa.Self()->IsExceptionPending()) { 9115d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return local_result; 9125d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } else { 9135d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return NULL; 9145d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 916cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) { 91800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 91900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return FindMethodID(soa, c, name, sig, false); 920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 921ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) { 92300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 92400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return FindMethodID(soa, c, name, sig, true); 925cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 926ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 92772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 92872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 92972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 93025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 93100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 93272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 93300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 934cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 935ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 93672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 93700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 93800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args)); 93900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 940cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 941ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 94272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 94300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 94400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args)); 94500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 946cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 947ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 94872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 94972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 95072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 95125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 95200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 95372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 954f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 955cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 956ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 95772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 95800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 95900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ(); 960cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 961ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 96272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 96300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 96400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ(); 965cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 966ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 96772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 96800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 96972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 97072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 97100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 97272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 973f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 974cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 975ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 97672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 97700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 97800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB(); 979cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 980ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 98172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 98200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 98300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB(); 984cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 985ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 98672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 98772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 98872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 98925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 99000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 99172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 992f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 993cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 994ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 99572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 99600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 99700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC(); 998cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 999ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 100072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 100100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC(); 1003cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1004ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 100572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 100672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 100772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 100825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 100900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 101072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1011f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1012cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1013ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 101472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 101500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 101600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD(); 1017cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1018ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 101972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 102000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 102100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD(); 1022cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1023ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 102472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 102500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 102672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 102772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 102800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 102972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1030f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1031cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1032ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 103372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 103400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 103500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF(); 1036cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1037ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 103872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 103900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 104000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF(); 1041cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1042ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 104372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 104472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 104572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 104625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 104700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 104872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1049f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1050cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1051ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 105272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 105300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 105400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI(); 1055cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1056ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 105772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 105800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 105900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI(); 1060cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1061ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 106272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 106372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 106472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 106525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 106600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 106772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1068f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1069cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1070ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 107172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 107200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ(); 1074cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1075ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 107672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 107700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 107800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ(); 1079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1080ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 108172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 108272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 108372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 108425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 108672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1087f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1088cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1089ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 109072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 109100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 109200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS(); 1093cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1094ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 109572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 109600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 109700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS(); 1098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1099ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 110072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 110172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 110272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 110325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 11041b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap); 110572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1107ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 110872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 110900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 111000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args); 1111cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1112ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 111372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 111400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 111500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args); 1116cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1117ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 11181bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1119cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 112072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 112125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 112200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 112300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result.GetL()); 1124cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1125cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return local_result; 1126cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1127ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1128cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject CallNonvirtualObjectMethodV(JNIEnv* env, 11291bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 113000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 113100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, args)); 113200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1133cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1134ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1135cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject CallNonvirtualObjectMethodA(JNIEnv* env, 11361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 113700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 113800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithJValues(soa, obj, mid, args)); 113900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1140cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1141ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1142cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, 11431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, ...) { 1144cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 114572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 114625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 114700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1148cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1149f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 1150cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1151ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, 11531bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 115400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 115500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetZ(); 1156cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1157ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, 11591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 116000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 116100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetZ(); 1162cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1163ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 11641bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1165cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 116672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 116725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 116800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1169cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1170f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 1171cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1172ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1173cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbyte CallNonvirtualByteMethodV(JNIEnv* env, 11741bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 117500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 117600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetB(); 1177cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1178ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1179cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbyte CallNonvirtualByteMethodA(JNIEnv* env, 11801bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 118100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 118200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetB(); 1183cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1184ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 11851bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 118600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1187cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 118872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 118900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1190cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1191f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 1192cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1193ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1194cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jchar CallNonvirtualCharMethodV(JNIEnv* env, 11951bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 119600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 119700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetC(); 1198cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1199ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1200cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jchar CallNonvirtualCharMethodA(JNIEnv* env, 12011bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 120200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 120300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetC(); 1204cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1205ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12061bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1207cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 120872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 120925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 121000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1211cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1212f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1213cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1214ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1215cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jshort CallNonvirtualShortMethodV(JNIEnv* env, 12161bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 121700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 121800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetS(); 1219cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1220ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1221cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jshort CallNonvirtualShortMethodA(JNIEnv* env, 12221bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 122300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 122400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetS(); 1225cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1226ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1228cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 122972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 123025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 123100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1232cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1233f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1234cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1235ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1236cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint CallNonvirtualIntMethodV(JNIEnv* env, 12371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 123800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 123900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetI(); 1240cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1241ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1242cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint CallNonvirtualIntMethodA(JNIEnv* env, 12431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 124400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 124500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetI(); 1246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1247ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12481bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1249cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 125072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 125125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 125200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1253cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1254f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1255cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1256ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jlong CallNonvirtualLongMethodV(JNIEnv* env, 12581bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 125900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 126000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetJ(); 1261cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1262ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1263cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jlong CallNonvirtualLongMethodA(JNIEnv* env, 12641bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 126500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 126600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetJ(); 1267cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1268ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12691bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1270cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 127172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 127225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 127300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1274cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1275f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1276cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1277ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1278cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, 12791bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 128000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 128100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetF(); 1282cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1283ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1284cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, 12851bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 128600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 128700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetF(); 1288cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1289ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12901bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1291cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 129272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 129325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 129400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1296f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1297cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1298ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1299cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, 13001bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 130100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 130200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetD(); 1303cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1304ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1305cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, 13061bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 130700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 130800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetD(); 1309cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1310ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13111bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1312cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 131372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 131425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 131500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, obj, mid, ap); 1316cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1317cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1318ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1319cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void CallNonvirtualVoidMethodV(JNIEnv* env, 13201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, va_list args) { 132100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 132200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, obj, mid, args); 1323cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1324ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void CallNonvirtualVoidMethodA(JNIEnv* env, 13261bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes jobject obj, jclass, jmethodID mid, jvalue* args) { 132700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 132800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithJValues(soa, obj, mid, args); 1329cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1330ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13315ee7a8b56dee896245e0f4ae5215f8b7376c1787Elliott Hughes static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) { 133200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 133300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return FindFieldID(soa, c, name, sig, false); 1334cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1335ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1336ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13375ee7a8b56dee896245e0f4ae5215f8b7376c1787Elliott Hughes static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) { 133800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 133900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return FindFieldID(soa, c, name, sig, true); 1340cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1341ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1342885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) { 134300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 134400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(obj); 134500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); 134600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(f->GetObject(o)); 1347cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1348ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1349885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) { 135000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 135100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); 13522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass())); 1353cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1354ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1355885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) { 135600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 135700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 135800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* v = soa.Decode<Object*>(java_value); 135900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); 1360885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes f->SetObject(o, v); 1361cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1362ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1363885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) { 136400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 136500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* v = soa.Decode<Object*>(java_value); 136600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); 13672fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers f->SetObject(f->GetDeclaringClass(), v); 1368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1369ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1370885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define GET_PRIMITIVE_FIELD(fn, instance) \ 137100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); \ 137200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(instance); \ 137300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); \ 1374885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes return f->fn(o) 1375885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 13762fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define GET_STATIC_PRIMITIVE_FIELD(fn) \ 13772fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ScopedObjectAccess soa(env); \ 13782fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers Field* f = soa.DecodeField(fid); \ 13792fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers return f->fn(f->GetDeclaringClass()) 13802fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 1381885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define SET_PRIMITIVE_FIELD(fn, instance, value) \ 138200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); \ 138300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(instance); \ 138400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Field* f = soa.DecodeField(fid); \ 1385885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes f->fn(o, value) 1386885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 13872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \ 13882fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ScopedObjectAccess soa(env); \ 13892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers Field* f = soa.DecodeField(fid); \ 13902fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers f->fn(f->GetDeclaringClass(), value) 13912fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 1392885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) { 1393885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetBoolean, obj); 1394cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1395ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1396885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) { 1397885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetByte, obj); 1398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1399ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1400885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) { 1401885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetChar, obj); 1402cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1403ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1404885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) { 1405885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetShort, obj); 1406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1407ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1408885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) { 1409885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetInt, obj); 1410cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1411ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1412885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) { 1413885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetLong, obj); 1414cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1415ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1416885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) { 1417885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetFloat, obj); 1418cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1419ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1420885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) { 1421885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes GET_PRIMITIVE_FIELD(GetDouble, obj); 1422cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1423ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) { 14252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetBoolean); 1426cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1427ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14281bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) { 14292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetByte); 143083ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 1431cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 14321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) { 14332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetChar); 14349b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro } 1435ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) { 14372fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetShort); 1438cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1439ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14401bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) { 14412fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetInt); 1442cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1443ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14441bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) { 14452fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetLong); 1446885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1447885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 14481bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) { 14492fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetFloat); 1450885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1451885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 14521bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) { 14532fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers GET_STATIC_PRIMITIVE_FIELD(GetDouble); 1454885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1455885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1456885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) { 1457885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetBoolean, obj, v); 1458885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1459885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1460885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) { 1461885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetByte, obj, v); 1462885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1463885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1464885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) { 1465885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetChar, obj, v); 1466885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1467885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1468885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) { 1469885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetFloat, obj, v); 1470885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1471885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1472885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) { 1473885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetDouble, obj, v); 1474885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1475885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1476885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) { 1477885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetInt, obj, v); 1478885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1479885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1480885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) { 1481885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetLong, obj, v); 1482885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1483885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1484885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) { 1485885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes SET_PRIMITIVE_FIELD(SetShort, obj, v); 1486885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1487885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1488885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) { 14892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetBoolean, v); 1490885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1491885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1492885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) { 14932fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetByte, v); 1494885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1495885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1496885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) { 14972fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetChar, v); 1498885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1499885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1500885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) { 15012fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetFloat, v); 1502885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1503885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1504885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) { 15052fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetDouble, v); 1506885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1507885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1508885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) { 15092fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetInt, v); 1510885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1511885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1512885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) { 15132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetLong, v); 1514885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1515885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1516885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) { 15172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers SET_STATIC_PRIMITIVE_FIELD(SetShort, v); 1518cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1519ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 152272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 152325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 152400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 152500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result.GetL()); 1526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1527cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return local_result; 1528cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1529ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15301bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 153100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 153200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, args)); 153300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1534cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1535ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 153700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 153800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithJValues(soa, NULL, mid, args)); 153900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1540cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1541ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15421bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1543cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 154472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 154525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 154600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1547cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1548f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 1549cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1550ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 155200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 155300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetZ(); 1554cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1555ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 155700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 155800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetZ(); 1559cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1560ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15611bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1562cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 156372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 156425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 156500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1566cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1567f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 1568cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1569ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 157100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 157200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetB(); 1573cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1574ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15751bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 157600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 157700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetB(); 1578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1579ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15801bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1581cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 158272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 158325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 158400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1585cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1586f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 1587cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1588ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15891bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 159000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 159100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetC(); 1592cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1593ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15941bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 159500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 159600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetC(); 1597cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1598ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15991bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1600cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 160172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 160225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 160300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1605f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1606cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1607ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16081bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 160900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 161000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetS(); 1611cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1612ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16131bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 161400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 161500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetS(); 1616cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1617ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16181bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1619cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 162072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 162125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 162200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1623cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1624f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1625cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1626ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 162800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 162900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetI(); 1630cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1631ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 163300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 163400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetI(); 1635cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1636ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1638cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 163972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 164025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 164100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1642cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1643f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1644cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1645ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16461bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 164700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 164800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetJ(); 1649cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1650ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 165200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 165300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetJ(); 1654cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1655ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1657cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 165872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 165925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 166000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1661cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1662f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1663cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1664ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16651bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 166600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 166700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetF(); 1668cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1669ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 167100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 167200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetF(); 1673cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1674ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16751bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1676cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 167772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 167825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 167900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1680cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1681f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1682cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1683ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16841bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 168500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 168600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetD(); 1687cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1688ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16891bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 169000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 169100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetD(); 1692cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1693ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16941bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1695cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 169672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 169725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 169800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, NULL, mid, ap); 1699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1700cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1701ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17021bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 170300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 170400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, NULL, mid, args); 1705cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1706ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17071bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 170800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 170900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithJValues(soa, NULL, mid, args); 1710cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1711ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1712814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) { 171300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 171450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers String* result = String::AllocFromUtf16(soa.Self(), char_count, chars); 171500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jstring>(result); 1716cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1717ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1718814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jstring NewStringUTF(JNIEnv* env, const char* utf) { 1719814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes if (utf == NULL) { 1720814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes return NULL; 1721814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 172200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 172350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers String* result = String::AllocFromModifiedUtf8(soa.Self(), utf); 172400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jstring>(result); 1725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1726ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1727814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jsize GetStringLength(JNIEnv* env, jstring java_string) { 172800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 172900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.Decode<String*>(java_string)->GetLength(); 1730814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 1731814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 1732814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) { 173300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 173400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.Decode<String*>(java_string)->GetUtfLength(); 1735814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 1736814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 1737b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, jchar* buf) { 173800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 173900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 1740b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes if (start < 0 || length < 0 || start + length > s->GetLength()) { 174100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowSIOOBE(soa, start, length, s->GetLength()); 1742b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } else { 1743b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset(); 1744b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes memcpy(buf, chars + start, length * sizeof(jchar)); 1745b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 17468a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes } 1747ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1748b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, char* buf) { 174900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 175000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 1751b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes if (start < 0 || length < 0 || start + length > s->GetLength()) { 175200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowSIOOBE(soa, start, length, s->GetLength()); 1753b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } else { 1754b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset(); 1755b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes ConvertUtf16ToModifiedUtf8(buf, chars + start, length); 1756b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 1757cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1758ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17597577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) { 176000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 176100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 17627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes const CharArray* chars = s->GetCharArray(); 176300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, chars); 17647577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (is_copy != NULL) { 17657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes *is_copy = JNI_FALSE; 17667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 17677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return chars->GetData() + s->GetOffset(); 1768cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1769ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar*) { 177100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 177200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray()); 1773cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1774ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) { 17767577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return GetStringChars(env, java_string, is_copy); 1777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1778ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17797577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) { 178000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 17817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return ReleaseStringChars(env, java_string, chars); 1782cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1783ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17847577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) { 17857577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (java_string == NULL) { 17867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return NULL; 17877577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 17887577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (is_copy != NULL) { 17897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes *is_copy = JNI_TRUE; 17907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 1791ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 179200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 17937577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes size_t byte_count = s->GetUtfLength(); 17947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes char* bytes = new char[byte_count + 1]; 17957934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom CHECK(bytes != NULL); // bionic aborts anyway. 17967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset(); 17977577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength()); 17987577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes bytes[byte_count] = '\0'; 17997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return bytes; 1800b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 1801b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 18027577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) { 18037577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes delete[] chars; 1804b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 1805b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 1806bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes static jsize GetArrayLength(JNIEnv* env, jarray java_array) { 180700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 180800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* obj = soa.Decode<Object*>(java_array); 180996a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (!obj->IsArrayInstance()) { 181096a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str()); 181196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 1812bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes Array* array = obj->AsArray(); 1813bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes return array->GetLength(); 1814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1815ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1816814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) { 181700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 181800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array); 181900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(array->Get(index)); 1820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1821d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes 1822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void SetObjectArrayElement(JNIEnv* env, 1823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes jobjectArray java_array, jsize index, jobject java_value) { 182400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 182500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array); 182600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* value = soa.Decode<Object*>(java_value); 1827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes array->Set(index, value); 1828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1829f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 1830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) { 183100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 183200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length); 1833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1834ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbyteArray NewByteArray(JNIEnv* env, jsize length) { 183600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 183700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length); 1838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1839ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jcharArray NewCharArray(JNIEnv* env, jsize length) { 184100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 184200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jcharArray, CharArray>(soa, length); 1843cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1844ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1845cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) { 184600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 184700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length); 1848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1849ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfloatArray NewFloatArray(JNIEnv* env, jsize length) { 185100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 185200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length); 1853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1854ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jintArray NewIntArray(JNIEnv* env, jsize length) { 185600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 185700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jintArray, IntArray>(soa, length); 1858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1859ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jlongArray NewLongArray(JNIEnv* env, jsize length) { 186100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 186200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jlongArray, LongArray>(soa, length); 1863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1864f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 1865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) { 186600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 186796a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (length < 0) { 186896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("NewObjectArray", "negative array length: %d", length); 186996a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 1870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 1871cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Compute the array class corresponding to the given element class. 187200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* element_class = soa.Decode<Class*>(element_jclass); 1873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes std::string descriptor; 1874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes descriptor += "["; 18756d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers descriptor += ClassHelper(element_class).GetDescriptor(); 1876cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 1877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Find the class. 18787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes ScopedLocalRef<jclass> java_array_class(env, FindClass(env, descriptor.c_str())); 18797577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (java_array_class.get() == NULL) { 1880cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 1881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 18837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // Allocate and initialize if necessary. 188400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* array_class = soa.Decode<Class*>(java_array_class.get()); 188550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length); 18867577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (initial_element != NULL) { 188700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* initial_object = soa.Decode<Object*>(initial_element); 18887577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes for (jsize i = 0; i < length; ++i) { 18897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes result->Set(i, initial_object); 18907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 18917577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 189200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobjectArray>(result); 1893f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes } 1894f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 1895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jshortArray NewShortArray(JNIEnv* env, jsize length) { 189600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 189700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jshortArray, ShortArray>(soa, length); 1898cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1899ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1900a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) { 190100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 190200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Array* array = soa.Decode<Array*>(java_array); 190300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, array); 1904a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers if (is_copy != NULL) { 1905a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers *is_copy = JNI_FALSE; 1906a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers } 1907a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers return array->GetRawData(array->GetClass()->GetComponentSize()); 1908b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 1909b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 19101bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void*, jint mode) { 1911ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1912b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 1913b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 19147577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) { 191500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 191600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy); 1917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1918ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19197577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) { 192000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 192100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy); 1922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1923ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) { 192500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 192600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy); 1927cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1928ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19297577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) { 193000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 193100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy); 1932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1933ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) { 193500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 193600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy); 1937cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1938ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) { 194000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 194100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy); 1942cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1943ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) { 194500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 194600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy); 1947cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1948ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) { 195000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 195100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy); 1952cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1953ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean*, jint mode) { 1955ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1956cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1957ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19581bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte*, jint mode) { 1959ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1960cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1961ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19621bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar*, jint mode) { 1963ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1964cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1965ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19661bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble*, jint mode) { 1967ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1968cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1969ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat*, jint mode) { 1971ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1972cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1973ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19741bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint*, jint mode) { 1975ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1976cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1977ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong*, jint mode) { 1979ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1980cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1981ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19821bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort*, jint mode) { 1983ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ReleasePrimitiveArray(env, array, mode); 1984cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1985ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1986814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, jboolean* buf) { 198700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 198800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf); 1989cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1990ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1991814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, jbyte* buf) { 199200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 199300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf); 1994cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1995ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1996814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, jchar* buf) { 199700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 199800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf); 1999cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2000ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2001814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, jdouble* buf) { 200200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 200300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf); 2004cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2005ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2006814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, jfloat* buf) { 200700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 200800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf); 2009cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2010ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2011814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, jint* buf) { 201200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 201300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf); 2014cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2015ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2016814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, jlong* buf) { 201700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 201800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf); 2019cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2020ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2021814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, jshort* buf) { 202200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 202300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf); 2024cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2025ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2026814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, const jboolean* buf) { 202700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 202800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf); 2029cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2030ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2031814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, const jbyte* buf) { 203200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 203300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf); 2034cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2035ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2036814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, const jchar* buf) { 203700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 203800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf); 2039cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2040ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2041814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, const jdouble* buf) { 204200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 204300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf); 2044cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2045ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2046814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, const jfloat* buf) { 204700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 204800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf); 2049cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2050ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2051814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, const jint* buf) { 205200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 205300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf); 2054cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2055ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2056814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, const jlong* buf) { 205700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 205800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf); 2059cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2060ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2061814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, const jshort* buf) { 206200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 206300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf); 2064cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2065ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 20665174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, jint method_count) { 2067c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes return RegisterNativeMethods(env, java_class, methods, method_count, true); 2068c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes } 2069c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes 2070c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, size_t method_count, bool return_errors) { 207100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 207200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 20735174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 2074c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes for (size_t i = 0; i < method_count; ++i) { 2075cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes const char* name = methods[i].name; 2076cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes const char* sig = methods[i].signature; 2077ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2078cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (*sig == '!') { 2079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // TODO: fast jni. it's too noisy to log all these. 2080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes ++sig; 2081cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 20820af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 208366f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* m = c->FindDirectMethod(name, sig); 20845174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m == NULL) { 20855174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes m = c->FindVirtualMethod(name, sig); 2086cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 20875174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m == NULL) { 2088c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(return_errors ? ERROR : FATAL) << "Failed to register native method " 2089c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes << PrettyDescriptor(c) << "." << name << sig; 209000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static"); 2091cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 20925174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } else if (!m->IsNative()) { 2093c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method " 2094c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes << PrettyDescriptor(c) << "." << name << sig 2095c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes << " as native"; 209600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, "native"); 2097cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 2098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 20995174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 21004dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]"; 21015174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 210200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m->RegisterNative(soa.Self(), methods[i].fnPtr); 21034dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 2104cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_OK; 21054dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 2106ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 21075174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes static jint UnregisterNatives(JNIEnv* env, jclass java_class) { 210800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 210900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 21105174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 21114dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]"; 21125174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 21135174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes for (size_t i = 0; i < c->NumDirectMethods(); ++i) { 211466f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* m = c->GetDirectMethod(i); 21155174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m->IsNative()) { 211600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m->UnregisterNative(soa.Self()); 21175174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 21185174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 21195174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { 212066f19258f9728d4ffe026074d8fd429d639802faMathieu Chartier AbstractMethod* m = c->GetVirtualMethod(i); 21215174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m->IsNative()) { 212200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m->UnregisterNative(soa.Self()); 21235174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 21245174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 21255174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 21265174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes return JNI_OK; 2127cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2128ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 212900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static jint MonitorEnter(JNIEnv* env, jobject java_object) 213000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) { 213100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 213200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 213300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers o->MonitorEnter(soa.Self()); 213400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 2135ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_ERR; 2136ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes } 213700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->monitors.Add(o); 2138ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_OK; 2139cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2140ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 214100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static jint MonitorExit(JNIEnv* env, jobject java_object) 214200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UNLOCK_FUNCTION(monitor_lock_) { 214300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 214400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 214500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers o->MonitorExit(soa.Self()); 214600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 2147ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_ERR; 2148ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes } 214900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->monitors.Remove(o); 2150ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_OK; 2151f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes } 2152ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2153cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint GetJavaVM(JNIEnv* env, JavaVM** vm) { 2154cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes Runtime* runtime = Runtime::Current(); 2155cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (runtime != NULL) { 215669f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes *vm = runtime->GetJavaVM(); 2157cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } else { 2158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *vm = NULL; 2159cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2160cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return (*vm != NULL) ? JNI_OK : JNI_ERR; 2161cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2162ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2163b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { 216496a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (capacity < 0) { 216562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %lld", capacity); 216696a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 216711a796e42027a926d972f1232484d577cbe01f84Elliott Hughes if (address == NULL && capacity != 0) { 216862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers JniAbortF("NewDirectByteBuffer", "non-zero capacity for NULL pointer: %lld", capacity); 216996a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 2170ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 217196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes // At the moment, the Java side is limited to 32 bits. 2172b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff); 2173b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes CHECK_LE(capacity, 0xffffffff); 2174b56812165dd3a2e6eb8b85c810943b3d7bd9bfc4Elliott Hughes jlong address_arg = reinterpret_cast<jlong>(address); 2175b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes jint capacity_arg = static_cast<jint>(capacity); 2176ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2177aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer, 2178aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes WellKnownClasses::java_nio_DirectByteBuffer_init, 2179eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes address_arg, capacity_arg); 2180ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? NULL : result; 2181cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2182ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2183b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) { 2184534f2b6f430c7984fda9333f8e72b37962b144b4Jeff Hao return reinterpret_cast<void*>(env->GetLongField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress)); 2185cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2186ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2187b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) { 2188aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity)); 2189cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2190ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2191b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) { 219296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (java_object == NULL) { 219396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("GetObjectRefType", "null object"); 219496a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 2195b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2196b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // Do we definitely know what kind of reference this is? 2197b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes IndirectRef ref = reinterpret_cast<IndirectRef>(java_object); 2198b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes IndirectRefKind kind = GetIndirectRefKind(ref); 2199b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes switch (kind) { 2200b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kLocal: 2201ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) { 22022ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNILocalRefType; 22032ced6a534157d5d963693346904389c19775d2daElliott Hughes } 22042ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNIInvalidRefType; 2205b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kGlobal: 2206b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIGlobalRefType; 2207b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kWeakGlobal: 2208b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIWeakGlobalRefType; 2209b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kSirtOrInvalid: 2210b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // Is it in a stack IRT? 2211ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (static_cast<JNIEnvExt*>(env)->self->SirtContains(java_object)) { 2212b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNILocalRefType; 2213b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2214b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2215ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (!static_cast<JNIEnvExt*>(env)->vm->work_around_app_jni_bugs) { 2216c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes return JNIInvalidRefType; 2217c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes } 2218c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes 2219b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // If we're handing out direct pointers, check whether it's a direct pointer 2220b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // to a local reference. 2221ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers { 2222ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 2223ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) { 2224ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) { 2225ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return JNILocalRefType; 2226ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers } 2227b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2228b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2229b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIInvalidRefType; 2230b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 22312e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom LOG(FATAL) << "IndirectRefKind[" << kind << "]"; 22322e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom return JNIInvalidRefType; 2233cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 223400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 223500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 2236ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity, 2237ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers const char* caller) { 223800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: we should try to expand the table if necessary. 223900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (desired_capacity < 1 || desired_capacity > static_cast<jint>(kLocalsMax)) { 224000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity; 224100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 224200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 224300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: this isn't quite right, since "capacity" includes holes. 2244ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers size_t capacity = static_cast<JNIEnvExt*>(env)->locals.Capacity(); 224500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity); 224600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!okay) { 2247ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 224800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowOutOfMemoryError(caller); 224900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 225000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return okay ? JNI_OK : JNI_ERR; 225100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 225200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 225300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template<typename JniT, typename ArtT> 225400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length) 2255b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 225696a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (length < 0) { 225796a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("NewPrimitiveArray", "negative array length: %d", length); 225896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 225950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ArtT* result = ArtT::Alloc(soa.Self(), length); 226000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<JniT>(result); 226100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 226200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 226300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename ArrayT, typename CArrayT, typename ArtArrayT> 226400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array, 226500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jboolean* is_copy) 2266b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 226700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array); 226800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, array); 226900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (is_copy != NULL) { 227000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers *is_copy = JNI_FALSE; 227100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 227200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return array->GetData(); 227300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 227400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 227500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename ArrayT> 2276ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, jint mode) { 227700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (mode != JNI_COMMIT) { 2278ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 227900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Array* array = soa.Decode<Array*>(java_array); 228000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UnpinPrimitiveArray(soa, array); 228100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 228200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 228300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 228400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename JavaArrayT, typename JavaT, typename ArrayT> 228500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array, 228600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize start, jsize length, JavaT* buf) 2287b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 228800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArrayT* array = soa.Decode<ArrayT*>(java_array); 228900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (start < 0 || length < 0 || start + length > array->GetLength()) { 229000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowAIOOBE(soa, array, start, length, "src"); 229100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 229200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaT* data = array->GetData(); 229300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers memcpy(buf, data + start, length * sizeof(JavaT)); 229400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 229500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 229600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 229700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename JavaArrayT, typename JavaT, typename ArrayT> 229800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array, 229900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize start, jsize length, const JavaT* buf) 2300b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 230100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArrayT* array = soa.Decode<ArrayT*>(java_array); 230200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (start < 0 || length < 0 || start + length > array->GetLength()) { 230300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowAIOOBE(soa, array, start, length, "dst"); 230400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 230500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaT* data = array->GetData(); 230600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers memcpy(data + start, buf, length * sizeof(JavaT)); 230700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 230800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 2309cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}; 2310ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 231188c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNINativeInterface gJniNativeInterface = { 2312ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved0. 2313ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved1. 2314ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved2. 2315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved3. 2316cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetVersion, 2317cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DefineClass, 2318cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FindClass, 2319cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FromReflectedMethod, 2320cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FromReflectedField, 2321cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ToReflectedMethod, 2322cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetSuperclass, 2323cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsAssignableFrom, 2324cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ToReflectedField, 2325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::Throw, 2326cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ThrowNew, 2327cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionOccurred, 2328cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionDescribe, 2329cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionClear, 2330cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FatalError, 2331cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::PushLocalFrame, 2332cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::PopLocalFrame, 2333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewGlobalRef, 2334cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteGlobalRef, 2335cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteLocalRef, 2336cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsSameObject, 2337cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewLocalRef, 2338cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::EnsureLocalCapacity, 2339cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::AllocObject, 2340cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObject, 2341cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectV, 2342cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectA, 2343cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectClass, 2344cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsInstanceOf, 2345cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetMethodID, 2346cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethod, 2347cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethodV, 2348cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethodA, 2349cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethod, 2350cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethodV, 2351cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethodA, 2352cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethod, 2353cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethodV, 2354cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethodA, 2355cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethod, 2356cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethodV, 2357cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethodA, 2358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethod, 2359cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethodV, 2360cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethodA, 2361cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethod, 2362cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethodV, 2363cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethodA, 2364cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethod, 2365cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethodV, 2366cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethodA, 2367cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethod, 2368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethodV, 2369cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethodA, 2370cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethod, 2371cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethodV, 2372cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethodA, 2373cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethod, 2374cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethodV, 2375cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethodA, 2376cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethod, 2377cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethodV, 2378cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethodA, 2379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethod, 2380cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethodV, 2381cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethodA, 2382cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethod, 2383cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethodV, 2384cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethodA, 2385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethod, 2386cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethodV, 2387cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethodA, 2388cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethod, 2389cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethodV, 2390cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethodA, 2391cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethod, 2392cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethodV, 2393cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethodA, 2394cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethod, 2395cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethodV, 2396cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethodA, 2397cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethod, 2398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethodV, 2399cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethodA, 2400cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethod, 2401cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethodV, 2402cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethodA, 2403cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethod, 2404cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethodV, 2405cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethodA, 2406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFieldID, 2407cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectField, 2408cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanField, 2409cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteField, 2410cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharField, 2411cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortField, 2412cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntField, 2413cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongField, 2414cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatField, 2415cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleField, 2416cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetObjectField, 2417cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetBooleanField, 2418cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetByteField, 2419cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetCharField, 2420cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetShortField, 2421cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetIntField, 2422cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetLongField, 2423cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetFloatField, 2424cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetDoubleField, 2425cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticMethodID, 2426cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethod, 2427cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethodV, 2428cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethodA, 2429cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethod, 2430cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethodV, 2431cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethodA, 2432cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethod, 2433cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethodV, 2434cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethodA, 2435cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethod, 2436cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethodV, 2437cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethodA, 2438cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethod, 2439cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethodV, 2440cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethodA, 2441cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethod, 2442cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethodV, 2443cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethodA, 2444cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethod, 2445cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethodV, 2446cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethodA, 2447cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethod, 2448cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethodV, 2449cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethodA, 2450cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethod, 2451cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethodV, 2452cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethodA, 2453cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethod, 2454cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethodV, 2455cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethodA, 2456cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticFieldID, 2457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticObjectField, 2458cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticBooleanField, 2459cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticByteField, 2460cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticCharField, 2461cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticShortField, 2462cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticIntField, 2463cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticLongField, 2464cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticFloatField, 2465cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticDoubleField, 2466cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticObjectField, 2467cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticBooleanField, 2468cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticByteField, 2469cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticCharField, 2470cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticShortField, 2471cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticIntField, 2472cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticLongField, 2473cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticFloatField, 2474cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticDoubleField, 2475cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewString, 2476cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringLength, 2477cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringChars, 2478cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringChars, 2479cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewStringUTF, 2480cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFLength, 2481cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFChars, 2482cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringUTFChars, 2483cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetArrayLength, 2484cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectArray, 2485cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectArrayElement, 2486cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetObjectArrayElement, 2487cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewBooleanArray, 2488cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewByteArray, 2489cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewCharArray, 2490cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewShortArray, 2491cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewIntArray, 2492cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewLongArray, 2493cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewFloatArray, 2494cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewDoubleArray, 2495cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanArrayElements, 2496cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteArrayElements, 2497cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharArrayElements, 2498cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortArrayElements, 2499cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntArrayElements, 2500cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongArrayElements, 2501cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatArrayElements, 2502cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleArrayElements, 2503cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseBooleanArrayElements, 2504cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseByteArrayElements, 2505cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseCharArrayElements, 2506cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseShortArrayElements, 2507cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseIntArrayElements, 2508cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseLongArrayElements, 2509cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseFloatArrayElements, 2510cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseDoubleArrayElements, 2511cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanArrayRegion, 2512cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteArrayRegion, 2513cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharArrayRegion, 2514cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortArrayRegion, 2515cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntArrayRegion, 2516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongArrayRegion, 2517cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatArrayRegion, 2518cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleArrayRegion, 2519cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetBooleanArrayRegion, 2520cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetByteArrayRegion, 2521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetCharArrayRegion, 2522cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetShortArrayRegion, 2523cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetIntArrayRegion, 2524cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetLongArrayRegion, 2525cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetFloatArrayRegion, 2526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetDoubleArrayRegion, 2527cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::RegisterNatives, 2528cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::UnregisterNatives, 2529cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::MonitorEnter, 2530cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::MonitorExit, 2531cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetJavaVM, 2532cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringRegion, 2533cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFRegion, 2534cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetPrimitiveArrayCritical, 2535cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleasePrimitiveArrayCritical, 2536cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringCritical, 2537cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringCritical, 2538cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewWeakGlobalRef, 2539cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteWeakGlobalRef, 2540cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionCheck, 2541cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewDirectByteBuffer, 2542cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDirectBufferAddress, 2543cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDirectBufferCapacity, 2544cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectRefType, 2545ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}; 2546ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 25477577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesJNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm) 254869f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes : self(self), 25497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm(vm), 25505a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers local_ref_cookie(IRT_FIRST_SEGMENT), 25515a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers locals(kLocalsInitial, kLocalsMax, kLocal), 25524ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes check_jni(false), 2553bbd76717c14822b68ae6d122d88610b46286272fElliott Hughes critical(false), 25545a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers monitors("monitors", kMonitorsInitial, kMonitorsMax) { 255588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = unchecked_functions = &gJniNativeInterface; 25564ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes if (vm->check_jni) { 255788c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes SetCheckJniEnabled(true); 2558a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } 25595a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers // The JniEnv local reference values must be at a consistent offset or else cross-compilation 25605a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers // errors will ensue. 25615a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12); 25625a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16); 256340ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes} 256440ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes 2565c1674ed06662420213441ff2b818f2f71f9098dcElliott HughesJNIEnvExt::~JNIEnvExt() { 2566c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 2567c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 256888c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JNIEnvExt::SetCheckJniEnabled(bool enabled) { 256988c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes check_jni = enabled; 257088c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface; 25714ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes} 25724ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes 257373e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JNIEnvExt::DumpReferenceTables(std::ostream& os) { 257473e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes locals.Dump(os); 257573e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes monitors.Dump(os); 25769d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 25779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 25781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid JNIEnvExt::PushFrame(int /*capacity*/) { 25791bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes // TODO: take 'capacity' into account. 25802ced6a534157d5d963693346904389c19775d2daElliott Hughes stacked_local_ref_cookies.push_back(local_ref_cookie); 25812ced6a534157d5d963693346904389c19775d2daElliott Hughes local_ref_cookie = locals.GetSegmentState(); 25822ced6a534157d5d963693346904389c19775d2daElliott Hughes} 25832ced6a534157d5d963693346904389c19775d2daElliott Hughes 25842ced6a534157d5d963693346904389c19775d2daElliott Hughesvoid JNIEnvExt::PopFrame() { 25852ced6a534157d5d963693346904389c19775d2daElliott Hughes locals.SetSegmentState(local_ref_cookie); 25862ced6a534157d5d963693346904389c19775d2daElliott Hughes local_ref_cookie = stacked_local_ref_cookies.back(); 25872ced6a534157d5d963693346904389c19775d2daElliott Hughes stacked_local_ref_cookies.pop_back(); 25882ced6a534157d5d963693346904389c19775d2daElliott Hughes} 25892ced6a534157d5d963693346904389c19775d2daElliott Hughes 25902dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersOffset JNIEnvExt::SegmentStateOffset() { 25912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) + 25922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IndirectReferenceTable::SegmentStateOffset().Int32Value()); 25932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 25942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2595ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro// JNI Invocation interface. 2596ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2597bddf97641c9371ec74c63bca52fff62fecd73750Brian Carlstromextern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { 25982ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args); 259983a25328c595975097cf3948451088cbfc64fc09Elliott Hughes if (IsBadJniVersion(args->version)) { 260083a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version; 26012ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_EVERSION; 26022ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26032ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro Runtime::Options options; 26042ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro for (int i = 0; i < args->nOptions; ++i) { 26052ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro JavaVMOption* option = &args->options[i]; 2606f1a5adc87760f938b01df26d906295063546b259Elliott Hughes options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo)); 26072ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26082ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro bool ignore_unrecognized = args->ignoreUnrecognized; 260900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Create(options, ignore_unrecognized)) { 26102ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_ERR; 26112ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 261200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Runtime* runtime = Runtime::Current(); 2613bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom bool started = runtime->Start(); 2614bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom if (!started) { 2615bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom delete Thread::Current()->GetJniEnv(); 2616bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom delete runtime->GetJavaVM(); 2617bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom LOG(WARNING) << "CreateJavaVM failed"; 2618bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom return JNI_ERR; 2619bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom } 262069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom *p_env = Thread::Current()->GetJniEnv(); 262169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom *p_vm = runtime->GetJavaVM(); 262269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return JNI_OK; 26232ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 26242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2625f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughesextern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) { 26262ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro Runtime* runtime = Runtime::Current(); 26272ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro if (runtime == NULL) { 2628f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes *vm_count = 0; 26292ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } else { 2630f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes *vm_count = 1; 263169f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes vms[0] = runtime->GetJavaVM(); 26322ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26332ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_OK; 26342ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 26352ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 26362ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro// Historically unsupported. 26371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesextern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) { 26382ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_ERR; 26392ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 26402ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2641cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JII { 2642cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public: 2643cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint DestroyJavaVM(JavaVM* vm) { 2644cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (vm == NULL) { 2645cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 2646cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 26476a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 26486a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes delete raw_vm->runtime; 26496a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes return JNI_OK; 26502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26512ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2652cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 26537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JII_AttachCurrentThread(vm, p_env, thr_args, false); 26542ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26552ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2656cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 26577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JII_AttachCurrentThread(vm, p_env, thr_args, true); 26582ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26592ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2660cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint DetachCurrentThread(JavaVM* vm) { 26614d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom if (vm == NULL || Thread::Current() == NULL) { 2662cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 2663cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 26646a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 26656a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes Runtime* runtime = raw_vm->runtime; 26666a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes runtime->DetachCurrentThread(); 26676a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes return JNI_OK; 26682ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 26692ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 2670cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint GetEnv(JavaVM* vm, void** env, jint version) { 267183a25328c595975097cf3948451088cbfc64fc09Elliott Hughes if (IsBadJniVersion(version)) { 267283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version; 2673cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_EVERSION; 2674cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2675cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (vm == NULL || env == NULL) { 2676cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 2677cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2678cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes Thread* thread = Thread::Current(); 2679cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (thread == NULL) { 2680cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *env = NULL; 2681cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_EDETACHED; 2682cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2683cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *env = thread->GetJniEnv(); 26842ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_OK; 26852ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 2686cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}; 26872ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 268888c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNIInvokeInterface gJniInvokeInterface = { 2689ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved0 2690ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved1 2691ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved2 2692cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::DestroyJavaVM, 2693cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::AttachCurrentThread, 2694cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::DetachCurrentThread, 2695cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::GetEnv, 2696cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::AttachCurrentThreadAsDaemon 2697ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}; 2698ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2699a09576416788b916095739e43a16917e7948f3a4Elliott HughesJavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options) 270069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes : runtime(runtime), 2701a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes check_jni_abort_hook(NULL), 2702b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes check_jni_abort_hook_data(NULL), 27034ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes check_jni(false), 27047934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom force_copy(false), // TODO: add a way to enable this 2705a09576416788b916095739e43a16917e7948f3a4Elliott Hughes trace(options->jni_trace_), 2706c2dc62d1c9241dfe880a81698713c314b13aa63fElliott Hughes work_around_app_jni_bugs(false), 270762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pins_lock("JNI pin table lock", kPinTableLock), 27082ced6a534157d5d963693346904389c19775d2daElliott Hughes pin_table("pin table", kPinTableInitial, kPinTableMax), 27098daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes globals_lock("JNI global reference table lock"), 2710bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes globals(gGlobalsInitial, gGlobalsMax, kGlobal), 27118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes weak_globals_lock("JNI weak global reference table lock"), 271279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes weak_globals(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal), 271300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers libraries_lock("JNI shared libraries map lock", kLoadLibraryLock), 271479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes libraries(new Libraries) { 271588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = unchecked_functions = &gJniInvokeInterface; 27164ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes if (options->check_jni_) { 271788c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes SetCheckJniEnabled(true); 2718a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } 2719f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes} 2720f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 2721de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott HughesJavaVMExt::~JavaVMExt() { 272279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes delete libraries; 2723de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes} 2724de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes 272588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JavaVMExt::SetCheckJniEnabled(bool enabled) { 272688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes check_jni = enabled; 272788c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface; 27284ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes} 27294ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes 2730ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughesvoid JavaVMExt::DumpForSigQuit(std::ostream& os) { 2731ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "JNI: CheckJNI is " << (check_jni ? "on" : "off"); 2732ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes if (force_copy) { 2733ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << " (with forcecopy)"; 2734ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2735ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off"); 273650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 2737ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 273850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 2739ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; pins=" << pin_table.Size(); 2740ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2741ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 274250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, globals_lock); 2743ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; globals=" << globals.Capacity(); 2744ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2745ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 274650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, weak_globals_lock); 2747ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes if (weak_globals.Capacity() > 0) { 2748ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << " (plus " << weak_globals.Capacity() << " weak)"; 2749ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2750ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2751ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << '\n'; 2752ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 2753ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 275450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 2755ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n"; 2756ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 2757ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes} 2758ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 275973e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JavaVMExt::DumpReferenceTables(std::ostream& os) { 276050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 27619d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 276250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, globals_lock); 276373e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes globals.Dump(os); 27649d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 27659d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 276650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, weak_globals_lock); 276773e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes weak_globals.Dump(os); 27689d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 27699d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 277050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 277173e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes pin_table.Dump(os); 27729d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 27739d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 27749d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 277500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool JavaVMExt::LoadNativeLibrary(const std::string& path, ClassLoader* class_loader, 277600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::string& detail) { 27777577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes detail.clear(); 2778cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // See if we've already loaded this library. If we have, and the class loader 2780cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // matches, return successfully without doing anything. 27817577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // TODO: for better results we should canonicalize the pathname (or even compare 27827577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // inodes). This implementation is fine if everybody is using System.loadLibrary. 278379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary* library; 278450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 278579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes { 278679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // TODO: move the locking (and more of this logic) into Libraries. 278750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 278879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes library = libraries->Get(path); 278979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 2790cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (library != NULL) { 2791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (library->GetClassLoader() != class_loader) { 27927577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // The library will be associated with class_loader. The JNI 27937577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // spec says we can't load the same library into more than one 27947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // class loader. 27957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes StringAppendF(&detail, "Shared library \"%s\" already opened by " 27967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes "ClassLoader %p; can't open in ClassLoader %p", 27977577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes path.c_str(), library->GetClassLoader(), class_loader); 27987577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes LOG(WARNING) << detail; 2799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 2800cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 28014dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Shared library \"" << path << "\" already loaded in " 28024dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes << "ClassLoader " << class_loader << "]"; 28031bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes if (!library->CheckOnLoadResult()) { 28047577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes StringAppendF(&detail, "JNI_OnLoad failed on a previous attempt " 28057577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes "to load \"%s\"", path.c_str()); 2806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 2807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return true; 2809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Open the shared library. Because we're using a full path, the system 2812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // doesn't have to search through LD_LIBRARY_PATH. (It may do so to 2813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // resolve this library's dependencies though.) 2814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Failures here are expected when java.library.path has several entries 2816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // and we have to hunt for the lib. 2817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 281800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Below we dlopen but there is no paired dlclose, this would be necessary if we supported 281900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // class unloading. Libraries will only be unloaded when the reference count (incremented by 282000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // dlopen) becomes zero from dlclose. 282100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 2822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // This can execute slowly for a large library on a busy system, so we 282300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // want to switch from kRunnable while it executes. This allows the GC to ignore us. 282400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad); 282500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY); 282600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 2827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 282884b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]"; 2829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (handle == NULL) { 28317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes detail = dlerror(); 283284b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail; 2833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 2834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Create a new entry. 283700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: move the locking (and more of this logic) into Libraries. 283800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool created_library = false; 283979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes { 284050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 284179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes library = libraries->Get(path); 284200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (library == NULL) { // We won race to get libraries_lock 284300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers library = new SharedLibrary(path, handle, class_loader); 284400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers libraries->Put(path, library); 284500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers created_library = true; 284679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 284700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 284800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!created_library) { 284900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(INFO) << "WOW: we lost a race to add shared library: " 285000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers << "\"" << path << "\" ClassLoader=" << class_loader; 285100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return library->CheckOnLoadResult(); 285279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 2853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 28544dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]"; 2855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 28567935372ab784477db452d11112cd60d26be87093Elliott Hughes bool was_successful = false; 285779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* sym = dlsym(handle, "JNI_OnLoad"); 285879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (sym == NULL) { 28594dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]"; 286085affca81271f573c75c32316aa6faa8e52448b1Elliott Hughes was_successful = true; 286179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } else { 286279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Call JNI_OnLoad. We have to override the current class 286379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // loader, which will always be "null" since the stuff at the 286479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // top of the stack is around Runtime.loadLibrary(). (See 286579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // the comments in the JNI FindClass function.) 286679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes typedef int (*JNI_OnLoadFn)(JavaVM*, void*); 286779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym); 2868365c10235438607541fa2259a5fec48061b90bd8Ian Rogers ClassLoader* old_class_loader = self->GetClassLoaderOverride(); 286979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes self->SetClassLoaderOverride(class_loader); 287079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 2871ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes int version = 0; 2872ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes { 287334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes ScopedThreadStateChange tsc(self, kNative); 28744dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]"; 2875ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes version = (*jni_on_load)(this, NULL); 287679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 287779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 2878aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom self->SetClassLoaderOverride(old_class_loader); 287979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 28807935372ab784477db452d11112cd60d26be87093Elliott Hughes if (version == JNI_ERR) { 28817935372ab784477db452d11112cd60d26be87093Elliott Hughes StringAppendF(&detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str()); 28827935372ab784477db452d11112cd60d26be87093Elliott Hughes } else if (IsBadJniVersion(version)) { 288375fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom StringAppendF(&detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d", 288475fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom path.c_str(), version); 288579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // It's unwise to call dlclose() here, but we can mark it 288679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // as bad and ensure that future load attempts will fail. 288779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // We don't know how far JNI_OnLoad got, so there could 288879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // be some partially-initialized stuff accessible through 288979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // newly-registered native method calls. We could try to 289079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // unregister them, but that doesn't seem worthwhile. 28917935372ab784477db452d11112cd60d26be87093Elliott Hughes } else { 28927935372ab784477db452d11112cd60d26be87093Elliott Hughes was_successful = true; 2893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 28947935372ab784477db452d11112cd60d26be87093Elliott Hughes VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure") 289575fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom << " from JNI_OnLoad in \"" << path << "\"]"; 289679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 2897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 28987935372ab784477db452d11112cd60d26be87093Elliott Hughes library->SetResult(was_successful); 28997935372ab784477db452d11112cd60d26be87093Elliott Hughes return was_successful; 290079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes} 290179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 290266f19258f9728d4ffe026074d8fd429d639802faMathieu Chartiervoid* JavaVMExt::FindCodeForNativeMethod(AbstractMethod* m) { 290379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes CHECK(m->IsNative()); 290479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 290579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Class* c = m->GetDeclaringClass(); 290679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 290779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // If this is a static method, it could be called before the class 290879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // has been initialized. 290979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (m->IsStatic()) { 29100045a290e6b79a274250e3112880c04bde437d4aIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) { 291179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return NULL; 291279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 291379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } else { 29142a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes CHECK(c->GetStatus() >= Class::kStatusInitializing) << c->GetStatus() << " " << PrettyMethod(m); 2915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 291679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 2917161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom std::string detail; 2918161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom void* native_method; 291950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 2920161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom { 292150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 2922161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom native_method = libraries->FindNativeMethod(m, detail); 2923161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 292462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Throwing can cause libraries_lock to be reacquired. 2925161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom if (native_method == NULL) { 292662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 292762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str()); 2928161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 2929161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom return native_method; 2930cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes} 2931cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 29322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) { 293350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 2934410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes { 293550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, globals_lock); 2936410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes globals.VisitRoots(visitor, arg); 2937410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes } 2938410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes { 293950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 2940410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes pin_table.VisitRoots(visitor, arg); 2941410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes } 2942410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes // The weak_globals table is visited by the GC itself (because it mutates the table). 2943410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes} 2944410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 2945c8fece309fa1d3514071fadaca34530648462b50Elliott Hughesvoid RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, 2946c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes size_t method_count) { 2947c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name)); 2948c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes if (c.get() == NULL) { 2949c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(FATAL) << "Couldn't find class: " << jni_class_name; 2950c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes } 2951c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false); 2952c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes} 2953c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes 2954df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers} // namespace art 2955b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2956b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) { 2957b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes switch (rhs) { 2958b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIInvalidRefType: 2959b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIInvalidRefType"; 2960b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 2961b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNILocalRefType: 2962b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNILocalRefType"; 2963b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 2964b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIGlobalRefType: 2965b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIGlobalRefType"; 2966b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 2967b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIWeakGlobalRefType: 2968b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIWeakGlobalRefType"; 2969b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 29702e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom default: 297124782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]"; 29722e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom return os; 2973b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2974b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes} 2975