Thu, 18 Apr 2013 08:05:35 -0700
8006267: InterfaceMethod_ref should allow invokestatic and invokespecial
Summary: Lambda changes; spec 0.6.2 - Allow static invokestatic and invokespecial calls to InterfaceMethod_ref
Reviewed-by: dholmes, acorn
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Wed Apr 17 08:20:02 2013 -0400 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Apr 18 08:05:35 2013 -0700 1.3 @@ -436,14 +436,19 @@ 1.4 ref_index, CHECK_(nullHandle)); 1.5 break; 1.6 case JVM_REF_invokeVirtual: 1.7 - case JVM_REF_invokeStatic: 1.8 - case JVM_REF_invokeSpecial: 1.9 case JVM_REF_newInvokeSpecial: 1.10 check_property( 1.11 tag.is_method(), 1.12 "Invalid constant pool index %u in class file %s (not a method)", 1.13 ref_index, CHECK_(nullHandle)); 1.14 break; 1.15 + case JVM_REF_invokeStatic: 1.16 + case JVM_REF_invokeSpecial: 1.17 + check_property( 1.18 + tag.is_method() || tag.is_interface_method(), 1.19 + "Invalid constant pool index %u in class file %s (not a method)", 1.20 + ref_index, CHECK_(nullHandle)); 1.21 + break; 1.22 case JVM_REF_invokeInterface: 1.23 check_property( 1.24 tag.is_interface_method(), 1.25 @@ -3837,7 +3842,7 @@ 1.26 } 1.27 1.28 if (TraceClassLoadingPreorder) { 1.29 - tty->print("[Loading %s", name->as_klass_external_name()); 1.30 + tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName"); 1.31 if (cfs->source() != NULL) tty->print(" from %s", cfs->source()); 1.32 tty->print_cr("]"); 1.33 }
2.1 --- a/src/share/vm/classfile/genericSignatures.cpp Wed Apr 17 08:20:02 2013 -0400 2.2 +++ b/src/share/vm/classfile/genericSignatures.cpp Thu Apr 18 08:05:35 2013 -0700 2.3 @@ -268,8 +268,15 @@ 2.4 Klass* outer = SystemDictionary::find( 2.5 outer_name, class_loader, protection_domain, CHECK_NULL); 2.6 if (outer == NULL && !THREAD->is_Compiler_thread()) { 2.7 - outer = SystemDictionary::resolve_super_or_fail(original_name, 2.8 - outer_name, class_loader, protection_domain, false, CHECK_NULL); 2.9 + if (outer_name == ik->super()->name()) { 2.10 + outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name, 2.11 + class_loader, protection_domain, 2.12 + false, CHECK_NULL); 2.13 + } 2.14 + else { 2.15 + outer = SystemDictionary::resolve_or_fail(outer_name, class_loader, 2.16 + protection_domain, false, CHECK_NULL); 2.17 + } 2.18 } 2.19 2.20 InstanceKlass* outer_ik;
3.1 --- a/src/share/vm/interpreter/linkResolver.cpp Wed Apr 17 08:20:02 2013 -0400 3.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Apr 18 08:05:35 2013 -0700 3.3 @@ -1014,13 +1014,28 @@ 3.4 resolved_method->name(), 3.5 resolved_method->signature())); 3.6 } 3.7 - // check if public 3.8 - if (!sel_method->is_public()) { 3.9 - ResourceMark rm(THREAD); 3.10 - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 3.11 - Method::name_and_sig_as_C_string(recv_klass(), 3.12 - sel_method->name(), 3.13 - sel_method->signature())); 3.14 + // check access 3.15 + if (sel_method->method_holder()->is_interface()) { 3.16 + // Method holder is an interface. Throw Illegal Access Error if sel_method 3.17 + // is neither public nor private. 3.18 + if (!(sel_method->is_public() || sel_method->is_private())) { 3.19 + ResourceMark rm(THREAD); 3.20 + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 3.21 + Method::name_and_sig_as_C_string(recv_klass(), 3.22 + sel_method->name(), 3.23 + sel_method->signature())); 3.24 + } 3.25 + } 3.26 + else { 3.27 + // Method holder is a class. Throw Illegal Access Error if sel_method 3.28 + // is not public. 3.29 + if (!sel_method->is_public()) { 3.30 + ResourceMark rm(THREAD); 3.31 + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), 3.32 + Method::name_and_sig_as_C_string(recv_klass(), 3.33 + sel_method->name(), 3.34 + sel_method->signature())); 3.35 + } 3.36 } 3.37 // check if abstract 3.38 if (check_null_and_abstract && sel_method->is_abstract()) {
4.1 --- a/src/share/vm/prims/methodHandles.cpp Wed Apr 17 08:20:02 2013 -0400 4.2 +++ b/src/share/vm/prims/methodHandles.cpp Thu Apr 18 08:05:35 2013 -0700 4.3 @@ -187,6 +187,11 @@ 4.4 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 4.5 } else if (mods.is_static()) { 4.6 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 4.7 + // Check if this method is a lambda method that is generated as 4.8 + // private static method. 4.9 + if (m->is_private() && m->method_holder()->is_interface()) { 4.10 + vmindex = klassItable::compute_itable_index(m); 4.11 + } 4.12 } else if (receiver_limit != mklass && 4.13 !receiver_limit->is_subtype_of(mklass)) { 4.14 return NULL; // bad receiver limit