mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
Improve error message formatting to give more information to user. Also, catch a corner case related to 6930553 and 6844449. Reviewed-by: kvn
This commit is contained in:
parent
16784a72e8
commit
b95f04efbf
2 changed files with 26 additions and 8 deletions
|
@ -560,6 +560,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case JVM_CONSTANT_InvokeDynamic:
|
||||||
case JVM_CONSTANT_Fieldref:
|
case JVM_CONSTANT_Fieldref:
|
||||||
case JVM_CONSTANT_Methodref:
|
case JVM_CONSTANT_Methodref:
|
||||||
case JVM_CONSTANT_InterfaceMethodref: {
|
case JVM_CONSTANT_InterfaceMethodref: {
|
||||||
|
|
|
@ -1700,9 +1700,11 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
|
||||||
message = generate_class_cast_message(objName, targetKlass->external_name());
|
message = generate_class_cast_message(objName, targetKlass->external_name());
|
||||||
} else {
|
} else {
|
||||||
// %%% need to get the MethodType string, without messing around too much
|
// %%% need to get the MethodType string, without messing around too much
|
||||||
|
const char* desc = NULL;
|
||||||
// Get a signature from the invoke instruction
|
// Get a signature from the invoke instruction
|
||||||
const char* mhName = "method handle";
|
const char* mhName = "method handle";
|
||||||
const char* targetType = "the required signature";
|
const char* targetType = "the required signature";
|
||||||
|
int targetArity = -1, mhArity = -1;
|
||||||
vframeStream vfst(thread, true);
|
vframeStream vfst(thread, true);
|
||||||
if (!vfst.at_end()) {
|
if (!vfst.at_end()) {
|
||||||
Bytecode_invoke call(vfst.method(), vfst.bci());
|
Bytecode_invoke call(vfst.method(), vfst.bci());
|
||||||
|
@ -1716,20 +1718,35 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
|
||||||
&& target->is_method_handle_invoke()
|
&& target->is_method_handle_invoke()
|
||||||
&& required == target->method_handle_type()) {
|
&& required == target->method_handle_type()) {
|
||||||
targetType = target->signature()->as_C_string();
|
targetType = target->signature()->as_C_string();
|
||||||
|
targetArity = ArgumentCount(target->signature()).size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
klassOop kignore; int fignore;
|
klassOop kignore; int dmf_flags = 0;
|
||||||
methodOop actual_method = MethodHandles::decode_method(actual,
|
methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
|
||||||
kignore, fignore);
|
if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
|
||||||
|
MethodHandles::_dmf_does_dispatch |
|
||||||
|
MethodHandles::_dmf_from_interface)) != 0)
|
||||||
|
actual_method = NULL; // MH does extra binds, drops, etc.
|
||||||
|
bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
|
||||||
if (actual_method != NULL) {
|
if (actual_method != NULL) {
|
||||||
if (methodOopDesc::is_method_handle_invoke_name(actual_method->name()))
|
mhName = actual_method->signature()->as_C_string();
|
||||||
mhName = "$";
|
mhArity = ArgumentCount(actual_method->signature()).size();
|
||||||
|
if (!actual_method->is_static()) mhArity += 1;
|
||||||
|
} else if (java_lang_invoke_MethodHandle::is_instance(actual)) {
|
||||||
|
oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual);
|
||||||
|
mhArity = java_lang_invoke_MethodType::ptype_count(mhType);
|
||||||
|
stringStream st;
|
||||||
|
java_lang_invoke_MethodType::print_signature(mhType, &st);
|
||||||
|
mhName = st.as_string();
|
||||||
|
}
|
||||||
|
if (targetArity != -1 && targetArity != mhArity) {
|
||||||
|
if (has_receiver && targetArity == mhArity-1)
|
||||||
|
desc = " cannot be called without a receiver argument as ";
|
||||||
else
|
else
|
||||||
mhName = actual_method->signature()->as_C_string();
|
desc = " cannot be called with a different arity as ";
|
||||||
if (mhName[0] == '$')
|
|
||||||
mhName = actual_method->signature()->as_C_string();
|
|
||||||
}
|
}
|
||||||
message = generate_class_cast_message(mhName, targetType,
|
message = generate_class_cast_message(mhName, targetType,
|
||||||
|
desc != NULL ? desc :
|
||||||
" cannot be called as ");
|
" cannot be called as ");
|
||||||
}
|
}
|
||||||
if (TraceMethodHandles) {
|
if (TraceMethodHandles) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue