Stash the directly-implemented interfaces in Proxy so we can implement Class.getInterfaces.
Also extend test 044 to spot this (found by a libcore test).
Change-Id: I50019db49c549f045d94173c3ed9ae81f05ef858
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c65cf7d..38ce30a 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2166,13 +2166,21 @@
klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
- // Create static field that holds throws, instance fields are inherited
- klass->SetSFields(AllocObjectArray<Field>(1));
- SirtRef<Field> sfield(AllocField());
- klass->SetStaticField(0, sfield.get());
- sfield->SetDexFieldIndex(-1);
- sfield->SetDeclaringClass(klass.get());
- sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
+ // Instance fields are inherited, but we add a couple of static fields...
+ klass->SetSFields(AllocObjectArray<Field>(2));
+ // 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by
+ // our proxy, so Class.getInterfaces doesn't return the flattened set.
+ SirtRef<Field> interfaces_sfield(AllocField());
+ klass->SetStaticField(0, interfaces_sfield.get());
+ interfaces_sfield->SetDexFieldIndex(0);
+ interfaces_sfield->SetDeclaringClass(klass.get());
+ interfaces_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
+ // 2. Create a static field 'throws' that holds exceptions thrown by our methods.
+ SirtRef<Field> throws_sfield(AllocField());
+ klass->SetStaticField(1, throws_sfield.get());
+ throws_sfield->SetDexFieldIndex(1);
+ throws_sfield->SetDeclaringClass(klass.get());
+ throws_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
// Proxies have 1 direct method, the constructor
klass->SetDirectMethods(AllocObjectArray<Method>(1));
@@ -2195,7 +2203,8 @@
klass->SetStatus(Class::kStatusError);
return NULL;
}
- sfield->SetObject(NULL, throws); // initialize throws field
+ interfaces_sfield->SetObject(NULL, interfaces);
+ throws_sfield->SetObject(NULL, throws);
klass->SetStatus(Class::kStatusInitialized);
// sanity checks
@@ -2211,12 +2220,17 @@
SirtRef<Method> prototype(methods->Get(i));
CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
}
- std::string throws_field_name("java.lang.Class[][] ");
- throws_field_name += name->ToModifiedUtf8();
- throws_field_name += ".throws";
- CHECK(PrettyField(klass->GetStaticField(0)) == throws_field_name);
+
+ std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces",
+ name->ToModifiedUtf8().c_str()));
+ CHECK_EQ(PrettyField(klass->GetStaticField(0)), interfaces_field_name);
+
+ std::string throws_field_name(StringPrintf("java.lang.Class[][] %s.throws",
+ name->ToModifiedUtf8().c_str()));
+ CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name);
SynthesizedProxyClass* synth_proxy_class = down_cast<SynthesizedProxyClass*>(klass.get());
+ CHECK_EQ(synth_proxy_class->GetInterfaces(), interfaces);
CHECK_EQ(synth_proxy_class->GetThrows(), throws);
}
return klass.get();