--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jun 10 08:27:35 2010 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Jun 15 15:57:36 2010 -0700
@@ -117,6 +117,29 @@
cp->string_index_at_put(index, string_index);
}
break;
+ case JVM_CONSTANT_MethodHandle :
+ case JVM_CONSTANT_MethodType :
+ if (!EnableMethodHandles ||
+ _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
+ classfile_parse_error(
+ (!EnableInvokeDynamic ?
+ "This JVM does not support constant tag %u in class file %s" :
+ "Class file version does not support constant tag %u in class file %s"),
+ tag, CHECK);
+ }
+ if (tag == JVM_CONSTANT_MethodHandle) {
+ cfs->guarantee_more(4, CHECK); // ref_kind, method_index, tag/access_flags
+ u1 ref_kind = cfs->get_u1_fast();
+ u2 method_index = cfs->get_u2_fast();
+ cp->method_handle_index_at_put(index, ref_kind, method_index);
+ } else if (tag == JVM_CONSTANT_MethodType) {
+ cfs->guarantee_more(3, CHECK); // signature_index, tag/access_flags
+ u2 signature_index = cfs->get_u2_fast();
+ cp->method_type_index_at_put(index, signature_index);
+ } else {
+ ShouldNotReachHere();
+ }
+ break;
case JVM_CONSTANT_Integer :
{
cfs->guarantee_more(5, CHECK); // bytes, tag/access_flags
@@ -337,6 +360,60 @@
cp->unresolved_string_at_put(index, sym);
}
break;
+ case JVM_CONSTANT_MethodHandle :
+ {
+ int ref_index = cp->method_handle_index_at(index);
+ check_property(
+ valid_cp_range(ref_index, length) &&
+ EnableMethodHandles,
+ "Invalid constant pool index %u in class file %s",
+ ref_index, CHECK_(nullHandle));
+ constantTag tag = cp->tag_at(ref_index);
+ int ref_kind = cp->method_handle_ref_kind_at(index);
+ switch (ref_kind) {
+ case JVM_REF_getField:
+ case JVM_REF_getStatic:
+ case JVM_REF_putField:
+ case JVM_REF_putStatic:
+ check_property(
+ tag.is_field(),
+ "Invalid constant pool index %u in class file %s (not a field)",
+ ref_index, CHECK_(nullHandle));
+ break;
+ case JVM_REF_invokeVirtual:
+ case JVM_REF_invokeStatic:
+ case JVM_REF_invokeSpecial:
+ case JVM_REF_newInvokeSpecial:
+ check_property(
+ tag.is_method(),
+ "Invalid constant pool index %u in class file %s (not a method)",
+ ref_index, CHECK_(nullHandle));
+ break;
+ case JVM_REF_invokeInterface:
+ check_property(
+ tag.is_interface_method(),
+ "Invalid constant pool index %u in class file %s (not an interface method)",
+ ref_index, CHECK_(nullHandle));
+ break;
+ default:
+ classfile_parse_error(
+ "Bad method handle kind at constant pool index %u in class file %s",
+ index, CHECK_(nullHandle));
+ }
+ // Keep the ref_index unchanged. It will be indirected at link-time.
+ }
+ break;
+ case JVM_CONSTANT_MethodType :
+ {
+ int ref_index = cp->method_type_index_at(index);
+ check_property(
+ valid_cp_range(ref_index, length) &&
+ cp->tag_at(ref_index).is_utf8() &&
+ EnableMethodHandles,
+ "Invalid constant pool index %u in class file %s",
+ ref_index, CHECK_(nullHandle));
+ }
+ break;
default:
fatal(err_msg("bad constant pool tag value %u",
cp->tag_at(index).value()));
@@ -452,6 +529,43 @@
}
break;
}
+ case JVM_CONSTANT_MethodHandle: {
+ int ref_index = cp->method_handle_index_at(index);
+ int ref_kind = cp->method_handle_ref_kind_at(index);
+ switch (ref_kind) {
+ case JVM_REF_invokeVirtual:
+ case JVM_REF_invokeStatic:
+ case JVM_REF_invokeSpecial:
+ case JVM_REF_newInvokeSpecial:
+ {
+ int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index);
+ int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
+ symbolHandle name(THREAD, cp->symbol_at(name_ref_index));
+ if (ref_kind == JVM_REF_newInvokeSpecial) {
+ if (name() != vmSymbols::object_initializer_name()) {
+ classfile_parse_error(
+ "Bad constructor name at constant pool index %u in class file %s",
+ name_ref_index, CHECK_(nullHandle));
+ }
+ } else {
+ if (name() == vmSymbols::object_initializer_name()) {
+ classfile_parse_error(
+ "Bad method name at constant pool index %u in class file %s",
+ name_ref_index, CHECK_(nullHandle));
+ }
+ }
+ }
+ break;
+ // Other ref_kinds are already fully checked in previous pass.
+ }
+ break;
+ }
+ case JVM_CONSTANT_MethodType: {
+ symbolHandle no_name = vmSymbolHandles::type_name(); // place holder
+ symbolHandle signature(THREAD, cp->method_type_signature_at(index));
+ verify_legal_method_signature(no_name, signature, CHECK_(nullHandle));
+ break;
+ }
} // end of switch
} // end of for
@@ -467,7 +581,7 @@
case JVM_CONSTANT_UnresolvedClass :
// Patching a class means pre-resolving it.
// The name in the constant pool is ignored.
- if (patch->klass() == SystemDictionary::Class_klass()) { // %%% java_lang_Class::is_instance
+ if (java_lang_Class::is_instance(patch())) {
guarantee_property(!java_lang_Class::is_primitive(patch()),
"Illegal class patch at %d in class file %s",
index, CHECK);