jni_internal.cc revision 055d46c479369ea825712834353660b45215c195
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 25590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier#include "atomic_integer.h" 2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 2776b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h" 281aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h" 29e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h" 3040ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes#include "class_linker.h" 314f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 321d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h" 333dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao#include "interpreter/interpreter.h" 342fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#include "invoke_arg_array_builder.h" 35ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro#include "jni.h" 36ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_field-inl.h" 37ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h" 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h" 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h" 436d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 442ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "runtime.h" 45a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 4600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 47a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "ScopedLocalRef.h" 482ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "thread.h" 492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utf.h" 50a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "UniquePtr.h" 51eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h" 52df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 53ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromusing ::art::mirror::ArtField; 54ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromusing ::art::mirror::ArtMethod; 553e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Array; 563e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::BooleanArray; 573e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ByteArray; 583e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::CharArray; 593e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Class; 603e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ClassLoader; 613e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::DoubleArray; 623e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::FloatArray; 633e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::IntArray; 643e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::LongArray; 653e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Object; 663e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ObjectArray; 673e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::ShortArray; 683e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::String; 693e3d591f781b771de89f3b989830da2b6ac6fac8Brian Carlstromusing ::art::mirror::Throwable; 702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 71bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesnamespace art { 72bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes 737934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsInitial = 32; // Arbitrary. 747934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsMax = 4096; // Arbitrary sanity check. 752ced6a534157d5d963693346904389c19775d2daElliott Hughes 767934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsInitial = 64; // Arbitrary. 777934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsMax = 512; // Arbitrary sanity check. 782ced6a534157d5d963693346904389c19775d2daElliott Hughes 797934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kPinTableInitial = 16; // Arbitrary. 807934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kPinTableMax = 1024; // Arbitrary sanity check. 812ced6a534157d5d963693346904389c19775d2daElliott Hughes 827934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsInitial = 512; // Arbitrary. 837934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 842ced6a534157d5d963693346904389c19775d2daElliott Hughes 857934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsInitial = 16; // Arbitrary. 867934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) 87df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 8800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jweak AddWeakGlobalReference(ScopedObjectAccess& soa, Object* obj) 89b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 90c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier return soa.Vm()->AddWeakGlobalReference(soa.Self(), obj); 9145619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers} 9245619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers 9319c5d3786894af707d8079231105bca1b7dcd096Jeff Haostatic bool IsBadJniVersion(int version) { 9419c5d3786894af707d8079231105bca1b7dcd096Jeff Hao // We don't support JNI_VERSION_1_1. These are the only other valid versions. 9519c5d3786894af707d8079231105bca1b7dcd096Jeff Hao return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6; 9619c5d3786894af707d8079231105bca1b7dcd096Jeff Hao} 9719c5d3786894af707d8079231105bca1b7dcd096Jeff Hao 98ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void CheckMethodArguments(ArtMethod* m, uint32_t* args) 99b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 100b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes MethodHelper mh(m); 10150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers const DexFile::TypeList* params = mh.GetParameterTypeList(); 10250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (params == NULL) { 10350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers return; // No arguments so nothing to check. 10450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers } 1055d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint32_t offset = 0; 10650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers uint32_t num_params = params->Size(); 107b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes size_t error_count = 0; 1085d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao if (!m->IsStatic()) { 1095d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao offset = 1; 1105d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 11150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers for (uint32_t i = 0; i < num_params; i++) { 11250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers uint16_t type_idx = params->GetTypeItem(i).type_idx_; 11350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Class* param_type = mh.GetClassFromTypeIdx(type_idx); 11450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (param_type == NULL) { 11550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 11650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers CHECK(self->IsExceptionPending()); 11750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " 11850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n" 11962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << self->GetException(NULL)->Dump(); 12050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers self->ClearException(); 12150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ++error_count; 12250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers } else if (!param_type->IsPrimitive()) { 12350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers // TODO: check primitives are in range. 1245d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* argument = reinterpret_cast<Object*>(args[i + offset]); 12550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers if (argument != NULL && !argument->InstanceOf(param_type)) { 126b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of " 127b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m); 128b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes ++error_count; 129b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 1305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) { 1315d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao offset++; 132b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 133b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 134b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes if (error_count > 0) { 135b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort 136b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes // with an argument. 1373f6635a2c84d645002f651c312d53f8348646c1fElliott Hughes JniAbortF(NULL, "bad arguments passed to %s (see above for details)", PrettyMethod(m).c_str()); 138b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes } 139b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes} 140b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes 141ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid InvokeWithArgArray(const ScopedObjectAccess& soa, ArtMethod* method, 1426474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao ArgArray* arg_array, JValue* result, char result_type) 143b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1443dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao uint32_t* args = arg_array->GetArray(); 14500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (UNLIKELY(soa.Env()->check_jni)) { 1463dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao CheckMethodArguments(method, args); 1473dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } 1487d658cf06827d409d76686da1cd2b6acb5977885Sebastien Hertz method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type); 1499b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 1509b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 15100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj, 15200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jmethodID mid, va_list args) 153b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 154ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = soa.DecodeMethod(mid); 1557a549467e332398229724058c07d998d0acfb0bbJeff Hao Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj); 1562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1606474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1616474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 16272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 16372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 164ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic ArtMethod* FindVirtualMethod(Object* receiver, ArtMethod* method) 165b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 16630b944557a969a9aea2098ce9bbcce05db9b1f22Brian Carlstrom return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method); 16772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 16872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 16900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess& soa, 17000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject obj, jmethodID mid, jvalue* args) 171b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 17200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* receiver = soa.Decode<Object*>(obj); 173ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 1742fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1755d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1762fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1786474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1796474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 18072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes} 18172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 18200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess& soa, 18300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject obj, jmethodID mid, va_list args) 184b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* receiver = soa.Decode<Object*>(obj); 186ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 1872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 1885d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 1892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 1905d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 1916474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 1926474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 193ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 194ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1956b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're 1966b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// separated with slashes but aren't wrapped with "L;" like regular descriptors 1976b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an 1986b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// exception; there the "L;" must be present ("[La/b/C;"). Historically we've 1996b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// supported names with dots too (such as "a.b.C"). 2000571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string NormalizeJniClassDescriptor(const char* name) { 2016b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes std::string result; 2026b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes // Add the missing "L;" if necessary. 2036b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes if (name[0] == '[') { 2046b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result = name; 2056b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } else { 2066b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += 'L'; 2076b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += name; 2086b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes result += ';'; 2096b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } 2106b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes // Rewrite '.' as '/' for backwards compatibility. 211a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes if (result.find('.') != std::string::npos) { 212a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes LOG(WARNING) << "Call to JNI FindClass with dots in name: " 213a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes << "\"" << name << "\""; 214a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes std::replace(result.begin(), result.end(), '.', '/'); 2156b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes } 2166b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes return result; 2176b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes} 2186b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes 21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowNoSuchMethodError(ScopedObjectAccess& soa, Class* c, 22000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* name, const char* sig, const char* kind) 221b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 22362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;", 22462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no %s method \"%s.%s%s\"", 22562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers kind, ClassHelper(c).GetDescriptor(), name, sig); 22614134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes} 22714134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes 228c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierstatic mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass) 229c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 230c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (LIKELY(klass->IsInitialized())) { 231c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return klass; 232c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier } 233c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier SirtRef<mirror::Class> sirt_klass(self, klass); 234c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(sirt_klass, true, true)) { 235c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 236c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier } 237c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return sirt_klass.get(); 238c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier} 239c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier 24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class, 24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* name, const char* sig, bool is_static) 242b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 243c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(jni_class)); 244c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 245c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 247ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 248ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = NULL; 249cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (is_static) { 250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindDirectMethod(name, sig); 251cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } else { 252cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindVirtualMethod(name, sig); 253cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (method == NULL) { 254cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // No virtual method matching the signature. Search declared 255cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // private methods and constructors. 256cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes method = c->FindDeclaredDirectMethod(name, sig); 257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 258cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 259ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (method == NULL || method->IsStatic() != is_static) { 26100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static"); 262cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 263cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 264ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 26500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeMethod(method); 266ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 267ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 268ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogersstatic ClassLoader* GetClassLoader(const ScopedObjectAccess& soa) 269b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 270ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = soa.Self()->GetCurrentMethod(NULL); 271ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set. 272ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) { 273ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return soa.Self()->GetClassLoaderOverride(); 27400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom } 275ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // If we have a method, use its ClassLoader for context. 276ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom if (method != NULL) { 277ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom return method->GetDeclaringClass()->GetClassLoader(); 278ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom } 279ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // We don't have a method, so try to use the system ClassLoader. 280ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom ClassLoader* class_loader = soa.Decode<ClassLoader*>(Runtime::Current()->GetSystemClassLoader()); 281ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom if (class_loader != NULL) { 282ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom return class_loader; 283ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom } 284ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // See if the override ClassLoader is set for gtests. 285ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom class_loader = soa.Self()->GetClassLoaderOverride(); 286ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom if (class_loader != NULL) { 287ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // If so, CommonTest should have set UseCompileTimeClassPath. 288ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom CHECK(Runtime::Current()->UseCompileTimeClassPath()); 289ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom return class_loader; 290ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom } 291ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom // Use the BOOTCLASSPATH. 292ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom return NULL; 29300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom} 29400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom 29500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name, 29600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* sig, bool is_static) 297b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 298c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(jni_class)); 299c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 300c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 301cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 302ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 303ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* field = NULL; 3040cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers Class* field_type; 3050cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 3060cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers if (sig[1] != '\0') { 30762509b662929175228bb0d0f014ef4ef4e33be10Jeff Hao SirtRef<mirror::ClassLoader> class_loader(soa.Self(), c->GetClassLoader()); 308590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier field_type = class_linker->FindClass(sig, class_loader); 3090cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } else { 3100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers field_type = class_linker->FindPrimitiveClass(*sig); 3110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 3120cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers if (field_type == NULL) { 3130cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers // Failed to find type from the signature of the field. 31400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers DCHECK(soa.Self()->IsExceptionPending()); 31562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location; 316ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<Throwable> cause(soa.Self(), soa.Self()->GetException(&throw_location)); 31700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ClearException(); 31862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", 31962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no type \"%s\" found and so no field \"%s\" could be found in class " 32062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "\"%s\" or its superclasses", sig, name, 32162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ClassHelper(c).GetDescriptor()); 32262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->GetException(NULL)->SetCause(cause.get()); 3230cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers return NULL; 3240cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (is_static) { 3266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor()); 3274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } else { 3286d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor()); 3294dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 330cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (field == NULL) { 33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 33262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;", 33362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "no \"%s\" field \"%s\" in class \"%s\" or its superclasses", 33462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers sig, name, ClassHelper(c).GetDescriptor()); 335cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return NULL; 336cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeField(field); 338ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro} 339ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 340423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartierstatic void PinPrimitiveArray(const ScopedObjectAccess& soa, Array* array) 341b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 34350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->pins_lock); 3447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm->pin_table.Add(array); 3457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 3467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 347423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartierstatic void UnpinPrimitiveArray(const ScopedObjectAccess& soa, Array* array) 348b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 34900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 35050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(soa.Self(), vm->pins_lock); 3517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm->pin_table.Remove(array); 3527577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 3537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 35400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowAIOOBE(ScopedObjectAccess& soa, Array* array, jsize start, 35500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize length, const char* identifier) 356b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 35754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes std::string type(PrettyTypeOf(array)); 35862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 35962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;", 36062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "%s offset=%d length=%d %s.length=%d", 36162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers type.c_str(), start, length, identifier, array->GetLength()); 362814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes} 3630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers 36400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length, 36500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize array_length) 366b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 36762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 36862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;", 36962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers "offset=%d length=%d string.length()=%d", start, length, 37062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers array_length); 371b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes} 372814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 37300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersint ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause) 374b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_) { 37500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Turn the const char* into a java.lang.String. 37600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg)); 37700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (msg != NULL && s.get() == NULL) { 37800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 379814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 380814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 38100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Choose an appropriate constructor and set up the arguments. 38200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jvalue args[2]; 38300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const char* signature; 38400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (msg == NULL && cause == NULL) { 38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "()V"; 38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else if (msg != NULL && cause == NULL) { 38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/String;)V"; 38800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = s.get(); 38900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else if (msg == NULL && cause != NULL) { 39000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/Throwable;)V"; 39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = cause; 392814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } else { 39300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V"; 39400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[0].l = s.get(); 39500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args[1].l = cause; 39600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 39700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jmethodID mid = env->GetMethodID(exception_class, "<init>", signature); 39800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (mid == NULL) { 399ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(ERROR) << "No <init>" << signature << " in " 40100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers << PrettyClass(soa.Decode<Class*>(exception_class)); 40200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 403814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 404a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 40500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args))); 40600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (exception.get() == NULL) { 40700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 40800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 409ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 41062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 41162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(throw_location, soa.Decode<Throwable*>(exception.get())); 41200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_OK; 413a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes} 414a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 415462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughesstatic jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) { 4167577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (vm == NULL || p_env == NULL) { 4177577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JNI_ERR; 4187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 4197577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 420462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes // Return immediately if we're already attached. 421cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes Thread* self = Thread::Current(); 422cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes if (self != NULL) { 423cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes *p_env = self->GetJniEnv(); 424cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes return JNI_OK; 425cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes } 426cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 427cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime; 428cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 429cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes // No threads allowed in zygote mode. 430cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes if (runtime->IsZygote()) { 431cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes LOG(ERROR) << "Attempt to attach a thread in the zygote"; 432cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes return JNI_ERR; 433cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes } 434cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes 435462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args); 436462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes const char* thread_name = NULL; 437365c10235438607541fa2259a5fec48061b90bd8Ian Rogers jobject thread_group = NULL; 438462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes if (args != NULL) { 43983a25328c595975097cf3948451088cbfc64fc09Elliott Hughes if (IsBadJniVersion(args->version)) { 44083a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to " 44183a25328c595975097cf3948451088cbfc64fc09Elliott Hughes << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": " 44283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes << args->version; 44383a25328c595975097cf3948451088cbfc64fc09Elliott Hughes return JNI_EVERSION; 4448692215f793cbf8be9c3d25a705074ca877e09b8Brian Carlstrom } 445462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes thread_name = args->name; 446365c10235438607541fa2259a5fec48061b90bd8Ian Rogers thread_group = args->group; 4477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 4487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 449664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) { 450120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers *p_env = NULL; 451120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return JNI_ERR; 452120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } else { 453120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers *p_env = Thread::Current()->GetJniEnv(); 454120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return JNI_OK; 455120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers } 4567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes} 4577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes 45879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass SharedLibrary { 45979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public: 46079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary(const std::string& path, void* handle, Object* class_loader) 46179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes : path_(path), 46279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes handle_(handle), 46331384c59bb4b387f29f2b6d4d3db886c29b81170Shih-wei Liao class_loader_(class_loader), 4648daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes jni_on_load_lock_("JNI_OnLoad lock"), 465c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_), 466d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers jni_on_load_thread_id_(Thread::Current()->GetThreadId()), 46779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes jni_on_load_result_(kPending) { 46879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 46979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 47079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Object* GetClassLoader() { 47179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return class_loader_; 47279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 47379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 47479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string GetPath() { 47579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return path_; 47679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 47779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 47879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes /* 4791bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes * Check the result of an earlier call to JNI_OnLoad on this library. 4801bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes * If the call has not yet finished in another thread, wait for it. 48179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes */ 48200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool CheckOnLoadResult() 48300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOCKS_EXCLUDED(jni_on_load_lock_) 484b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 48579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Thread* self = Thread::Current(); 48600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad); 48700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool okay; 48800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers { 48950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, jni_on_load_lock_); 49000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 491d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers if (jni_on_load_thread_id_ == self->GetThreadId()) { 49200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Check this so we don't end up waiting for ourselves. We need to return "true" so the 49300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // caller can continue. 49400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\""; 49500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers okay = true; 49600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 49700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers while (jni_on_load_result_ == kPending) { 49800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]"; 499c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_.Wait(self); 50000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 50179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 50200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers okay = (jni_on_load_result_ == kOkay); 50300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" " 50400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers << (okay ? "succeeded" : "failed") << "]"; 50500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 50679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 50700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 50879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return okay; 50979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 51079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) { 512c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers Thread* self = Thread::Current(); 513c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers MutexLock mu(self, jni_on_load_lock_); 514f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes 51579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes jni_on_load_result_ = result ? kOkay : kFailed; 516dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes jni_on_load_thread_id_ = 0; 51779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 51879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Broadcast a wakeup to anybody sleeping on the condition variable. 519c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers jni_on_load_cond_.Broadcast(self); 52079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 52179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 52279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* FindSymbol(const std::string& symbol_name) { 52379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return dlsym(handle_, symbol_name.c_str()); 52479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 52579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 5268f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier void VisitRoots(RootVisitor* visitor, void* arg) { 5278f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier if (class_loader_ != nullptr) { 5288f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier class_loader_ = visitor(class_loader_, arg); 5298f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier } 5308f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier } 5318f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier 53279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private: 53379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes enum JNI_OnLoadState { 53479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kPending, 53579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kFailed, 53679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes kOkay, 53779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes }; 53879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 53979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Path to library "/system/lib/libjni.so". 54079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string path_; 54179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 54279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // The void* returned by dlopen(3). 54379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* handle_; 54479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 54579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // The ClassLoader this library is associated with. 54679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Object* class_loader_; 54779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 54879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Guards remaining items. 54900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 55079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Wait for JNI_OnLoad in other thread. 551c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_); 55279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Recursive invocation guard. 553f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_); 55479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Result of earlier JNI_OnLoad call. 555f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_); 55679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes}; 55779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 55879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes// This exists mainly to keep implementation details out of the header file. 55979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass Libraries { 56079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public: 56179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Libraries() { 56279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 56379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 56479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes ~Libraries() { 565c31664f3d82e6cd68275a529a8a73f067a52e8beElliott Hughes STLDeleteValues(&libraries_); 56679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 56779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 568ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes void Dump(std::ostream& os) const { 569ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes bool first = true; 57002e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier for (const auto& library : libraries_) { 571ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes if (!first) { 572ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << ' '; 573ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 574ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes first = false; 57502e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier os << library.first; 576ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 577ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 578ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 579ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes size_t size() const { 580ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes return libraries_.size(); 581ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 582ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 58379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary* Get(const std::string& path) { 58402e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier auto it = libraries_.find(path); 585712462a887a1bd31ab49d06c4e63ab8b7191b37dIan Rogers return (it == libraries_.end()) ? NULL : it->second; 58679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 58779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 58879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void Put(const std::string& path, SharedLibrary* library) { 589a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes libraries_.Put(path, library); 59079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 59179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 59279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // See section 11.3 "Linking Native Methods" of the JNI spec. 593ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void* FindNativeMethod(const ArtMethod* m, std::string& detail) 594b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 59579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string jni_short_name(JniShortName(m)); 59679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes std::string jni_long_name(JniLongName(m)); 5974b093bfcbddd0e8f708da87f333cc98bc9f233e1Elliott Hughes const ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader(); 59802e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier for (const auto& lib : libraries_) { 59902e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier SharedLibrary* library = lib.second; 60079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (library->GetClassLoader() != declaring_class_loader) { 60179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // We only search libraries loaded by the appropriate ClassLoader. 60279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes continue; 60379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 60479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Try the short name then the long name... 60579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* fn = library->FindSymbol(jni_short_name); 60679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (fn == NULL) { 60779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes fn = library->FindSymbol(jni_long_name); 60879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 60979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (fn != NULL) { 6104dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Found native code for " << PrettyMethod(m) 6114dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes << " in \"" << library->GetPath() << "\"]"; 61279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return fn; 61379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 61479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 61579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes detail += "No implementation found for "; 616a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes detail += PrettyMethod(m); 61792827a5fc2598589b3717269cc09c33b8c53f30bBrian Carlstrom detail += " (tried " + jni_short_name + " and " + jni_long_name + ")"; 61879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes LOG(ERROR) << detail; 61979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes return NULL; 62079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 62179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 6228f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier void VisitRoots(RootVisitor* visitor, void* arg) { 6238f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier for (auto& lib_pair : libraries_) { 6248f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier lib_pair.second->VisitRoots(visitor, arg); 6258f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier } 6268f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier } 6278f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier 62879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private: 629a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes SafeMap<std::string, SharedLibrary*> libraries_; 63079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes}; 63179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 63200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersJValue InvokeWithJValues(const ScopedObjectAccess& soa, jobject obj, jmethodID mid, 63300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jvalue* args) { 634ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = soa.DecodeMethod(mid); 6357a549467e332398229724058c07d998d0acfb0bbJeff Hao Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj); 6362fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 6375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue result; 6382fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength()); 6395d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.BuildArgArray(soa, receiver, args); 6406474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]); 6416474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao return result; 642d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes} 643d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes 644bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers#define CHECK_NON_NULL_ARGUMENT(fn, value) \ 645bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers if (UNLIKELY(value == NULL)) { \ 646bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers JniAbortF(#fn, #value " == null"); \ 647bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers } 648bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers 6494ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers#define CHECK_NON_NULL_MEMCPY_ARGUMENT(fn, length, value) \ 6504ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers if (UNLIKELY(length != 0 && value == NULL)) { \ 6514ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers JniAbortF(#fn, #value " == null"); \ 6524ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers } 6534ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers 654cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JNI { 655cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public: 65625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static jint GetVersion(JNIEnv*) { 657cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_VERSION_1_6; 658cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 659cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 66025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) { 661cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI DefineClass is not supported"; 66218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes return NULL; 66318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 66418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 665cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jclass FindClass(JNIEnv* env, const char* name) { 666bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(FindClass, name); 6675fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Runtime* runtime = Runtime::Current(); 6685fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes ClassLinker* class_linker = runtime->GetClassLinker(); 669cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes std::string descriptor(NormalizeJniClassDescriptor(name)); 670ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ScopedObjectAccess soa(env); 6715fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes Class* c = NULL; 6725fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes if (runtime->IsStarted()) { 673590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier SirtRef<mirror::ClassLoader> class_loader(soa.Self(), GetClassLoader(soa)); 674590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier c = class_linker->FindClass(descriptor.c_str(), class_loader); 6755fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes } else { 676c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes c = class_linker->FindSystemClass(descriptor.c_str()); 6775fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes } 67800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c); 679cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 680ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 681cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) { 682bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, java_method); 68300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 684ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject art_method = env->GetObjectField(java_method, 685ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod); 686ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = soa.Decode<ArtMethod*>(art_method); 687ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom DCHECK(method != NULL); 68800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeMethod(method); 68918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 69018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 691cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) { 692bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(FromReflectedField, java_field); 69300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 694ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject art_field = env->GetObjectField(java_field, 695ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom WellKnownClasses::java_lang_reflect_Field_artField); 696ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* field = soa.Decode<ArtField*>(art_field); 697ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom DCHECK(field != NULL); 69800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.EncodeField(field); 699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 70018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 701cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) { 702bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(ToReflectedMethod, mid); 70300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 704ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* m = soa.DecodeMethod(mid); 705ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject art_method = soa.AddLocalReference<jobject>(m); 706ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method); 707ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom if (env->ExceptionCheck()) { 708ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return NULL; 709ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } 710ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SetObjectField(env, 711ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom reflect_method, 712ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, 713ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art_method); 714ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return reflect_method; 71518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 716ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) { 718bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(ToReflectedField, fid); 71900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 720ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); 721ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject art_field = soa.AddLocalReference<jobject>(f); 722ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field); 723ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom if (env->ExceptionCheck()) { 724ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return NULL; 725ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } 726ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SetObjectField(env, 727ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom reflect_field, 728ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom WellKnownClasses::java_lang_reflect_Field_artField, 729ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom art_field); 730ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return reflect_field; 731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 732cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 73337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jclass GetObjectClass(JNIEnv* env, jobject java_object) { 734bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetObjectClass, java_object); 73500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 73600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 73700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(o->GetClass()); 73837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 73937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 740885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jclass GetSuperclass(JNIEnv* env, jclass java_class) { 741bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetSuperclass, java_class); 74200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 74300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 74400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jclass>(c->GetSuperClass()); 74518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 74618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 74737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) { 748bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class1); 749bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class2); 75000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 75100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c1 = soa.Decode<Class*>(java_class1); 75200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c2 = soa.Decode<Class*>(java_class2); 75337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return c1->IsAssignableFrom(c2) ? JNI_TRUE : JNI_FALSE; 754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 75518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 756e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) { 757bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(IsInstanceOf, java_class); 75837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes if (jobj == NULL) { 7595d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom // Note: JNI is different from regular Java instanceof in this respect 76037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_TRUE; 76137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } else { 762ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ScopedObjectAccess soa(env); 76300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* obj = soa.Decode<Object*>(jobj); 76400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 765e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE; 76637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 76737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 76837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 76937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jint Throw(JNIEnv* env, jthrowable java_exception) { 77000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 77100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Throwable* exception = soa.Decode<Throwable*>(java_exception); 77237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes if (exception == NULL) { 77337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_ERR; 77437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 77562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow(); 77662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(throw_location, exception); 77737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes return JNI_OK; 77837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 77937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 780e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) { 781bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(ThrowNew, c); 782a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes return ThrowNewException(env, c, msg, NULL); 78337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 78437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 78537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static jboolean ExceptionCheck(JNIEnv* env) { 786120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE; 78737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes } 78837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes 78937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static void ExceptionClear(JNIEnv* env) { 790120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers static_cast<JNIEnvExt*>(env)->self->ClearException(); 79118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 79218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 79337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes static void ExceptionDescribe(JNIEnv* env) { 79400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 79572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 796ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<Object> old_throw_this_object(soa.Self(), NULL); 797ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<ArtMethod> old_throw_method(soa.Self(), NULL); 798ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom SirtRef<Throwable> old_exception(soa.Self(), NULL); 79962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t old_throw_dex_pc; 80062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers { 80162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation old_throw_location; 802ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location); 80362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_this_object.reset(old_throw_location.GetThis()); 80462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_method.reset(old_throw_location.GetMethod()); 80562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_exception.reset(old_exception_obj); 80662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc = old_throw_location.GetDexPc(); 80762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 80862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 80962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ScopedLocalRef<jthrowable> exception(env, soa.AddLocalReference<jthrowable>(old_exception.get())); 81072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get())); 81172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V"); 81272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes if (mid == NULL) { 81372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes LOG(WARNING) << "JNI WARNING: no printStackTrace()V in " 81462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers << PrettyTypeOf(old_exception.get()); 81572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } else { 81672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes env->CallVoidMethod(exception.get(), mid); 81762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (soa.Self()->IsExceptionPending()) { 81862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(NULL)) 81972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes << " thrown while calling printStackTrace"; 82062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->ClearException(); 82172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 82272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 82362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(), 82462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers old_throw_dex_pc); 82572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 82662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers soa.Self()->SetException(gc_safe_throw_location, old_exception.get()); 827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 82818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jthrowable ExceptionOccurred(JNIEnv* env) { 83000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 83162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Object* exception = soa.Self()->GetException(NULL); 83200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jthrowable>(exception); 83318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes } 83418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 83525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers static void FatalError(JNIEnv*, const char* msg) { 836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(FATAL) << "JNI FatalError called: " << msg; 837cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 83818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes 8392ced6a534157d5d963693346904389c19775d2daElliott Hughes static jint PushLocalFrame(JNIEnv* env, jint capacity) { 840ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (EnsureLocalCapacity(env, capacity, "PushLocalFrame") != JNI_OK) { 8412ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNI_ERR; 8422ced6a534157d5d963693346904389c19775d2daElliott Hughes } 843ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers static_cast<JNIEnvExt*>(env)->PushFrame(capacity); 844cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_OK; 845c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes } 846c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes 8472ced6a534157d5d963693346904389c19775d2daElliott Hughes static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) { 84800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 84900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* survivor = soa.Decode<Object*>(java_survivor); 85000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->PopFrame(); 85100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(survivor); 852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 853c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes 8542ced6a534157d5d963693346904389c19775d2daElliott Hughes static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) { 855ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return EnsureLocalCapacity(env, desired_capacity, "EnsureLocalCapacity"); 85672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes } 85772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes 858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject NewGlobalRef(JNIEnv* env, jobject obj) { 85925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 860e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier Object* decoded_obj = soa.Decode<Object*>(obj); 861e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier // Check for null after decoding the object to handle cleared weak globals. 862e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier if (decoded_obj == nullptr) { 863e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier return nullptr; 864e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier } 86500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaVMExt* vm = soa.Vm(); 866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes IndirectReferenceTable& globals = vm->globals; 867b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers WriterMutexLock mu(soa.Self(), vm->globals_lock); 86800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj); 869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return reinterpret_cast<jobject>(ref); 870c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes } 871ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteGlobalRef(JNIEnv* env, jobject obj) { 873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return; 875cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 876ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm; 877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes IndirectReferenceTable& globals = vm->globals; 878ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self; 879b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers WriterMutexLock mu(self, vm->globals_lock); 880ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) { 882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") " 883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes << "failed to find entry"; 884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 886ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 887cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) { 88800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 88900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj)); 890cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 891ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) { 893c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier if (obj != nullptr) { 894c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier ScopedObjectAccess soa(env); 895c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj); 896cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 898ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jobject NewLocalRef(JNIEnv* env, jobject obj) { 90025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 901e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier mirror::Object* decoded_obj = soa.Decode<Object*>(obj); 902e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier // Check for null after decoding the object to handle cleared weak globals. 903e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier if (decoded_obj == nullptr) { 904e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier return nullptr; 905e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier } 906e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier return soa.AddLocalReference<jobject>(decoded_obj); 9074dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 908ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static void DeleteLocalRef(JNIEnv* env, jobject obj) { 910cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (obj == NULL) { 911cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return; 912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 913ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals; 914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 915ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie; 916cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (!locals.Remove(cookie, obj)) { 917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Attempting to delete a local reference that is not in the 918cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // topmost local reference frame is a no-op. DeleteLocalRef returns 919cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // void and doesn't throw any exceptions, but we should probably 920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // complain about it so the user will notice that things aren't 921cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // going quite the way they expect. 922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") " 923cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes << "failed to find entry"; 924cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 92583ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 927cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) { 928ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom if (obj1 == obj2) { 929ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return JNI_TRUE; 930ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } else { 931ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ScopedObjectAccess soa(env); 932ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2)) ? JNI_TRUE : JNI_FALSE; 933ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom } 93483ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 935cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 936885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject AllocObject(JNIEnv* env, jclass java_class) { 937bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(AllocObject, java_class); 93800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 939c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class)); 940c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 941c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 942885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 94350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self())); 944cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 945cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 946bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) { 947cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list args; 94872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(args, mid); 949bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObject, java_class); 950bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObject, mid); 951bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jobject result = NewObjectV(env, java_class, mid, args); 952cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(args); 953cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return result; 954cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 955cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 95672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) { 957bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObjectV, java_class); 958bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObjectV, mid); 95900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 960c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class)); 961c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 962c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 963885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 96450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Object* result = c->AllocObject(soa.Self()); 965c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (result == nullptr) { 966c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 96730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 96800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result); 96972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args); 97000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!soa.Self()->IsExceptionPending()) { 9715d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return local_result; 9725d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } else { 973c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 9745d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 975cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 976cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 97772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) { 978bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObjectA, java_class); 979bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(NewObjectA, mid); 98000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 981c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier Class* c = EnsureInitialized(soa.Self(), soa.Decode<Class*>(java_class)); 982c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 983c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 984885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 98550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Object* result = c->AllocObject(soa.Self()); 98630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes if (result == NULL) { 98730646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes return NULL; 98830646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes } 98900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobjectArray>(result); 99072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args); 99100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!soa.Self()->IsExceptionPending()) { 9925d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return local_result; 9935d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } else { 9945d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers return NULL; 9955d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers } 996cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 997cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 998bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) { 999bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetMethodID, java_class); 1000bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetMethodID, name); 1001bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetMethodID, sig); 100200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1003bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return FindMethodID(soa, java_class, name, sig, false); 1004cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1005ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1006bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name, 1007bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const char* sig) { 1008bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, java_class); 1009bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, name); 1010bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, sig); 101100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1012bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return FindMethodID(soa, java_class, name, sig, true); 1013cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1014ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 101572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 101672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 101772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1018bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethod, obj); 1019bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethod, mid); 102025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 102100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 102272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 102300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1024cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1025ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 102672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1027bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, obj); 1028bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, mid); 102900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 103000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args)); 103100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1032cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1033ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 103472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1035bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, obj); 1036bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, mid); 103700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 103800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args)); 103900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1040cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1041ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 104272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 104372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 104472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1045bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, obj); 1046bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, mid); 104725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 104800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 104972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1050f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 1051cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1052ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 105372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1054bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, obj); 1055bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, mid); 105600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 105700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ(); 1058cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1059ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 106072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1061bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, obj); 1062bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, mid); 106300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 106400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ(); 1065cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1066ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 106772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 106872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 106972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1070bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethod, obj); 1071bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethod, mid); 1072bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers ScopedObjectAccess soa(env); 107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 107472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1075f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 1076cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1077ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 107872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1079bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethodV, obj); 1080bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethodV, mid); 108100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 108200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB(); 1083cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1084ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 108572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1086bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethodA, obj); 1087bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallByteMethodA, mid); 108800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 108900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB(); 1090cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1091ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 109272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 109372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 109472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1095bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethod, obj); 1096bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethod, mid); 109725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 109972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1100f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 1101cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1102ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 110372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1104bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethodV, obj); 1105bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethodV, mid); 110600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 110700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC(); 1108cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1109ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 111072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1111bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethodA, obj); 1112bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallCharMethodA, mid); 111300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 111400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC(); 1115cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1116ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 111772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 111872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 111972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1120bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, obj); 1121bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, mid); 112225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 112300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 112472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1125f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1126cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1127ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 112872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1129bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, obj); 1130bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, mid); 113100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 113200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD(); 1133cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1134ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 113572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1136bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, obj); 1137bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, mid); 113800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 113900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD(); 1140cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1141ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 114272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 114372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 114472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1145bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethod, obj); 1146bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethod, mid); 1147bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers ScopedObjectAccess soa(env); 114800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 114972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1150f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1151cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1152ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 115372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1154bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, obj); 1155bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, mid); 115600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 115700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF(); 1158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1159ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 116072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1161bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, obj); 1162bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, mid); 116300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 116400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF(); 1165cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1166ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 116772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 116872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 116972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1170bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethod, obj); 1171bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethod, mid); 117225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 117300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 117472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1175f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1176cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1177ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 117872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1179bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethodV, obj); 1180bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethodV, mid); 118100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 118200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI(); 1183cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1184ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 118572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1186bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethodA, obj); 1187bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallIntMethodA, mid); 118800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 118900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI(); 1190cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1191ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 119272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 119372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 119472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1195bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethod, obj); 1196bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethod, mid); 119725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 119800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 119972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1200f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1201cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1202ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 120372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1204bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethodV, obj); 1205bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethodV, mid); 120600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 120700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ(); 1208cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1209ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 121072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1211bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethodA, obj); 1212bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallLongMethodA, mid); 121300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 121400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ(); 1215cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1216ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 121772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 121872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 121972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1220bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethod, obj); 1221bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethod, mid); 122225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 122300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap)); 122472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1225f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1226cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1227ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 122872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1229bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethodV, obj); 1230bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethodV, mid); 123100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 123200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS(); 1233cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1234ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 123572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1236bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethodA, obj); 1237bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallShortMethodA, mid); 123800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 123900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS(); 1240cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1241ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 124272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) { 124372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_list ap; 124472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1245bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethod, obj); 1246bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethod, mid); 124725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 12481b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap); 124972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_end(ap); 1250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1251ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 125272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) { 1253bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, obj); 1254bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, mid); 125500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 125600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args); 1257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1258ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 125972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) { 1260bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, obj); 1261bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, mid); 126200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 126300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args); 1264cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1265ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 12661bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1267cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 126872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1269bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, obj); 1270bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, mid); 127125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 127200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 127300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result.GetL()); 1274cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1275cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return local_result; 1276cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1277ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1278bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1279bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1280bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, obj); 1281bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, mid); 128200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 128300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, args)); 128400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1285cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1286ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1287bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1288bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1289bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, obj); 1290bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, mid); 129100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 129200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithJValues(soa, obj, mid, args)); 129300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1294cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1295ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1296bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1297bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers ...) { 1298cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 129972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1300bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, obj); 1301bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, mid); 130225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 130300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1304cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1305f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 1306cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1307ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1309bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1310bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, obj); 1311bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, mid); 131200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 131300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetZ(); 1314cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1316bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1317bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1318bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, obj); 1319bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, mid); 132000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 132100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetZ(); 1322cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1323ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 132672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1327bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, obj); 1328bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, mid); 132925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 133000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1331cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1332f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 1333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1337bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, obj); 1338bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, mid); 133900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 134000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetB(); 1341cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1342ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1343bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1344bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1345bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, obj); 1346bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, mid); 134700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 134800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetB(); 1349cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1350ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1352cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 135372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1354bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, obj); 1355bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, mid); 1356bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers ScopedObjectAccess soa(env); 135700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1359f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 1360cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1361ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1362bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1363bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1364bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, obj); 1365bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, mid); 136600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 136700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetC(); 1368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1369ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1371bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1372bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, obj); 1373bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, mid); 137400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 137500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetC(); 1376cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1377ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 13781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 138072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1381bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, obj); 1382bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, mid); 138325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 138400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1386f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1387cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1388ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1389bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1390bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1391bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, obj); 1392bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, mid); 139300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 139400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetS(); 1395cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1396ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1397bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1398bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1399bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, obj); 1400bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, mid); 140100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 140200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetS(); 1403cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1404ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14051bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 140772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1408bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, obj); 1409bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, mid); 141025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 141100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1412cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1413f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1414cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1415ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1418bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, obj); 1419bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, mid); 142000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 142100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetI(); 1422cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1423ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1424bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1425bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1426bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, obj); 1427bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, mid); 142800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 142900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetI(); 1430cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1431ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1433cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 143472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1435bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, obj); 1436bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, mid); 143725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 143800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1439cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1440f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1441cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1442ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1443bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1444bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1445bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, obj); 1446bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, mid); 144700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 144800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetJ(); 1449cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1450ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1451bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1452bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1453bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, obj); 1454bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, mid); 145500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 145600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetJ(); 1457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1460cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 146172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1462bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, obj); 1463bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, mid); 146425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 146500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1466cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1467f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1468cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1469ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1470bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1471bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1472bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, obj); 1473bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, mid); 147400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 147500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetF(); 1476cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1477ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1478bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1479bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1480bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, obj); 1481bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, mid); 148200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 148300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetF(); 1484cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1485ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 14861bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1487cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 148872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1489bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, obj); 1490bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, mid); 149125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 149200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, obj, mid, ap)); 1493cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1494f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1495cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1496ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1497bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1498bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers va_list args) { 1499bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, obj); 1500bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, mid); 150100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 150200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, obj, mid, args).GetD(); 1503cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1504ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1505bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1506bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1507bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, obj); 1508bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, mid); 150900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 151000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, obj, mid, args).GetD(); 1511cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1512ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 15131bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) { 1514cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 151572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1516bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, obj); 1517bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, mid); 151825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 151900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, obj, mid, ap); 1520cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1522ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1523ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1524ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom va_list args) { 1525bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, obj); 1526bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, mid); 152700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 152800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, obj, mid, args); 1529cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1530ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1531bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid, 1532bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jvalue* args) { 1533bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, obj); 1534bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, mid); 153500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 153600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithJValues(soa, obj, mid, args); 1537cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1538ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1539bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) { 1540bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetFieldID, java_class); 1541bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetFieldID, name); 1542bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetFieldID, sig); 154300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1544bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return FindFieldID(soa, java_class, name, sig, false); 1545cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1546ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1547bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name, 1548bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const char* sig) { 1549bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, java_class); 1550bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, name); 1551bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetFieldID, sig); 155200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1553bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return FindFieldID(soa, java_class, name, sig, true); 1554cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1555ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1556885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) { 1557bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetObjectField, obj); 1558bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetObjectField, fid); 155900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 156000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(obj); 1561ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); 156200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(f->GetObject(o)); 1563cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1564ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1565885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) { 1566bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStaticObjectField, fid); 156700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 1568ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); 15692fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass())); 1570cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1571ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1572885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) { 1573bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetObjectField, java_object); 1574bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetObjectField, fid); 157500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 157600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 157700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* v = soa.Decode<Object*>(java_value); 1578ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); 1579885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes f->SetObject(o, v); 1580cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1581ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1582885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) { 1583bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetStaticObjectField, fid); 158400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 158500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* v = soa.Decode<Object*>(java_value); 1586ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); 15872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers f->SetObject(f->GetDeclaringClass(), v); 1588cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1589ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1590885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define GET_PRIMITIVE_FIELD(fn, instance) \ 1591bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(Get #fn Field, instance); \ 1592bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(Get #fn Field, fid); \ 159300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); \ 159400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(instance); \ 1595ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); \ 1596bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return f->Get ##fn (o) 1597885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 15982fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define GET_STATIC_PRIMITIVE_FIELD(fn) \ 1599bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStatic #fn Field, fid); \ 16002fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ScopedObjectAccess soa(env); \ 1601ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); \ 1602bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return f->Get ##fn (f->GetDeclaringClass()) 16032fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 1604885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define SET_PRIMITIVE_FIELD(fn, instance, value) \ 1605bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(Set #fn Field, instance); \ 1606bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(Set #fn Field, fid); \ 160700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); \ 160800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(instance); \ 1609ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); \ 1610bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers f->Set ##fn(o, value) 1611885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 16122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \ 1613bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetStatic #fn Field, fid); \ 16142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ScopedObjectAccess soa(env); \ 1615ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtField* f = soa.DecodeField(fid); \ 1616bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers f->Set ##fn(f->GetDeclaringClass(), value) 16172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 1618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) { 1619bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Boolean, obj); 1620cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1621ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1622885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) { 1623bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Byte, obj); 1624cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1625ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1626885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) { 1627bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Char, obj); 1628cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1629ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1630885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) { 1631bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Short, obj); 1632cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1633ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1634885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) { 1635bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Int, obj); 1636cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1637ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1638885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) { 1639bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Long, obj); 1640cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1641ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1642885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) { 1643bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Float, obj); 1644cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1645ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1646885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) { 1647bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_PRIMITIVE_FIELD(Double, obj); 1648cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1649ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16501bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) { 1651bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Boolean); 1652cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1653ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) { 1655bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Byte); 165683ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro } 1657cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 16581bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) { 1659bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Char); 16609b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro } 1661ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16621bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) { 1663bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Short); 1664cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1665ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16661bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) { 1667bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Int); 1668cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1669ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 16701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) { 1671bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Long); 1672885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1673885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 16741bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) { 1675bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Float); 1676885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1677885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 16781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) { 1679bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers GET_STATIC_PRIMITIVE_FIELD(Double); 1680885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1681885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1682885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) { 1683bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Boolean, obj, v); 1684885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1685885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1686885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) { 1687bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Byte, obj, v); 1688885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1689885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1690885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) { 1691bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Char, obj, v); 1692885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1693885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1694885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) { 1695bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Float, obj, v); 1696885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1697885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1698885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) { 1699bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Double, obj, v); 1700885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1701885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1702885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) { 1703bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Int, obj, v); 1704885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1705885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1706885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) { 1707bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Long, obj, v); 1708885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1709885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1710885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) { 1711bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_PRIMITIVE_FIELD(Short, obj, v); 1712885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1713885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1714885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) { 1715bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Boolean, v); 1716885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1717885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1718885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) { 1719bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Byte, v); 1720885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1721885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1722885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) { 1723bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Char, v); 1724885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1725885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1726885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) { 1727bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Float, v); 1728885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1729885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1730885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) { 1731bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Double, v); 1732885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1733885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1734885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) { 1735bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Int, v); 1736885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1737885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1738885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) { 1739bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Long, v); 1740885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes } 1741885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes 1742885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) { 1743bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers SET_STATIC_PRIMITIVE_FIELD(Short, v); 1744cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1745ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17461bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 174872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1749bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethod, mid); 175025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 175100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 175200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject local_result = soa.AddLocalReference<jobject>(result.GetL()); 1753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return local_result; 1755cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1756ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17571bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1758bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodV, mid); 175900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 176000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, args)); 176100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1763ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17641bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1765bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodA, mid); 176600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 176700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithJValues(soa, NULL, mid, args)); 176800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result.GetL()); 1769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1770ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17711bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1772cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 177372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1774bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethod, mid); 177525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 177600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1778f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetZ(); 1779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1780ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17811bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1782bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodV, mid); 178300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 178400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetZ(); 1785cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1786ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17871bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1788bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodA, mid); 178900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 179000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetZ(); 1791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1792ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 17931bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1794cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 179572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1796bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticByteMethod, mid); 179725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 179800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1800f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetB(); 1801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1802ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18031bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1804bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodV, mid); 180500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 180600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetB(); 1807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1808ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18091bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1810bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodA, mid); 181100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 181200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetB(); 1813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1814ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18151bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 181772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1818bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticCharMethod, mid); 181925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 182000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1822f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetC(); 1823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1824ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18251bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1826bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodV, mid); 182700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 182800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetC(); 1829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1830ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18311bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1832bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodA, mid); 183300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 183400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetC(); 1835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1836ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 183972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1840bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticShortMethod, mid); 184125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 184200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1843cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1844f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetS(); 1845cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1846ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18471bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1848bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodV, mid); 184900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 185000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetS(); 1851cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1852ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18531bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1854bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodA, mid); 185500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 185600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetS(); 1857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1858ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 186172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1862bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticIntMethod, mid); 186325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 186400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1866f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetI(); 1867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1868ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18691bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1870bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodV, mid); 187100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 187200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetI(); 1873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1874ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18751bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1876bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodA, mid); 187700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 187800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetI(); 1879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1880ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18811bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 188372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1884bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticLongMethod, mid); 188525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 188600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1887cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1888f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetJ(); 1889cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1890ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18911bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1892bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodV, mid); 189300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 189400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetJ(); 1895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1896ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 18971bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1898bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodA, mid); 189900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 190000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetJ(); 1901cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1902ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19031bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1904cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 190572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1906bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethod, mid); 190725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 190800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1910f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetF(); 1911cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1912ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19131bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1914bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodV, mid); 191500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 191600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetF(); 1917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1918ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19191bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1920bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodA, mid); 192100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 192200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetF(); 1923cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1924ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19251bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 192772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1928bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethod, mid); 192925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 193000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JValue result(InvokeWithVarArgs(soa, NULL, mid, ap)); 1931cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1932f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes return result.GetD(); 1933cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1934ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19351bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1936bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodV, mid); 193700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 193800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithVarArgs(soa, NULL, mid, args).GetD(); 1939cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1940ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19411bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1942bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodA, mid); 194300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 194400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return InvokeWithJValues(soa, NULL, mid, args).GetD(); 1945cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1946ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19471bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) { 1948cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_list ap; 194972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes va_start(ap, mid); 1950bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethod, mid); 195125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers ScopedObjectAccess soa(env); 195200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, NULL, mid, ap); 1953cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes va_end(ap); 1954cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1955ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) { 1957bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodV, mid); 195800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 195900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithVarArgs(soa, NULL, mid, args); 1960cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1961ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 19621bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) { 1963bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodA, mid); 196400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 196500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers InvokeWithJValues(soa, NULL, mid, args); 1966cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1967ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1968814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) { 19691d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(char_count < 0)) { 19701d99e4549309d05007d041d058b1878de88e9585Ian Rogers JniAbortF("NewString", "char_count < 0: %d", char_count); 19711d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 19721d99e4549309d05007d041d058b1878de88e9585Ian Rogers } 19731d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(chars == nullptr && char_count > 0)) { 19741d99e4549309d05007d041d058b1878de88e9585Ian Rogers JniAbortF("NewString", "chars == null && char_count > 0"); 19751d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 1976bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers } 197700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 197850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers String* result = String::AllocFromUtf16(soa.Self(), char_count, chars); 197900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jstring>(result); 1980cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1981ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1982814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jstring NewStringUTF(JNIEnv* env, const char* utf) { 1983814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes if (utf == NULL) { 1984814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes return NULL; 1985814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 198600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 198750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers String* result = String::AllocFromModifiedUtf8(soa.Self(), utf); 198800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jstring>(result); 1989cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 1990ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 1991814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jsize GetStringLength(JNIEnv* env, jstring java_string) { 1992bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string); 199300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 199400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.Decode<String*>(java_string)->GetLength(); 1995814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 1996814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 1997814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) { 1998bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string); 199900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 200000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.Decode<String*>(java_string)->GetUtfLength(); 2001814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes } 2002814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes 2003bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, 2004bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jchar* buf) { 2005bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringRegion, java_string); 200600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 200700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 2008b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes if (start < 0 || length < 0 || start + length > s->GetLength()) { 200900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowSIOOBE(soa, start, length, s->GetLength()); 2010b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } else { 20114ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf); 2012b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset(); 2013b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes memcpy(buf, chars + start, length * sizeof(jchar)); 2014b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 20158a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes } 2016ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2017bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, 2018bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers char* buf) { 2019bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string); 202000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 202100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 2022b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes if (start < 0 || length < 0 || start + length > s->GetLength()) { 202300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowSIOOBE(soa, start, length, s->GetLength()); 2024b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } else { 20254ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringUTFRegion, length, buf); 2026b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset(); 2027b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes ConvertUtf16ToModifiedUtf8(buf, chars + start, length); 2028b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2029cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2030ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 20317577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) { 2032bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string); 203300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 203400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 2035423d2a3dcbb260b020efb5da59f784c9f02accbfMathieu Chartier CharArray* chars = s->GetCharArray(); 203600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, chars); 2037590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (is_copy != nullptr) { 2038590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *is_copy = JNI_TRUE; 2039590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 2040590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier int32_t char_count = s->GetLength(); 2041590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier int32_t offset = s->GetOffset(); 2042590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier jchar* bytes = new jchar[char_count + 1]; 2043590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier for (int32_t i = 0; i < char_count; i++) { 2044590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier bytes[i] = chars->Get(i + offset); 20457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 2046590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier bytes[char_count] = '\0'; 2047590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return bytes; 2048cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2049ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2050590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) { 2051bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string); 2052590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier delete[] chars; 205300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 205400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray()); 2055cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2056ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 20577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) { 20587577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return GetStringChars(env, java_string, is_copy); 2059cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2060ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 20617577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) { 20627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return ReleaseStringChars(env, java_string, chars); 2063cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2064ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 20657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) { 20667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (java_string == NULL) { 20677577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return NULL; 20687577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 20697577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes if (is_copy != NULL) { 20707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes *is_copy = JNI_TRUE; 20717577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 2072ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 207300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers String* s = soa.Decode<String*>(java_string); 20747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes size_t byte_count = s->GetUtfLength(); 20757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes char* bytes = new char[byte_count + 1]; 20767934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom CHECK(bytes != NULL); // bionic aborts anyway. 20777577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset(); 20787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength()); 20797577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes bytes[byte_count] = '\0'; 20807577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return bytes; 2081b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2082b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 20837577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) { 20847577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes delete[] chars; 2085b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2086b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2087bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes static jsize GetArrayLength(JNIEnv* env, jarray java_array) { 2088bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetArrayLength, java_array); 208900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 209000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* obj = soa.Decode<Object*>(java_array); 2091ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom if (UNLIKELY(!obj->IsArrayInstance())) { 209296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str()); 209396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 2094bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes Array* array = obj->AsArray(); 2095bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes return array->GetLength(); 2096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2097ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2098814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) { 2099bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetObjectArrayElement, java_array); 210000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 210100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array); 210200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(array->Get(index)); 2103cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2104d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes 2105bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index, 2106bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jobject java_value) { 2107bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetObjectArrayElement, java_array); 210800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 210900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array); 211000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* value = soa.Decode<Object*>(java_value); 2111cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes array->Set(index, value); 2112cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2113f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 2114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) { 211500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 211600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length); 2117cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2118ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2119cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jbyteArray NewByteArray(JNIEnv* env, jsize length) { 212000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 212100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length); 2122cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2123ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2124cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jcharArray NewCharArray(JNIEnv* env, jsize length) { 212500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 212600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jcharArray, CharArray>(soa, length); 2127cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2128ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2129cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) { 213000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 213100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length); 2132cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2133ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2134cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jfloatArray NewFloatArray(JNIEnv* env, jsize length) { 213500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 213600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length); 2137cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2138ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2139cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jintArray NewIntArray(JNIEnv* env, jsize length) { 214000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 214100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jintArray, IntArray>(soa, length); 2142cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2143ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2144cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jlongArray NewLongArray(JNIEnv* env, jsize length) { 214500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 214600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jlongArray, LongArray>(soa, length); 2147cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2148f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 21491d99e4549309d05007d041d058b1878de88e9585Ian Rogers static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, 21501d99e4549309d05007d041d058b1878de88e9585Ian Rogers jobject initial_element) { 21511d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(length < 0)) { 215296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("NewObjectArray", "negative array length: %d", length); 21531d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 215496a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 2155cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 2156cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Compute the array class corresponding to the given element class. 2157ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ScopedObjectAccess soa(env); 21581d99e4549309d05007d041d058b1878de88e9585Ian Rogers Class* array_class; 21591d99e4549309d05007d041d058b1878de88e9585Ian Rogers { 21601d99e4549309d05007d041d058b1878de88e9585Ian Rogers Class* element_class = soa.Decode<Class*>(element_jclass); 21611d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(element_class->IsPrimitive())) { 21621d99e4549309d05007d041d058b1878de88e9585Ian Rogers JniAbortF("NewObjectArray", "not an object type: %s", 21631d99e4549309d05007d041d058b1878de88e9585Ian Rogers PrettyDescriptor(element_class).c_str()); 21641d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 21651d99e4549309d05007d041d058b1878de88e9585Ian Rogers } 21661d99e4549309d05007d041d058b1878de88e9585Ian Rogers std::string descriptor("["); 21671d99e4549309d05007d041d058b1878de88e9585Ian Rogers descriptor += ClassHelper(element_class).GetDescriptor(); 21681d99e4549309d05007d041d058b1878de88e9585Ian Rogers 21691d99e4549309d05007d041d058b1878de88e9585Ian Rogers // Find the class. 21701d99e4549309d05007d041d058b1878de88e9585Ian Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 21711d99e4549309d05007d041d058b1878de88e9585Ian Rogers SirtRef<mirror::ClassLoader> class_loader(soa.Self(), element_class->GetClassLoader()); 21721d99e4549309d05007d041d058b1878de88e9585Ian Rogers array_class = class_linker->FindClass(descriptor.c_str(), class_loader); 21731d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(array_class == nullptr)) { 21741d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 21751d99e4549309d05007d041d058b1878de88e9585Ian Rogers } 2176cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2177cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 21787577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // Allocate and initialize if necessary. 217950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length); 21801d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (result != nullptr && initial_element != nullptr) { 218100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* initial_object = soa.Decode<Object*>(initial_element); 21821d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (initial_object != nullptr) { 21831d99e4549309d05007d041d058b1878de88e9585Ian Rogers mirror::Class* element_class = result->GetClass()->GetComponentType(); 21841d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) { 21851d99e4549309d05007d041d058b1878de88e9585Ian Rogers JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with element " 21861d99e4549309d05007d041d058b1878de88e9585Ian Rogers "type of '%s'", PrettyDescriptor(initial_object->GetClass()).c_str(), 21871d99e4549309d05007d041d058b1878de88e9585Ian Rogers PrettyDescriptor(element_class).c_str()); 21881d99e4549309d05007d041d058b1878de88e9585Ian Rogers 21891d99e4549309d05007d041d058b1878de88e9585Ian Rogers } else { 21901d99e4549309d05007d041d058b1878de88e9585Ian Rogers for (jsize i = 0; i < length; ++i) { 21911d99e4549309d05007d041d058b1878de88e9585Ian Rogers result->SetWithoutChecks(i, initial_object); 21921d99e4549309d05007d041d058b1878de88e9585Ian Rogers } 21931d99e4549309d05007d041d058b1878de88e9585Ian Rogers } 21947577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 21957577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes } 219600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobjectArray>(result); 2197f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes } 2198f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 2199cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jshortArray NewShortArray(JNIEnv* env, jsize length) { 220000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 220100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return NewPrimitiveArray<jshortArray, ShortArray>(soa, length); 2202cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2203ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2204a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) { 2205bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayCritical, java_array); 220600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 220700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Array* array = soa.Decode<Array*>(java_array); 2208590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::Heap* heap = Runtime::Current()->GetHeap(); 2209590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (heap->IsMovableObject(array)) { 22101d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier heap->IncrementDisableMovingGC(soa.Self()); 2211590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete. 2212590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier array = soa.Decode<Array*>(java_array); 2213590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 221400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, array); 2215590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (is_copy != nullptr) { 2216a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers *is_copy = JNI_FALSE; 2217a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers } 22183e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier return array->GetRawData(array->GetClass()->GetComponentSize()); 2219b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2220b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2221590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* elements, jint mode) { 2222bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(ReleasePrimitiveArrayCritical, array); 2223590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2224b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2225b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 22267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) { 2227bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetBooleanArrayElements, array); 222800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 222900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy); 2230cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2231ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) { 2233bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetByteArrayElements, array); 223400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 223500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy); 2236cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2237ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) { 2239bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetCharArrayElements, array); 224000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 224100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy); 2242cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2243ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) { 2245bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetDoubleArrayElements, array); 224600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 224700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy); 2248cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2249ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) { 2251bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetFloatArrayElements, array); 225200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 225300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy); 2254cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2255ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) { 2257bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetIntArrayElements, array); 225800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 225900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy); 2260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) { 2263bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetLongArrayElements, array); 226400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 226500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy); 2266cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2267ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 22687577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) { 2269bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetShortArrayElements, array); 227000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 227100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy); 2272cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2273ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2274590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements, 2275590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier jint mode) { 2276590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2277cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2278ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2279590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) { 2280590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2281cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2282ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2283590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) { 2284590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2285cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2286ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2287590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements, 2288590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier jint mode) { 2289590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2290cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2291ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2292590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements, 2293590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier jint mode) { 2294590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2296ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2297590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) { 2298590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2299cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2300ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2301590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) { 2302590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2303cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2304ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2305590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements, 2306590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier jint mode) { 2307590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ReleasePrimitiveArray(env, array, elements, mode); 2308cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2309ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2310bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, 2311bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jboolean* buf) { 231200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 231300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf); 2314cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2316bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, 2317bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jbyte* buf) { 231800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 231900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf); 2320cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2321ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2322bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, 2323bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jchar* buf) { 232400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 232500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf); 2326cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2327ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2328bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, 2329bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jdouble* buf) { 233000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 233100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf); 2332cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2333ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2334bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, 2335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jfloat* buf) { 233600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 233700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf); 2338cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2339ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2340bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, 2341bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jint* buf) { 234200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 234300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf); 2344cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2345ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2346bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, 2347bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jlong* buf) { 234800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 234900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf); 2350cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2351ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2352bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, 2353bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jshort* buf) { 235400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 235500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf); 2356cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2357ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2358bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length, 2359bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jboolean* buf) { 236000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 236100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf); 2362cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2363ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2364bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length, 2365bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jbyte* buf) { 236600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 236700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf); 2368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2369ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length, 2371bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jchar* buf) { 237200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 237300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf); 2374cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2375ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2376bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length, 2377bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jdouble* buf) { 237800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 237900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf); 2380cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2381ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2382bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length, 2383bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jfloat* buf) { 238400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 238500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf); 2386cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2387ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2388bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length, 2389bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jint* buf) { 239000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 239100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf); 2392cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2393ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2394bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length, 2395bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jlong* buf) { 239600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 239700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf); 2398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2399ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2400bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length, 2401bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers const jshort* buf) { 240200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 240300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf); 2404cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2405ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2406bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, 2407bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jint method_count) { 2408c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes return RegisterNativeMethods(env, java_class, methods, method_count, true); 2409c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes } 2410c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes 2411bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods, 2412bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jint method_count, bool return_errors) { 2413bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers if (UNLIKELY(method_count < 0)) { 2414aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes JniAbortF("RegisterNatives", "negative method count: %d", method_count); 2415bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return JNI_ERR; // Not reached. 2416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers } 2417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(RegisterNatives, java_class); 241800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 241900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 2420bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers if (UNLIKELY(method_count == 0)) { 2421bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for " 2422bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers << PrettyDescriptor(c); 2423bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers return JNI_OK; 2424bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers } 2425bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(RegisterNatives, methods); 2426bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers for (jint i = 0; i < method_count; ++i) { 2427cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes const char* name = methods[i].name; 2428cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes const char* sig = methods[i].signature; 24291eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers bool is_fast = false; 2430cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (*sig == '!') { 24311eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers is_fast = true; 2432cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes ++sig; 2433cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 24340af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes 2435ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* m = c->FindDirectMethod(name, sig); 24365174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m == NULL) { 24375174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes m = c->FindVirtualMethod(name, sig); 2438cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 24395174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m == NULL) { 2440c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(return_errors ? ERROR : FATAL) << "Failed to register native method " 2441bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers << PrettyDescriptor(c) << "." << name << sig; 244200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static"); 2443cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 24445174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } else if (!m->IsNative()) { 2445c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method " 2446bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers << PrettyDescriptor(c) << "." << name << sig 2447bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers << " as native"; 244800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowNoSuchMethodError(soa, c, name, sig, "native"); 2449cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 2450cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 24515174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 24524dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]"; 24535174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 24541eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers m->RegisterNative(soa.Self(), methods[i].fnPtr, is_fast); 24554dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 2456cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_OK; 24574dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers } 2458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 24595174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes static jint UnregisterNatives(JNIEnv* env, jclass java_class) { 2460bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(UnregisterNatives, java_class); 246100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 246200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Class* c = soa.Decode<Class*>(java_class); 24635174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 24644dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]"; 24655174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 24665174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes for (size_t i = 0; i < c->NumDirectMethods(); ++i) { 2467ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* m = c->GetDirectMethod(i); 24685174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m->IsNative()) { 246900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m->UnregisterNative(soa.Self()); 24705174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 24715174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 24725174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { 2473ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* m = c->GetVirtualMethod(i); 24745174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes if (m->IsNative()) { 247500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m->UnregisterNative(soa.Self()); 24765174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 24775174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes } 24785174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes 24795174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes return JNI_OK; 2480cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2481ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 248200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static jint MonitorEnter(JNIEnv* env, jobject java_object) 248300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) { 2484bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(MonitorEnter, java_object); 248500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 248600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 248700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers o->MonitorEnter(soa.Self()); 248800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 2489ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_ERR; 2490ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes } 249100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->monitors.Add(o); 2492ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_OK; 2493cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2494ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 249500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static jint MonitorExit(JNIEnv* env, jobject java_object) 249600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers UNLOCK_FUNCTION(monitor_lock_) { 2497bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(MonitorExit, java_object); 249800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ScopedObjectAccess soa(env); 249900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Object* o = soa.Decode<Object*>(java_object); 250000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers o->MonitorExit(soa.Self()); 250100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 2502ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_ERR; 2503ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes } 250400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->monitors.Remove(o); 2505ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes return JNI_OK; 2506f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes } 2507ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2508cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint GetJavaVM(JNIEnv* env, JavaVM** vm) { 2509bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetJavaVM, vm); 2510cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes Runtime* runtime = Runtime::Current(); 2511cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (runtime != NULL) { 251269f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes *vm = runtime->GetJavaVM(); 2513cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } else { 2514cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *vm = NULL; 2515cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return (*vm != NULL) ? JNI_OK : JNI_ERR; 2517cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2518ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2519b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { 252096a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes if (capacity < 0) { 252162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %lld", capacity); 252296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 252311a796e42027a926d972f1232484d577cbe01f84Elliott Hughes if (address == NULL && capacity != 0) { 252462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers JniAbortF("NewDirectByteBuffer", "non-zero capacity for NULL pointer: %lld", capacity); 252596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 2526ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 252796a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes // At the moment, the Java side is limited to 32 bits. 2528b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff); 2529b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes CHECK_LE(capacity, 0xffffffff); 2530b56812165dd3a2e6eb8b85c810943b3d7bd9bfc4Elliott Hughes jlong address_arg = reinterpret_cast<jlong>(address); 2531b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes jint capacity_arg = static_cast<jint>(capacity); 2532ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2533aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer, 2534aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes WellKnownClasses::java_nio_DirectByteBuffer_init, 2535eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes address_arg, capacity_arg); 2536ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? NULL : result; 2537cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2538ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2539b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) { 2540534f2b6f430c7984fda9333f8e72b37962b144b4Jeff Hao return reinterpret_cast<void*>(env->GetLongField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress)); 2541cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2542ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2543b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) { 2544aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity)); 2545cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 2546ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2547b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) { 2548bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetObjectRefType, java_object); 2549b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2550b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // Do we definitely know what kind of reference this is? 2551b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes IndirectRef ref = reinterpret_cast<IndirectRef>(java_object); 2552b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes IndirectRefKind kind = GetIndirectRefKind(ref); 2553b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes switch (kind) { 2554b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kLocal: 2555ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) { 25562ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNILocalRefType; 25572ced6a534157d5d963693346904389c19775d2daElliott Hughes } 25582ced6a534157d5d963693346904389c19775d2daElliott Hughes return JNIInvalidRefType; 2559b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kGlobal: 2560b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIGlobalRefType; 2561b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kWeakGlobal: 2562b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIWeakGlobalRefType; 2563b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case kSirtOrInvalid: 2564b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // Is it in a stack IRT? 2565ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (static_cast<JNIEnvExt*>(env)->self->SirtContains(java_object)) { 2566b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNILocalRefType; 2567b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2568b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 2569ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (!static_cast<JNIEnvExt*>(env)->vm->work_around_app_jni_bugs) { 2570c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes return JNIInvalidRefType; 2571c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes } 2572c5bfa8f49d8548d7c685a99b411311ef56bedffaElliott Hughes 2573b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // If we're handing out direct pointers, check whether it's a direct pointer 2574b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes // to a local reference. 2575ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers { 2576ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 2577ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) { 2578ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) { 2579ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers return JNILocalRefType; 2580ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers } 2581b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2582b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 2583b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return JNIInvalidRefType; 2584b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 25852e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom LOG(FATAL) << "IndirectRefKind[" << kind << "]"; 25862e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom return JNIInvalidRefType; 2587cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 258800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 258900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private: 2590ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity, 2591ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers const char* caller) { 259200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: we should try to expand the table if necessary. 2593aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) { 259400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity; 259500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return JNI_ERR; 259600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 259700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: this isn't quite right, since "capacity" includes holes. 2598ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers size_t capacity = static_cast<JNIEnvExt*>(env)->locals.Capacity(); 259900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity); 260000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!okay) { 2601ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers ScopedObjectAccess soa(env); 260200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Self()->ThrowOutOfMemoryError(caller); 260300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 260400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return okay ? JNI_OK : JNI_ERR; 260500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 260600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 260700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template<typename JniT, typename ArtT> 260800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length) 2609b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 26101d99e4549309d05007d041d058b1878de88e9585Ian Rogers if (UNLIKELY(length < 0)) { 261196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes JniAbortF("NewPrimitiveArray", "negative array length: %d", length); 26121d99e4549309d05007d041d058b1878de88e9585Ian Rogers return nullptr; 261396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes } 261450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ArtT* result = ArtT::Alloc(soa.Self(), length); 261500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<JniT>(result); 261600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 261700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 261800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename ArrayT, typename CArrayT, typename ArtArrayT> 261900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array, 262000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jboolean* is_copy) 2621b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 262200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array); 262300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers PinPrimitiveArray(soa, array); 2624590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Only make a copy if necessary. 2625590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (Runtime::Current()->GetHeap()->IsMovableObject(array)) { 2626590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (is_copy != nullptr) { 2627590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *is_copy = JNI_TRUE; 2628590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 2629590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static const size_t component_size = array->GetClass()->GetComponentSize(); 2630590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t size = array->GetLength() * component_size; 2631590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier void* data = new uint64_t[RoundUp(size, 8) / 8]; 2632590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier memcpy(data, array->GetData(), size); 2633590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return reinterpret_cast<CArrayT>(data); 2634590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } else { 2635590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (is_copy != nullptr) { 2636590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *is_copy = JNI_FALSE; 2637590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 2638590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return reinterpret_cast<CArrayT>(array->GetData()); 263900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 264000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 264100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 2642590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier template <typename ArrayT, typename ElementT> 2643590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) { 2644590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ScopedObjectAccess soa(env); 2645590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier Array* array = soa.Decode<Array*>(java_array); 2646590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t component_size = array->GetClass()->GetComponentSize(); 2647590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier void* array_data = array->GetRawData(component_size); 2648590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier gc::Heap* heap = Runtime::Current()->GetHeap(); 2649590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier bool is_copy = array_data != reinterpret_cast<void*>(elements); 2650590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier size_t bytes = array->GetLength() * component_size; 2651590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier VLOG(heap) << "Release primitive array " << env << " array_data " << array_data 2652590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier << " elements " << reinterpret_cast<void*>(elements); 2653590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier // Don't need to copy if we had a direct pointer. 2654590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (mode != JNI_ABORT && is_copy) { 2655590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier memcpy(array_data, elements, bytes); 2656590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 265700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (mode != JNI_COMMIT) { 2658590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (is_copy) { 2659590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier delete[] reinterpret_cast<uint64_t*>(elements); 26603e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier } else if (heap->IsMovableObject(array)) { 26611d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier // Non copy to a movable object must means that we had disabled the moving GC. 26621d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier heap->DecrementDisableMovingGC(soa.Self()); 2663590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 26643e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier UnpinPrimitiveArray(soa, array); 266500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 266600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 266700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 266800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename JavaArrayT, typename JavaT, typename ArrayT> 266900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array, 267000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize start, jsize length, JavaT* buf) 2671b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2672bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayRegion, java_array); 267300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArrayT* array = soa.Decode<ArrayT*>(java_array); 267400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (start < 0 || length < 0 || start + length > array->GetLength()) { 267500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowAIOOBE(soa, array, start, length, "src"); 267600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 26774ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf); 267800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaT* data = array->GetData(); 267900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers memcpy(buf, data + start, length * sizeof(JavaT)); 268000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 268100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 268200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 268300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers template <typename JavaArrayT, typename JavaT, typename ArrayT> 268400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array, 268500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jsize start, jsize length, const JavaT* buf) 2686b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2687bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers CHECK_NON_NULL_ARGUMENT(SetPrimitiveArrayRegion, java_array); 268800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ArrayT* array = soa.Decode<ArrayT*>(java_array); 268900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (start < 0 || length < 0 || start + length > array->GetLength()) { 269000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ThrowAIOOBE(soa, array, start, length, "dst"); 269100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } else { 26924ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf); 269300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers JavaT* data = array->GetData(); 269400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers memcpy(data + start, buf, length * sizeof(JavaT)); 269500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 269600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 2697cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}; 2698ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 269988c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNINativeInterface gJniNativeInterface = { 2700ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved0. 2701ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved1. 2702ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved2. 2703ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved3. 2704cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetVersion, 2705cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DefineClass, 2706cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FindClass, 2707cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FromReflectedMethod, 2708cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FromReflectedField, 2709cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ToReflectedMethod, 2710cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetSuperclass, 2711cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsAssignableFrom, 2712cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ToReflectedField, 2713cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::Throw, 2714cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ThrowNew, 2715cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionOccurred, 2716cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionDescribe, 2717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionClear, 2718cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::FatalError, 2719cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::PushLocalFrame, 2720cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::PopLocalFrame, 2721cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewGlobalRef, 2722cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteGlobalRef, 2723cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteLocalRef, 2724cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsSameObject, 2725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewLocalRef, 2726cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::EnsureLocalCapacity, 2727cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::AllocObject, 2728cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObject, 2729cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectV, 2730cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectA, 2731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectClass, 2732cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::IsInstanceOf, 2733cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetMethodID, 2734cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethod, 2735cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethodV, 2736cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallObjectMethodA, 2737cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethod, 2738cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethodV, 2739cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallBooleanMethodA, 2740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethod, 2741cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethodV, 2742cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallByteMethodA, 2743cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethod, 2744cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethodV, 2745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallCharMethodA, 2746cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethod, 2747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethodV, 2748cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallShortMethodA, 2749cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethod, 2750cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethodV, 2751cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallIntMethodA, 2752cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethod, 2753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethodV, 2754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallLongMethodA, 2755cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethod, 2756cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethodV, 2757cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallFloatMethodA, 2758cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethod, 2759cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethodV, 2760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallDoubleMethodA, 2761cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethod, 2762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethodV, 2763cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallVoidMethodA, 2764cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethod, 2765cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethodV, 2766cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualObjectMethodA, 2767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethod, 2768cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethodV, 2769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualBooleanMethodA, 2770cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethod, 2771cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethodV, 2772cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualByteMethodA, 2773cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethod, 2774cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethodV, 2775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualCharMethodA, 2776cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethod, 2777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethodV, 2778cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualShortMethodA, 2779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethod, 2780cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethodV, 2781cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualIntMethodA, 2782cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethod, 2783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethodV, 2784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualLongMethodA, 2785cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethod, 2786cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethodV, 2787cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualFloatMethodA, 2788cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethod, 2789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethodV, 2790cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualDoubleMethodA, 2791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethod, 2792cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethodV, 2793cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallNonvirtualVoidMethodA, 2794cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFieldID, 2795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectField, 2796cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanField, 2797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteField, 2798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharField, 2799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortField, 2800cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntField, 2801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongField, 2802cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatField, 2803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleField, 2804cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetObjectField, 2805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetBooleanField, 2806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetByteField, 2807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetCharField, 2808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetShortField, 2809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetIntField, 2810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetLongField, 2811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetFloatField, 2812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetDoubleField, 2813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticMethodID, 2814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethod, 2815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethodV, 2816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticObjectMethodA, 2817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethod, 2818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethodV, 2819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticBooleanMethodA, 2820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethod, 2821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethodV, 2822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticByteMethodA, 2823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethod, 2824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethodV, 2825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticCharMethodA, 2826cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethod, 2827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethodV, 2828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticShortMethodA, 2829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethod, 2830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethodV, 2831cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticIntMethodA, 2832cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethod, 2833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethodV, 2834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticLongMethodA, 2835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethod, 2836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethodV, 2837cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticFloatMethodA, 2838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethod, 2839cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethodV, 2840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticDoubleMethodA, 2841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethod, 2842cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethodV, 2843cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::CallStaticVoidMethodA, 2844cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticFieldID, 2845cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticObjectField, 2846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticBooleanField, 2847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticByteField, 2848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticCharField, 2849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticShortField, 2850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticIntField, 2851cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticLongField, 2852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticFloatField, 2853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStaticDoubleField, 2854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticObjectField, 2855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticBooleanField, 2856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticByteField, 2857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticCharField, 2858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticShortField, 2859cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticIntField, 2860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticLongField, 2861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticFloatField, 2862cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetStaticDoubleField, 2863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewString, 2864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringLength, 2865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringChars, 2866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringChars, 2867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewStringUTF, 2868cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFLength, 2869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFChars, 2870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringUTFChars, 2871cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetArrayLength, 2872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewObjectArray, 2873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectArrayElement, 2874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetObjectArrayElement, 2875cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewBooleanArray, 2876cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewByteArray, 2877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewCharArray, 2878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewShortArray, 2879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewIntArray, 2880cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewLongArray, 2881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewFloatArray, 2882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewDoubleArray, 2883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanArrayElements, 2884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteArrayElements, 2885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharArrayElements, 2886cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortArrayElements, 2887cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntArrayElements, 2888cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongArrayElements, 2889cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatArrayElements, 2890cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleArrayElements, 2891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseBooleanArrayElements, 2892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseByteArrayElements, 2893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseCharArrayElements, 2894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseShortArrayElements, 2895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseIntArrayElements, 2896cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseLongArrayElements, 2897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseFloatArrayElements, 2898cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseDoubleArrayElements, 2899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetBooleanArrayRegion, 2900cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetByteArrayRegion, 2901cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetCharArrayRegion, 2902cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetShortArrayRegion, 2903cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetIntArrayRegion, 2904cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetLongArrayRegion, 2905cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetFloatArrayRegion, 2906cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDoubleArrayRegion, 2907cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetBooleanArrayRegion, 2908cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetByteArrayRegion, 2909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetCharArrayRegion, 2910cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetShortArrayRegion, 2911cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetIntArrayRegion, 2912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetLongArrayRegion, 2913cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetFloatArrayRegion, 2914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::SetDoubleArrayRegion, 2915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::RegisterNatives, 2916cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::UnregisterNatives, 2917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::MonitorEnter, 2918cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::MonitorExit, 2919cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetJavaVM, 2920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringRegion, 2921cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringUTFRegion, 2922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetPrimitiveArrayCritical, 2923cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleasePrimitiveArrayCritical, 2924cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetStringCritical, 2925cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ReleaseStringCritical, 2926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewWeakGlobalRef, 2927cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::DeleteWeakGlobalRef, 2928cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::ExceptionCheck, 2929cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::NewDirectByteBuffer, 2930cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDirectBufferAddress, 2931cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetDirectBufferCapacity, 2932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JNI::GetObjectRefType, 2933ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}; 2934ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 29357577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesJNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm) 293669f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes : self(self), 29377577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes vm(vm), 29385a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers local_ref_cookie(IRT_FIRST_SEGMENT), 29395a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers locals(kLocalsInitial, kLocalsMax, kLocal), 29404ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes check_jni(false), 2941bbd76717c14822b68ae6d122d88610b46286272fElliott Hughes critical(false), 29425a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers monitors("monitors", kMonitorsInitial, kMonitorsMax) { 294388c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = unchecked_functions = &gJniNativeInterface; 29444ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes if (vm->check_jni) { 294588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes SetCheckJniEnabled(true); 2946a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } 29475a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers // The JniEnv local reference values must be at a consistent offset or else cross-compilation 29485a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers // errors will ensue. 29495a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12); 29505a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16); 295140ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes} 295240ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes 2953c1674ed06662420213441ff2b818f2f71f9098dcElliott HughesJNIEnvExt::~JNIEnvExt() { 2954c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes} 2955c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 2956590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierjobject JNIEnvExt::NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2957590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (obj == nullptr) { 2958590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return nullptr; 2959590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 2960590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return reinterpret_cast<jobject>(locals.Add(local_ref_cookie, obj)); 2961590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier} 2962590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier 2963590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartiervoid JNIEnvExt::DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2964590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (obj != nullptr) { 2965590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier locals.Remove(local_ref_cookie, reinterpret_cast<IndirectRef>(obj)); 2966590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 2967590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier} 296888c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JNIEnvExt::SetCheckJniEnabled(bool enabled) { 296988c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes check_jni = enabled; 297088c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface; 29714ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes} 29724ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes 297373e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JNIEnvExt::DumpReferenceTables(std::ostream& os) { 297473e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes locals.Dump(os); 297573e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes monitors.Dump(os); 29769d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 29779d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 29781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesvoid JNIEnvExt::PushFrame(int /*capacity*/) { 29791bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes // TODO: take 'capacity' into account. 29802ced6a534157d5d963693346904389c19775d2daElliott Hughes stacked_local_ref_cookies.push_back(local_ref_cookie); 29812ced6a534157d5d963693346904389c19775d2daElliott Hughes local_ref_cookie = locals.GetSegmentState(); 29822ced6a534157d5d963693346904389c19775d2daElliott Hughes} 29832ced6a534157d5d963693346904389c19775d2daElliott Hughes 29842ced6a534157d5d963693346904389c19775d2daElliott Hughesvoid JNIEnvExt::PopFrame() { 29852ced6a534157d5d963693346904389c19775d2daElliott Hughes locals.SetSegmentState(local_ref_cookie); 29862ced6a534157d5d963693346904389c19775d2daElliott Hughes local_ref_cookie = stacked_local_ref_cookies.back(); 29872ced6a534157d5d963693346904389c19775d2daElliott Hughes stacked_local_ref_cookies.pop_back(); 29882ced6a534157d5d963693346904389c19775d2daElliott Hughes} 29892ced6a534157d5d963693346904389c19775d2daElliott Hughes 29902dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersOffset JNIEnvExt::SegmentStateOffset() { 29912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) + 29922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers IndirectReferenceTable::SegmentStateOffset().Int32Value()); 29932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 29942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2995ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro// JNI Invocation interface. 2996ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 2997bddf97641c9371ec74c63bca52fff62fecd73750Brian Carlstromextern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) { 29982ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args); 299983a25328c595975097cf3948451088cbfc64fc09Elliott Hughes if (IsBadJniVersion(args->version)) { 300083a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version; 30012ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_EVERSION; 30022ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30032ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro Runtime::Options options; 30042ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro for (int i = 0; i < args->nOptions; ++i) { 30052ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro JavaVMOption* option = &args->options[i]; 3006f1a5adc87760f938b01df26d906295063546b259Elliott Hughes options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo)); 30072ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30082ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro bool ignore_unrecognized = args->ignoreUnrecognized; 300900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!Runtime::Create(options, ignore_unrecognized)) { 30102ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_ERR; 30112ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 301200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Runtime* runtime = Runtime::Current(); 3013bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom bool started = runtime->Start(); 3014bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom if (!started) { 3015bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom delete Thread::Current()->GetJniEnv(); 3016bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom delete runtime->GetJavaVM(); 3017bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom LOG(WARNING) << "CreateJavaVM failed"; 3018bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom return JNI_ERR; 3019bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom } 302069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom *p_env = Thread::Current()->GetJniEnv(); 302169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom *p_vm = runtime->GetJavaVM(); 302269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return JNI_OK; 30232ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 30242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3025f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughesextern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) { 30262ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro Runtime* runtime = Runtime::Current(); 30272ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro if (runtime == NULL) { 3028f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes *vm_count = 0; 30292ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } else { 3030f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes *vm_count = 1; 303169f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes vms[0] = runtime->GetJavaVM(); 30322ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30332ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_OK; 30342ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 30352ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 30362ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro// Historically unsupported. 30371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesextern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) { 30382ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_ERR; 30392ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro} 30402ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3041cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JII { 3042cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public: 3043cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint DestroyJavaVM(JavaVM* vm) { 3044cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (vm == NULL) { 3045cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 3046cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 30476a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 30486a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes delete raw_vm->runtime; 30496a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes return JNI_OK; 30502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30512ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3052cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 30537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JII_AttachCurrentThread(vm, p_env, thr_args, false); 30542ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30552ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3056cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) { 30577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes return JII_AttachCurrentThread(vm, p_env, thr_args, true); 30582ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30592ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3060cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint DetachCurrentThread(JavaVM* vm) { 30614d5714378c3433ba7e351cbf6a6713fb49c31784Brian Carlstrom if (vm == NULL || Thread::Current() == NULL) { 3062cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 3063cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 30646a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm); 30656a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes Runtime* runtime = raw_vm->runtime; 30666a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes runtime->DetachCurrentThread(); 30676a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes return JNI_OK; 30682ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 30692ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 3070cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes static jint GetEnv(JavaVM* vm, void** env, jint version) { 30713b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes // GetEnv always returns a JNIEnv* for the most current supported JNI version, 30723b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes // and unlike other calls that take a JNI version doesn't care if you supply 30733b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes // JNI_VERSION_1_1, which we don't otherwise support. 30743b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) { 307583a25328c595975097cf3948451088cbfc64fc09Elliott Hughes LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version; 3076cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_EVERSION; 3077cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3078cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (vm == NULL || env == NULL) { 3079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_ERR; 3080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3081cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes Thread* thread = Thread::Current(); 3082cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (thread == NULL) { 3083cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *env = NULL; 3084cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return JNI_EDETACHED; 3085cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3086cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes *env = thread->GetJniEnv(); 30872ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro return JNI_OK; 30882ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro } 3089cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}; 30902ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro 309188c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNIInvokeInterface gJniInvokeInterface = { 3092ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved0 3093ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved1 3094ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro NULL, // reserved2 3095cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::DestroyJavaVM, 3096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::AttachCurrentThread, 3097cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::DetachCurrentThread, 3098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::GetEnv, 3099cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes JII::AttachCurrentThreadAsDaemon 3100ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}; 3101ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro 3102a09576416788b916095739e43a16917e7948f3a4Elliott HughesJavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options) 310369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes : runtime(runtime), 3104a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes check_jni_abort_hook(NULL), 3105b264f081424642b06b0bbe7102781895d41faa9dElliott Hughes check_jni_abort_hook_data(NULL), 31064ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes check_jni(false), 31077934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom force_copy(false), // TODO: add a way to enable this 3108a09576416788b916095739e43a16917e7948f3a4Elliott Hughes trace(options->jni_trace_), 3109c2dc62d1c9241dfe880a81698713c314b13aa63fElliott Hughes work_around_app_jni_bugs(false), 311062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pins_lock("JNI pin table lock", kPinTableLock), 31112ced6a534157d5d963693346904389c19775d2daElliott Hughes pin_table("pin table", kPinTableInitial, kPinTableMax), 31128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes globals_lock("JNI global reference table lock"), 3113bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes globals(gGlobalsInitial, gGlobalsMax, kGlobal), 311400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers libraries_lock("JNI shared libraries map lock", kLoadLibraryLock), 3115c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier libraries(new Libraries), 3116c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_lock_("JNI weak global reference table lock"), 3117c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal), 3118c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier allow_new_weak_globals_(true), 3119c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) { 312088c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = unchecked_functions = &gJniInvokeInterface; 31214ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes if (options->check_jni_) { 312288c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes SetCheckJniEnabled(true); 3123a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes } 3124f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes} 3125f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes 3126de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott HughesJavaVMExt::~JavaVMExt() { 312779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes delete libraries; 3128de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes} 3129de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes 3130c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartierjweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) { 3131c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier if (obj == nullptr) { 3132c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier return nullptr; 3133c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier } 3134c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3135c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier while (UNLIKELY(!allow_new_weak_globals_)) { 3136c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_add_condition_.WaitHoldingLocks(self); 3137c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier } 3138c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj); 3139c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier return reinterpret_cast<jweak>(ref); 3140c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier} 3141c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier 3142c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) { 3143c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3144c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) { 3145c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") " 3146c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier << "failed to find entry"; 3147c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier } 3148c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier} 3149c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier 315088c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JavaVMExt::SetCheckJniEnabled(bool enabled) { 315188c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes check_jni = enabled; 315288c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface; 31534ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes} 31544ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes 3155ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughesvoid JavaVMExt::DumpForSigQuit(std::ostream& os) { 3156ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "JNI: CheckJNI is " << (check_jni ? "on" : "off"); 3157ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes if (force_copy) { 3158ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << " (with forcecopy)"; 3159ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3160ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off"); 316150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 3162ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 316350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 3164ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; pins=" << pin_table.Size(); 3165ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3166ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 3167b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers ReaderMutexLock mu(self, globals_lock); 3168ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "; globals=" << globals.Capacity(); 3169ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3170ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 3171c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3172c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier if (weak_globals_.Capacity() > 0) { 3173c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier os << " (plus " << weak_globals_.Capacity() << " weak)"; 3174ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3175ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3176ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << '\n'; 3177ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 3178ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes { 317950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 3180ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n"; 3181ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes } 3182ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes} 3183ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes 3184c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::DisallowNewWeakGlobals() { 3185c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(Thread::Current(), weak_globals_lock_); 3186c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier allow_new_weak_globals_ = false; 3187c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier} 3188c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier 3189c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::AllowNewWeakGlobals() { 3190c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier Thread* self = Thread::Current(); 3191c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3192c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier allow_new_weak_globals_ = true; 3193c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_add_condition_.Broadcast(self); 3194c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier} 3195c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier 3196c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiermirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) { 3197c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3198c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier while (UNLIKELY(!allow_new_weak_globals_)) { 3199c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_add_condition_.WaitHoldingLocks(self); 3200c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier } 3201c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier return const_cast<mirror::Object*>(weak_globals_.Get(ref)); 3202c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier} 3203c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier 320473e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JavaVMExt::DumpReferenceTables(std::ostream& os) { 320550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 32069d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 3207b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers ReaderMutexLock mu(self, globals_lock); 320873e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes globals.Dump(os); 32099d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 32109d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 3211c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier MutexLock mu(self, weak_globals_lock_); 3212c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier weak_globals_.Dump(os); 32139d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 32149d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes { 321550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 321673e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes pin_table.Dump(os); 32179d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes } 32189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes} 32199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes 3220055d46c479369ea825712834353660b45215c195Mathieu Chartierbool JavaVMExt::LoadNativeLibrary(const std::string& path, 3221055d46c479369ea825712834353660b45215c195Mathieu Chartier const SirtRef<ClassLoader>& class_loader, 32221eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers std::string* detail) { 32231eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers detail->clear(); 3224cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3225cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // See if we've already loaded this library. If we have, and the class loader 3226cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // matches, return successfully without doing anything. 32277577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // TODO: for better results we should canonicalize the pathname (or even compare 32287577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // inodes). This implementation is fine if everybody is using System.loadLibrary. 322979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes SharedLibrary* library; 323050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 323179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes { 323279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // TODO: move the locking (and more of this logic) into Libraries. 323350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 323479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes library = libraries->Get(path); 323579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 3236cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (library != NULL) { 3237055d46c479369ea825712834353660b45215c195Mathieu Chartier if (library->GetClassLoader() != class_loader.get()) { 32387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // The library will be associated with class_loader. The JNI 32397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // spec says we can't load the same library into more than one 32407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes // class loader. 32411eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers StringAppendF(detail, "Shared library \"%s\" already opened by " 32427577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes "ClassLoader %p; can't open in ClassLoader %p", 3243055d46c479369ea825712834353660b45215c195Mathieu Chartier path.c_str(), library->GetClassLoader(), class_loader.get()); 32447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes LOG(WARNING) << detail; 3245cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 3246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 32474dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Shared library \"" << path << "\" already loaded in " 3248055d46c479369ea825712834353660b45215c195Mathieu Chartier << "ClassLoader " << class_loader.get() << "]"; 32491bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes if (!library->CheckOnLoadResult()) { 32501eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers StringAppendF(detail, "JNI_OnLoad failed on a previous attempt " 32517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes "to load \"%s\"", path.c_str()); 3252cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 3253cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3254cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return true; 3255cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3256cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Open the shared library. Because we're using a full path, the system 3258cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // doesn't have to search through LD_LIBRARY_PATH. (It may do so to 3259cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // resolve this library's dependencies though.) 3260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3261cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Failures here are expected when java.library.path has several entries 3262cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // and we have to hunt for the lib. 3263cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 326400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Below we dlopen but there is no paired dlclose, this would be necessary if we supported 326500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // class unloading. Libraries will only be unloaded when the reference count (incremented by 326600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // dlopen) becomes zero from dlclose. 326700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 3268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // This can execute slowly for a large library on a busy system, so we 326900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // want to switch from kRunnable while it executes. This allows the GC to ignore us. 327000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad); 327100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY); 327200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->TransitionFromSuspendedToRunnable(); 3273cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 327484b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]"; 3275cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3276cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes if (handle == NULL) { 32771eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers *detail = dlerror(); 327884b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail; 3279cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes return false; 3280cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 3281cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3282cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes // Create a new entry. 328300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // TODO: move the locking (and more of this logic) into Libraries. 328400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers bool created_library = false; 328579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes { 328650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 328779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes library = libraries->Get(path); 328800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (library == NULL) { // We won race to get libraries_lock 3289055d46c479369ea825712834353660b45215c195Mathieu Chartier library = new SharedLibrary(path, handle, class_loader.get()); 329000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers libraries->Put(path, library); 329100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers created_library = true; 329279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 329300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 329400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (!created_library) { 329500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers LOG(INFO) << "WOW: we lost a race to add shared library: " 3296055d46c479369ea825712834353660b45215c195Mathieu Chartier << "\"" << path << "\" ClassLoader=" << class_loader.get(); 329700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return library->CheckOnLoadResult(); 329879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 3299cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 3300055d46c479369ea825712834353660b45215c195Mathieu Chartier VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader.get() 3301055d46c479369ea825712834353660b45215c195Mathieu Chartier << "]"; 3302cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 33037935372ab784477db452d11112cd60d26be87093Elliott Hughes bool was_successful = false; 330479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes void* sym = dlsym(handle, "JNI_OnLoad"); 330579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (sym == NULL) { 33064dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]"; 330785affca81271f573c75c32316aa6faa8e52448b1Elliott Hughes was_successful = true; 330879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } else { 330979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // Call JNI_OnLoad. We have to override the current class 331079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // loader, which will always be "null" since the stuff at the 331179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // top of the stack is around Runtime.loadLibrary(). (See 331279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // the comments in the JNI FindClass function.) 331379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes typedef int (*JNI_OnLoadFn)(JavaVM*, void*); 331479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym); 3315590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier SirtRef<ClassLoader> old_class_loader(self, self->GetClassLoaderOverride()); 3316055d46c479369ea825712834353660b45215c195Mathieu Chartier self->SetClassLoaderOverride(class_loader.get()); 331779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3318ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes int version = 0; 3319ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes { 332034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes ScopedThreadStateChange tsc(self, kNative); 33214dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]"; 3322ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes version = (*jni_on_load)(this, NULL); 332379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 332479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3325590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier self->SetClassLoaderOverride(old_class_loader.get()); 332679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 33277935372ab784477db452d11112cd60d26be87093Elliott Hughes if (version == JNI_ERR) { 33281eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers StringAppendF(detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str()); 33297935372ab784477db452d11112cd60d26be87093Elliott Hughes } else if (IsBadJniVersion(version)) { 33301eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers StringAppendF(detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d", 333175fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom path.c_str(), version); 333279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // It's unwise to call dlclose() here, but we can mark it 333379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // as bad and ensure that future load attempts will fail. 333479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // We don't know how far JNI_OnLoad got, so there could 333579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // be some partially-initialized stuff accessible through 333679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // newly-registered native method calls. We could try to 333779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // unregister them, but that doesn't seem worthwhile. 33387935372ab784477db452d11112cd60d26be87093Elliott Hughes } else { 33397935372ab784477db452d11112cd60d26be87093Elliott Hughes was_successful = true; 3340cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 33417935372ab784477db452d11112cd60d26be87093Elliott Hughes VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure") 334275fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom << " from JNI_OnLoad in \"" << path << "\"]"; 334379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 3344cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 33457935372ab784477db452d11112cd60d26be87093Elliott Hughes library->SetResult(was_successful); 33467935372ab784477db452d11112cd60d26be87093Elliott Hughes return was_successful; 334779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes} 334879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3349ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) { 335079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes CHECK(m->IsNative()); 335179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 335279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes Class* c = m->GetDeclaringClass(); 335379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 335479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // If this is a static method, it could be called before the class 335579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes // has been initialized. 335679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes if (m->IsStatic()) { 3357c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier c = EnsureInitialized(Thread::Current(), c); 3358c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (c == nullptr) { 3359c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 336079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } 336179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes } else { 3362b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m); 3363cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes } 336479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes 3365161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom std::string detail; 3366161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom void* native_method; 336750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 3368161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom { 336950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, libraries_lock); 3370161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom native_method = libraries->FindNativeMethod(m, detail); 3371161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 337262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Throwing can cause libraries_lock to be reacquired. 3373161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom if (native_method == NULL) { 337462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 337562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str()); 3376161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 3377161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom return native_method; 3378cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes} 3379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes 33806aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartiervoid JavaVMExt::SweepJniWeakGlobals(RootVisitor visitor, void* arg) { 3381810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier MutexLock mu(Thread::Current(), weak_globals_lock_); 3382810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier for (mirror::Object** entry : weak_globals_) { 33836aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier mirror::Object* obj = *entry; 33846aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier mirror::Object* new_obj = visitor(obj, arg); 33856aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier if (new_obj == nullptr) { 33866aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier new_obj = kClearedJniWeakGlobal; 33876aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier } 33886aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier *entry = new_obj; 33896aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier } 33906aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier} 33916aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier 33922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersvoid JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) { 339350b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers Thread* self = Thread::Current(); 3394410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes { 3395b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers ReaderMutexLock mu(self, globals_lock); 3396410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes globals.VisitRoots(visitor, arg); 3397410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes } 3398410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes { 339950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(self, pins_lock); 3400410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes pin_table.VisitRoots(visitor, arg); 3401410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes } 34028f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier { 34038f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier MutexLock mu(self, libraries_lock); 34048f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier // Libraries contains shared libraries which hold a pointer to a class loader. 34058f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier libraries->VisitRoots(visitor, arg); 34068f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier } 3407410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes // The weak_globals table is visited by the GC itself (because it mutates the table). 3408410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes} 3409410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes 3410c8fece309fa1d3514071fadaca34530648462b50Elliott Hughesvoid RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods, 3411bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers jint method_count) { 3412c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name)); 3413c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes if (c.get() == NULL) { 3414c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes LOG(FATAL) << "Couldn't find class: " << jni_class_name; 3415c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes } 3416c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false); 3417c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes} 3418c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes 3419df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers} // namespace art 3420b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes 3421b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) { 3422b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes switch (rhs) { 3423b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIInvalidRefType: 3424b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIInvalidRefType"; 3425b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 3426b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNILocalRefType: 3427b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNILocalRefType"; 3428b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 3429b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIGlobalRefType: 3430b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIGlobalRefType"; 3431b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 3432b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes case JNIWeakGlobalRefType: 3433b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes os << "JNIWeakGlobalRefType"; 3434b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes return os; 34352e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom default: 343624782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]"; 34372e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom return os; 3438b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes } 3439b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes} 3440