8006267: InterfaceMethod_ref should allow invokestatic and invokespecial
Lambda changes; spec 0.6.2 - Allow static invokestatic and invokespecial calls to InterfaceMethod_ref Reviewed-by: dholmes, acorn
This commit is contained in:
parent
54b7ae1ff9
commit
f63b13e379
@ -436,14 +436,19 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
ref_index, CHECK_(nullHandle));
|
||||
break;
|
||||
case JVM_REF_invokeVirtual:
|
||||
case JVM_REF_invokeStatic:
|
||||
case JVM_REF_invokeSpecial:
|
||||
case JVM_REF_newInvokeSpecial:
|
||||
check_property(
|
||||
tag.is_method(),
|
||||
"Invalid constant pool index %u in class file %s (not a method)",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
break;
|
||||
case JVM_REF_invokeStatic:
|
||||
case JVM_REF_invokeSpecial:
|
||||
check_property(
|
||||
tag.is_method() || tag.is_interface_method(),
|
||||
"Invalid constant pool index %u in class file %s (not a method)",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
break;
|
||||
case JVM_REF_invokeInterface:
|
||||
check_property(
|
||||
tag.is_interface_method(),
|
||||
@ -3837,7 +3842,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
}
|
||||
|
||||
if (TraceClassLoadingPreorder) {
|
||||
tty->print("[Loading %s", name->as_klass_external_name());
|
||||
tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName");
|
||||
if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
|
||||
tty->print_cr("]");
|
||||
}
|
||||
|
@ -268,8 +268,15 @@ ClassDescriptor* ClassDescriptor::parse_generic_signature(
|
||||
Klass* outer = SystemDictionary::find(
|
||||
outer_name, class_loader, protection_domain, CHECK_NULL);
|
||||
if (outer == NULL && !THREAD->is_Compiler_thread()) {
|
||||
outer = SystemDictionary::resolve_super_or_fail(original_name,
|
||||
outer_name, class_loader, protection_domain, false, CHECK_NULL);
|
||||
if (outer_name == ik->super()->name()) {
|
||||
outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name,
|
||||
class_loader, protection_domain,
|
||||
false, CHECK_NULL);
|
||||
}
|
||||
else {
|
||||
outer = SystemDictionary::resolve_or_fail(outer_name, class_loader,
|
||||
protection_domain, false, CHECK_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceKlass* outer_ik;
|
||||
|
@ -1014,13 +1014,28 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHand
|
||||
resolved_method->name(),
|
||||
resolved_method->signature()));
|
||||
}
|
||||
// check if public
|
||||
if (!sel_method->is_public()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||
Method::name_and_sig_as_C_string(recv_klass(),
|
||||
sel_method->name(),
|
||||
sel_method->signature()));
|
||||
// check access
|
||||
if (sel_method->method_holder()->is_interface()) {
|
||||
// Method holder is an interface. Throw Illegal Access Error if sel_method
|
||||
// is neither public nor private.
|
||||
if (!(sel_method->is_public() || sel_method->is_private())) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||
Method::name_and_sig_as_C_string(recv_klass(),
|
||||
sel_method->name(),
|
||||
sel_method->signature()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Method holder is a class. Throw Illegal Access Error if sel_method
|
||||
// is not public.
|
||||
if (!sel_method->is_public()) {
|
||||
ResourceMark rm(THREAD);
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
|
||||
Method::name_and_sig_as_C_string(recv_klass(),
|
||||
sel_method->name(),
|
||||
sel_method->signature()));
|
||||
}
|
||||
}
|
||||
// check if abstract
|
||||
if (check_null_and_abstract && sel_method->is_abstract()) {
|
||||
|
@ -187,6 +187,11 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
|
||||
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
|
||||
} else if (mods.is_static()) {
|
||||
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
|
||||
// Check if this method is a lambda method that is generated as
|
||||
// private static method.
|
||||
if (m->is_private() && m->method_holder()->is_interface()) {
|
||||
vmindex = klassItable::compute_itable_index(m);
|
||||
}
|
||||
} else if (receiver_limit != mklass &&
|
||||
!receiver_limit->is_subtype_of(mklass)) {
|
||||
return NULL; // bad receiver limit
|
||||
|
Loading…
Reference in New Issue
Block a user