interpreter: Fix proxy method invocation with access checks enabled.
Interpret with access checks uses type information stored by a dex file,
so we need to get the original interface method (which is guaranteed
to be dex file backed) in that case.
Does not change method invoke target, just the method used for checks.
The existing 044-proxy test already covers this, so no regression test
necessary. Remove fixed tests from the blacklist.
Bug: 26846861
Bug: 22414682
Change-Id: I28c3707e38c1f69ea9d3660f68136f688122ac4e
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 6c9cc70..09d8601 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -637,17 +637,25 @@
self, new_shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction);
self->EndAssertNoThreadSuspension(old_cause);
+ // ArtMethod here is needed to check type information of the call site against the callee.
+ // Type information is retrieved from a DexFile/DexCache for that respective declared method.
+ //
+ // As a special case for proxy methods, which are not dex-backed,
+ // we have to retrieve type information from the proxy's method
+ // interface method instead (which is dex backed since proxies are never interfaces).
+ ArtMethod* method = new_shadow_frame->GetMethod()->GetInterfaceMethodIfProxy(sizeof(void*));
+
// We need to do runtime check on reference assignment. We need to load the shorty
// to get the exact type of each reference argument.
- const DexFile::TypeList* params = new_shadow_frame->GetMethod()->GetParameterTypeList();
+ const DexFile::TypeList* params = method->GetParameterTypeList();
uint32_t shorty_len = 0;
- const char* shorty = new_shadow_frame->GetMethod()->GetShorty(&shorty_len);
+ const char* shorty = method->GetShorty(&shorty_len);
// Handle receiver apart since it's not part of the shorty.
size_t dest_reg = first_dest_reg;
size_t arg_offset = 0;
- if (!new_shadow_frame->GetMethod()->IsStatic()) {
+ if (!method->IsStatic()) {
size_t receiver_reg = is_range ? vregC : arg[0];
new_shadow_frame->SetVRegReference(dest_reg, shadow_frame.GetVRegReference(receiver_reg));
++dest_reg;
@@ -667,7 +675,7 @@
if (do_assignability_check && o != nullptr) {
size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
Class* arg_type =
- new_shadow_frame->GetMethod()->GetClassFromTypeIndex(
+ method->GetClassFromTypeIndex(
params->GetTypeItem(shorty_pos).type_idx_, true /* resolve */, pointer_size);
if (arg_type == nullptr) {
CHECK(self->IsExceptionPending());
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 7400248..b79602a 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -302,17 +302,12 @@
# Temporarily disable some broken tests when forcing access checks in interpreter b/22414682
TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := \
- 004-JniTest \
- 005-annotations \
- 044-proxy \
073-mismatched-field \
- 088-monitor-verification \
135-MirandaDispatch \
137-cfi \
412-new-array \
471-uninitialized-locals \
506-verify-aput \
- 554-jit-profile-file \
800-smali
ifneq (,$(filter interp-ac,$(COMPILER_TYPES)))