Home | History | Annotate | Download | only in runtime
      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 "art_method-inl.h"
     21 #include "class_linker.h"
     22 #include "common_throws.h"
     23 #include "dex_file-inl.h"
     24 #include "indirect_reference_table-inl.h"
     25 #include "jni_internal.h"
     26 #include "mirror/abstract_method.h"
     27 #include "mirror/class-inl.h"
     28 #include "mirror/object_array-inl.h"
     29 #include "nth_caller_visitor.h"
     30 #include "scoped_thread_state_change.h"
     31 #include "stack.h"
     32 #include "well_known_classes.h"
     33 
     34 namespace art {
     35 
     36 class ArgArray {
     37  public:
     38   ArgArray(const char* shorty, uint32_t shorty_len)
     39       : shorty_(shorty), shorty_len_(shorty_len), num_bytes_(0) {
     40     size_t num_slots = shorty_len + 1;  // +1 in case of receiver.
     41     if (LIKELY((num_slots * 2) < kSmallArgArraySize)) {
     42       // We can trivially use the small arg array.
     43       arg_array_ = small_arg_array_;
     44     } else {
     45       // Analyze shorty to see if we need the large arg array.
     46       for (size_t i = 1; i < shorty_len; ++i) {
     47         char c = shorty[i];
     48         if (c == 'J' || c == 'D') {
     49           num_slots++;
     50         }
     51       }
     52       if (num_slots <= kSmallArgArraySize) {
     53         arg_array_ = small_arg_array_;
     54       } else {
     55         large_arg_array_.reset(new uint32_t[num_slots]);
     56         arg_array_ = large_arg_array_.get();
     57       }
     58     }
     59   }
     60 
     61   uint32_t* GetArray() {
     62     return arg_array_;
     63   }
     64 
     65   uint32_t GetNumBytes() {
     66     return num_bytes_;
     67   }
     68 
     69   void Append(uint32_t value) {
     70     arg_array_[num_bytes_ / 4] = value;
     71     num_bytes_ += 4;
     72   }
     73 
     74   void Append(mirror::Object* obj) SHARED_REQUIRES(Locks::mutator_lock_) {
     75     Append(StackReference<mirror::Object>::FromMirrorPtr(obj).AsVRegValue());
     76   }
     77 
     78   void AppendWide(uint64_t value) {
     79     arg_array_[num_bytes_ / 4] = value;
     80     arg_array_[(num_bytes_ / 4) + 1] = value >> 32;
     81     num_bytes_ += 8;
     82   }
     83 
     84   void AppendFloat(float value) {
     85     jvalue jv;
     86     jv.f = value;
     87     Append(jv.i);
     88   }
     89 
     90   void AppendDouble(double value) {
     91     jvalue jv;
     92     jv.d = value;
     93     AppendWide(jv.j);
     94   }
     95 
     96   void BuildArgArrayFromVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
     97                                 mirror::Object* receiver, va_list ap)
     98       SHARED_REQUIRES(Locks::mutator_lock_) {
     99     // Set receiver if non-null (method is not static)
    100     if (receiver != nullptr) {
    101       Append(receiver);
    102     }
    103     for (size_t i = 1; i < shorty_len_; ++i) {
    104       switch (shorty_[i]) {
    105         case 'Z':
    106         case 'B':
    107         case 'C':
    108         case 'S':
    109         case 'I':
    110           Append(va_arg(ap, jint));
    111           break;
    112         case 'F':
    113           AppendFloat(va_arg(ap, jdouble));
    114           break;
    115         case 'L':
    116           Append(soa.Decode<mirror::Object*>(va_arg(ap, jobject)));
    117           break;
    118         case 'D':
    119           AppendDouble(va_arg(ap, jdouble));
    120           break;
    121         case 'J':
    122           AppendWide(va_arg(ap, jlong));
    123           break;
    124 #ifndef NDEBUG
    125         default:
    126           LOG(FATAL) << "Unexpected shorty character: " << shorty_[i];
    127 #endif
    128       }
    129     }
    130   }
    131 
    132   void BuildArgArrayFromJValues(const ScopedObjectAccessAlreadyRunnable& soa,
    133                                 mirror::Object* receiver, jvalue* args)
    134       SHARED_REQUIRES(Locks::mutator_lock_) {
    135     // Set receiver if non-null (method is not static)
    136     if (receiver != nullptr) {
    137       Append(receiver);
    138     }
    139     for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) {
    140       switch (shorty_[i]) {
    141         case 'Z':
    142           Append(args[args_offset].z);
    143           break;
    144         case 'B':
    145           Append(args[args_offset].b);
    146           break;
    147         case 'C':
    148           Append(args[args_offset].c);
    149           break;
    150         case 'S':
    151           Append(args[args_offset].s);
    152           break;
    153         case 'I':
    154         case 'F':
    155           Append(args[args_offset].i);
    156           break;
    157         case 'L':
    158           Append(soa.Decode<mirror::Object*>(args[args_offset].l));
    159           break;
    160         case 'D':
    161         case 'J':
    162           AppendWide(args[args_offset].j);
    163           break;
    164 #ifndef NDEBUG
    165         default:
    166           LOG(FATAL) << "Unexpected shorty character: " << shorty_[i];
    167 #endif
    168       }
    169     }
    170   }
    171 
    172   void BuildArgArrayFromFrame(ShadowFrame* shadow_frame, uint32_t arg_offset)
    173       SHARED_REQUIRES(Locks::mutator_lock_) {
    174     // Set receiver if non-null (method is not static)
    175     size_t cur_arg = arg_offset;
    176     if (!shadow_frame->GetMethod()->IsStatic()) {
    177       Append(shadow_frame->GetVReg(cur_arg));
    178       cur_arg++;
    179     }
    180     for (size_t i = 1; i < shorty_len_; ++i) {
    181       switch (shorty_[i]) {
    182         case 'Z':
    183         case 'B':
    184         case 'C':
    185         case 'S':
    186         case 'I':
    187         case 'F':
    188         case 'L':
    189           Append(shadow_frame->GetVReg(cur_arg));
    190           cur_arg++;
    191           break;
    192         case 'D':
    193         case 'J':
    194           AppendWide(shadow_frame->GetVRegLong(cur_arg));
    195           cur_arg++;
    196           cur_arg++;
    197           break;
    198 #ifndef NDEBUG
    199         default:
    200           LOG(FATAL) << "Unexpected shorty character: " << shorty_[i];
    201 #endif
    202       }
    203     }
    204   }
    205 
    206   static void ThrowIllegalPrimitiveArgumentException(const char* expected,
    207                                                      const char* found_descriptor)
    208       SHARED_REQUIRES(Locks::mutator_lock_) {
    209     ThrowIllegalArgumentException(
    210         StringPrintf("Invalid primitive conversion from %s to %s", expected,
    211                      PrettyDescriptor(found_descriptor).c_str()).c_str());
    212   }
    213 
    214   bool BuildArgArrayFromObjectArray(mirror::Object* receiver,
    215                                     mirror::ObjectArray<mirror::Object>* args, ArtMethod* m)
    216       SHARED_REQUIRES(Locks::mutator_lock_) {
    217     const DexFile::TypeList* classes = 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         size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    226         mirror::Class* dst_class =
    227             m->GetClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_,
    228                                      true /* resolve */,
    229                                      pointer_size);
    230         if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) {
    231           ThrowIllegalArgumentException(
    232               StringPrintf("method %s argument %zd has type %s, got %s",
    233                   PrettyMethod(m, false).c_str(),
    234                   args_offset + 1,  // Humans don't count from 0.
    235                   PrettyDescriptor(dst_class).c_str(),
    236                   PrettyTypeOf(arg).c_str()).c_str());
    237           return false;
    238         }
    239       }
    240 
    241 #define DO_FIRST_ARG(match_descriptor, get_fn, append) { \
    242           if (LIKELY(arg != nullptr && arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
    243             ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
    244             append(primitive_field-> get_fn(arg));
    245 
    246 #define DO_ARG(match_descriptor, get_fn, append) \
    247           } else if (LIKELY(arg != nullptr && \
    248                             arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
    249             ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
    250             append(primitive_field-> get_fn(arg));
    251 
    252 #define DO_FAIL(expected) \
    253           } else { \
    254             if (arg->GetClass<>()->IsPrimitive()) { \
    255               std::string temp; \
    256               ThrowIllegalPrimitiveArgumentException(expected, \
    257                                                      arg->GetClass<>()->GetDescriptor(&temp)); \
    258             } else { \
    259               ThrowIllegalArgumentException(\
    260                   StringPrintf("method %s argument %zd has type %s, got %s", \
    261                       PrettyMethod(m, false).c_str(), \
    262                       args_offset + 1, \
    263                       expected, \
    264                       PrettyTypeOf(arg).c_str()).c_str()); \
    265             } \
    266             return false; \
    267           } }
    268 
    269       switch (shorty_[i]) {
    270         case 'L':
    271           Append(arg);
    272           break;
    273         case 'Z':
    274           DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append)
    275           DO_FAIL("boolean")
    276           break;
    277         case 'B':
    278           DO_FIRST_ARG("Ljava/lang/Byte;", GetByte, Append)
    279           DO_FAIL("byte")
    280           break;
    281         case 'C':
    282           DO_FIRST_ARG("Ljava/lang/Character;", GetChar, Append)
    283           DO_FAIL("char")
    284           break;
    285         case 'S':
    286           DO_FIRST_ARG("Ljava/lang/Short;", GetShort, Append)
    287           DO_ARG("Ljava/lang/Byte;", GetByte, Append)
    288           DO_FAIL("short")
    289           break;
    290         case 'I':
    291           DO_FIRST_ARG("Ljava/lang/Integer;", GetInt, Append)
    292           DO_ARG("Ljava/lang/Character;", GetChar, Append)
    293           DO_ARG("Ljava/lang/Short;", GetShort, Append)
    294           DO_ARG("Ljava/lang/Byte;", GetByte, Append)
    295           DO_FAIL("int")
    296           break;
    297         case 'J':
    298           DO_FIRST_ARG("Ljava/lang/Long;", GetLong, AppendWide)
    299           DO_ARG("Ljava/lang/Integer;", GetInt, AppendWide)
    300           DO_ARG("Ljava/lang/Character;", GetChar, AppendWide)
    301           DO_ARG("Ljava/lang/Short;", GetShort, AppendWide)
    302           DO_ARG("Ljava/lang/Byte;", GetByte, AppendWide)
    303           DO_FAIL("long")
    304           break;
    305         case 'F':
    306           DO_FIRST_ARG("Ljava/lang/Float;", GetFloat, AppendFloat)
    307           DO_ARG("Ljava/lang/Long;", GetLong, AppendFloat)
    308           DO_ARG("Ljava/lang/Integer;", GetInt, AppendFloat)
    309           DO_ARG("Ljava/lang/Character;", GetChar, AppendFloat)
    310           DO_ARG("Ljava/lang/Short;", GetShort, AppendFloat)
    311           DO_ARG("Ljava/lang/Byte;", GetByte, AppendFloat)
    312           DO_FAIL("float")
    313           break;
    314         case 'D':
    315           DO_FIRST_ARG("Ljava/lang/Double;", GetDouble, AppendDouble)
    316           DO_ARG("Ljava/lang/Float;", GetFloat, AppendDouble)
    317           DO_ARG("Ljava/lang/Long;", GetLong, AppendDouble)
    318           DO_ARG("Ljava/lang/Integer;", GetInt, AppendDouble)
    319           DO_ARG("Ljava/lang/Character;", GetChar, AppendDouble)
    320           DO_ARG("Ljava/lang/Short;", GetShort, AppendDouble)
    321           DO_ARG("Ljava/lang/Byte;", GetByte, AppendDouble)
    322           DO_FAIL("double")
    323           break;
    324 #ifndef NDEBUG
    325         default:
    326           LOG(FATAL) << "Unexpected shorty character: " << shorty_[i];
    327           UNREACHABLE();
    328 #endif
    329       }
    330 #undef DO_FIRST_ARG
    331 #undef DO_ARG
    332 #undef DO_FAIL
    333     }
    334     return true;
    335   }
    336 
    337  private:
    338   enum { kSmallArgArraySize = 16 };
    339   const char* const shorty_;
    340   const uint32_t shorty_len_;
    341   uint32_t num_bytes_;
    342   uint32_t* arg_array_;
    343   uint32_t small_arg_array_[kSmallArgArraySize];
    344   std::unique_ptr<uint32_t[]> large_arg_array_;
    345 };
    346 
    347 static void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args)
    348     SHARED_REQUIRES(Locks::mutator_lock_) {
    349   const DexFile::TypeList* params = m->GetParameterTypeList();
    350   if (params == nullptr) {
    351     return;  // No arguments so nothing to check.
    352   }
    353   uint32_t offset = 0;
    354   uint32_t num_params = params->Size();
    355   size_t error_count = 0;
    356   if (!m->IsStatic()) {
    357     offset = 1;
    358   }
    359   // TODO: If args contain object references, it may cause problems.
    360   Thread* const self = Thread::Current();
    361   size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    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 = m->GetClassFromTypeIndex(type_idx,
    365                                                          true /* resolve*/,
    366                                                          pointer_size);
    367     if (param_type == nullptr) {
    368       CHECK(self->IsExceptionPending());
    369       LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
    370           << m->GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
    371           << self->GetException()->Dump();
    372       self->ClearException();
    373       ++error_count;
    374     } else if (!param_type->IsPrimitive()) {
    375       // TODO: There is a compaction bug here since GetClassFromTypeIdx can cause thread suspension,
    376       // this is a hard to fix problem since the args can contain Object*, we need to save and
    377       // restore them by using a visitor similar to the ones used in the trampoline entrypoints.
    378       mirror::Object* argument =
    379           (reinterpret_cast<StackReference<mirror::Object>*>(&args[i + offset]))->AsMirrorPtr();
    380       if (argument != nullptr && !argument->InstanceOf(param_type)) {
    381         LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
    382                    << PrettyTypeOf(argument) << " as argument " << (i + 1)
    383                    << " to " << PrettyMethod(m);
    384         ++error_count;
    385       }
    386     } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) {
    387       offset++;
    388     } else {
    389       int32_t arg = static_cast<int32_t>(args[i + offset]);
    390       if (param_type->IsPrimitiveBoolean()) {
    391         if (arg != JNI_TRUE && arg != JNI_FALSE) {
    392           LOG(ERROR) << "JNI ERROR (app bug): expected jboolean (0/1) but got value of "
    393               << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m);
    394           ++error_count;
    395         }
    396       } else if (param_type->IsPrimitiveByte()) {
    397         if (arg < -128 || arg > 127) {
    398           LOG(ERROR) << "JNI ERROR (app bug): expected jbyte but got value of "
    399               << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m);
    400           ++error_count;
    401         }
    402       } else if (param_type->IsPrimitiveChar()) {
    403         if (args[i + offset] > 0xFFFF) {
    404           LOG(ERROR) << "JNI ERROR (app bug): expected jchar but got value of "
    405               << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m);
    406           ++error_count;
    407         }
    408       } else if (param_type->IsPrimitiveShort()) {
    409         if (arg < -32768 || arg > 0x7FFF) {
    410           LOG(ERROR) << "JNI ERROR (app bug): expected jshort but got value of "
    411               << arg << " as argument " << (i + 1) << " to " << PrettyMethod(m);
    412           ++error_count;
    413         }
    414       }
    415     }
    416   }
    417   if (UNLIKELY(error_count > 0)) {
    418     // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort
    419     // with an argument.
    420     vm->JniAbortF(nullptr, "bad arguments passed to %s (see above for details)",
    421                   PrettyMethod(m).c_str());
    422   }
    423 }
    424 
    425 static ArtMethod* FindVirtualMethod(mirror::Object* receiver, ArtMethod* method)
    426     SHARED_REQUIRES(Locks::mutator_lock_) {
    427   return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method, sizeof(void*));
    428 }
    429 
    430 
    431 static void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa,
    432                                ArtMethod* method, ArgArray* arg_array, JValue* result,
    433                                const char* shorty)
    434     SHARED_REQUIRES(Locks::mutator_lock_) {
    435   uint32_t* args = arg_array->GetArray();
    436   if (UNLIKELY(soa.Env()->check_jni)) {
    437     CheckMethodArguments(soa.Vm(), method->GetInterfaceMethodIfProxy(sizeof(void*)), args);
    438   }
    439   method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, shorty);
    440 }
    441 
    442 JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid,
    443                          va_list args)
    444     SHARED_REQUIRES(Locks::mutator_lock_) {
    445   // We want to make sure that the stack is not within a small distance from the
    446   // protected region in case we are calling into a leaf function whose stack
    447   // check has been elided.
    448   if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
    449     ThrowStackOverflowError(soa.Self());
    450     return JValue();
    451   }
    452 
    453   ArtMethod* method = soa.DecodeMethod(mid);
    454   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
    455   if (is_string_init) {
    456     // Replace calls to String.<init> with equivalent StringFactory call.
    457     method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
    458   }
    459   mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
    460   uint32_t shorty_len = 0;
    461   const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len);
    462   JValue result;
    463   ArgArray arg_array(shorty, shorty_len);
    464   arg_array.BuildArgArrayFromVarArgs(soa, receiver, args);
    465   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
    466   if (is_string_init) {
    467     // For string init, remap original receiver to StringFactory result.
    468     UpdateReference(soa.Self(), obj, result.GetL());
    469   }
    470   return result;
    471 }
    472 
    473 JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid,
    474                          jvalue* args) {
    475   // We want to make sure that the stack is not within a small distance from the
    476   // protected region in case we are calling into a leaf function whose stack
    477   // check has been elided.
    478   if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
    479     ThrowStackOverflowError(soa.Self());
    480     return JValue();
    481   }
    482 
    483   ArtMethod* method = soa.DecodeMethod(mid);
    484   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
    485   if (is_string_init) {
    486     // Replace calls to String.<init> with equivalent StringFactory call.
    487     method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
    488   }
    489   mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
    490   uint32_t shorty_len = 0;
    491   const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len);
    492   JValue result;
    493   ArgArray arg_array(shorty, shorty_len);
    494   arg_array.BuildArgArrayFromJValues(soa, receiver, args);
    495   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
    496   if (is_string_init) {
    497     // For string init, remap original receiver to StringFactory result.
    498     UpdateReference(soa.Self(), obj, result.GetL());
    499   }
    500   return result;
    501 }
    502 
    503 JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
    504                                            jobject obj, jmethodID mid, jvalue* args) {
    505   // We want to make sure that the stack is not within a small distance from the
    506   // protected region in case we are calling into a leaf function whose stack
    507   // check has been elided.
    508   if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
    509     ThrowStackOverflowError(soa.Self());
    510     return JValue();
    511   }
    512 
    513   mirror::Object* receiver = soa.Decode<mirror::Object*>(obj);
    514   ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
    515   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
    516   if (is_string_init) {
    517     // Replace calls to String.<init> with equivalent StringFactory call.
    518     method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
    519     receiver = nullptr;
    520   }
    521   uint32_t shorty_len = 0;
    522   const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len);
    523   JValue result;
    524   ArgArray arg_array(shorty, shorty_len);
    525   arg_array.BuildArgArrayFromJValues(soa, receiver, args);
    526   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
    527   if (is_string_init) {
    528     // For string init, remap original receiver to StringFactory result.
    529     UpdateReference(soa.Self(), obj, result.GetL());
    530   }
    531   return result;
    532 }
    533 
    534 JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
    535                                            jobject obj, jmethodID mid, va_list args) {
    536   // We want to make sure that the stack is not within a small distance from the
    537   // protected region in case we are calling into a leaf function whose stack
    538   // check has been elided.
    539   if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
    540     ThrowStackOverflowError(soa.Self());
    541     return JValue();
    542   }
    543 
    544   mirror::Object* receiver = soa.Decode<mirror::Object*>(obj);
    545   ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
    546   bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor();
    547   if (is_string_init) {
    548     // Replace calls to String.<init> with equivalent StringFactory call.
    549     method = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
    550     receiver = nullptr;
    551   }
    552   uint32_t shorty_len = 0;
    553   const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len);
    554   JValue result;
    555   ArgArray arg_array(shorty, shorty_len);
    556   arg_array.BuildArgArrayFromVarArgs(soa, receiver, args);
    557   InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
    558   if (is_string_init) {
    559     // For string init, remap original receiver to StringFactory result.
    560     UpdateReference(soa.Self(), obj, result.GetL());
    561   }
    562   return result;
    563 }
    564 
    565 jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod,
    566                      jobject javaReceiver, jobject javaArgs, size_t num_frames) {
    567   // We want to make sure that the stack is not within a small distance from the
    568   // protected region in case we are calling into a leaf function whose stack
    569   // check has been elided.
    570   if (UNLIKELY(__builtin_frame_address(0) <
    571                soa.Self()->GetStackEndForInterpreter(true))) {
    572     ThrowStackOverflowError(soa.Self());
    573     return nullptr;
    574   }
    575 
    576   auto* abstract_method = soa.Decode<mirror::AbstractMethod*>(javaMethod);
    577   const bool accessible = abstract_method->IsAccessible();
    578   ArtMethod* m = abstract_method->GetArtMethod();
    579 
    580   mirror::Class* declaring_class = m->GetDeclaringClass();
    581   if (UNLIKELY(!declaring_class->IsInitialized())) {
    582     StackHandleScope<1> hs(soa.Self());
    583     Handle<mirror::Class> h_class(hs.NewHandle(declaring_class));
    584     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) {
    585       return nullptr;
    586     }
    587     declaring_class = h_class.Get();
    588   }
    589 
    590   mirror::Object* receiver = nullptr;
    591   if (!m->IsStatic()) {
    592     // Replace calls to String.<init> with equivalent StringFactory call.
    593     if (declaring_class->IsStringClass() && m->IsConstructor()) {
    594       jmethodID mid = soa.EncodeMethod(m);
    595       m = soa.DecodeMethod(WellKnownClasses::StringInitToStringFactoryMethodID(mid));
    596       CHECK(javaReceiver == nullptr);
    597     } else {
    598       // Check that the receiver is non-null and an instance of the field's declaring class.
    599       receiver = soa.Decode<mirror::Object*>(javaReceiver);
    600       if (!VerifyObjectIsClass(receiver, declaring_class)) {
    601         return nullptr;
    602       }
    603 
    604       // Find the actual implementation of the virtual method.
    605       m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m, sizeof(void*));
    606     }
    607   }
    608 
    609   // Get our arrays of arguments and their types, and check they're the same size.
    610   auto* objects = soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs);
    611   auto* np_method = m->GetInterfaceMethodIfProxy(sizeof(void*));
    612   const DexFile::TypeList* classes = np_method->GetParameterTypeList();
    613   uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size();
    614   uint32_t arg_count = (objects != nullptr) ? objects->GetLength() : 0;
    615   if (arg_count != classes_size) {
    616     ThrowIllegalArgumentException(StringPrintf("Wrong number of arguments; expected %d, got %d",
    617                                                classes_size, arg_count).c_str());
    618     return nullptr;
    619   }
    620 
    621   // If method is not set to be accessible, verify it can be accessed by the caller.
    622   mirror::Class* calling_class = nullptr;
    623   if (!accessible && !VerifyAccess(soa.Self(), receiver, declaring_class, m->GetAccessFlags(),
    624                                    &calling_class, num_frames)) {
    625     ThrowIllegalAccessException(
    626         StringPrintf("Class %s cannot access %s method %s of class %s",
    627             calling_class == nullptr ? "null" : PrettyClass(calling_class).c_str(),
    628             PrettyJavaAccessFlags(m->GetAccessFlags()).c_str(),
    629             PrettyMethod(m).c_str(),
    630             m->GetDeclaringClass() == nullptr ? "null" :
    631                 PrettyClass(m->GetDeclaringClass()).c_str()).c_str());
    632     return nullptr;
    633   }
    634 
    635   // Invoke the method.
    636   JValue result;
    637   uint32_t shorty_len = 0;
    638   const char* shorty = np_method->GetShorty(&shorty_len);
    639   ArgArray arg_array(shorty, shorty_len);
    640   if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method)) {
    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 
    672 mirror::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 
    737 static std::string UnboxingFailureKind(ArtField* f)
    738     SHARED_REQUIRES(Locks::mutator_lock_) {
    739   if (f != nullptr) {
    740     return "field " + PrettyField(f, false);
    741   }
    742   return "result";
    743 }
    744 
    745 static bool UnboxPrimitive(mirror::Object* o,
    746                            mirror::Class* dst_class, ArtField* f,
    747                            JValue* unboxed_value)
    748     SHARED_REQUIRES(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->GetIFieldsPtr()->At(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 
    827 bool 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 
    833 bool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue* unboxed_value) {
    834   return UnboxPrimitive(o, dst_class, nullptr, unboxed_value);
    835 }
    836 
    837 mirror::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 
    843 bool 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 
    857 bool 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 
    877 void 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.
    887 void 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