Materialize method descriptors when instantiating method objects.
Previously, when comparing method descriptors, one had to piecewise
compare the leaves of a method structure for equality.
With this change a flat method descriptor is computed and associated
to an object. This will simplify comparisons for descriptor equality
used during verification and reflective method retrieval.
Change-Id: I91e5ac76fb3816a36716b34fe43d05cd7364897b
diff --git a/src/dex_file.cc b/src/dex_file.cc
index b61babf..0cf98b1 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -342,6 +342,40 @@
}
}
+// Materializes the method descriptor for a method prototype. Method
+// descriptors are not stored directly in the dex file. Instead, one
+// 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('(');
+ const TypeList* type_list = GetProtoParameters(proto_id);
+ size_t parameter_length = 0;
+ if (type_list != NULL) {
+ // A non-zero number of arguments. Append the type names.
+ for (size_t i = 0; i < type_list->Size(); ++i) {
+ const TypeItem& type_item = type_list->GetTypeItem(i);
+ uint32_t type_idx = type_item.type_idx_;
+ int32_t type_length;
+ const char* name = dexStringByTypeIdx(type_idx, &type_length);
+ parameter_length += type_length;
+ descriptor.append(name);
+ }
+ }
+ descriptor.push_back(')');
+ uint32_t return_type_idx = proto_id.return_type_idx_;
+ int32_t return_type_length;
+ const char* name = dexStringByTypeIdx(return_type_idx, &return_type_length);
+ descriptor.append(name);
+ // 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 )
+ return c_string.release();
+}
+
// Read a signed integer. "zwidth" is the zero-based byte count.
static int32_t ReadSignedInt(const byte* ptr, int zwidth)
{