summaryrefslogtreecommitdiffstats
path: root/runtime/verifier
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-05-07 19:47:17 -0700
committerIan Rogers <irogers@google.com>2014-05-07 22:11:21 -0700
commita4cf1df04b3de24e69c044e0aae4c2573d6c37d1 (patch)
tree507b362e03d6cb18cc5f9b114bf35b2d6c3001c0 /runtime/verifier
parent410d87ff51e9432768924d2f294592818f93c244 (diff)
downloadart-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.cc16
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;