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.cc b/src/object.cc
index 7b47d9f..f47f16e 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -103,8 +103,24 @@
}
Class* Field::GetType() const {
- // Do full linkage (which sets dex cache value to speed next call)
- return Runtime::Current()->GetClassLinker()->ResolveType(GetTypeIdx(), this);
+ if (type_ == NULL) {
+ type_ = Runtime::Current()->GetClassLinker()->ResolveType(GetTypeIdx(), this);
+ }
+ return type_;
+}
+
+void Field::InitJavaFields() {
+ Thread* self = Thread::Current();
+ ScopedThreadStateChange tsc(self, Thread::kRunnable);
+ MonitorEnter(self);
+ if (type_ == NULL) {
+ InitJavaFieldsLocked();
+ }
+ MonitorExit(self);
+}
+
+void Field::InitJavaFieldsLocked() {
+ GetType(); // Sets type_ as a side-effect. May throw.
}
Field* Field::FindInstanceFieldFromCode(uint32_t field_idx, const Method* referrer) {
@@ -308,15 +324,23 @@
}
// TODO: get global references for these
+Class* Method::java_lang_reflect_Constructor_ = NULL;
Class* Method::java_lang_reflect_Method_ = NULL;
-void Method::SetClass(Class* java_lang_reflect_Method) {
+void Method::SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method) {
+ CHECK(java_lang_reflect_Constructor_ == NULL);
+ CHECK(java_lang_reflect_Constructor != NULL);
+ java_lang_reflect_Constructor_ = java_lang_reflect_Constructor;
+
CHECK(java_lang_reflect_Method_ == NULL);
CHECK(java_lang_reflect_Method != NULL);
java_lang_reflect_Method_ = java_lang_reflect_Method;
}
-void Method::ResetClass() {
+void Method::ResetClasses() {
+ CHECK(java_lang_reflect_Constructor_ != NULL);
+ java_lang_reflect_Constructor_ = NULL;
+
CHECK(java_lang_reflect_Method_ != NULL);
java_lang_reflect_Method_ = NULL;
}
@@ -648,7 +672,7 @@
!iter.HasNext(); iter.Next()) {
uint32_t iter_type_idx = iter.Get().type_idx_;
// Catch all case
- if(iter_type_idx == DexFile::kDexNoIndex) {
+ if (iter_type_idx == DexFile::kDexNoIndex) {
return iter.Get().address_;
}
// Does this catch exception type apply?
@@ -1186,6 +1210,19 @@
return Alloc(array_class, component_count, array_class->GetComponentSize());
}
+bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
+ Thread::Current()->ThrowNewException("Ljava/lang/ArrayIndexOutOfBoundsException;",
+ "length=%i; index=%i", length_, index);
+ return false;
+}
+
+bool Array::ThrowArrayStoreException(Object* object) const {
+ Thread::Current()->ThrowNewException("Ljava/lang/ArrayStoreException;",
+ "Can't store an element of type %s into an array of type %s",
+ PrettyTypeOf(object).c_str(), PrettyTypeOf(this).c_str());
+ return false;
+}
+
template<typename T>
PrimitiveArray<T>* PrimitiveArray<T>::Alloc(size_t length) {
DCHECK(array_class_ != NULL);