--- a/hotspot/src/share/vm/classfile/verifier.cpp Mon Apr 20 14:48:03 2009 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Tue Apr 21 23:21:04 2009 -0700
@@ -1174,6 +1174,7 @@
&this_uninit, return_type, cp, CHECK_VERIFY(this));
no_control_flow = false; break;
case Bytecodes::_invokeinterface :
+ case Bytecodes::_invokedynamic :
verify_invoke_instructions(
&bcs, code_length, ¤t_frame,
&this_uninit, return_type, cp, CHECK_VERIFY(this));
@@ -1895,12 +1896,23 @@
Bytecodes::Code opcode = bcs->code();
unsigned int types = (opcode == Bytecodes::_invokeinterface
? 1 << JVM_CONSTANT_InterfaceMethodref
+ : opcode == Bytecodes::_invokedynamic
+ ? 1 << JVM_CONSTANT_NameAndType
: 1 << JVM_CONSTANT_Methodref);
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
// Get method name and signature
- symbolHandle method_name(THREAD, cp->name_ref_at(index));
- symbolHandle method_sig(THREAD, cp->signature_ref_at(index));
+ symbolHandle method_name;
+ symbolHandle method_sig;
+ if (opcode == Bytecodes::_invokedynamic) {
+ int name_index = cp->name_ref_index_at(index);
+ int sig_index = cp->signature_ref_index_at(index);
+ method_name = symbolHandle(THREAD, cp->symbol_at(name_index));
+ method_sig = symbolHandle(THREAD, cp->symbol_at(sig_index));
+ } else {
+ method_name = symbolHandle(THREAD, cp->name_ref_at(index));
+ method_sig = symbolHandle(THREAD, cp->signature_ref_at(index));
+ }
if (!SignatureVerifier::is_valid_method_signature(method_sig)) {
class_format_error(
@@ -1910,8 +1922,17 @@
}
// Get referenced class type
- VerificationType ref_class_type = cp_ref_index_to_type(
- index, cp, CHECK_VERIFY(this));
+ VerificationType ref_class_type;
+ if (opcode == Bytecodes::_invokedynamic) {
+ if (!EnableInvokeDynamic) {
+ class_format_error(
+ "invokedynamic instructions not enabled on this JVM",
+ _klass->external_name());
+ return;
+ }
+ } else {
+ ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this));
+ }
// For a small signature length, we just allocate 128 bytes instead
// of parsing the signature once to find its size.
@@ -1970,6 +1991,14 @@
}
}
+ if (opcode == Bytecodes::_invokedynamic) {
+ address bcp = bcs->bcp();
+ if (*(bcp+3) != 0 || *(bcp+4) != 0) {
+ verify_error(bci, "Third and fourth operand bytes of invokedynamic must be zero");
+ return;
+ }
+ }
+
if (method_name->byte_at(0) == '<') {
// Make sure <init> can only be invoked by invokespecial
if (opcode != Bytecodes::_invokespecial ||
@@ -1994,7 +2023,8 @@
current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
}
// Check objectref on operand stack
- if (opcode != Bytecodes::_invokestatic) {
+ if (opcode != Bytecodes::_invokestatic &&
+ opcode != Bytecodes::_invokedynamic) {
if (method_name() == vmSymbols::object_initializer_name()) { // <init> method
verify_invoke_init(bcs, ref_class_type, current_frame,
code_length, this_uninit, cp, CHECK_VERIFY(this));