Mercurial > hg > graal-compiler
diff src/share/vm/classfile/verifier.cpp @ 726:be93aad57795
6655646: dynamic languages need dynamically linked call sites
Summary: invokedynamic instruction (JSR 292 RI)
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Tue, 21 Apr 2009 23:21:04 -0700 |
parents | a45484ea312d |
children | bd02caa94611 |
line wrap: on
line diff
--- a/src/share/vm/classfile/verifier.cpp Mon Apr 20 14:48:03 2009 -0700 +++ b/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));