blob: c2c09cac98ffe7e276592d14469773ababee1ad0 [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
#include "src/globals.h"
#include "src/logging.h"
#include "src/object.h"
#include "src/dex_file.h"
#include "src/raw_dex_file.h"
#include <algorithm>
namespace art {
bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
size_t i = 0;
while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
++i;
}
if (descriptor1.find('/', i) != StringPiece::npos ||
descriptor2.find('/', i) != StringPiece::npos) {
return false;
} else {
return true;
}
}
#if 0
bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
size_t size = std::min(descriptor1.size(), descriptor2.size());
std::pair<StringPiece::const_iterator, StringPiece::const_iterator> pos;
pos = std::mismatch(descriptor1.begin(), descriptor1.begin() + size, descriptor2.begin());
return !(*(pos.second).rfind('/') != npos && descriptor2.rfind('/') != npos);
}
#endif
bool Class::IsInSamePackage(const Class* that) const {
const Class* klass1 = this;
const Class* klass2 = that;
if (klass1 == klass2) {
return true;
}
// Class loaders must match.
if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
return false;
}
// Arrays are in the same package when their element classes are.
if (klass1->IsArray()) {
klass1 = klass1->GetComponentType();
}
if (klass2->IsArray()) {
klass2 = klass2->GetComponentType();
}
// Compare the package part of the descriptor string.
return IsInSamePackage(klass1->descriptor_, klass2->descriptor_);
}
uint32_t Method::NumArgRegisters() {
CHECK(shorty_ != NULL);
uint32_t num_registers = 0;
for (int i = 1; i < shorty_.length(); ++i) {
char ch = shorty_[i];
if (ch == 'D' || ch == 'J') {
num_registers += 2;
} else {
num_registers += 1;
}
}
return num_registers;
}
bool Method::HasSameArgumentTypes(const Method* that) const {
const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_);
const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_);
// TODO: compare ProtoId objects for equality and exit early
const RawDexFile::TypeList* type_list1 = raw1->GetProtoParameters(proto1);
size_t arity1 = (type_list1 == NULL) ? 0 : type_list1->Size();
const RawDexFile::TypeList* type_list2 = raw2->GetProtoParameters(proto2);
size_t arity2 = (type_list2 == NULL) ? 0 : type_list2->Size();
if (arity1 != arity2) {
return false;
}
for (size_t i = 0; i < arity1; ++i) {
uint32_t type_idx1 = type_list1->GetTypeItem(i).type_idx_;
const char* type1 = raw1->dexStringByTypeIdx(type_idx1);
uint32_t type_idx2 = type_list2->GetTypeItem(i).type_idx_;
const char* type2 = raw2->dexStringByTypeIdx(type_idx2);
if (strcmp(type1, type2) != 0) {
return false;
}
}
return true;
}
bool Method::HasSameReturnType(const Method* that) const {
const RawDexFile* raw1 = this->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(this->proto_idx_);
const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_);
const RawDexFile* raw2 = that->GetClass()->GetDexFile()->GetRaw();
const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(that->proto_idx_);
const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_);
return (strcmp(type1, type2) == 0);
}
Method* Class::FindDirectMethodLocally(const StringPiece& name,
const StringPiece& descriptor) const {
return NULL; // TODO
}
static const char* kClassStatusNames[] = {
"Error",
"NotReady",
"Idx",
"Loaded",
"Resolved",
"Verifying",
"Verified",
"Initializing",
"Initialized"
};
std::ostream& operator<<(std::ostream& os, const Class::Status& rhs) {
if (rhs >= Class::kStatusError && rhs <= Class::kStatusInitialized) {
os << kClassStatusNames[rhs - 1];
} else {
os << "Class::Status[" << int(rhs) << "]";
}
return os;
}
} // namespace art