diff options
author | Ian Rogers <irogers@google.com> | 2014-05-07 19:47:17 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-05-07 22:11:21 -0700 |
commit | a4cf1df04b3de24e69c044e0aae4c2573d6c37d1 (patch) | |
tree | 507b362e03d6cb18cc5f9b114bf35b2d6c3001c0 /runtime/verifier | |
parent | 410d87ff51e9432768924d2f294592818f93c244 (diff) | |
download | art-a4cf1df04b3de24e69c044e0aae4c2573d6c37d1.zip art-a4cf1df04b3de24e69c044e0aae4c2573d6c37d1.tar.gz art-a4cf1df04b3de24e69c044e0aae4c2573d6c37d1.tar.bz2 |
Allow invoke-virtual-quick on interface types.
Fix a broken assumption that receivers for invoke-virtual are non-interface
types.
Bug: 14469172
Change-Id: I0d6e19141d4f52a4bd27bf1cb5f8d0e85fc9cf49
Diffstat (limited to 'runtime/verifier')
-rw-r--r-- | runtime/verifier/method_verifier.cc | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index bf1de86..41ff96e 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3125,11 +3125,19 @@ mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'"; return nullptr; } - mirror::ObjectArray<mirror::ArtMethod>* vtable = actual_arg_type.GetClass()->GetVTable(); - CHECK(vtable != nullptr) << PrettyDescriptor(actual_arg_type.GetClass()); + mirror::ObjectArray<mirror::ArtMethod>* vtable = nullptr; + mirror::Class* klass = actual_arg_type.GetClass(); + if (klass->IsInterface()) { + // Derive Object.class from Class.class.getSuperclass(). + mirror::Class* object_klass = klass->GetClass()->GetSuperClass(); + CHECK(object_klass->IsObjectClass()); + vtable = object_klass->GetVTable(); + } else { + vtable = klass->GetVTable(); + } + CHECK(vtable != nullptr) << PrettyDescriptor(klass); uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - CHECK_LT(static_cast<int32_t>(vtable_index), vtable->GetLength()) - << PrettyDescriptor(actual_arg_type.GetClass()); + CHECK_LT(static_cast<int32_t>(vtable_index), vtable->GetLength()) << PrettyDescriptor(klass); mirror::ArtMethod* res_method = vtable->Get(vtable_index); CHECK(!Thread::Current()->IsExceptionPending()); return res_method; |