We now include the type of the callee and the callsite.
This change also fixes a call to ThrowWrongMethodTypeException that
passed arguments in the wrong order.
Test: make test-art-host
Change-Id: I3ced2e331cb49b616a8374f5a604dafa37330059
void ThrowWrongMethodTypeException(mirror::MethodType* callee_type,
mirror::MethodType* callsite_type) {
- // TODO(narayan): Should we provide more detail here ? The RI doesn't bother.
- UNUSED(callee_type);
- UNUSED(callsite_type);
-
ThrowException("Ljava/lang/invoke/WrongMethodTypeException;",
nullptr,
- "Invalid method type for signature polymorphic call");
+ StringPrintf("Expected %s but was %s",
+ callee_type->PrettyDescriptor().c_str(),
+ callsite_type->PrettyDescriptor().c_str()).c_str());
}
} // namespace art
Handle<mirror::MethodType> handle_type(hs.NewHandle(method_handle->GetMethodType()));
CHECK(handle_type.Get() != nullptr);
if (UNLIKELY(is_invoke_exact && !callsite_type->IsExactMatch(handle_type.Get()))) {
- ThrowWrongMethodTypeException(callsite_type.Get(), handle_type.Get());
+ ThrowWrongMethodTypeException(handle_type.Get(), callsite_type.Get());
return false;
}
return true;
}
+std::string MethodType::PrettyDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
+ std::ostringstream ss;
+ ss << "(";
+
+ mirror::ObjectArray<Class>* const p_types = GetPTypes();
+ const int32_t params_length = p_types->GetLength();
+ for (int32_t i = 0; i < params_length; ++i) {
+ ss << p_types->GetWithoutChecks(i)->PrettyDescriptor();
+ if (i != (params_length - 1)) {
+ ss << ", ";
+ }
+ }
+
+ ss << ")";
+ ss << GetRType()->PrettyDescriptor();
+
+ return ss.str();
+}
+
void MethodType::SetClass(Class* klass) {
CHECK(static_class_.IsNull()) << static_class_.Read() << " " << klass;
CHECK(klass != nullptr);
// iff. they have the same return types and parameter types.
bool IsExactMatch(mirror::MethodType* other) REQUIRES_SHARED(Locks::mutator_lock_);
+ // Returns the pretty descriptor for this method type, suitable for display in
+ // exception messages and the like.
+ std::string PrettyDescriptor() REQUIRES_SHARED(Locks::mutator_lock_);
+
private:
static MemberOffset FormOffset() {
return MemberOffset(OFFSETOF_MEMBER(MethodType, form_));
foo_A
foo_B
privateRyan_D
+Received exception: Expected (java.lang.String, java.lang.String)java.lang.String but was (java.lang.String, java.lang.Object)void
public static void main(String[] args) throws Throwable {
testfindSpecial_invokeSuperBehaviour();
testfindSpecial_invokeDirectBehaviour();
+ testExceptionDetailMessages();
}
public static void testfindSpecial_invokeSuperBehaviour() throws Throwable {
} catch (IllegalAccessException expected) {
}
}
+
+ public static void testExceptionDetailMessages() throws Throwable {
+ MethodHandle handle = MethodHandles.lookup().findVirtual(String.class, "concat",
+ MethodType.methodType(String.class, String.class));
+
+ try {
+ handle.invokeExact("a", new Object());
+ System.out.println("invokeExact(\"a\", new Object()) unexpectedly succeeded.");
+ } catch (WrongMethodTypeException ex) {
+ System.out.println("Received exception: " + ex.getMessage());
+ }
+ }
}