hotspot/src/share/vm/classfile/classFileParser.cpp
changeset 12231 6a9cfc59a18a
parent 11423 cb215b69197c
child 12369 48fd3da4025c
child 12267 a43041fec343
equal deleted inserted replaced
12112:56e3093129dc 12231:6a9cfc59a18a
  2313 
  2313 
  2314 // Inner classes can be static, private or protected (classic VM does this)
  2314 // Inner classes can be static, private or protected (classic VM does this)
  2315 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
  2315 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
  2316 
  2316 
  2317 // Return number of classes in the inner classes attribute table
  2317 // Return number of classes in the inner classes attribute table
  2318 u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  2318 u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
       
  2319                                                             bool parsed_enclosingmethod_attribute,
       
  2320                                                             u2 enclosing_method_class_index,
       
  2321                                                             u2 enclosing_method_method_index,
       
  2322                                                             constantPoolHandle cp,
       
  2323                                                             instanceKlassHandle k, TRAPS) {
  2319   ClassFileStream* cfs = stream();
  2324   ClassFileStream* cfs = stream();
  2320   cfs->guarantee_more(2, CHECK_0);  // length
  2325   u1* current_mark = cfs->current();
  2321   u2 length = cfs->get_u2_fast();
  2326   u2 length = 0;
  2322 
  2327   if (inner_classes_attribute_start != NULL) {
  2323   // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
  2328     cfs->set_current(inner_classes_attribute_start);
  2324   typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
  2329     cfs->guarantee_more(2, CHECK_0);  // length
       
  2330     length = cfs->get_u2_fast();
       
  2331   }
       
  2332 
       
  2333   // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
       
  2334   // method data:
       
  2335   //   [inner_class_info_index,
       
  2336   //    outer_class_info_index,
       
  2337   //    inner_name_index,
       
  2338   //    inner_class_access_flags,
       
  2339   //    ...
       
  2340   //    enclosing_method_class_index,
       
  2341   //    enclosing_method_method_index]
       
  2342   int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
       
  2343   typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
  2325   typeArrayHandle inner_classes(THREAD, ic);
  2344   typeArrayHandle inner_classes(THREAD, ic);
  2326   int index = 0;
  2345   int index = 0;
  2327   int cp_size = cp->length();
  2346   int cp_size = cp->length();
  2328   cfs->guarantee_more(8 * length, CHECK_0);  // 4-tuples of u2
  2347   cfs->guarantee_more(8 * length, CHECK_0);  // 4-tuples of u2
  2329   for (int n = 0; n < length; n++) {
  2348   for (int n = 0; n < length; n++) {
  2370     inner_classes->short_at_put(index++, inner_access_flags.as_short());
  2389     inner_classes->short_at_put(index++, inner_access_flags.as_short());
  2371   }
  2390   }
  2372 
  2391 
  2373   // 4347400: make sure there's no duplicate entry in the classes array
  2392   // 4347400: make sure there's no duplicate entry in the classes array
  2374   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
  2393   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
  2375     for(int i = 0; i < inner_classes->length(); i += 4) {
  2394     for(int i = 0; i < length * 4; i += 4) {
  2376       for(int j = i + 4; j < inner_classes->length(); j += 4) {
  2395       for(int j = i + 4; j < length * 4; j += 4) {
  2377         guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
  2396         guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
  2378                             inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
  2397                             inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
  2379                             inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
  2398                             inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
  2380                             inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)),
  2399                             inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)),
  2381                             "Duplicate entry in InnerClasses in class file %s",
  2400                             "Duplicate entry in InnerClasses in class file %s",
  2382                             CHECK_0);
  2401                             CHECK_0);
  2383       }
  2402       }
  2384     }
  2403     }
  2385   }
  2404   }
  2386 
  2405 
       
  2406   // Set EnclosingMethod class and method indexes.
       
  2407   if (parsed_enclosingmethod_attribute) {
       
  2408     inner_classes->short_at_put(index++, enclosing_method_class_index);
       
  2409     inner_classes->short_at_put(index++, enclosing_method_method_index);
       
  2410   }
       
  2411   assert(index == size, "wrong size");
       
  2412 
  2387   // Update instanceKlass with inner class info.
  2413   // Update instanceKlass with inner class info.
  2388   k->set_inner_classes(inner_classes());
  2414   k->set_inner_classes(inner_classes());
       
  2415 
       
  2416   // Restore buffer's current position.
       
  2417   cfs->set_current(current_mark);
       
  2418 
  2389   return length;
  2419   return length;
  2390 }
  2420 }
  2391 
  2421 
  2392 void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  2422 void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  2393   k->set_is_synthetic();
  2423   k->set_is_synthetic();
  2488   bool parsed_bootstrap_methods_attribute = false;
  2518   bool parsed_bootstrap_methods_attribute = false;
  2489   u1* runtime_visible_annotations = NULL;
  2519   u1* runtime_visible_annotations = NULL;
  2490   int runtime_visible_annotations_length = 0;
  2520   int runtime_visible_annotations_length = 0;
  2491   u1* runtime_invisible_annotations = NULL;
  2521   u1* runtime_invisible_annotations = NULL;
  2492   int runtime_invisible_annotations_length = 0;
  2522   int runtime_invisible_annotations_length = 0;
       
  2523   u1* inner_classes_attribute_start = NULL;
       
  2524   u4  inner_classes_attribute_length = 0;
       
  2525   u2  enclosing_method_class_index = 0;
       
  2526   u2  enclosing_method_method_index = 0;
  2493   // Iterate over attributes
  2527   // Iterate over attributes
  2494   while (attributes_count--) {
  2528   while (attributes_count--) {
  2495     cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
  2529     cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
  2496     u2 attribute_name_index = cfs->get_u2_fast();
  2530     u2 attribute_name_index = cfs->get_u2_fast();
  2497     u4 attribute_length = cfs->get_u4_fast();
  2531     u4 attribute_length = cfs->get_u4_fast();
  2520       if (parsed_innerclasses_attribute) {
  2554       if (parsed_innerclasses_attribute) {
  2521         classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK);
  2555         classfile_parse_error("Multiple InnerClasses attributes in class file %s", CHECK);
  2522       } else {
  2556       } else {
  2523         parsed_innerclasses_attribute = true;
  2557         parsed_innerclasses_attribute = true;
  2524       }
  2558       }
  2525       u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
  2559       inner_classes_attribute_start = cfs->get_u1_buffer();
  2526       if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
  2560       inner_classes_attribute_length = attribute_length;
  2527         guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
  2561       cfs->skip_u1(inner_classes_attribute_length, CHECK);
  2528                           "Wrong InnerClasses attribute length in class file %s", CHECK);
       
  2529       }
       
  2530     } else if (tag == vmSymbols::tag_synthetic()) {
  2562     } else if (tag == vmSymbols::tag_synthetic()) {
  2531       // Check for Synthetic tag
  2563       // Check for Synthetic tag
  2532       // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
  2564       // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
  2533       if (attribute_length != 0) {
  2565       if (attribute_length != 0) {
  2534         classfile_parse_error(
  2566         classfile_parse_error(
  2566           classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK);
  2598           classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK);
  2567         }   else {
  2599         }   else {
  2568           parsed_enclosingmethod_attribute = true;
  2600           parsed_enclosingmethod_attribute = true;
  2569         }
  2601         }
  2570         cfs->guarantee_more(4, CHECK);  // class_index, method_index
  2602         cfs->guarantee_more(4, CHECK);  // class_index, method_index
  2571         u2 class_index  = cfs->get_u2_fast();
  2603         enclosing_method_class_index  = cfs->get_u2_fast();
  2572         u2 method_index = cfs->get_u2_fast();
  2604         enclosing_method_method_index = cfs->get_u2_fast();
  2573         if (class_index == 0) {
  2605         if (enclosing_method_class_index == 0) {
  2574           classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
  2606           classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
  2575         }
  2607         }
  2576         // Validate the constant pool indices and types
  2608         // Validate the constant pool indices and types
  2577         if (!cp->is_within_bounds(class_index) ||
  2609         if (!cp->is_within_bounds(enclosing_method_class_index) ||
  2578             !is_klass_reference(cp, class_index)) {
  2610             !is_klass_reference(cp, enclosing_method_class_index)) {
  2579           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
  2611           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
  2580         }
  2612         }
  2581         if (method_index != 0 &&
  2613         if (enclosing_method_method_index != 0 &&
  2582             (!cp->is_within_bounds(method_index) ||
  2614             (!cp->is_within_bounds(enclosing_method_method_index) ||
  2583              !cp->tag_at(method_index).is_name_and_type())) {
  2615              !cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
  2584           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
  2616           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
  2585         }
  2617         }
  2586         k->set_enclosing_method_indices(class_index, method_index);
       
  2587       } else if (tag == vmSymbols::tag_bootstrap_methods() &&
  2618       } else if (tag == vmSymbols::tag_bootstrap_methods() &&
  2588                  _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
  2619                  _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
  2589         if (parsed_bootstrap_methods_attribute)
  2620         if (parsed_bootstrap_methods_attribute)
  2590           classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
  2621           classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
  2591         parsed_bootstrap_methods_attribute = true;
  2622         parsed_bootstrap_methods_attribute = true;
  2603                                                      runtime_visible_annotations_length,
  2634                                                      runtime_visible_annotations_length,
  2604                                                      runtime_invisible_annotations,
  2635                                                      runtime_invisible_annotations,
  2605                                                      runtime_invisible_annotations_length,
  2636                                                      runtime_invisible_annotations_length,
  2606                                                      CHECK);
  2637                                                      CHECK);
  2607   k->set_class_annotations(annotations());
  2638   k->set_class_annotations(annotations());
       
  2639 
       
  2640   if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
       
  2641     u2 num_of_classes = parse_classfile_inner_classes_attribute(
       
  2642                             inner_classes_attribute_start,
       
  2643                             parsed_innerclasses_attribute,
       
  2644                             enclosing_method_class_index,
       
  2645                             enclosing_method_method_index,
       
  2646                             cp, k, CHECK);
       
  2647     if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
       
  2648       guarantee_property(
       
  2649         inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
       
  2650         "Wrong InnerClasses attribute length in class file %s", CHECK);
       
  2651     }
       
  2652   }
  2608 
  2653 
  2609   if (_max_bootstrap_specifier_index >= 0) {
  2654   if (_max_bootstrap_specifier_index >= 0) {
  2610     guarantee_property(parsed_bootstrap_methods_attribute,
  2655     guarantee_property(parsed_bootstrap_methods_attribute,
  2611                        "Missing BootstrapMethods attribute in class file %s", CHECK);
  2656                        "Missing BootstrapMethods attribute in class file %s", CHECK);
  2612   }
  2657   }