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);