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