src/share/vm/classfile/classFileParser.cpp

changeset 3670
f7c4174b33ba
parent 3384
2b3acb34791f
child 3686
749b1464aa81
child 3701
49036505ab5f
     1.1 --- a/src/share/vm/classfile/classFileParser.cpp	Fri Mar 09 13:34:45 2012 -0800
     1.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Tue Mar 13 13:50:48 2012 -0400
     1.3 @@ -2315,13 +2315,32 @@
     1.4  #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
     1.5  
     1.6  // Return number of classes in the inner classes attribute table
     1.7 -u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
     1.8 +u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
     1.9 +                                                            bool parsed_enclosingmethod_attribute,
    1.10 +                                                            u2 enclosing_method_class_index,
    1.11 +                                                            u2 enclosing_method_method_index,
    1.12 +                                                            constantPoolHandle cp,
    1.13 +                                                            instanceKlassHandle k, TRAPS) {
    1.14    ClassFileStream* cfs = stream();
    1.15 -  cfs->guarantee_more(2, CHECK_0);  // length
    1.16 -  u2 length = cfs->get_u2_fast();
    1.17 -
    1.18 -  // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
    1.19 -  typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
    1.20 +  u1* current_mark = cfs->current();
    1.21 +  u2 length = 0;
    1.22 +  if (inner_classes_attribute_start != NULL) {
    1.23 +    cfs->set_current(inner_classes_attribute_start);
    1.24 +    cfs->guarantee_more(2, CHECK_0);  // length
    1.25 +    length = cfs->get_u2_fast();
    1.26 +  }
    1.27 +
    1.28 +  // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
    1.29 +  // method data:
    1.30 +  //   [inner_class_info_index,
    1.31 +  //    outer_class_info_index,
    1.32 +  //    inner_name_index,
    1.33 +  //    inner_class_access_flags,
    1.34 +  //    ...
    1.35 +  //    enclosing_method_class_index,
    1.36 +  //    enclosing_method_method_index]
    1.37 +  int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
    1.38 +  typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
    1.39    typeArrayHandle inner_classes(THREAD, ic);
    1.40    int index = 0;
    1.41    int cp_size = cp->length();
    1.42 @@ -2372,8 +2391,8 @@
    1.43  
    1.44    // 4347400: make sure there's no duplicate entry in the classes array
    1.45    if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
    1.46 -    for(int i = 0; i < inner_classes->length(); i += 4) {
    1.47 -      for(int j = i + 4; j < inner_classes->length(); j += 4) {
    1.48 +    for(int i = 0; i < length * 4; i += 4) {
    1.49 +      for(int j = i + 4; j < length * 4; j += 4) {
    1.50          guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
    1.51                              inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
    1.52                              inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
    1.53 @@ -2384,8 +2403,19 @@
    1.54      }
    1.55    }
    1.56  
    1.57 +  // Set EnclosingMethod class and method indexes.
    1.58 +  if (parsed_enclosingmethod_attribute) {
    1.59 +    inner_classes->short_at_put(index++, enclosing_method_class_index);
    1.60 +    inner_classes->short_at_put(index++, enclosing_method_method_index);
    1.61 +  }
    1.62 +  assert(index == size, "wrong size");
    1.63 +
    1.64    // Update instanceKlass with inner class info.
    1.65    k->set_inner_classes(inner_classes());
    1.66 +
    1.67 +  // Restore buffer's current position.
    1.68 +  cfs->set_current(current_mark);
    1.69 +
    1.70    return length;
    1.71  }
    1.72  
    1.73 @@ -2490,6 +2520,10 @@
    1.74    int runtime_visible_annotations_length = 0;
    1.75    u1* runtime_invisible_annotations = NULL;
    1.76    int runtime_invisible_annotations_length = 0;
    1.77 +  u1* inner_classes_attribute_start = NULL;
    1.78 +  u4  inner_classes_attribute_length = 0;
    1.79 +  u2  enclosing_method_class_index = 0;
    1.80 +  u2  enclosing_method_method_index = 0;
    1.81    // Iterate over attributes
    1.82    while (attributes_count--) {
    1.83      cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
    1.84 @@ -2522,11 +2556,9 @@
    1.85        } else {
    1.86          parsed_innerclasses_attribute = true;
    1.87        }
    1.88 -      u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
    1.89 -      if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
    1.90 -        guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
    1.91 -                          "Wrong InnerClasses attribute length in class file %s", CHECK);
    1.92 -      }
    1.93 +      inner_classes_attribute_start = cfs->get_u1_buffer();
    1.94 +      inner_classes_attribute_length = attribute_length;
    1.95 +      cfs->skip_u1(inner_classes_attribute_length, CHECK);
    1.96      } else if (tag == vmSymbols::tag_synthetic()) {
    1.97        // Check for Synthetic tag
    1.98        // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
    1.99 @@ -2568,22 +2600,21 @@
   1.100            parsed_enclosingmethod_attribute = true;
   1.101          }
   1.102          cfs->guarantee_more(4, CHECK);  // class_index, method_index
   1.103 -        u2 class_index  = cfs->get_u2_fast();
   1.104 -        u2 method_index = cfs->get_u2_fast();
   1.105 -        if (class_index == 0) {
   1.106 +        enclosing_method_class_index  = cfs->get_u2_fast();
   1.107 +        enclosing_method_method_index = cfs->get_u2_fast();
   1.108 +        if (enclosing_method_class_index == 0) {
   1.109            classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
   1.110          }
   1.111          // Validate the constant pool indices and types
   1.112 -        if (!cp->is_within_bounds(class_index) ||
   1.113 -            !is_klass_reference(cp, class_index)) {
   1.114 +        if (!cp->is_within_bounds(enclosing_method_class_index) ||
   1.115 +            !is_klass_reference(cp, enclosing_method_class_index)) {
   1.116            classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
   1.117          }
   1.118 -        if (method_index != 0 &&
   1.119 -            (!cp->is_within_bounds(method_index) ||
   1.120 -             !cp->tag_at(method_index).is_name_and_type())) {
   1.121 +        if (enclosing_method_method_index != 0 &&
   1.122 +            (!cp->is_within_bounds(enclosing_method_method_index) ||
   1.123 +             !cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
   1.124            classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
   1.125          }
   1.126 -        k->set_enclosing_method_indices(class_index, method_index);
   1.127        } else if (tag == vmSymbols::tag_bootstrap_methods() &&
   1.128                   _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
   1.129          if (parsed_bootstrap_methods_attribute)
   1.130 @@ -2606,6 +2637,20 @@
   1.131                                                       CHECK);
   1.132    k->set_class_annotations(annotations());
   1.133  
   1.134 +  if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
   1.135 +    u2 num_of_classes = parse_classfile_inner_classes_attribute(
   1.136 +                            inner_classes_attribute_start,
   1.137 +                            parsed_innerclasses_attribute,
   1.138 +                            enclosing_method_class_index,
   1.139 +                            enclosing_method_method_index,
   1.140 +                            cp, k, CHECK);
   1.141 +    if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
   1.142 +      guarantee_property(
   1.143 +        inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
   1.144 +        "Wrong InnerClasses attribute length in class file %s", CHECK);
   1.145 +    }
   1.146 +  }
   1.147 +
   1.148    if (_max_bootstrap_specifier_index >= 0) {
   1.149      guarantee_property(parsed_bootstrap_methods_attribute,
   1.150                         "Missing BootstrapMethods attribute in class file %s", CHECK);

mercurial