Finish implementation of ResolveField and ResolveMethod
Change-Id: I854e17b4cccd05b26f83c77230f7323c898802c9
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 7a93d48..e3912d1 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1866,7 +1866,7 @@
uint32_t method_idx,
DexCache* dex_cache,
const ClassLoader* class_loader,
- /*MethodType*/ int method_type) {
+ bool is_direct) {
Method* resolved = dex_cache->GetResolvedMethod(method_idx);
if (resolved != NULL) {
return resolved;
@@ -1877,8 +1877,13 @@
return NULL;
}
- // TODO resolve using class, method_id, and method type.
- // resolved = ...
+ const char* name = dex_file.dexStringById(method_id.name_idx_);
+ const char* signature = dex_file.CreateMethodDescriptor(method_id.proto_idx_, NULL);
+ if (is_direct) {
+ resolved = klass->FindDirectMethod(name, signature);
+ } else {
+ resolved = klass->FindVirtualMethod(name, signature);
+ }
if (resolved != NULL) {
dex_cache->SetResolvedMethod(method_idx, resolved);
} else {
@@ -1902,8 +1907,13 @@
return NULL;
}
- // TODO resolve using class, field_id, and is_static.
- // resolved = ...
+ const char* name = dex_file.dexStringById(field_id.name_idx_);
+ const char* type = dex_file.dexStringByTypeIdx(field_id.type_idx_);
+ if (is_static) {
+ resolved = klass->FindStaticField(name, type);
+ } else {
+ resolved = klass->FindInstanceField(name, type);
+ }
if (resolved != NULL) {
dex_cache->SetResolvedfield(field_idx, resolved);
} else {
diff --git a/src/class_linker.h b/src/class_linker.h
index 4cf82c6..cb21cb1 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -74,7 +74,7 @@
uint32_t method_idx,
DexCache* dex_cache,
const ClassLoader* class_loader,
- /*MethodType*/ int method_type);
+ bool is_direct);
// Resolve a method with a given ID from the DexFile, storing the
// result in DexCache. The ClassLinker and ClassLoader are used as
diff --git a/src/compiler.cc b/src/compiler.cc
index 52babf7..0324586 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -46,14 +46,18 @@
class_linker->ResolveType(dex_file, i, dex_cache, class_loader);
}
for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
- // TODO: move resolution into compiler proper where we will know method_type
- int method_type = 0;
- class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, method_type);
+ // unknown if direct or virtual, try both
+ Method* method = class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, false);
+ if (method == NULL) {
+ class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, true);
+ }
}
for (size_t i = 0; i < dex_cache->NumFields(); i++) {
- // TODO: move resolution into compiler proper where we will know is_static
- bool is_static = false;
- class_linker->ResolveField(dex_file, i, dex_cache, class_loader, is_static);
+ // unknown if instance or static, try both
+ Field* field = class_linker->ResolveField(dex_file, i, dex_cache, class_loader, false);
+ if (field == NULL) {
+ class_linker->ResolveMethod(dex_file, i, dex_cache, class_loader, true);
+ }
}
}
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 997a4e6..5300026 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -86,15 +86,13 @@
}
EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumMethods());
for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
- // TODO: ClassLinker::ResolveMethod
- // Method* method = dex_cache->GetResolvedMethod(i);
- // EXPECT_TRUE(method != NULL);
+ Method* method = dex_cache->GetResolvedMethod(i);
+ EXPECT_TRUE(method != NULL);
}
EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumFields());
for (size_t i = 0; i < dex_cache->NumFields(); i++) {
- // TODO: ClassLinker::ResolveField
- // Field* field = dex_cache->GetResolvedField(i);
- // EXPECT_TRUE(field != NULL);
+ Field* field = dex_cache->GetResolvedField(i);
+ EXPECT_TRUE(field != NULL);
}
}
diff --git a/src/dex_file.cc b/src/dex_file.cc
index c828df6..f7dec88 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -383,7 +383,6 @@
// must assemble the descriptor from references in the prototype.
char* DexFile::CreateMethodDescriptor(uint32_t proto_idx,
int32_t* unicode_length) const {
- CHECK(unicode_length != NULL);
const ProtoId& proto_id = GetProtoId(proto_idx);
std::string descriptor;
descriptor.push_back('(');
@@ -408,7 +407,9 @@
// TODO: should this just return a std::string?
scoped_ptr<char> c_string(new char[descriptor.size() + 1]);
strcpy(c_string.get(), descriptor.c_str());
- *unicode_length = parameter_length + return_type_length + 2; // 2 for ( and )
+ if (unicode_length != NULL) {
+ *unicode_length = parameter_length + return_type_length + 2; // 2 for ( and )
+ }
return c_string.release();
}