diff options
Diffstat (limited to 'runtime/reflection.cc')
| -rw-r--r-- | runtime/reflection.cc | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 4d2450135e..a2b4cb37a9 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -216,43 +216,54 @@ class ArgArray { } bool BuildArgArrayFromObjectArray(ObjPtr<mirror::Object> receiver, - ObjPtr<mirror::ObjectArray<mirror::Object>> args, - ArtMethod* m) + ObjPtr<mirror::ObjectArray<mirror::Object>> raw_args, + ArtMethod* m, + Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { const DexFile::TypeList* classes = m->GetParameterTypeList(); // Set receiver if non-null (method is not static) if (receiver != nullptr) { Append(receiver); } + StackHandleScope<2> hs(self); + MutableHandle<mirror::Object> arg(hs.NewHandle<mirror::Object>(nullptr)); + Handle<mirror::ObjectArray<mirror::Object>> args( + hs.NewHandle<mirror::ObjectArray<mirror::Object>>(raw_args)); for (size_t i = 1, args_offset = 0; i < shorty_len_; ++i, ++args_offset) { - ObjPtr<mirror::Object> arg(args->Get(args_offset)); - if (((shorty_[i] == 'L') && (arg != nullptr)) || ((arg == nullptr && shorty_[i] != 'L'))) { - PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + arg.Assign(args->Get(args_offset)); + if (((shorty_[i] == 'L') && (arg.Get() != nullptr)) || + ((arg.Get() == nullptr && shorty_[i] != 'L'))) { + // TODO: The method's parameter's type must have been previously resolved, yet + // we've seen cases where it's not b/34440020. ObjPtr<mirror::Class> dst_class( m->GetClassFromTypeIndex(classes->GetTypeItem(args_offset).type_idx_, - true /* resolve */, - pointer_size)); - if (UNLIKELY(arg == nullptr || !arg->InstanceOf(dst_class))) { + true /* resolve */)); + if (dst_class.Ptr() == nullptr) { + CHECK(self->IsExceptionPending()); + return false; + } + if (UNLIKELY(arg.Get() == nullptr || !arg->InstanceOf(dst_class))) { ThrowIllegalArgumentException( StringPrintf("method %s argument %zd has type %s, got %s", m->PrettyMethod(false).c_str(), args_offset + 1, // Humans don't count from 0. mirror::Class::PrettyDescriptor(dst_class).c_str(), - mirror::Object::PrettyTypeOf(arg).c_str()).c_str()); + mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str()); return false; } } #define DO_FIRST_ARG(match_descriptor, get_fn, append) { \ - if (LIKELY(arg != nullptr && arg->GetClass()->DescriptorEquals(match_descriptor))) { \ + if (LIKELY(arg.Get() != nullptr && \ + arg->GetClass()->DescriptorEquals(match_descriptor))) { \ ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ - append(primitive_field-> get_fn(arg)); + append(primitive_field-> get_fn(arg.Get())); #define DO_ARG(match_descriptor, get_fn, append) \ - } else if (LIKELY(arg != nullptr && \ + } else if (LIKELY(arg.Get() != nullptr && \ arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \ ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \ - append(primitive_field-> get_fn(arg)); + append(primitive_field-> get_fn(arg.Get())); #define DO_FAIL(expected) \ } else { \ @@ -266,14 +277,14 @@ class ArgArray { ArtMethod::PrettyMethod(m, false).c_str(), \ args_offset + 1, \ expected, \ - mirror::Object::PrettyTypeOf(arg).c_str()).c_str()); \ + mirror::Object::PrettyTypeOf(arg.Get()).c_str()).c_str()); \ } \ return false; \ } } switch (shorty_[i]) { case 'L': - Append(arg); + Append(arg.Get()); break; case 'Z': DO_FIRST_ARG("Ljava/lang/Boolean;", GetBoolean, Append) @@ -363,12 +374,9 @@ static void CheckMethodArguments(JavaVMExt* vm, ArtMethod* m, uint32_t* args) } // TODO: If args contain object references, it may cause problems. Thread* const self = Thread::Current(); - PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); for (uint32_t i = 0; i < num_params; i++) { dex::TypeIndex type_idx = params->GetTypeItem(i).type_idx_; - ObjPtr<mirror::Class> param_type(m->GetClassFromTypeIndex(type_idx, - true /* resolve*/, - pointer_size)); + ObjPtr<mirror::Class> param_type(m->GetClassFromTypeIndex(type_idx, true /* resolve */)); if (param_type == nullptr) { CHECK(self->IsExceptionPending()); LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: " @@ -649,7 +657,7 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM uint32_t shorty_len = 0; const char* shorty = np_method->GetShorty(&shorty_len); ArgArray arg_array(shorty, shorty_len); - if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method)) { + if (!arg_array.BuildArgArrayFromObjectArray(receiver, objects, np_method, soa.Self())) { CHECK(soa.Self()->IsExceptionPending()); return nullptr; } |