summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sebastien Hertz <shertz@google.com> 2014-04-01 14:39:44 +0200
committer Sebastien Hertz <shertz@google.com> 2014-04-01 15:20:11 +0200
commit80989a6bf3e24b31c7210c76be81ad40f43c63be (patch)
tree6e3365de360d3d02c14ce614e1755620e8b9f7bb
parenta708e32a9f764a48175e705ec4bcd2201c84f492 (diff)
Fix ClassHelper::GetDirectInterface for proxy class
Returns only the direct interfaces implemented by the proxy class. We collect them from the "interfaces" field in the synthesized proxy class instead of looking into the iftable. Also updates proxy_test to reflect this change. Bug: 13689930 Change-Id: I926e2ed30f9e65972d700a378671cec82dedaa7c
-rw-r--r--runtime/object_utils.h10
-rw-r--r--runtime/proxy_test.cc65
2 files changed, 64 insertions, 11 deletions
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 63801d3a3f..072f074e85 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -25,6 +25,7 @@
#include "mirror/class.h"
#include "mirror/dex_cache.h"
#include "mirror/iftable.h"
+#include "mirror/proxy.h"
#include "mirror/string.h"
#include "runtime.h"
@@ -133,7 +134,9 @@ class ClassHelper {
} else if (klass_->IsArrayClass()) {
return 2;
} else if (klass_->IsProxyClass()) {
- return klass_->GetIfTable()->Count();
+ mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
+ mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
+ return interfaces != nullptr ? interfaces->GetLength() : 0;
} else {
const DexFile::TypeList* interfaces = GetInterfaceTypeList();
if (interfaces == nullptr) {
@@ -164,7 +167,10 @@ class ClassHelper {
return GetClassLinker()->FindSystemClass(Thread::Current(), "Ljava/io/Serializable;");
}
} else if (klass_->IsProxyClass()) {
- return klass_->GetIfTable()->GetInterface(idx);
+ mirror::SynthesizedProxyClass* proxyClass = reinterpret_cast<mirror::SynthesizedProxyClass*>(klass_);
+ mirror::ObjectArray<mirror::Class>* interfaces = proxyClass->GetInterfaces();
+ DCHECK(interfaces != nullptr);
+ return interfaces->Get(idx);
} else {
uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index 6453cb4d48..eebfba8798 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -107,7 +107,8 @@ class ProxyTest : public CommonCompilerTest {
TEST_F(ProxyTest, ProxyClassHelper) {
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("Interfaces");
- SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
+ soa.Decode<mirror::ClassLoader*>(jclass_loader));
mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
@@ -120,20 +121,66 @@ TEST_F(ProxyTest, ProxyClassHelper) {
mirror::Class* proxyClass = GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces);
ASSERT_TRUE(proxyClass != nullptr);
ASSERT_TRUE(proxyClass->IsProxyClass());
-
- mirror::Class* javaIoSerializable = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/Serializable;");
- ASSERT_TRUE(javaIoSerializable != nullptr);
+ ASSERT_TRUE(proxyClass->IsInitialized());
// Check ClassHelper for proxy.
ClassHelper kh(proxyClass);
- EXPECT_EQ(kh.NumDirectInterfaces(), 3U); // java.io.Serializable, Interfaces$I and Interfaces$J.
- EXPECT_EQ(javaIoSerializable, kh.GetDirectInterface(0));
- EXPECT_EQ(I, kh.GetDirectInterface(1));
- EXPECT_EQ(J, kh.GetDirectInterface(2));
+ EXPECT_EQ(kh.NumDirectInterfaces(), 2U); // Interfaces$I and Interfaces$J.
+ EXPECT_EQ(I, kh.GetDirectInterface(0));
+ EXPECT_EQ(J, kh.GetDirectInterface(1));
std::string proxyClassDescriptor(kh.GetDescriptor());
EXPECT_EQ("L$Proxy1234;", proxyClassDescriptor);
-// EXPECT_EQ(nullptr, kh.GetSourceFile());
}
+// Creates a proxy class and check FieldHelper works correctly.
+TEST_F(ProxyTest, ProxyFieldHelper) {
+ ScopedObjectAccess soa(Thread::Current());
+ jobject jclass_loader = LoadDex("Interfaces");
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
+ soa.Decode<mirror::ClassLoader*>(jclass_loader));
+
+ mirror::Class* I = class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader);
+ mirror::Class* J = class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader);
+ ASSERT_TRUE(I != nullptr);
+ ASSERT_TRUE(J != nullptr);
+ std::vector<mirror::Class*> interfaces;
+ interfaces.push_back(I);
+ interfaces.push_back(J);
+
+ mirror::Class* proxyClass = GenerateProxyClass(soa, jclass_loader, "$Proxy1234", interfaces);
+ ASSERT_TRUE(proxyClass != nullptr);
+ ASSERT_TRUE(proxyClass->IsProxyClass());
+ ASSERT_TRUE(proxyClass->IsInitialized());
+
+ mirror::ObjectArray<mirror::ArtField>* instance_fields = proxyClass->GetIFields();
+ EXPECT_TRUE(instance_fields == nullptr);
+
+ mirror::ObjectArray<mirror::ArtField>* static_fields = proxyClass->GetSFields();
+ ASSERT_TRUE(static_fields != nullptr);
+ ASSERT_EQ(2, static_fields->GetLength());
+
+ mirror::Class* interfacesFieldClass = class_linker_->FindSystemClass(soa.Self(),
+ "[Ljava/lang/Class;");
+ ASSERT_TRUE(interfacesFieldClass != nullptr);
+ mirror::Class* throwsFieldClass = class_linker_->FindSystemClass(soa.Self(),
+ "[[Ljava/lang/Class;");
+ ASSERT_TRUE(throwsFieldClass != nullptr);
+
+ // Test "Class[] interfaces" field.
+ FieldHelper fh(static_fields->Get(0));
+ EXPECT_EQ("interfaces", std::string(fh.GetName()));
+ EXPECT_EQ("[Ljava/lang/Class;", std::string(fh.GetTypeDescriptor()));
+ EXPECT_EQ(interfacesFieldClass, fh.GetType());
+ EXPECT_EQ("L$Proxy1234;", std::string(fh.GetDeclaringClassDescriptor()));
+ EXPECT_FALSE(fh.IsPrimitiveType());
+
+ // Test "Class[][] throws" field.
+ fh.ChangeField(static_fields->Get(1));
+ EXPECT_EQ("throws", std::string(fh.GetName()));
+ EXPECT_EQ("[[Ljava/lang/Class;", std::string(fh.GetTypeDescriptor()));
+ EXPECT_EQ(throwsFieldClass, fh.GetType());
+ EXPECT_EQ("L$Proxy1234;", std::string(fh.GetDeclaringClassDescriptor()));
+ EXPECT_FALSE(fh.IsPrimitiveType());
+}
} // namespace art