reflection.cc revision c785344b87221f5e4e6473e5b762e4e61fe65dcf
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "reflection-inl.h" 18 19#include "art_field-inl.h" 20#include "class_linker.h" 21#include "common_throws.h" 22#include "dex_file-inl.h" 23#include "entrypoints/entrypoint_utils.h" 24#include "jni_internal.h" 25#include "mirror/art_method-inl.h" 26#include "mirror/class-inl.h" 27#include "mirror/object_array-inl.h" 28#include "nth_caller_visitor.h" 29#include "scoped_thread_state_change.h" 30#include "stack.h" 31#include "well_known_classes.h" 32 33namespace art { 34 35class ArgArray { 36 public: 37 explicit ArgArray(const char* shorty, uint32_t shorty_len) 38 : shorty_(shorty), shorty_len_(shorty_len), num_bytes_(0) { 39 size_t num_slots = shorty_len + 1; // +1 in case of receiver. 40 if (LIKELY((num_slots * 2) < kSmallArgArraySize)) { 41 // We can trivially use the small arg array. 42 arg_array_ = small_arg_array_; 43 } else { 44 // Analyze shorty to see if we need the large arg array. 45 for (size_t i = 1; i < shorty_len; ++i) { 46 char c = shorty[i]; 47 if (c == 'J' || c == 'D') { 48 num_slots++; 49 } 50 } 51 if (num_slots <= kSmallArgArraySize) { 52 arg_array_ = small_arg_array_; 53 } else { 54 large_arg_array_.reset(new uint32_t[num_slots]); 55 arg_array_ = large_arg_array_.get(); 56 } 57 } 58 } 59 60 uint32_t* GetArray() { 61 return arg_array_; 62 } 63 64 uint32_t GetNumBytes() { 65 return num_bytes_; 66 } 67 68 void Append(uint32_t value) { 69 arg_array_[num_bytes_ / 4] = value; 70 num_bytes_ += 4; 71 } 72 73 void Append(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 74 Append(StackReference<mirror::Object>::FromMirrorPtr(obj).AsVRegValue()); 75 } 76 77 void AppendWide(uint64_t value) { 78 arg_array_[num_bytes_ / 4] = value; 79 arg_array_[(num_bytes_ / 4) + 1] = value >> 32; 80 num_bytes_ += 8; 81 } 82 83 void AppendFloat(float value) { 84 jvalue jv; 85 jv.f = value; 86 Append(jv.i); 87 } 88 89 void AppendDouble(double value) { 90 jvalue jv; 91 jv.d = value; 92 AppendWide(jv.j); 93 } 94 95 void BuildArgArrayFromVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 96 mirror::Object* receiver, va_list ap) 97 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 98 // Set receiver if non-null (method is not static) 99 if (receiver != nullptr) { 100 Append(receiver); 101 } 102 for (size_t i = 1; i < shorty_len_; ++i) { 103 switch (shorty_[i]) { 104 case 'Z': 105 case 'B': 106 case 'C': 107 case 'S': 108 case 'I': 109 Append(va_arg(ap, jint)); 110 break; 111 case 'F': 112 AppendFloat(va_arg(ap, jdouble)); 113 break; 114 case 'L': 115 Append(soa.Decode<mirror::Object*>(va_arg(ap, jobject))); 116 break; 117 case 'D': 118 AppendDouble(va_arg(ap, jdouble)); 119 break; 120 case 'J': 121 AppendWide(va_arg(ap, jlong)); 122 break; 123#ifndef NDEBUG 124 default: 125 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 126#endif 127 } 128 } 129 } 130 131 void BuildArgArrayFromJValues(const ScopedObjectAccessAlreadyRunnable& soa, 132 mirror::Object* receiver, jvalue* args) 133 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 134 // Set receiver if non-null (method is not static) 135 if (receiver != nullptr) { 136 Append(receiver); 137 } 138 for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 139 switch (shorty_[i]) { 140 case 'Z': 141 Append(args[args_offset].z); 142 break; 143 case 'B': 144 Append(args[args_offset].b); 145 break; 146 case 'C': 147 Append(args[args_offset].c); 148 break; 149 case 'S': 150 Append(args[args_offset].s); 151 break; 152 case 'I': 153 case 'F': 154 Append(args[args_offset].i); 155 break; 156 case 'L': 157 Append(soa.Decode<mirror::Object*>(args[args_offset].l)); 158 break; 159 case 'D': 160 case 'J': 161 AppendWide(args[args_offset].j); 162 break; 163#ifndef NDEBUG 164 default: 165 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 166#endif 167 } 168 } 169 } 170 171 void BuildArgArrayFromFrame(ShadowFrame* shadow_frame, uint32_t arg_offset) 172 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 173 // Set receiver if non-null (method is not static) 174 size_t cur_arg = arg_offset; 175 if (!shadow_frame->GetMethod()->IsStatic()) { 176 Append(shadow_frame->GetVReg(cur_arg)); 177 cur_arg++; 178 } 179 for (size_t i = 1; i < shorty_len_; ++i) { 180 switch (shorty_[i]) { 181 case 'Z': 182 case 'B': 183 case 'C': 184 case 'S': 185 case 'I': 186 case 'F': 187 case 'L': 188 Append(shadow_frame->GetVReg(cur_arg)); 189 cur_arg++; 190 break; 191 case 'D': 192 case 'J': 193 AppendWide(shadow_frame->GetVRegLong(cur_arg)); 194 cur_arg++; 195 cur_arg++; 196 break; 197#ifndef NDEBUG 198 default: 199 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 200#endif 201 } 202 } 203 } 204 205 static void ThrowIllegalPrimitiveArgumentException(const char* expected, 206 const char* found_descriptor) 207 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 208 ThrowIllegalArgumentException( 209 StringPrintf("Invalid primitive conversion from %s to %s", expected, 210 PrettyDescriptor(found_descriptor).c_str()).c_str()); 211 } 212 213 bool BuildArgArrayFromObjectArray(mirror::Object* receiver, 214 mirror::ObjectArray<mirror::Object>* args, 215 Handle<mirror::ArtMethod> h_m) 216 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 217 const DexFile::TypeList* classes = h_m->GetParameterTypeList(); 218 // Set receiver if non-null (method is not static) 219 if (receiver != nullptr) { 220 Append(receiver); 221 } 222 for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { 223 mirror::Object* arg = args->Get(args_offset); 224 if (((shorty_[i] == 'L') && (arg != nullptr)) || ((arg == nullptr && shorty_[i] != 'L'))) { 225 mirror::Class* dst_class = 226 h_m->GetClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_, true); 227 if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) { 228 ThrowIllegalArgumentException( 229 StringPrintf("method %s argument %zd has type %s, got %s", 230 PrettyMethod(h_m.Get(), false).c_str(), 231 args_offset + 1, // Humans don't count from 0. 232 PrettyDescriptor(dst_class).c_str(), 233 PrettyTypeOf(arg).c_str()).c_str()); 234 return false; 235 } 236 } 237 238#define DO_FIRST_ARG(match_descriptor, get_fn, append) { \ 239 if (LIKELY(arg != nullptr && arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ 240 ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 241 append(primitive_field-> get_fn(arg)); 242 243#define DO_ARG(match_descriptor, get_fn, append) \ 244 } else if (LIKELY(arg != nullptr && \ 245 arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ 246 ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ 247 append(primitive_field-> get_fn(arg)); 248 249#define DO_FAIL(expected) \ 250 } else { \ 251 if (arg->GetClass<>()->IsPrimitive()) { \ 252 std::string temp; \ 253 ThrowIllegalPrimitiveArgumentException(expected, \ 254 arg->GetClass<>()->GetDescriptor(&temp)); \ 255 } else { \ 256 ThrowIllegalArgumentException(\ 257 StringPrintf("method %s argument %zd has type %s, got %s", \ 258 PrettyMethod(h_m.Get(), false).c_str(), \ 259 args_offset + 1, \ 260 expected, \ 261 PrettyTypeOf(arg).c_str()).c_str()); \ 262 } \ 263 return false; \ 264 } } 265 266 switch (shorty_[i]) { 267 case 'L': 268 Append(arg); 269 break; 270 case 'Z': 271 DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append) 272 DO_FAIL("boolean") 273 break; 274 case 'B': 275 DO_FIRST_ARG("Ljava/lang/Byte;", GetByte, Append) 276 DO_FAIL("byte") 277 break; 278 case 'C': 279 DO_FIRST_ARG("Ljava/lang/Character;", GetChar, Append) 280 DO_FAIL("char") 281 break; 282 case 'S': 283 DO_FIRST_ARG("Ljava/lang/Short;", GetShort, Append) 284 DO_ARG("Ljava/lang/Byte;", GetByte, Append) 285 DO_FAIL("short") 286 break; 287 case 'I': 288 DO_FIRST_ARG("Ljava/lang/Integer;", GetInt, Append) 289 DO_ARG("Ljava/lang/Character;", GetChar, Append) 290 DO_ARG("Ljava/lang/Short;", GetShort, Append) 291 DO_ARG("Ljava/lang/Byte;", GetByte, Append) 292 DO_FAIL("int") 293 break; 294 case 'J': 295 DO_FIRST_ARG("Ljava/lang/Long;", GetLong, AppendWide) 296 DO_ARG("Ljava/lang/Integer;", GetInt, AppendWide) 297 DO_ARG("Ljava/lang/Character;", GetChar, AppendWide) 298 DO_ARG("Ljava/lang/Short;", GetShort, AppendWide) 299 DO_ARG("Ljava/lang/Byte;", GetByte, AppendWide) 300 DO_FAIL("long") 301 break; 302 case 'F': 303 DO_FIRST_ARG("Ljava/lang/Float;", GetFloat, AppendFloat) 304 DO_ARG("Ljava/lang/Long;", GetLong, AppendFloat) 305 DO_ARG("Ljava/lang/Integer;", GetInt, AppendFloat) 306 DO_ARG("Ljava/lang/Character;", GetChar, AppendFloat) 307 DO_ARG("Ljava/lang/Short;", GetShort, AppendFloat) 308 DO_ARG("Ljava/lang/Byte;", GetByte, AppendFloat) 309 DO_FAIL("float") 310 break; 311 case 'D': 312 DO_FIRST_ARG("Ljava/lang/Double;", GetDouble, AppendDouble) 313 DO_ARG("Ljava/lang/Float;", GetFloat, AppendDouble) 314 DO_ARG("Ljava/lang/Long;", GetLong, AppendDouble) 315 DO_ARG("Ljava/lang/Integer;", GetInt, AppendDouble) 316 DO_ARG("Ljava/lang/Character;", GetChar, AppendDouble) 317 DO_ARG("Ljava/lang/Short;", GetShort, AppendDouble) 318 DO_ARG("Ljava/lang/Byte;", GetByte, AppendDouble) 319 DO_FAIL("double") 320 break; 321#ifndef NDEBUG 322 default: 323 LOG(FATAL) << "Unexpected shorty character: " << shorty_[i]; 324 UNREACHABLE(); 325#endif 326 } 327#undef DO_FIRST_ARG 328#undef DO_ARG 329#undef DO_FAIL 330 } 331 return true; 332 } 333 334 private: 335 enum { kSmallArgArraySize = 16 }; 336 const char* const shorty_; 337 const uint32_t shorty_len_; 338 uint32_t num_bytes_; 339 uint32_t* arg_array_; 340 uint32_t small_arg_array_[kSmallArgArraySize]; 341 std::unique_ptr<uint32_t[]> large_arg_array_; 342}; 343 344static void CheckMethodArguments(JavaVMExt* vm, mirror::ArtMethod* m, uint32_t* args) 345 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 346 const DexFile::TypeList* params = m->GetParameterTypeList(); 347 if (params == nullptr) { 348 return; // No arguments so nothing to check. 349 } 350 uint32_t offset = 0; 351 uint32_t num_params = params->Size(); 352 size_t error_count = 0; 353 if (!m->IsStatic()) { 354 offset = 1; 355 } 356 // TODO: If args contain object references, it may cause problems. 357 Thread* self = Thread::Current(); 358 StackHandleScope<1> hs(self); 359 Handle<mirror::ArtMethod> h_m(hs.NewHandle(m)); 360 for (uint32_t i = 0; i < num_params; i++) { 361 uint16_t type_idx = params->GetTypeItem(i).type_idx_; 362 mirror::Class* param_type = h_m->GetClassFromTypeIndex(type_idx, true); 363 if (param_type == nullptr) { 364 CHECK(self->IsExceptionPending()); 365 LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " 366 << h_m->GetTypeDescriptorFromTypeIdx(type_idx) << "\n" 367 << self->GetException()->Dump(); 368 self->ClearException(); 369 ++error_count; 370 } else if (!param_type->IsPrimitive()) { 371 // TODO: There is a compaction bug here since GetClassFromTypeIdx can cause thread suspension, 372 // this is a hard to fix problem since the args can contain Object*, we need to save and 373 // restore them by using a visitor similar to the ones used in the trampoline entrypoints. 374 mirror::Object* argument = 375 (reinterpret_cast<StackReference<mirror::Object>*>(&args[i + offset]))->AsMirrorPtr(); 376 if (argument != nullptr && !argument->InstanceOf(param_type)) { 377 LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of " 378 << PrettyTypeOf(argument) << " as argument " << (i + 1) 379 << " to " << PrettyMethod(h_m.Get()); 380 ++error_count; 381 } 382 } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) { 383 offset++; 384 } else { 385 int32_t arg = static_cast<int32_t>(args[i + offset]); 386 if (param_type->IsPrimitiveBoolean()) { 387 if (arg != JNI_TRUE && arg != JNI_FALSE) { 388 LOG(ERROR) << "JNI ERROR (app bug): expected jboolean (0/1) but got value of " 389 << arg << " as argument " << (i + 1) << " to " << PrettyMethod(h_m.Get()); 390 ++error_count; 391 } 392 } else if (param_type->IsPrimitiveByte()) { 393 if (arg < -128 || arg > 127) { 394 LOG(ERROR) << "JNI ERROR (app bug): expected jbyte but got value of " 395 << arg << " as argument " << (i + 1) << " to " << PrettyMethod(h_m.Get()); 396 ++error_count; 397 } 398 } else if (param_type->IsPrimitiveChar()) { 399 if (args[i + offset] > 0xFFFF) { 400 LOG(ERROR) << "JNI ERROR (app bug): expected jchar but got value of " 401 << arg << " as argument " << (i + 1) << " to " << PrettyMethod(h_m.Get()); 402 ++error_count; 403 } 404 } else if (param_type->IsPrimitiveShort()) { 405 if (arg < -32768 || arg > 0x7FFF) { 406 LOG(ERROR) << "JNI ERROR (app bug): expected jshort but got value of " 407 << arg << " as argument " << (i + 1) << " to " << PrettyMethod(h_m.Get()); 408 ++error_count; 409 } 410 } 411 } 412 } 413 if (UNLIKELY(error_count > 0)) { 414 // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort 415 // with an argument. 416 vm->JniAbortF(nullptr, "bad arguments passed to %s (see above for details)", 417 PrettyMethod(h_m.Get()).c_str()); 418 } 419} 420 421static mirror::ArtMethod* FindVirtualMethod(mirror::Object* receiver, 422 mirror::ArtMethod* method) 423 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 424 return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method); 425} 426 427 428static void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa, 429 mirror::ArtMethod* method, ArgArray* arg_array, JValue* result, 430 const char* shorty) 431 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 432 uint32_t* args = arg_array->GetArray(); 433 if (UNLIKELY(soa.Env()->check_jni)) { 434 CheckMethodArguments(soa.Vm(), method, args); 435 } 436 method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty); 437} 438 439JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid, 440 va_list args) 441 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 442 // We want to make sure that the stack is not within a small distance from the 443 // protected region in case we are calling into a leaf function whose stack 444 // check has been elided. 445 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 446 ThrowStackOverflowError(soa.Self()); 447 return JValue(); 448 } 449 450 mirror::ArtMethod* method = soa.DecodeMethod(mid); 451 mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); 452 uint32_t shorty_len = 0; 453 const char* shorty = method->GetShorty(&shorty_len); 454 JValue result; 455 ArgArray arg_array(shorty, shorty_len); 456 arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 457 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 458 return result; 459} 460 461JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, mirror::Object* receiver, 462 jmethodID mid, jvalue* args) { 463 // We want to make sure that the stack is not within a small distance from the 464 // protected region in case we are calling into a leaf function whose stack 465 // check has been elided. 466 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 467 ThrowStackOverflowError(soa.Self()); 468 return JValue(); 469 } 470 471 mirror::ArtMethod* method = soa.DecodeMethod(mid); 472 uint32_t shorty_len = 0; 473 const char* shorty = method->GetShorty(&shorty_len); 474 JValue result; 475 ArgArray arg_array(shorty, shorty_len); 476 arg_array.BuildArgArrayFromJValues(soa, receiver, args); 477 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 478 return result; 479} 480 481JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, 482 mirror::Object* receiver, jmethodID mid, jvalue* args) { 483 // We want to make sure that the stack is not within a small distance from the 484 // protected region in case we are calling into a leaf function whose stack 485 // check has been elided. 486 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 487 ThrowStackOverflowError(soa.Self()); 488 return JValue(); 489 } 490 491 mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 492 uint32_t shorty_len = 0; 493 const char* shorty = method->GetShorty(&shorty_len); 494 JValue result; 495 ArgArray arg_array(shorty, shorty_len); 496 arg_array.BuildArgArrayFromJValues(soa, receiver, args); 497 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 498 return result; 499} 500 501JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, 502 jobject obj, jmethodID mid, va_list args) { 503 // We want to make sure that the stack is not within a small distance from the 504 // protected region in case we are calling into a leaf function whose stack 505 // check has been elided. 506 if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) { 507 ThrowStackOverflowError(soa.Self()); 508 return JValue(); 509 } 510 511 mirror::Object* receiver = soa.Decode<mirror::Object*>(obj); 512 mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); 513 uint32_t shorty_len = 0; 514 const char* shorty = method->GetShorty(&shorty_len); 515 JValue result; 516 ArgArray arg_array(shorty, shorty_len); 517 arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); 518 InvokeWithArgArray(soa, method, &arg_array, &result, shorty); 519 return result; 520} 521 522void InvokeWithShadowFrame(Thread* self, ShadowFrame* shadow_frame, uint16_t arg_offset, 523 JValue* result) { 524 // We want to make sure that the stack is not within a small distance from the 525 // protected region in case we are calling into a leaf function whose stack 526 // check has been elided. 527 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 528 ThrowStackOverflowError(self); 529 return; 530 } 531 uint32_t shorty_len; 532 const char* shorty = shadow_frame->GetMethod()->GetShorty(&shorty_len); 533 ArgArray arg_array(shorty, shorty_len); 534 arg_array.BuildArgArrayFromFrame(shadow_frame, arg_offset); 535 shadow_frame->GetMethod()->Invoke(self, arg_array.GetArray(), arg_array.GetNumBytes(), result, 536 shorty); 537} 538 539jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod, 540 jobject javaReceiver, jobject javaArgs, bool accessible) { 541 // We want to make sure that the stack is not within a small distance from the 542 // protected region in case we are calling into a leaf function whose stack 543 // check has been elided. 544 if (UNLIKELY(__builtin_frame_address(0) < 545 soa.Self()->GetStackEndForInterpreter(true))) { 546 ThrowStackOverflowError(soa.Self()); 547 return nullptr; 548 } 549 550 mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod); 551 552 mirror::Class* declaring_class = m->GetDeclaringClass(); 553 if (UNLIKELY(!declaring_class->IsInitialized())) { 554 StackHandleScope<1> hs(soa.Self()); 555 Handle<mirror::Class> h_class(hs.NewHandle(declaring_class)); 556 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) { 557 return nullptr; 558 } 559 declaring_class = h_class.Get(); 560 } 561 562 mirror::Object* receiver = nullptr; 563 if (!m->IsStatic()) { 564 // Check that the receiver is non-null and an instance of the field's declaring class. 565 receiver = soa.Decode<mirror::Object*>(javaReceiver); 566 if (!VerifyObjectIsClass(receiver, declaring_class)) { 567 return nullptr; 568 } 569 570 // Find the actual implementation of the virtual method. 571 m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m); 572 } 573 574 // Get our arrays of arguments and their types, and check they're the same size. 575 mirror::ObjectArray<mirror::Object>* objects = 576 soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs); 577 const DexFile::TypeList* classes = m->GetParameterTypeList(); 578 uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size(); 579 uint32_t arg_count = (objects != nullptr) ? objects->GetLength() : 0; 580 if (arg_count != classes_size) { 581 ThrowIllegalArgumentException(StringPrintf("Wrong number of arguments; expected %d, got %d", 582 classes_size, arg_count).c_str()); 583 return nullptr; 584 } 585 586 // If method is not set to be accessible, verify it can be accessed by the caller. 587 mirror::Class* calling_class = nullptr; 588 if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags(), 589 &calling_class, 2)) { 590 ThrowIllegalAccessException( 591 StringPrintf("Class %s cannot access %s method %s of class %s", 592 calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(), 593 PrettyJavaAccessFlags(m->GetAccessFlags()).c_str(), 594 PrettyMethod(m).c_str(), 595 m->GetDeclaringClass() == nullptr ? "null" : 596 PrettyClass(m->GetDeclaringClass()).c_str()).c_str()); 597 return nullptr; 598 } 599 600 // Invoke the method. 601 JValue result; 602 uint32_t shorty_len = 0; 603 const char* shorty = m->GetShorty(&shorty_len); 604 ArgArray arg_array(shorty, shorty_len); 605 StackHandleScope<1> hs(soa.Self()); 606 Handle<mirror::ArtMethod> h_m(hs.NewHandle(m)); 607 if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, h_m)) { 608 CHECK(soa.Self()->IsExceptionPending()); 609 return nullptr; 610 } 611 612 InvokeWithArgArray(soa, m, &arg_array, &result, shorty); 613 614 // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early. 615 if (soa.Self()->IsExceptionPending()) { 616 jthrowable th = soa.Env()->ExceptionOccurred(); 617 soa.Env()->ExceptionClear(); 618 jclass exception_class = soa.Env()->FindClass("java/lang/reflect/InvocationTargetException"); 619 jmethodID mid = soa.Env()->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V"); 620 jobject exception_instance = soa.Env()->NewObject(exception_class, mid, th); 621 soa.Env()->Throw(reinterpret_cast<jthrowable>(exception_instance)); 622 return nullptr; 623 } 624 625 // Box if necessary and return. 626 return soa.AddLocalReference<jobject>(BoxPrimitive(Primitive::GetType(shorty[0]), result)); 627} 628 629mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) { 630 if (src_class == Primitive::kPrimNot) { 631 return value.GetL(); 632 } 633 if (src_class == Primitive::kPrimVoid) { 634 // There's no such thing as a void field, and void methods invoked via reflection return null. 635 return nullptr; 636 } 637 638 jmethodID m = nullptr; 639 const char* shorty; 640 switch (src_class) { 641 case Primitive::kPrimBoolean: 642 m = WellKnownClasses::java_lang_Boolean_valueOf; 643 shorty = "LZ"; 644 break; 645 case Primitive::kPrimByte: 646 m = WellKnownClasses::java_lang_Byte_valueOf; 647 shorty = "LB"; 648 break; 649 case Primitive::kPrimChar: 650 m = WellKnownClasses::java_lang_Character_valueOf; 651 shorty = "LC"; 652 break; 653 case Primitive::kPrimDouble: 654 m = WellKnownClasses::java_lang_Double_valueOf; 655 shorty = "LD"; 656 break; 657 case Primitive::kPrimFloat: 658 m = WellKnownClasses::java_lang_Float_valueOf; 659 shorty = "LF"; 660 break; 661 case Primitive::kPrimInt: 662 m = WellKnownClasses::java_lang_Integer_valueOf; 663 shorty = "LI"; 664 break; 665 case Primitive::kPrimLong: 666 m = WellKnownClasses::java_lang_Long_valueOf; 667 shorty = "LJ"; 668 break; 669 case Primitive::kPrimShort: 670 m = WellKnownClasses::java_lang_Short_valueOf; 671 shorty = "LS"; 672 break; 673 default: 674 LOG(FATAL) << static_cast<int>(src_class); 675 shorty = nullptr; 676 } 677 678 ScopedObjectAccessUnchecked soa(Thread::Current()); 679 DCHECK_EQ(soa.Self()->GetState(), kRunnable); 680 681 ArgArray arg_array(shorty, 2); 682 JValue result; 683 if (src_class == Primitive::kPrimDouble || src_class == Primitive::kPrimLong) { 684 arg_array.AppendWide(value.GetJ()); 685 } else { 686 arg_array.Append(value.GetI()); 687 } 688 689 soa.DecodeMethod(m)->Invoke(soa.Self(), arg_array.GetArray(), arg_array.GetNumBytes(), 690 &result, shorty); 691 return result.GetL(); 692} 693 694static std::string UnboxingFailureKind(ArtField* f) 695 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 696 if (f != nullptr) { 697 return "field " + PrettyField(f, false); 698 } 699 return "result"; 700} 701 702static bool UnboxPrimitive(mirror::Object* o, 703 mirror::Class* dst_class, ArtField* f, 704 JValue* unboxed_value) 705 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 706 bool unbox_for_result = (f == nullptr); 707 if (!dst_class->IsPrimitive()) { 708 if (UNLIKELY(o != nullptr && !o->InstanceOf(dst_class))) { 709 if (!unbox_for_result) { 710 ThrowIllegalArgumentException(StringPrintf("%s has type %s, got %s", 711 UnboxingFailureKind(f).c_str(), 712 PrettyDescriptor(dst_class).c_str(), 713 PrettyTypeOf(o).c_str()).c_str()); 714 } else { 715 ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s", 716 PrettyTypeOf(o).c_str(), 717 PrettyDescriptor(dst_class).c_str()).c_str()); 718 } 719 return false; 720 } 721 unboxed_value->SetL(o); 722 return true; 723 } 724 if (UNLIKELY(dst_class->GetPrimitiveType() == Primitive::kPrimVoid)) { 725 ThrowIllegalArgumentException(StringPrintf("Can't unbox %s to void", 726 UnboxingFailureKind(f).c_str()).c_str()); 727 return false; 728 } 729 if (UNLIKELY(o == nullptr)) { 730 if (!unbox_for_result) { 731 ThrowIllegalArgumentException(StringPrintf("%s has type %s, got null", 732 UnboxingFailureKind(f).c_str(), 733 PrettyDescriptor(dst_class).c_str()).c_str()); 734 } else { 735 ThrowNullPointerException(StringPrintf("Expected to unbox a '%s' primitive type but was returned null", 736 PrettyDescriptor(dst_class).c_str()).c_str()); 737 } 738 return false; 739 } 740 741 JValue boxed_value; 742 mirror::Class* klass = o->GetClass(); 743 mirror::Class* src_class = nullptr; 744 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 745 ArtField* primitive_field = &klass->GetIFields()[0]; 746 if (klass->DescriptorEquals("Ljava/lang/Boolean;")) { 747 src_class = class_linker->FindPrimitiveClass('Z'); 748 boxed_value.SetZ(primitive_field->GetBoolean(o)); 749 } else if (klass->DescriptorEquals("Ljava/lang/Byte;")) { 750 src_class = class_linker->FindPrimitiveClass('B'); 751 boxed_value.SetB(primitive_field->GetByte(o)); 752 } else if (klass->DescriptorEquals("Ljava/lang/Character;")) { 753 src_class = class_linker->FindPrimitiveClass('C'); 754 boxed_value.SetC(primitive_field->GetChar(o)); 755 } else if (klass->DescriptorEquals("Ljava/lang/Float;")) { 756 src_class = class_linker->FindPrimitiveClass('F'); 757 boxed_value.SetF(primitive_field->GetFloat(o)); 758 } else if (klass->DescriptorEquals("Ljava/lang/Double;")) { 759 src_class = class_linker->FindPrimitiveClass('D'); 760 boxed_value.SetD(primitive_field->GetDouble(o)); 761 } else if (klass->DescriptorEquals("Ljava/lang/Integer;")) { 762 src_class = class_linker->FindPrimitiveClass('I'); 763 boxed_value.SetI(primitive_field->GetInt(o)); 764 } else if (klass->DescriptorEquals("Ljava/lang/Long;")) { 765 src_class = class_linker->FindPrimitiveClass('J'); 766 boxed_value.SetJ(primitive_field->GetLong(o)); 767 } else if (klass->DescriptorEquals("Ljava/lang/Short;")) { 768 src_class = class_linker->FindPrimitiveClass('S'); 769 boxed_value.SetS(primitive_field->GetShort(o)); 770 } else { 771 std::string temp; 772 ThrowIllegalArgumentException( 773 StringPrintf("%s has type %s, got %s", UnboxingFailureKind(f).c_str(), 774 PrettyDescriptor(dst_class).c_str(), 775 PrettyDescriptor(o->GetClass()->GetDescriptor(&temp)).c_str()).c_str()); 776 return false; 777 } 778 779 return ConvertPrimitiveValue(unbox_for_result, 780 src_class->GetPrimitiveType(), dst_class->GetPrimitiveType(), 781 boxed_value, unboxed_value); 782} 783 784bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, ArtField* f, 785 JValue* unboxed_value) { 786 DCHECK(f != nullptr); 787 return UnboxPrimitive(o, dst_class, f, unboxed_value); 788} 789 790bool UnboxPrimitiveForResult(mirror::Object* o, 791 mirror::Class* dst_class, JValue* unboxed_value) { 792 return UnboxPrimitive(o, dst_class, nullptr, unboxed_value); 793} 794 795bool VerifyAccess(Thread* self, mirror::Object* obj, mirror::Class* declaring_class, 796 uint32_t access_flags, mirror::Class** calling_class, size_t num_frames) { 797 if ((access_flags & kAccPublic) != 0) { 798 return true; 799 } 800 NthCallerVisitor visitor(self, num_frames); 801 visitor.WalkStack(); 802 if (UNLIKELY(visitor.caller == nullptr)) { 803 // The caller is an attached native thread. 804 return false; 805 } 806 mirror::Class* caller_class = visitor.caller->GetDeclaringClass(); 807 if (caller_class == declaring_class) { 808 return true; 809 } 810 ScopedAssertNoThreadSuspension sants(self, "verify-access"); 811 *calling_class = caller_class; 812 if ((access_flags & kAccPrivate) != 0) { 813 return false; 814 } 815 if ((access_flags & kAccProtected) != 0) { 816 if (obj != nullptr && !obj->InstanceOf(caller_class) && 817 !declaring_class->IsInSamePackage(caller_class)) { 818 return false; 819 } else if (declaring_class->IsAssignableFrom(caller_class)) { 820 return true; 821 } 822 } 823 return declaring_class->IsInSamePackage(caller_class); 824} 825 826void InvalidReceiverError(mirror::Object* o, mirror::Class* c) { 827 std::string expected_class_name(PrettyDescriptor(c)); 828 std::string actual_class_name(PrettyTypeOf(o)); 829 ThrowIllegalArgumentException(StringPrintf("Expected receiver of type %s, but got %s", 830 expected_class_name.c_str(), 831 actual_class_name.c_str()).c_str()); 832} 833 834} // namespace art 835