8188145: MethodHandle resolution should follow JVMS sequence of lookup by name & type before type descriptor resolution

Reviewed-by: kvn, psandoz
This commit is contained in:
Vladimir Ivanov 2018-01-12 01:52:06 +03:00
parent e2f5722888
commit 1b558514ff
7 changed files with 216 additions and 24 deletions

View file

@ -122,6 +122,48 @@ enum {
ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
};
int MethodHandles::ref_kind_to_flags(int ref_kind) {
assert(ref_kind_is_valid(ref_kind), "%d", ref_kind);
int flags = (ref_kind << REFERENCE_KIND_SHIFT);
if (ref_kind_is_field(ref_kind)) {
flags |= IS_FIELD;
} else if (ref_kind_is_method(ref_kind)) {
flags |= IS_METHOD;
} else if (ref_kind == JVM_REF_newInvokeSpecial) {
flags |= IS_CONSTRUCTOR;
}
return flags;
}
Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
Handle empty;
Handle type(THREAD, java_lang_invoke_MemberName::type(mname()));
if (!java_lang_String::is_instance_inlined(type())) {
return type; // already resolved
}
Symbol* signature = java_lang_String::as_symbol_or_null(type());
if (signature == NULL) {
return empty; // no such signature exists in the VM
}
Handle resolved;
int flags = java_lang_invoke_MemberName::flags(mname());
switch (flags & ALL_KINDS) {
case IS_METHOD:
case IS_CONSTRUCTOR:
resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
break;
case IS_FIELD:
resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
break;
default:
THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
}
if (resolved.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MemberName type", empty);
}
return resolved;
}
oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
// This method is used from java.lang.invoke.MemberName constructors.
// It fills in the new MemberName from a java.lang.reflect.Member.