diff options
| -rw-r--r-- | runtime/class_linker.cc | 3 | ||||
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 26 | ||||
| -rw-r--r-- | test/Android.run-test.mk | 1 |
3 files changed, 27 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index c80f91a7b8..e4f492b221 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4104,9 +4104,10 @@ ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, ArtMethod void ClassLinker::CreateProxyConstructor(Handle<mirror::Class> klass, ArtMethod* out) { // Create constructor for Proxy that must initialize the method. - CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 19u); + CHECK_EQ(GetClassRoot(kJavaLangReflectProxy)->NumDirectMethods(), 18u); ArtMethod* proxy_constructor = GetClassRoot(kJavaLangReflectProxy)->GetDirectMethodUnchecked( 2, image_pointer_size_); + DCHECK_EQ(std::string(proxy_constructor->GetName()), "<init>"); // Ensure constructor is in dex cache so that we can use the dex cache to look up the overridden // constructor method. GetClassRoot(kJavaLangReflectProxy)->GetDexCache()->SetResolvedMethod( diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 0663b7ef78..51611753c8 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -316,7 +316,31 @@ inline ArtField* FindFieldFromCode(uint32_t field_idx, ArtMethod* referrer, default: is_primitive = true; is_set = true; is_static = true; break; } ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static); + + ArtField* resolved_field; + if (access_check) { + // Slow path: According to JLS 13.4.8, a linkage error may occur if a compile-time + // qualifying type of a field and the resolved run-time qualifying type of a field differed + // in their static-ness. + // + // In particular, don't assume the dex instruction already correctly knows if the + // real field is static or not. The resolution must not be aware of this. + ArtMethod* method = referrer->GetInterfaceMethodIfProxy(sizeof(void*)); + + StackHandleScope<2> hs(self); + Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(method->GetDexCache())); + Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(method->GetClassLoader())); + + resolved_field = class_linker->ResolveFieldJLS(*method->GetDexFile(), + field_idx, + h_dex_cache, + h_class_loader); + } else { + // Fast path: Verifier already would've called ResolveFieldJLS and we wouldn't + // be executing here if there was a static/non-static mismatch. + resolved_field = class_linker->ResolveField(field_idx, referrer, is_static); + } + if (UNLIKELY(resolved_field == nullptr)) { DCHECK(self->IsExceptionPending()); // Throw exception and unwind. return nullptr; // Failure. diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index e48694c4a5..870b51468a 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -302,7 +302,6 @@ TEST_ART_BROKEN_NO_RELOCATE_TESTS := # Temporarily disable some broken tests when forcing access checks in interpreter b/22414682 TEST_ART_BROKEN_INTERPRETER_ACCESS_CHECK_TESTS := \ - 073-mismatched-field \ 135-MirandaDispatch \ 137-cfi \ 412-new-array \ |