va_end(args);
}
+void ThrowNoSuchMethodError(const char* kind,
+ Class* c, const StringPiece& name, const StringPiece& signature) {
+ DexCache* dex_cache = c->GetDexCache();
+ std::stringstream msg;
+ msg << "no " << kind << " method " << name << "." << signature
+ << " in class " << c->GetDescriptor()->ToModifiedUtf8()
+ << " or its superclasses";
+ if (dex_cache) {
+ msg << " (defined in " << dex_cache->GetLocation()->ToModifiedUtf8() << ")";
+ }
+ Thread::Current()->ThrowNewException("Ljava/lang/NoSuchMethodError;", "%s", msg.str().c_str());
+}
+
void ThrowEarlierClassFailure(Class* c) {
/*
* The class failed to initialize on a previous attempt, so we want to throw
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
if (klass == NULL) {
+ DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
}
if (resolved != NULL) {
dex_cache->SetResolvedMethod(method_idx, resolved);
} else {
- DCHECK(Thread::Current()->IsExceptionPending());
+ ThrowNoSuchMethodError(is_direct ? "direct" : "virtual", klass, name, signature);
}
return resolved;
}
}
if (method == NULL || method->IsStatic() != is_static) {
- Thread* self = Thread::Current();
std::string method_name(PrettyMethod(method));
// TODO: try searching for the opposite kind of method from is_static
// for better diagnostics?
- self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+ ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
"no %s method %s", is_static ? "static" : "non-static",
method_name.c_str());
return NULL;
m = c->FindVirtualMethod(name, sig);
}
if (m == NULL) {
- Thread* self = Thread::Current();
std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
- self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+ ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
"no method \"%s.%s%s\"",
class_descriptor.c_str(), name, sig);
return JNI_ERR;
} else if (!m->IsNative()) {
- Thread* self = Thread::Current();
std::string class_descriptor(c->GetDescriptor()->ToModifiedUtf8());
- self->ThrowNewException("Ljava/lang/NoSuchMethodError;",
+ ts.Self()->ThrowNewException("Ljava/lang/NoSuchMethodError;",
"method \"%s.%s%s\" is not native",
class_descriptor.c_str(), name, sig);
return JNI_ERR;
}
Method* Class::FindVirtualMethod(const StringPiece& name,
- const StringPiece& descriptor) {
+ const StringPiece& signature) {
for (Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
- Method* method = klass->FindDeclaredVirtualMethod(name, descriptor);
+ Method* method = klass->FindDeclaredVirtualMethod(name, signature);
if (method != NULL) {
return method;
}