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