src/share/vm/classfile/classFileParser.cpp

changeset 1957
136b78722a08
parent 1907
c18cbe5936b8
child 1963
2389669474a6
     1.1 --- a/src/share/vm/classfile/classFileParser.cpp	Mon Jun 07 14:17:01 2010 -0700
     1.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Wed Jun 09 18:50:45 2010 -0700
     1.3 @@ -113,6 +113,29 @@
     1.4            cp->string_index_at_put(index, string_index);
     1.5          }
     1.6          break;
     1.7 +      case JVM_CONSTANT_MethodHandle :
     1.8 +      case JVM_CONSTANT_MethodType :
     1.9 +        if (!EnableMethodHandles ||
    1.10 +            _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
    1.11 +          classfile_parse_error(
    1.12 +            (!EnableInvokeDynamic ?
    1.13 +             "This JVM does not support constant tag %u in class file %s" :
    1.14 +             "Class file version does not support constant tag %u in class file %s"),
    1.15 +            tag, CHECK);
    1.16 +        }
    1.17 +        if (tag == JVM_CONSTANT_MethodHandle) {
    1.18 +          cfs->guarantee_more(4, CHECK);  // ref_kind, method_index, tag/access_flags
    1.19 +          u1 ref_kind = cfs->get_u1_fast();
    1.20 +          u2 method_index = cfs->get_u2_fast();
    1.21 +          cp->method_handle_index_at_put(index, ref_kind, method_index);
    1.22 +        } else if (tag == JVM_CONSTANT_MethodType) {
    1.23 +          cfs->guarantee_more(3, CHECK);  // signature_index, tag/access_flags
    1.24 +          u2 signature_index = cfs->get_u2_fast();
    1.25 +          cp->method_type_index_at_put(index, signature_index);
    1.26 +        } else {
    1.27 +          ShouldNotReachHere();
    1.28 +        }
    1.29 +        break;
    1.30        case JVM_CONSTANT_Integer :
    1.31          {
    1.32            cfs->guarantee_more(5, CHECK);  // bytes, tag/access_flags
    1.33 @@ -333,6 +356,60 @@
    1.34            cp->unresolved_string_at_put(index, sym);
    1.35          }
    1.36          break;
    1.37 +      case JVM_CONSTANT_MethodHandle :
    1.38 +        {
    1.39 +          int ref_index = cp->method_handle_index_at(index);
    1.40 +          check_property(
    1.41 +            valid_cp_range(ref_index, length) &&
    1.42 +                EnableMethodHandles,
    1.43 +              "Invalid constant pool index %u in class file %s",
    1.44 +              ref_index, CHECK_(nullHandle));
    1.45 +          constantTag tag = cp->tag_at(ref_index);
    1.46 +          int ref_kind  = cp->method_handle_ref_kind_at(index);
    1.47 +          switch (ref_kind) {
    1.48 +          case JVM_REF_getField:
    1.49 +          case JVM_REF_getStatic:
    1.50 +          case JVM_REF_putField:
    1.51 +          case JVM_REF_putStatic:
    1.52 +            check_property(
    1.53 +              tag.is_field(),
    1.54 +              "Invalid constant pool index %u in class file %s (not a field)",
    1.55 +              ref_index, CHECK_(nullHandle));
    1.56 +            break;
    1.57 +          case JVM_REF_invokeVirtual:
    1.58 +          case JVM_REF_invokeStatic:
    1.59 +          case JVM_REF_invokeSpecial:
    1.60 +          case JVM_REF_newInvokeSpecial:
    1.61 +            check_property(
    1.62 +              tag.is_method(),
    1.63 +              "Invalid constant pool index %u in class file %s (not a method)",
    1.64 +              ref_index, CHECK_(nullHandle));
    1.65 +            break;
    1.66 +          case JVM_REF_invokeInterface:
    1.67 +            check_property(
    1.68 +              tag.is_interface_method(),
    1.69 +              "Invalid constant pool index %u in class file %s (not an interface method)",
    1.70 +              ref_index, CHECK_(nullHandle));
    1.71 +            break;
    1.72 +          default:
    1.73 +            classfile_parse_error(
    1.74 +              "Bad method handle kind at constant pool index %u in class file %s",
    1.75 +              index, CHECK_(nullHandle));
    1.76 +          }
    1.77 +          // Keep the ref_index unchanged.  It will be indirected at link-time.
    1.78 +        }
    1.79 +        break;
    1.80 +      case JVM_CONSTANT_MethodType :
    1.81 +        {
    1.82 +          int ref_index = cp->method_type_index_at(index);
    1.83 +          check_property(
    1.84 +            valid_cp_range(ref_index, length) &&
    1.85 +                cp->tag_at(ref_index).is_utf8() &&
    1.86 +                EnableMethodHandles,
    1.87 +              "Invalid constant pool index %u in class file %s",
    1.88 +              ref_index, CHECK_(nullHandle));
    1.89 +        }
    1.90 +        break;
    1.91        default:
    1.92          fatal(err_msg("bad constant pool tag value %u",
    1.93                        cp->tag_at(index).value()));
    1.94 @@ -416,6 +493,43 @@
    1.95          }
    1.96          break;
    1.97        }
    1.98 +      case JVM_CONSTANT_MethodHandle: {
    1.99 +        int ref_index = cp->method_handle_index_at(index);
   1.100 +        int ref_kind  = cp->method_handle_ref_kind_at(index);
   1.101 +        switch (ref_kind) {
   1.102 +        case JVM_REF_invokeVirtual:
   1.103 +        case JVM_REF_invokeStatic:
   1.104 +        case JVM_REF_invokeSpecial:
   1.105 +        case JVM_REF_newInvokeSpecial:
   1.106 +          {
   1.107 +            int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index);
   1.108 +            int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
   1.109 +            symbolHandle name(THREAD, cp->symbol_at(name_ref_index));
   1.110 +            if (ref_kind == JVM_REF_newInvokeSpecial) {
   1.111 +              if (name() != vmSymbols::object_initializer_name()) {
   1.112 +                classfile_parse_error(
   1.113 +                  "Bad constructor name at constant pool index %u in class file %s",
   1.114 +                  name_ref_index, CHECK_(nullHandle));
   1.115 +              }
   1.116 +            } else {
   1.117 +              if (name() == vmSymbols::object_initializer_name()) {
   1.118 +                classfile_parse_error(
   1.119 +                  "Bad method name at constant pool index %u in class file %s",
   1.120 +                  name_ref_index, CHECK_(nullHandle));
   1.121 +              }
   1.122 +            }
   1.123 +          }
   1.124 +          break;
   1.125 +          // Other ref_kinds are already fully checked in previous pass.
   1.126 +        }
   1.127 +        break;
   1.128 +      }
   1.129 +      case JVM_CONSTANT_MethodType: {
   1.130 +        symbolHandle no_name = vmSymbolHandles::type_name(); // place holder
   1.131 +        symbolHandle signature(THREAD, cp->method_type_signature_at(index));
   1.132 +        verify_legal_method_signature(no_name, signature, CHECK_(nullHandle));
   1.133 +        break;
   1.134 +      }
   1.135      }  // end of switch
   1.136    }  // end of for
   1.137  
   1.138 @@ -431,7 +545,7 @@
   1.139    case JVM_CONSTANT_UnresolvedClass :
   1.140      // Patching a class means pre-resolving it.
   1.141      // The name in the constant pool is ignored.
   1.142 -    if (patch->klass() == SystemDictionary::Class_klass()) { // %%% java_lang_Class::is_instance
   1.143 +    if (java_lang_Class::is_instance(patch())) {
   1.144        guarantee_property(!java_lang_Class::is_primitive(patch()),
   1.145                           "Illegal class patch at %d in class file %s",
   1.146                           index, CHECK);

mercurial