1418d20fc407052d4152157f61e7453359f902383Elliott Hughes/* 2418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Copyright (C) 2011 The Android Open Source Project 3418d20fc407052d4152157f61e7453359f902383Elliott Hughes * 4418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5418d20fc407052d4152157f61e7453359f902383Elliott Hughes * you may not use this file except in compliance with the License. 6418d20fc407052d4152157f61e7453359f902383Elliott Hughes * You may obtain a copy of the License at 7418d20fc407052d4152157f61e7453359f902383Elliott Hughes * 8418d20fc407052d4152157f61e7453359f902383Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9418d20fc407052d4152157f61e7453359f902383Elliott Hughes * 10418d20fc407052d4152157f61e7453359f902383Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11418d20fc407052d4152157f61e7453359f902383Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12418d20fc407052d4152157f61e7453359f902383Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13418d20fc407052d4152157f61e7453359f902383Elliott Hughes * See the License for the specific language governing permissions and 14418d20fc407052d4152157f61e7453359f902383Elliott Hughes * limitations under the License. 15418d20fc407052d4152157f61e7453359f902383Elliott Hughes */ 16418d20fc407052d4152157f61e7453359f902383Elliott Hughes 1776433275dbe39e5ced1c223b006d1b900b1937f6Mathieu Chartier#include "reflection-inl.h" 18418d20fc407052d4152157f61e7453359f902383Elliott Hughes 19c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 20e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 21418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "class_linker.h" 2262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 234f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 2439b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao#include "indirect_reference_table-inl.h" 25418d20fc407052d4152157f61e7453359f902383Elliott Hughes#include "jni_internal.h" 26fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier#include "mirror/abstract_method.h" 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h" 2911d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao#include "nth_caller_visitor.h" 3000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 3153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#include "stack.h" 3200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h" 33418d20fc407052d4152157f61e7453359f902383Elliott Hughes 34418d20fc407052d4152157f61e7453359f902383Elliott Hughesnamespace art { 35418d20fc407052d4152157f61e7453359f902383Elliott Hughes 3653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogersclass ArgArray { 3753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers public: 383887c468d731420e929e6ad3acf190d5431e94fcRoland Levillain ArgArray(const char* shorty, uint32_t shorty_len) 3953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers : shorty_(shorty), shorty_len_(shorty_len), num_bytes_(0) { 4053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers size_t num_slots = shorty_len + 1; // +1 in case of receiver. 4153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (LIKELY((num_slots * 2) < kSmallArgArraySize)) { 4253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // We can trivially use the small arg array. 4353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_ = small_arg_array_; 4453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else { 4553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Analyze shorty to see if we need the large arg array. 4653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (size_t i = 1; i < shorty_len; ++i) { 4753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers char c = shorty[i]; 4853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (c == 'J' || c == 'D') { 4953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers num_slots++; 5053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 5153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 5253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (num_slots <= kSmallArgArraySize) { 5353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_ = small_arg_array_; 5453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else { 5553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers large_arg_array_.reset(new uint32_t[num_slots]); 5653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_ = large_arg_array_.get(); 5753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 5853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 5953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 6053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 6153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t* GetArray() { 6253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return arg_array_; 6353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 6453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 6553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t GetNumBytes() { 6653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return num_bytes_; 6753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 6853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 6953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers void Append(uint32_t value) { 7053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_[num_bytes_ / 4] = value; 7153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers num_bytes_ += 4; 7253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 7353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 7490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void Append(mirror::Object* obj) SHARED_REQUIRES(Locks::mutator_lock_) { 7553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(StackReference<mirror::Object>::FromMirrorPtr(obj).AsVRegValue()); 7653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 7753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 7853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers void AppendWide(uint64_t value) { 7953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_[num_bytes_ / 4] = value; 8053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers arg_array_[(num_bytes_ / 4) + 1] = value >> 32; 8153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers num_bytes_ += 8; 8253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 8353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 8453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers void AppendFloat(float value) { 8553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jvalue jv; 8653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jv.f = value; 8753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(jv.i); 8853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 8953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 9053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers void AppendDouble(double value) { 9153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jvalue jv; 9253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jv.d = value; 9353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendWide(jv.j); 9453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 9553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 962b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier void BuildArgArrayFromVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 972b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier mirror::Object* receiver, va_list ap) 9890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 9953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Set receiver if non-null (method is not static) 10053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (receiver != nullptr) { 10153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(receiver); 10253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 10353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (size_t i = 1; i < shorty_len_; ++i) { 10453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers switch (shorty_[i]) { 10553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'Z': 10653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'B': 10753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'C': 10853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'S': 10953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'I': 11053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(va_arg(ap, jint)); 11153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 11253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'F': 11353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendFloat(va_arg(ap, jdouble)); 11453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 11553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'L': 11653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(soa.Decode<mirror::Object*>(va_arg(ap, jobject))); 11753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 11853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'D': 11953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendDouble(va_arg(ap, jdouble)); 12053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 12153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'J': 12253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendWide(va_arg(ap, jlong)); 12353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 12453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#ifndef NDEBUG 12553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers default: 12653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 12753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#endif 12853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 12953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 13053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 13153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 1322b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier void BuildArgArrayFromJValues(const ScopedObjectAccessAlreadyRunnable& soa, 1332b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier mirror::Object* receiver, jvalue* args) 13490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 13553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Set receiver if non-null (method is not static) 13653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (receiver != nullptr) { 13753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(receiver); 13853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 13953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 14053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers switch (shorty_[i]) { 14153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'Z': 14253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(args[args_offset].z); 14353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 14453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'B': 14553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(args[args_offset].b); 14653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 14753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'C': 14853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(args[args_offset].c); 14953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 15053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'S': 15153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(args[args_offset].s); 15253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 15353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'I': 15453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'F': 15553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(args[args_offset].i); 15653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 15753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'L': 15853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(soa.Decode<mirror::Object*>(args[args_offset].l)); 15953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 16053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'D': 16153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'J': 16253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendWide(args[args_offset].j); 16353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 16453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#ifndef NDEBUG 16553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers default: 16653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 16753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#endif 16853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 16953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 17053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 17153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 17253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers void BuildArgArrayFromFrame(ShadowFrame* shadow_frame, uint32_t arg_offset) 17390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 17453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Set receiver if non-null (method is not static) 17553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers size_t cur_arg = arg_offset; 17653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (!shadow_frame->GetMethod()->IsStatic()) { 17753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(shadow_frame->GetVReg(cur_arg)); 17853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers cur_arg++; 17953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 18053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (size_t i = 1; i < shorty_len_; ++i) { 18153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers switch (shorty_[i]) { 18253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'Z': 18353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'B': 18453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'C': 18553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'S': 18653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'I': 18753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'F': 18853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'L': 18953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(shadow_frame->GetVReg(cur_arg)); 19053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers cur_arg++; 19153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 19253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'D': 19353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'J': 19453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers AppendWide(shadow_frame->GetVRegLong(cur_arg)); 19553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers cur_arg++; 19653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers cur_arg++; 19753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 19853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#ifndef NDEBUG 19953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers default: 20053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 20153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#endif 20253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 20353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 20453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 20553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 20653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers static void ThrowIllegalPrimitiveArgumentException(const char* expected, 2071ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers const char* found_descriptor) 20890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 2090aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException( 21053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers StringPrintf("Invalid primitive conversion from %s to %s", expected, 2111ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers PrettyDescriptor(found_descriptor).c_str()).c_str()); 21253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 21353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 2146a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers bool BuildArgArrayFromObjectArray(mirror::Object* receiver, 215e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier mirror::ObjectArray<mirror::Object>* args, ArtMethod* m) 21690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 217e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile::TypeList* classes = m->GetParameterTypeList(); 21853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Set receiver if non-null (method is not static) 21953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (receiver != nullptr) { 22053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(receiver); 22153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 22253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 22353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers mirror::Object* arg = args->Get(args_offset); 22453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (((shorty_[i] == 'L') && (arg != nullptr)) || ((arg == nullptr && shorty_[i] != 'L'))) { 22505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 22653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers mirror::Class* dst_class = 22705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko m->GetClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_, 22805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko true /* resolve */, 22905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko pointer_size); 23053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) { 2310aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException( 23211e4c038c5e319ee7dd423ff47ef9411920d198eIan Rogers StringPrintf("method %s argument %zd has type %s, got %s", 233e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier PrettyMethod(m, false).c_str(), 23453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers args_offset + 1, // Humans don't count from 0. 23553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers PrettyDescriptor(dst_class).c_str(), 23653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers PrettyTypeOf(arg).c_str()).c_str()); 23753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return false; 23853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 23953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 24053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 24153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#define DO_FIRST_ARG(match_descriptor, get_fn, append) { \ 242f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier if (LIKELY(arg != nullptr && arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ 243c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 24453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers append(primitive_field-> get_fn(arg)); 24553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 24653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#define DO_ARG(match_descriptor, get_fn, append) \ 247f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (LIKELY(arg != nullptr && \ 248f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ 249c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 25053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers append(primitive_field-> get_fn(arg)); 25153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 25253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#define DO_FAIL(expected) \ 25353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else { \ 25453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (arg->GetClass<>()->IsPrimitive()) { \ 2551ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers std::string temp; \ 256f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier ThrowIllegalPrimitiveArgumentException(expected, \ 2571ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers arg->GetClass<>()->GetDescriptor(&temp)); \ 25853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else { \ 2590aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException(\ 26011e4c038c5e319ee7dd423ff47ef9411920d198eIan Rogers StringPrintf("method %s argument %zd has type %s, got %s", \ 261e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier PrettyMethod(m, false).c_str(), \ 26253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers args_offset + 1, \ 26353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers expected, \ 26453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers PrettyTypeOf(arg).c_str()).c_str()); \ 26553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } \ 26653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return false; \ 26753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } } 26853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 26953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers switch (shorty_[i]) { 27053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'L': 27153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers Append(arg); 27253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 27353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'Z': 27453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append) 27553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("boolean") 27653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 27753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'B': 27853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Byte;", GetByte, Append) 27953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("byte") 28053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 28153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'C': 28253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Character;", GetChar, Append) 28353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("char") 28453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 28553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'S': 28653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Short;", GetShort, Append) 28753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Byte;", GetByte, Append) 28853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("short") 28953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 29053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'I': 29153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Integer;", GetInt, Append) 29253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Character;", GetChar, Append) 29353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Short;", GetShort, Append) 29453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Byte;", GetByte, Append) 29553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("int") 29653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 29753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'J': 29853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Long;", GetLong, AppendWide) 29953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Integer;", GetInt, AppendWide) 30053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Character;", GetChar, AppendWide) 30153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Short;", GetShort, AppendWide) 30253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Byte;", GetByte, AppendWide) 30353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("long") 30453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 30553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'F': 30653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Float;", GetFloat, AppendFloat) 30753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Long;", GetLong, AppendFloat) 30853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Integer;", GetInt, AppendFloat) 30953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Character;", GetChar, AppendFloat) 31053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Short;", GetShort, AppendFloat) 31153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Byte;", GetByte, AppendFloat) 31253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("float") 31353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 31453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers case 'D': 31553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FIRST_ARG("Ljava/lang/Double;", GetDouble, AppendDouble) 31653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Float;", GetFloat, AppendDouble) 31753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Long;", GetLong, AppendDouble) 31853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Integer;", GetInt, AppendDouble) 31953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Character;", GetChar, AppendDouble) 32053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Short;", GetShort, AppendDouble) 32153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_ARG("Ljava/lang/Byte;", GetByte, AppendDouble) 32253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DO_FAIL("double") 32353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers break; 32453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#ifndef NDEBUG 32553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers default: 32653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 327a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers UNREACHABLE(); 32853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#endif 32953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 33053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#undef DO_FIRST_ARG 33153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#undef DO_ARG 33253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#undef DO_FAIL 33353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 33453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return true; 33553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 33653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 33753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers private: 33853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers enum { kSmallArgArraySize = 16 }; 33953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers const char* const shorty_; 34053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers const uint32_t shorty_len_; 34153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t num_bytes_; 34253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t* arg_array_; 34353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t small_arg_array_[kSmallArgArraySize]; 344700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<uint32_t[]> large_arg_array_; 34553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers}; 34653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 347e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierstatic void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args) 34890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 349bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::TypeList* params = m->GetParameterTypeList(); 35053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (params == nullptr) { 35153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return; // No arguments so nothing to check. 35253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 35353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t offset = 0; 35453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t num_params = params->Size(); 35553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers size_t error_count = 0; 35653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (!m->IsStatic()) { 35753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers offset = 1; 35853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 359a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers // TODO: If args contain object references, it may cause problems. 360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier Thread* const self = Thread::Current(); 36105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); 36253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers for (uint32_t i = 0; i < num_params; i++) { 36353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint16_t type_idx = params->GetTypeItem(i).type_idx_; 36405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::Class* param_type = m->GetClassFromTypeIndex(type_idx, 36505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko true /* resolve*/, 36605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko pointer_size); 36753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (param_type == nullptr) { 36853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers CHECK(self->IsExceptionPending()); 36953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " 370e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << m->GetTypeDescriptorFromTypeIdx(type_idx) << "\n" 37114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray << self->GetException()->Dump(); 37253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers self->ClearException(); 37353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ++error_count; 37453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else if (!param_type->IsPrimitive()) { 375bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier // TODO: There is a compaction bug here since GetClassFromTypeIdx can cause thread suspension, 376bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier // this is a hard to fix problem since the args can contain Object*, we need to save and 377bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier // restore them by using a visitor similar to the ones used in the trampoline entrypoints. 37868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers mirror::Object* argument = 37968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers (reinterpret_cast<StackReference<mirror::Object>*>(&args[i + offset]))->AsMirrorPtr(); 38053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (argument != nullptr && !argument->InstanceOf(param_type)) { 38153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of " 38253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers << PrettyTypeOf(argument) << " as argument " << (i + 1) 383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << " to " << PrettyMethod(m); 38453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ++error_count; 38553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 38653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) { 38753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers offset++; 38868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } else { 38968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers int32_t arg = static_cast<int32_t>(args[i + offset]); 39068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (param_type->IsPrimitiveBoolean()) { 39168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (arg != JNI_TRUE && arg != JNI_FALSE) { 39268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers LOG(ERROR) << "JNI ERROR (app bug): expected jboolean (0/1) but got value of " 393e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m); 39468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ++error_count; 39568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 39668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } else if (param_type->IsPrimitiveByte()) { 39768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (arg < -128 || arg > 127) { 39868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers LOG(ERROR) << "JNI ERROR (app bug): expected jbyte but got value of " 399e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m); 40068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ++error_count; 40168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 40268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } else if (param_type->IsPrimitiveChar()) { 40368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (args[i + offset] > 0xFFFF) { 40468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers LOG(ERROR) << "JNI ERROR (app bug): expected jchar but got value of " 405e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m); 40668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ++error_count; 40768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 40868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } else if (param_type->IsPrimitiveShort()) { 40968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (arg < -32768 || arg > 0x7FFF) { 41068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers LOG(ERROR) << "JNI ERROR (app bug): expected jshort but got value of " 411e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m); 41268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ++error_count; 41368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 41468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 41553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 41653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 41768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers if (UNLIKELY(error_count > 0)) { 41853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort 41953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // with an argument. 42068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers vm->JniAbortF(nullptr, "bad arguments passed to %s (see above for details)", 421e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier PrettyMethod(m).c_str()); 42253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 42353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 42453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 425e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierstatic ArtMethod* FindVirtualMethod(mirror::Object* receiver, ArtMethod* method) 42690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 427e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method, sizeof(void*)); 42853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 42953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 43053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 4312b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartierstatic void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa, 432e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, ArgArray* arg_array, JValue* result, 4332b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier const char* shorty) 43490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 43553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t* args = arg_array->GetArray(); 43653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (UNLIKELY(soa.Env()->check_jni)) { 437e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier CheckMethodArguments(soa.Vm(), method->GetInterfaceMethodIfProxy(sizeof(void*)), args); 43853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 43953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty); 44053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 44153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 4422b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierJValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid, 4432b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier va_list args) 44490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 445648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // We want to make sure that the stack is not within a small distance from the 446648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // protected region in case we are calling into a leaf function whose stack 447648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // check has been elided. 448648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 449648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ThrowStackOverflowError(soa.Self()); 450648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return JValue(); 451648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 452648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 453e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = soa.DecodeMethod(mid); 45439b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 45539b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 45639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // Replace calls to String.<init> with equivalent StringFactory call. 45739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid)); 45839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 45953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); 460bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 461e80673245c0433a71a4930e460be5dc0920885b2Andreas Gampe const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); 46253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers JValue result; 463bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier ArgArray arg_array(shorty, shorty_len); 464e18fdd2f0e57873c22113975739139abe7418e09Ian Rogers arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 465bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 46639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 46739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // For string init, remap original receiver to StringFactory result. 46883c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao UpdateReference(soa.Self(), obj, result.GetL()); 46939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 47053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return result; 47153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 47253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 47339b6c24ce68cf05db0f82f454b4401cfb03d675fJeff HaoJValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid, 47439b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao jvalue* args) { 475648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // We want to make sure that the stack is not within a small distance from the 476648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // protected region in case we are calling into a leaf function whose stack 477648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // check has been elided. 478648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 479648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ThrowStackOverflowError(soa.Self()); 480648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return JValue(); 481648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 482648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 483e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = soa.DecodeMethod(mid); 48439b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 48539b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 48639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // Replace calls to String.<init> with equivalent StringFactory call. 48739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid)); 48839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 48939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); 490bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 491e80673245c0433a71a4930e460be5dc0920885b2Andreas Gampe const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); 49253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers JValue result; 493bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier ArgArray arg_array(shorty, shorty_len); 494e18fdd2f0e57873c22113975739139abe7418e09Ian Rogers arg_array.BuildArgArrayFromJValues(soa, receiver, args); 495bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 49639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 49739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // For string init, remap original receiver to StringFactory result. 49883c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao UpdateReference(soa.Self(), obj, result.GetL()); 49939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 50053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return result; 50153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 50253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 5032b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierJValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, 50439b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao jobject obj, jmethodID mid, jvalue* args) { 505648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // We want to make sure that the stack is not within a small distance from the 506648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // protected region in case we are calling into a leaf function whose stack 507648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // check has been elided. 508648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 509648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ThrowStackOverflowError(soa.Self()); 510648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return JValue(); 511648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 512648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 51339b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao mirror::Object* receiver = soa.Decode<mirror::Object*>(obj); 514e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 51539b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 51639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 51739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // Replace calls to String.<init> with equivalent StringFactory call. 51839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid)); 51939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao receiver = nullptr; 52039b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 521bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 522e80673245c0433a71a4930e460be5dc0920885b2Andreas Gampe const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); 52353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers JValue result; 524bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier ArgArray arg_array(shorty, shorty_len); 525e18fdd2f0e57873c22113975739139abe7418e09Ian Rogers arg_array.BuildArgArrayFromJValues(soa, receiver, args); 526bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 52739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 52839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // For string init, remap original receiver to StringFactory result. 52983c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao UpdateReference(soa.Self(), obj, result.GetL()); 53039b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 53153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return result; 53253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 53353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 5342b7c4d196c8abe32f4ca633534917da9de53c359Mathieu ChartierJValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 53553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers jobject obj, jmethodID mid, va_list args) { 536648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // We want to make sure that the stack is not within a small distance from the 537648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // protected region in case we are calling into a leaf function whose stack 538648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // check has been elided. 539648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 540648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ThrowStackOverflowError(soa.Self()); 541648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return JValue(); 542648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 543648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 54453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers mirror::Object* receiver = soa.Decode<mirror::Object*>(obj); 545e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 54639b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); 54739b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 54839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // Replace calls to String.<init> with equivalent StringFactory call. 54939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid)); 55039b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao receiver = nullptr; 55139b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 552bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 553e80673245c0433a71a4930e460be5dc0920885b2Andreas Gampe const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); 55453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers JValue result; 555bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier ArgArray arg_array(shorty, shorty_len); 556e18fdd2f0e57873c22113975739139abe7418e09Ian Rogers arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 557bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 55839b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao if (is_string_init) { 55939b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao // For string init, remap original receiver to StringFactory result. 56083c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao UpdateReference(soa.Self(), obj, result.GetL()); 56139b6c24ce68cf05db0f82f454b4401cfb03d675fJeff Hao } 56253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return result; 56353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers} 56453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers 5652b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartierjobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod, 566fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier jobject javaReceiver, jobject javaArgs, size_t num_frames) { 567648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // We want to make sure that the stack is not within a small distance from the 568648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // protected region in case we are calling into a leaf function whose stack 569648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // check has been elided. 570648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (UNLIKELY(__builtin_frame_address(0) < 571648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison soa.Self()->GetStackEndForInterpreter(true))) { 572648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ThrowStackOverflowError(soa.Self()); 573648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return nullptr; 574648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 575648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 576fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier auto* abstract_method = soa.Decode<mirror::AbstractMethod*>(javaMethod); 577fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier const bool accessible = abstract_method->IsAccessible(); 578e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* m = abstract_method->GetArtMethod(); 5792a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 5802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* declaring_class = m->GetDeclaringClass(); 581c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (UNLIKELY(!declaring_class->IsInitialized())) { 582eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(soa.Self()); 583eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> h_class(hs.NewHandle(declaring_class)); 5847b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) { 585c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier return nullptr; 586c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier } 587eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier declaring_class = h_class.Get(); 5882a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes } 5892a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 59053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers mirror::Object* receiver = nullptr; 5912a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes if (!m->IsStatic()) { 592848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Replace calls to String.<init> with equivalent StringFactory call. 593848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (declaring_class->IsStringClass() && m->IsConstructor()) { 594848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao jmethodID mid = soa.EncodeMethod(m); 595848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao m = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid)); 596848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao CHECK(javaReceiver == nullptr); 597848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else { 598848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Check that the receiver is non-null and an instance of the field's declaring class. 599848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao receiver = soa.Decode<mirror::Object*>(javaReceiver); 600848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (!VerifyObjectIsClass(receiver, declaring_class)) { 601848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return nullptr; 602848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 6032a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 604848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Find the actual implementation of the virtual method. 605e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m, sizeof(void*)); 606848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 6072a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes } 6082a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 6092a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes // Get our arrays of arguments and their types, and check they're the same size. 610fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier auto* objects = soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs); 611e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* np_method = m->GetInterfaceMethodIfProxy(sizeof(void*)); 612e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const DexFile::TypeList* classes = np_method->GetParameterTypeList(); 61353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size(); 61453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers uint32_t arg_count = (objects != nullptr) ? objects->GetLength() : 0; 6156d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers if (arg_count != classes_size) { 6160aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException(StringPrintf("Wrong number of arguments; expected %d, got %d", 61762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers classes_size, arg_count).c_str()); 618a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers return nullptr; 6192a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes } 6202a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 621cb4581aa13d6f43f705535818a4d0893d551be3aJeff Hao // If method is not set to be accessible, verify it can be accessed by the caller. 622c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe mirror::Class* calling_class = nullptr; 623c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags(), 624fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier &calling_class, num_frames)) { 6250aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalAccessException( 626c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe StringPrintf("Class %s cannot access %s method %s of class %s", 627c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(), 628c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe PrettyJavaAccessFlags(m->GetAccessFlags()).c_str(), 629c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe PrettyMethod(m).c_str(), 630c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe m->GetDeclaringClass() == nullptr ? "null" : 631c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe PrettyClass(m->GetDeclaringClass()).c_str()).c_str()); 63211d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao return nullptr; 63311d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao } 63411d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao 63553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // Invoke the method. 63653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers JValue result; 637bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 638e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier const char* shorty = np_method->GetShorty(&shorty_len); 639bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier ArgArray arg_array(shorty, shorty_len); 640e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method)) { 64153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers CHECK(soa.Self()->IsExceptionPending()); 64253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return nullptr; 6432a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes } 6442a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 645bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier InvokeWithArgArray(soa, m, &arg_array, &result, shorty); 6462a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 6472a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early. 64800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (soa.Self()->IsExceptionPending()) { 649a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier // If we get another exception when we are trying to wrap, then just use that instead. 65000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jthrowable th = soa.Env()->ExceptionOccurred(); 651a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier soa.Self()->ClearException(); 65200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jclass exception_class = soa.Env()->FindClass("java/lang/reflect/InvocationTargetException"); 653a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (exception_class == nullptr) { 654a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier soa.Self()->AssertPendingOOMException(); 655a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier return nullptr; 656a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 65700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jmethodID mid = soa.Env()->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V"); 658a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier CHECK(mid != nullptr); 65900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers jobject exception_instance = soa.Env()->NewObject(exception_class, mid, th); 660a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (exception_instance == nullptr) { 661a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier soa.Self()->AssertPendingOOMException(); 662a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier return nullptr; 663a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier } 66400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers soa.Env()->Throw(reinterpret_cast<jthrowable>(exception_instance)); 665a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers return nullptr; 6662a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes } 6672a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 6682a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes // Box if necessary and return. 669a0485607a4a4d8c683a9849f6f20902c4e1da7a4Ian Rogers return soa.AddLocalReference<jobject>(BoxPrimitive(Primitive::GetType(shorty[0]), result)); 6702a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes} 6712a20cfd0b7fc81099f5de0da782ebcc1cb262792Elliott Hughes 6722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersmirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) { 6736b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom if (src_class == Primitive::kPrimNot) { 674af6e67a4816d2593586115b89faa659225363246Ian Rogers return value.GetL(); 675418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 67653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers if (src_class == Primitive::kPrimVoid) { 67753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers // There's no such thing as a void field, and void methods invoked via reflection return null. 67853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers return nullptr; 67953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers } 680418d20fc407052d4152157f61e7453359f902383Elliott Hughes 68184956ff6c0ff150d86a08157216ded79217d860aIan Rogers jmethodID m = nullptr; 6820177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers const char* shorty; 6836b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom switch (src_class) { 6846b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimBoolean: 68500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Boolean_valueOf; 6860177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LZ"; 687418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 6886b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimByte: 68900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Byte_valueOf; 6900177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LB"; 691418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 6926b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimChar: 69300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Character_valueOf; 6940177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LC"; 695418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 6966b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimDouble: 69700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Double_valueOf; 6980177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LD"; 699418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 7006b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimFloat: 70100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Float_valueOf; 7020177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LF"; 703418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 7046b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimInt: 70500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Integer_valueOf; 7060177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LI"; 707418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 7086b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimLong: 70900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Long_valueOf; 7100177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LJ"; 711418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 7126b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom case Primitive::kPrimShort: 71300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers m = WellKnownClasses::java_lang_Short_valueOf; 7140177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = "LS"; 715418d20fc407052d4152157f61e7453359f902383Elliott Hughes break; 716418d20fc407052d4152157f61e7453359f902383Elliott Hughes default: 7176b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom LOG(FATAL) << static_cast<int>(src_class); 7180177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers shorty = nullptr; 719418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 720418d20fc407052d4152157f61e7453359f902383Elliott Hughes 72150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers ScopedObjectAccessUnchecked soa(Thread::Current()); 72253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers DCHECK_EQ(soa.Self()->GetState(), kRunnable); 7235d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 72453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers ArgArray arg_array(shorty, 2); 725af6e67a4816d2593586115b89faa659225363246Ian Rogers JValue result; 7265d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao if (src_class == Primitive::kPrimDouble || src_class == Primitive::kPrimLong) { 7275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.AppendWide(value.GetJ()); 7285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } else { 7295d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_array.Append(value.GetI()); 7305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 7315d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 7325d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.DecodeMethod(m)->Invoke(soa.Self(), arg_array.GetArray(), arg_array.GetNumBytes(), 7330177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers &result, shorty); 734af6e67a4816d2593586115b89faa659225363246Ian Rogers return result.GetL(); 735418d20fc407052d4152157f61e7453359f902383Elliott Hughes} 736418d20fc407052d4152157f61e7453359f902383Elliott Hughes 737c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierstatic std::string UnboxingFailureKind(ArtField* f) 73890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 73984956ff6c0ff150d86a08157216ded79217d860aIan Rogers if (f != nullptr) { 740aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes return "field " + PrettyField(f, false); 741aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes } 742aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes return "result"; 743aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes} 744aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes 7450aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffraystatic bool UnboxPrimitive(mirror::Object* o, 746c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier mirror::Class* dst_class, ArtField* f, 74784956ff6c0ff150d86a08157216ded79217d860aIan Rogers JValue* unboxed_value) 74890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 74984956ff6c0ff150d86a08157216ded79217d860aIan Rogers bool unbox_for_result = (f == nullptr); 7506b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom if (!dst_class->IsPrimitive()) { 75184956ff6c0ff150d86a08157216ded79217d860aIan Rogers if (UNLIKELY(o != nullptr && !o->InstanceOf(dst_class))) { 75262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!unbox_for_result) { 7530aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException(StringPrintf("%s has type %s, got %s", 75484956ff6c0ff150d86a08157216ded79217d860aIan Rogers UnboxingFailureKind(f).c_str(), 75562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(dst_class).c_str(), 75662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyTypeOf(o).c_str()).c_str()); 75762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 7580aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s", 75962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyTypeOf(o).c_str(), 760df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom PrettyDescriptor(dst_class).c_str()).c_str()); 76162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 762418d20fc407052d4152157f61e7453359f902383Elliott Hughes return false; 763418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 76484956ff6c0ff150d86a08157216ded79217d860aIan Rogers unboxed_value->SetL(o); 765418d20fc407052d4152157f61e7453359f902383Elliott Hughes return true; 76662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 76762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (UNLIKELY(dst_class->GetPrimitiveType() == Primitive::kPrimVoid)) { 7680aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException(StringPrintf("Can't unbox %s to void", 76984956ff6c0ff150d86a08157216ded79217d860aIan Rogers UnboxingFailureKind(f).c_str()).c_str()); 770418d20fc407052d4152157f61e7453359f902383Elliott Hughes return false; 771418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 77284956ff6c0ff150d86a08157216ded79217d860aIan Rogers if (UNLIKELY(o == nullptr)) { 77362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (!unbox_for_result) { 7740aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException(StringPrintf("%s has type %s, got null", 77584956ff6c0ff150d86a08157216ded79217d860aIan Rogers UnboxingFailureKind(f).c_str(), 77662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(dst_class).c_str()).c_str()); 77762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 7780aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException(StringPrintf("Expected to unbox a '%s' primitive type but was returned null", 77962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PrettyDescriptor(dst_class).c_str()).c_str()); 78062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 781418d20fc407052d4152157f61e7453359f902383Elliott Hughes return false; 782418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 783418d20fc407052d4152157f61e7453359f902383Elliott Hughes 7841d878f3e1c39162496d7c061f7f6710e414d182bElliott Hughes JValue boxed_value; 785f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier mirror::Class* klass = o->GetClass(); 78684956ff6c0ff150d86a08157216ded79217d860aIan Rogers mirror::Class* src_class = nullptr; 787c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 78854d220eb9cc51215d75b9e0fe921b94bebbb3fd6Mathieu Chartier ArtField* primitive_field = &klass->GetIFieldsPtr()->At(0); 789f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier if (klass->DescriptorEquals("Ljava/lang/Boolean;")) { 790418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('Z'); 791f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetZ(primitive_field->GetBoolean(o)); 792f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Byte;")) { 793418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('B'); 794f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetB(primitive_field->GetByte(o)); 795f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Character;")) { 796418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('C'); 797f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetC(primitive_field->GetChar(o)); 798f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Float;")) { 799418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('F'); 800f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetF(primitive_field->GetFloat(o)); 801f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Double;")) { 802418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('D'); 803f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetD(primitive_field->GetDouble(o)); 804f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Integer;")) { 805418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('I'); 806f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetI(primitive_field->GetInt(o)); 807f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Long;")) { 808418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('J'); 809f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetJ(primitive_field->GetLong(o)); 810f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier } else if (klass->DescriptorEquals("Ljava/lang/Short;")) { 811418d20fc407052d4152157f61e7453359f902383Elliott Hughes src_class = class_linker->FindPrimitiveClass('S'); 812f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes boxed_value.SetS(primitive_field->GetShort(o)); 813418d20fc407052d4152157f61e7453359f902383Elliott Hughes } else { 8141ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers std::string temp; 8150aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException( 8161ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers StringPrintf("%s has type %s, got %s", UnboxingFailureKind(f).c_str(), 8171ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers PrettyDescriptor(dst_class).c_str(), 8181ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers PrettyDescriptor(o->GetClass()->GetDescriptor(&temp)).c_str()).c_str()); 819418d20fc407052d4152157f61e7453359f902383Elliott Hughes return false; 820418d20fc407052d4152157f61e7453359f902383Elliott Hughes } 821418d20fc407052d4152157f61e7453359f902383Elliott Hughes 8220aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray return ConvertPrimitiveValue(unbox_for_result, 82362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers src_class->GetPrimitiveType(), dst_class->GetPrimitiveType(), 8246b4ef025af12b158d117fc80fc79acf620f411a0Brian Carlstrom boxed_value, unboxed_value); 825418d20fc407052d4152157f61e7453359f902383Elliott Hughes} 826418d20fc407052d4152157f61e7453359f902383Elliott Hughes 827c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierbool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, ArtField* f, 82884956ff6c0ff150d86a08157216ded79217d860aIan Rogers JValue* unboxed_value) { 82984956ff6c0ff150d86a08157216ded79217d860aIan Rogers DCHECK(f != nullptr); 8300aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray return UnboxPrimitive(o, dst_class, f, unboxed_value); 831aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes} 832aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes 833f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartierbool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue* unboxed_value) { 8340aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray return UnboxPrimitive(o, dst_class, nullptr, unboxed_value); 835aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes} 836aaa5edcf2deb1bddcbf5fb27820ad2240ac5b4f2Elliott Hughes 837f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartiermirror::Class* GetCallingClass(Thread* self, size_t num_frames) { 838f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier NthCallerVisitor visitor(self, num_frames); 839f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier visitor.WalkStack(); 840f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier return visitor.caller != nullptr ? visitor.caller->GetDeclaringClass() : nullptr; 841f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier} 842f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier 843c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampebool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class, 844ca239af73e512df5eeb80fe6c09c2ca614649e06Mathieu Chartier uint32_t access_flags, mirror::Class** calling_class, size_t num_frames) { 84576433275dbe39e5ced1c223b006d1b900b1937f6Mathieu Chartier if ((access_flags & kAccPublic) != 0) { 84676433275dbe39e5ced1c223b006d1b900b1937f6Mathieu Chartier return true; 84776433275dbe39e5ced1c223b006d1b900b1937f6Mathieu Chartier } 848f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier auto* klass = GetCallingClass(self, num_frames); 849f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier if (UNLIKELY(klass == nullptr)) { 8503bd7a6c1716935e758f230e2f199128cb3c28b42Vladimir Marko // The caller is an attached native thread. 85176433275dbe39e5ced1c223b006d1b900b1937f6Mathieu Chartier return false; 8523bd7a6c1716935e758f230e2f199128cb3c28b42Vladimir Marko } 853f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier *calling_class = klass; 854f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier return VerifyAccess(self, obj, declaring_class, access_flags, klass); 855f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier} 856f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier 857f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartierbool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class, 858f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier uint32_t access_flags, mirror::Class* calling_class) { 859f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier if (calling_class == declaring_class) { 86011d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao return true; 86111d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao } 862c0d8229898c44c0f604f08a5df1de83ff56c18fdAndreas Gampe ScopedAssertNoThreadSuspension sants(self, "verify-access"); 863cb4581aa13d6f43f705535818a4d0893d551be3aJeff Hao if ((access_flags & kAccPrivate) != 0) { 86411d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao return false; 86511d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao } 866cb4581aa13d6f43f705535818a4d0893d551be3aJeff Hao if ((access_flags & kAccProtected) != 0) { 867f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier if (obj != nullptr && !obj->InstanceOf(calling_class) && 868f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier !declaring_class->IsInSamePackage(calling_class)) { 86911d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao return false; 870f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier } else if (declaring_class->IsAssignableFrom(calling_class)) { 87111d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao return true; 87211d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao } 87311d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao } 874f36cb5f65cb150151aa40b23937e2b0ad75cc546Mathieu Chartier return declaring_class->IsInSamePackage(calling_class); 87511d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao} 87611d5d8fffe41cc7daadbfa2ca98ecb978f3029afJeff Hao 877daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartiervoid InvalidReceiverError(mirror::Object* o, mirror::Class* c) { 878daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier std::string expected_class_name(PrettyDescriptor(c)); 879daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier std::string actual_class_name(PrettyTypeOf(o)); 880daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier ThrowIllegalArgumentException(StringPrintf("Expected receiver of type %s, but got %s", 881daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier expected_class_name.c_str(), 882daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier actual_class_name.c_str()).c_str()); 883daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier} 884daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier 88583c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao// This only works if there's one reference which points to the object in obj. 88683c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao// Will need to be fixed if there's cases where it's not. 88783c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Haovoid UpdateReference(Thread* self, jobject obj, mirror::Object* result) { 88883c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao IndirectRef ref = reinterpret_cast<IndirectRef>(obj); 88983c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao IndirectRefKind kind = GetIndirectRefKind(ref); 89083c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao if (kind == kLocal) { 89183c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao self->GetJniEnv()->locals.Update(obj, result); 89283c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao } else if (kind == kHandleScopeOrInvalid) { 89383c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao LOG(FATAL) << "Unsupported UpdateReference for kind kHandleScopeOrInvalid"; 89483c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao } else if (kind == kGlobal) { 89583c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao self->GetJniEnv()->vm->UpdateGlobal(self, ref, result); 89683c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao } else { 89783c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao DCHECK_EQ(kind, kWeakGlobal); 89883c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao self->GetJniEnv()->vm->UpdateWeakGlobal(self, ref, result); 89983c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao } 90083c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao} 90183c81955bfbfe8fbe6daf215ca73e436747e3e60Jeff Hao 902418d20fc407052d4152157f61e7453359f902383Elliott Hughes} // namespace art 903