summaryrefslogtreecommitdiff
path: root/src/object.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.cc')
-rw-r--r--src/object.cc95
1 files changed, 82 insertions, 13 deletions
diff --git a/src/object.cc b/src/object.cc
index aeaa19b24d..e8aeecdaff 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -201,12 +201,12 @@ void Field::SetChar(Object* object, uint16_t c) const {
Set32(object, c);
}
-uint16_t Field::GetShort(const Object* object) const {
+int16_t Field::GetShort(const Object* object) const {
DCHECK(GetType()->IsPrimitiveShort());
return Get32(object);
}
-void Field::SetShort(Object* object, uint16_t s) const {
+void Field::SetShort(Object* object, int16_t s) const {
DCHECK(GetType()->IsPrimitiveShort());
Set32(object, s);
}
@@ -560,9 +560,28 @@ size_t Method::ReturnSize() const {
return ShortyCharToSize(GetShorty()->CharAt(0));
}
-bool Method::HasSameNameAndDescriptor(const Method* that) const {
- return (this->GetName()->Equals(that->GetName()) &&
- this->GetSignature()->Equals(that->GetSignature()));
+Method* Method::FindOverriddenMethod() const {
+ if (IsStatic()) {
+ return NULL;
+ }
+ Class* declaring_class = GetDeclaringClass();
+ Class* super_class = declaring_class->GetSuperClass();
+ uint16_t method_index = GetMethodIndex();
+ ObjectArray<Method>* super_class_vtable = super_class->GetVTable();
+ Method* result = NULL;
+ if (super_class_vtable != NULL && method_index < super_class_vtable->GetLength()) {
+ result = super_class_vtable->Get(method_index);
+ } else {
+ ObjectArray<Class>* interfaces = declaring_class->GetInterfaces();
+ String* name = GetName();
+ String* signature = GetSignature();
+ for (int32_t i = 0; i < interfaces->GetLength() && result == NULL; i++) {
+ Class* interface = interfaces->Get(i);
+ result = interface->FindInterfaceMethod(name, signature);
+ }
+ }
+ DCHECK (result == NULL || HasSameNameAndSignature(result));
+ return result;
}
uint32_t Method::ToDexPC(const uintptr_t pc) const {
@@ -990,8 +1009,7 @@ Method* Class::FindVirtualMethodForInterface(Method* method) {
return NULL;
}
-Method* Class::FindInterfaceMethod(const StringPiece& name,
- const StringPiece& signature) {
+Method* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
// Check the current class before checking the interfaces.
Method* method = FindVirtualMethod(name, signature);
if (method != NULL) {
@@ -1009,6 +1027,24 @@ Method* Class::FindInterfaceMethod(const StringPiece& name,
return NULL;
}
+Method* Class::FindInterfaceMethod(String* name, String* signature) const {
+ // Check the current class before checking the interfaces.
+ Method* method = FindVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ int32_t iftable_count = GetIfTableCount();
+ ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ Class* interface = iftable->Get(i)->GetInterface();
+ method = interface->FindVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
const StringPiece& signature) {
for (size_t i = 0; i < NumDirectMethods(); ++i) {
@@ -1033,20 +1069,41 @@ Method* Class::FindDirectMethod(const StringPiece& name,
}
Method* Class::FindDeclaredVirtualMethod(const StringPiece& name,
- const StringPiece& signature) {
+ const StringPiece& signature) const {
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
Method* method = GetVirtualMethod(i);
- if (method->GetName()->Equals(name) &&
- method->GetSignature()->Equals(signature)) {
+ if (method->GetName()->Equals(name) && method->GetSignature()->Equals(signature)) {
return method;
}
}
return NULL;
}
-Method* Class::FindVirtualMethod(const StringPiece& name,
- const StringPiece& signature) {
- for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+Method* Class::FindDeclaredVirtualMethod(String* name, String* signature) const {
+ for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+ Method* method = GetVirtualMethod(i);
+ if (method->GetName() == name && method->GetSignature() == signature) {
+ return method;
+ } else {
+ LOG(INFO) << "Find (" << name->ToModifiedUtf8() << ", " << signature->ToModifiedUtf8()
+ << ") != " << PrettyMethod(method);
+ }
+ }
+ return NULL;
+}
+
+Method* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ Method* method = klass->FindDeclaredVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+Method* Class::FindVirtualMethod(String* name, String* signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
Method* method = klass->FindDeclaredVirtualMethod(name, signature);
if (method != NULL) {
return method;
@@ -1175,6 +1232,9 @@ template class PrimitiveArray<int32_t>; // IntArray
template class PrimitiveArray<int64_t>; // LongArray
template class PrimitiveArray<int16_t>; // ShortArray
+// Explicitly instantiate Class[][]
+template class ObjectArray<ObjectArray<Class> >;
+
// TODO: get global references for these
Class* String::java_lang_String_ = NULL;
@@ -1350,6 +1410,15 @@ std::string String::ToModifiedUtf8() const {
return result;
}
+bool Throwable::IsCheckedException() const {
+ Class* error = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Error;");
+ if (InstanceOf(error)) {
+ return false;
+ }
+ Class* jlre = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/RuntimeException;");
+ return !InstanceOf(jlre);
+}
+
Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {