Implement Class.getDeclared(Constructors|Fields|Methods).
This required making sure that a Method* that represents a constructor
has java.lang.reflect.Constructor as its class.
Change-Id: I25908845a2b8d686d5404ac584693db0edd5853c
diff --git a/src/object.h b/src/object.h
index 69f8c14..ba8aaa9 100644
--- a/src/object.h
+++ b/src/object.h
@@ -442,12 +442,16 @@
false);
}
+ bool IsPublic() const {
+ return (GetAccessFlags() & kAccPublic) != 0;
+ }
+
bool IsStatic() const {
return (GetAccessFlags() & kAccStatic) != 0;
}
bool IsFinal() const {
- return (access_flags_ & kAccFinal) != 0;
+ return (GetAccessFlags() & kAccFinal) != 0;
}
uint32_t GetTypeIdx() const;
@@ -524,6 +528,8 @@
return (GetAccessFlags() & kAccVolatile) != 0;
}
+ void InitJavaFields();
+
private:
// private implementation of field access using raw data
uint32_t Get32(const Object* object) const;
@@ -533,6 +539,8 @@
Object* GetObj(const Object* object) const;
void SetObj(Object* object, const Object* new_value) const;
+ void InitJavaFieldsLocked();
+
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class in which this field is declared.
@@ -543,7 +551,7 @@
const String* name_;
// Type of the field
- Class* type_;
+ mutable Class* type_;
uint32_t generic_types_are_initialized_;
@@ -642,17 +650,18 @@
return (GetAccessFlags() & synchonized) != 0;
}
- // Returns true if the method is declared final.
bool IsFinal() const {
return (GetAccessFlags() & kAccFinal) != 0;
}
- // Returns true if the method is declared native.
+ bool IsMiranda() const {
+ return (GetAccessFlags() & kAccMiranda) != 0;
+ }
+
bool IsNative() const {
return (GetAccessFlags() & kAccNative) != 0;
}
- // Returns true if the method is declared abstract.
bool IsAbstract() const {
return (GetAccessFlags() & kAccAbstract) != 0;
}
@@ -947,14 +956,17 @@
// Find the catch block for the given exception type and dex_pc
uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc) const;
- static Class* GetJavaLangReflectMethod() {
- DCHECK(java_lang_reflect_Method_ != NULL);
+ static void SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method);
+
+ static Class* GetConstructorClass() {
+ return java_lang_reflect_Constructor_;
+ }
+
+ static Class* GetMethodClass() {
return java_lang_reflect_Method_;
}
- static void SetClass(Class* java_lang_reflect_Method);
- static Class* GetMethodClass() { return java_lang_reflect_Method_; }
- static void ResetClass();
+ static void ResetClasses();
void InitJavaFields();
@@ -1079,6 +1091,7 @@
uint32_t java_slot_;
+ static Class* java_lang_reflect_Constructor_;
static Class* java_lang_reflect_Method_;
friend class ImageWriter; // for relocating code_ and invoke_stub_
@@ -1125,14 +1138,15 @@
protected:
bool IsValidIndex(int32_t index) const {
if (index < 0 || index >= length_) {
- Thread* self = Thread::Current();
- self->ThrowNewException("Ljava/lang/ArrayIndexOutOfBoundsException;",
- "length=%i; index=%i", length_, index);
- return false;
+ return ThrowArrayIndexOutOfBoundsException(index);
}
return true;
}
+ protected:
+ bool ThrowArrayIndexOutOfBoundsException(int32_t index) const;
+ bool ThrowArrayStoreException(Object* object) const;
+
private:
// The number of array elements.
int32_t length_;
@@ -2097,10 +2111,8 @@
}
inline bool Object::IsMethod() const {
- Class* java_lang_Class = GetClass()->GetClass();
- Class* java_lang_reflect_Method =
- java_lang_Class->GetDirectMethod(0)->GetClass();
- return GetClass() == java_lang_reflect_Method;
+ Class* c = GetClass();
+ return c == Method::GetMethodClass() || c == Method::GetConstructorClass();
}
inline bool Object::IsReferenceInstance() const {
@@ -2209,9 +2221,10 @@
if (IsValidIndex(i)) {
if (object != NULL) {
Class* element_class = GetClass()->GetComponentType();
- DCHECK(!element_class->IsPrimitive());
- // TODO: ArrayStoreException
- CHECK(object->InstanceOf(element_class));
+ if (!object->InstanceOf(element_class)) {
+ ThrowArrayStoreException(object);
+ return;
+ }
}
MemberOffset data_offset(DataOffset().Int32Value() + i * sizeof(Object*));
SetFieldObject(data_offset, object, false);
@@ -2251,8 +2264,10 @@
CHECK(!element_class->IsPrimitive());
for (size_t i=0; i < length; i++) {
Object* object = src->GetFieldObject<Object*>(src_offset, false);
- // TODO: ArrayStoreException
- CHECK(object == NULL || object->InstanceOf(element_class));
+ if (object != NULL && !object->InstanceOf(element_class)) {
+ dst->ThrowArrayStoreException(object);
+ return;
+ }
dst->SetFieldObject(dst_offset, object, false);
src_offset = MemberOffset(src_offset.Uint32Value() + sizeof(Object*));
dst_offset = MemberOffset(dst_offset.Uint32Value() + sizeof(Object*));
@@ -2567,9 +2582,10 @@
// Check class is loaded or this is java.lang.String that has a
// circularity issue during loading the names of its members
DCHECK(IsLoaded() || IsErroneous() ||
- this == String::GetJavaLangString() ||
- this == Field::GetJavaLangReflectField() ||
- this == Method::GetJavaLangReflectMethod()) << PrettyClass(this);
+ this == String::GetJavaLangString() ||
+ this == Field::GetJavaLangReflectField() ||
+ this == Method::GetConstructorClass() ||
+ this == Method::GetMethodClass()) << PrettyClass(this);
return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
}