diff -r 9e8daec25638 -r ecc7862946d4 hotspot/src/share/vm/classfile/verifier.cpp --- 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 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()) { // method verify_invoke_init(bcs, ref_class_type, current_frame, code_length, this_uninit, cp, CHECK_VERIFY(this));