8006267: InterfaceMethod_ref should allow invokestatic and invokespecial

Thu, 18 Apr 2013 08:05:35 -0700

author
bharadwaj
date
Thu, 18 Apr 2013 08:05:35 -0700
changeset 4960
41ed397cc0cd
parent 4958
63e31ce40bdb
child 4961
7815eaceaa8c

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

src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/genericSignatures.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/methodHandles.cpp file | annotate | diff | comparison | revisions
     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

mercurial