-
Enhancement
-
Resolution: Fixed
-
P4
-
8
-
None
-
generic
-
generic
-
Verified
Minor:
0) 5.1: invokedynamc -> invokedynamic
1) JVMS7 4.4.9 mentions CONSTANT_NameAndType_info when it means CONSTANT_MethodType_info.
2) JVMS7 4.7.21 attribute_length mentions "default value" when it should be "number of invokedynamic instructions in this ClassFile structure."
3) 5.1 should clarify symbolic references to method handles and method types:
- A symbolic reference to a method handle is derived from ... Such a reference gives a symbolic reference to a field of a class or interface, or a method of a class, or a method of an interface, depending on the kind of the method handle."
- A symbolic reference to a method type is derived from ... Such a reference gives a method descriptor (4.3.3).
4) JVMS7 5.4.3.5 Table 5.1 Kind 8 says "void" but it should say "V", the descriptor type for void.
5) JVMS7 5.4.3.6 mentions MethodHandle twice in the tuple returned by call site specifier resolution. It should be "Class, j.l.i.MethodHandle, j.l.i.MethodType, and String."
6) JVMS7 5.5 says "The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic)." - this omits kind 8 (REF_newInvokeSpecial) whose bytecode behavior embeds a 'new' instruction and thus should trigger initialization.
Major:
7) JVMS7 5.4.3.5 says to resolve "all symbolic references to classes mentioned in the method descriptor encapsulated by the method type". The textual contents of the method descriptor are not resolved per se. But what if there are no constant pool entries for the so-mentioned classes? That's fine, because the JVM should act as follows:
***
To resolve an unresolved symbolic reference to a method type, it is as if resolution occurs on unresolved symbolic references to classes and interfaces whose names correspond to the types given in the method descriptor (4.3.3).
Note: This resolution occurs regardless of whether the run time constant pool actually contains symbolic references to these classes and interfaces. Also, the resolution occurs on _unresolved_ symbolic references, so a failure to resolve one method type will not necessarily lead to a later failure to resolve another method type with the same textual method descriptor, if suitable classes and interfaces can be loaded by the time.
***
7a) On a related note, JVMS7 5.4.3.1 says "If C is an array class and its element type is a reference type, then the symbolic reference to the class or interface representing the element type is resolved by invoking 5.4.3.1 recursively." The phrase "_the_ symbolic reference" implies such a reference exists in the run time constant pool, but JVM implementations are not strict about this. That is, a class file's constant pool may have a CONSTANT_Class_info for "[LFoo;" without a CONSTANT_Class_info for "LFoo;", and a JVM implementation will have no trouble resolving the element type Foo. Still, if such a reference exists in the run time constant pool, then it must be used, because any prior failure to resolve it must be respected. Yet, it's a pain to say "use the reference from the run time constant pool if it exists, otherwise spin up an unresolved reference in the style of method type resolution" - after all, there is no real confusion by JVM implementations. I feel only a small change to 5.4.3.1 is justified: "..., then _a_ symbolic reference to the class or interface...".
8) JVMS7 5.4.3.5 is also loose with resolvable entities in the paragraph "To resolve MH, ...":
- f and m are member names extracted by the constant pool. We can't resolve "member names", but we can simply say to resolve R itself (the symbolic reference to a field or method within MH).
- A* and T are type names extracted from the constant pool. We can't resolve "type names", so we need to turn them into proper symbolic references to classes or interfaces. We might consider synthesizing and resolving a symbolic reference to a method type based on the type names in A* and T. However, this method type would be easy to confuse with the method type derived from Table 5.2 a few paragraphs later. We should prefer to reuse the technique from (7), to resolve individual type names.
JVMS7 5.4.3.5 also says, just before Table 5.2, "... as if by resolution of a symbolic reference to the method descriptor given for the kind of MH in Table 5.2." but there is no such thing as a symbolic reference to a method descriptor. We need to wrap the method descriptor in a method type, and resolve that. So, overall, JVMS8 should say:
***
To resolve MH, all symbolic references to classes, interfaces, fields, and methods in MH's bytecode behavior are resolved, using the following three steps:
- First, R is resolved.
- Second, resolution occurs as if on unresolved symbolic references to classes and interfaces whose names correspond to each type in A*, and to the type T, in that order.
- Third, a reference to an instance of java.lang.invoke.MethodType is obtained as if by resolution of a symbolic reference to a method type (5.1) that contains the method descriptor specified in Table 5.2 based on the kind of MH. It is as if the symbolic reference to a method handle contains a symbolic reference to the method type that the resolved method handle will eventually have. The detailed structure of the method type is obtained by inspecting Table 2.
In every step, any exception that can be thrown as a result of failure of resolution of a symbolic reference to a class, interface, field, or method can be thrown as a result of method handle resolution.
Note: The intent is that resolving a method handle can be done in exactly the same circumstances ...
***
As a general point of specification, all "as if" resolution should be done on _unresolved_ symbolic references.
9) JVMS7 5.4.3.6 should have a cross-ref to 4.7.21 (BootstrapMethods attribute) in the first bullet point after "the _bootstrap method_". 4.7.21 itself should enhance the note about the kind of method handle which may serve as a bootstrap method: "The reference_kind ... should have the value 6 or 8, and the reference_index item should specify a static method or constructor that takes three arguments of type java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType. (The form of the method handle is driven by the the continuing resolution of the call site specifier in invokedynamic, where execution of MethodHandle.invoke requires that the bootstrap method handle be adjustable to the actual arguments being passed (as if by MH.asType).) Otherwise, invocation of the bootstrap method handle ..."
10) invokedynamic instruction spec
The JVMS7 text is:
***
Next, as part of the continuing resolution of the call site specifier, the bootstrap method is invoked as if by execution of an invokevirtual instruction that contains a runtime constant pool index to a symbolic reference to a method (§5.1) with the following properties:
• The method’s name is invoke;
• The method’s descriptor has a return type of java.lang.invoke.CallSite; ...
• The method’s descriptor has parameter types derived from the items pushed on to the operand stack, as follows. The first four parameter types in the descriptor are java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType, in that order. If the call site specifier ...
• The method’s symbolic reference to the class in which the method is to be found indicates the class java.lang.invoke.MethodHandle.
***
A MethodHandle instance is pushed on the stack as the receiver, so the method descriptor should not (in fact, must not) include MethodHandle. Thus there are _three_ parameter types, not four. Also, the text should be clearer that the symbolic method reference is to a signature polymorphic method:
***
... as if by execution of an invokevirtual instruction that contains a runtime constant pool index to a symbolic reference M where:
• M is a symbolic reference to a method of a class (§5.1);
• for the symbolic reference to the class in which the method is to be found, M gives java.lang.invoke.MethodHandle;
• for the name of the method, M gives invoke;
• for the descriptor of the method, M gives a return type of java.lang.invoke.CallSite and gives parameter types derived from the items pushed on to the operand stack. The first _three_ parameter types in the descriptor are java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType, in that order. If the call site specifier has any static arguments, then a parameter type ... or double.
where it is as if the following items were pushed ...
Note: The symbolic reference M describes a method which is signature polymorphic (§2.9). Due to the operation of invokevirtual on a signature polymorphic method named "invoke", the type descriptor of the receiving method handle (representing the bootstrap method) need not be semantically equal to the method descriptor given by M. For example, the first parameter type given by M could be Object instead of MethodHandles.Lookup, and the return type given by M could be Object instead of java.lang.invoke.CallSite. As long as the bootstrap method can be invoked by the invoke method without a java.lang.invoke.WrongMethodType exception being thrown, the type descriptor of the method handle which represents the bootstrap method is arbitrary.
***
0) 5.1: invokedynamc -> invokedynamic
1) JVMS7 4.4.9 mentions CONSTANT_NameAndType_info when it means CONSTANT_MethodType_info.
2) JVMS7 4.7.21 attribute_length mentions "default value" when it should be "number of invokedynamic instructions in this ClassFile structure."
3) 5.1 should clarify symbolic references to method handles and method types:
- A symbolic reference to a method handle is derived from ... Such a reference gives a symbolic reference to a field of a class or interface, or a method of a class, or a method of an interface, depending on the kind of the method handle."
- A symbolic reference to a method type is derived from ... Such a reference gives a method descriptor (4.3.3).
4) JVMS7 5.4.3.5 Table 5.1 Kind 8 says "void" but it should say "V", the descriptor type for void.
5) JVMS7 5.4.3.6 mentions MethodHandle twice in the tuple returned by call site specifier resolution. It should be "Class, j.l.i.MethodHandle, j.l.i.MethodType, and String."
6) JVMS7 5.5 says "The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic)." - this omits kind 8 (REF_newInvokeSpecial) whose bytecode behavior embeds a 'new' instruction and thus should trigger initialization.
Major:
7) JVMS7 5.4.3.5 says to resolve "all symbolic references to classes mentioned in the method descriptor encapsulated by the method type". The textual contents of the method descriptor are not resolved per se. But what if there are no constant pool entries for the so-mentioned classes? That's fine, because the JVM should act as follows:
***
To resolve an unresolved symbolic reference to a method type, it is as if resolution occurs on unresolved symbolic references to classes and interfaces whose names correspond to the types given in the method descriptor (4.3.3).
Note: This resolution occurs regardless of whether the run time constant pool actually contains symbolic references to these classes and interfaces. Also, the resolution occurs on _unresolved_ symbolic references, so a failure to resolve one method type will not necessarily lead to a later failure to resolve another method type with the same textual method descriptor, if suitable classes and interfaces can be loaded by the time.
***
7a) On a related note, JVMS7 5.4.3.1 says "If C is an array class and its element type is a reference type, then the symbolic reference to the class or interface representing the element type is resolved by invoking 5.4.3.1 recursively." The phrase "_the_ symbolic reference" implies such a reference exists in the run time constant pool, but JVM implementations are not strict about this. That is, a class file's constant pool may have a CONSTANT_Class_info for "[LFoo;" without a CONSTANT_Class_info for "LFoo;", and a JVM implementation will have no trouble resolving the element type Foo. Still, if such a reference exists in the run time constant pool, then it must be used, because any prior failure to resolve it must be respected. Yet, it's a pain to say "use the reference from the run time constant pool if it exists, otherwise spin up an unresolved reference in the style of method type resolution" - after all, there is no real confusion by JVM implementations. I feel only a small change to 5.4.3.1 is justified: "..., then _a_ symbolic reference to the class or interface...".
8) JVMS7 5.4.3.5 is also loose with resolvable entities in the paragraph "To resolve MH, ...":
- f and m are member names extracted by the constant pool. We can't resolve "member names", but we can simply say to resolve R itself (the symbolic reference to a field or method within MH).
- A* and T are type names extracted from the constant pool. We can't resolve "type names", so we need to turn them into proper symbolic references to classes or interfaces. We might consider synthesizing and resolving a symbolic reference to a method type based on the type names in A* and T. However, this method type would be easy to confuse with the method type derived from Table 5.2 a few paragraphs later. We should prefer to reuse the technique from (7), to resolve individual type names.
JVMS7 5.4.3.5 also says, just before Table 5.2, "... as if by resolution of a symbolic reference to the method descriptor given for the kind of MH in Table 5.2." but there is no such thing as a symbolic reference to a method descriptor. We need to wrap the method descriptor in a method type, and resolve that. So, overall, JVMS8 should say:
***
To resolve MH, all symbolic references to classes, interfaces, fields, and methods in MH's bytecode behavior are resolved, using the following three steps:
- First, R is resolved.
- Second, resolution occurs as if on unresolved symbolic references to classes and interfaces whose names correspond to each type in A*, and to the type T, in that order.
- Third, a reference to an instance of java.lang.invoke.MethodType is obtained as if by resolution of a symbolic reference to a method type (5.1) that contains the method descriptor specified in Table 5.2 based on the kind of MH. It is as if the symbolic reference to a method handle contains a symbolic reference to the method type that the resolved method handle will eventually have. The detailed structure of the method type is obtained by inspecting Table 2.
In every step, any exception that can be thrown as a result of failure of resolution of a symbolic reference to a class, interface, field, or method can be thrown as a result of method handle resolution.
Note: The intent is that resolving a method handle can be done in exactly the same circumstances ...
***
As a general point of specification, all "as if" resolution should be done on _unresolved_ symbolic references.
9) JVMS7 5.4.3.6 should have a cross-ref to 4.7.21 (BootstrapMethods attribute) in the first bullet point after "the _bootstrap method_". 4.7.21 itself should enhance the note about the kind of method handle which may serve as a bootstrap method: "The reference_kind ... should have the value 6 or 8, and the reference_index item should specify a static method or constructor that takes three arguments of type java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType. (The form of the method handle is driven by the the continuing resolution of the call site specifier in invokedynamic, where execution of MethodHandle.invoke requires that the bootstrap method handle be adjustable to the actual arguments being passed (as if by MH.asType).) Otherwise, invocation of the bootstrap method handle ..."
10) invokedynamic instruction spec
The JVMS7 text is:
***
Next, as part of the continuing resolution of the call site specifier, the bootstrap method is invoked as if by execution of an invokevirtual instruction that contains a runtime constant pool index to a symbolic reference to a method (§5.1) with the following properties:
• The method’s name is invoke;
• The method’s descriptor has a return type of java.lang.invoke.CallSite; ...
• The method’s descriptor has parameter types derived from the items pushed on to the operand stack, as follows. The first four parameter types in the descriptor are java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType, in that order. If the call site specifier ...
• The method’s symbolic reference to the class in which the method is to be found indicates the class java.lang.invoke.MethodHandle.
***
A MethodHandle instance is pushed on the stack as the receiver, so the method descriptor should not (in fact, must not) include MethodHandle. Thus there are _three_ parameter types, not four. Also, the text should be clearer that the symbolic method reference is to a signature polymorphic method:
***
... as if by execution of an invokevirtual instruction that contains a runtime constant pool index to a symbolic reference M where:
• M is a symbolic reference to a method of a class (§5.1);
• for the symbolic reference to the class in which the method is to be found, M gives java.lang.invoke.MethodHandle;
• for the name of the method, M gives invoke;
• for the descriptor of the method, M gives a return type of java.lang.invoke.CallSite and gives parameter types derived from the items pushed on to the operand stack. The first _three_ parameter types in the descriptor are java.lang.invoke.MethodHandles.Lookup, String, and java.lang.invoke.MethodType, in that order. If the call site specifier has any static arguments, then a parameter type ... or double.
where it is as if the following items were pushed ...
Note: The symbolic reference M describes a method which is signature polymorphic (§2.9). Due to the operation of invokevirtual on a signature polymorphic method named "invoke", the type descriptor of the receiving method handle (representing the bootstrap method) need not be semantically equal to the method descriptor given by M. For example, the first parameter type given by M could be Object instead of MethodHandles.Lookup, and the return type given by M could be Object instead of java.lang.invoke.CallSite. As long as the bootstrap method can be invoked by the invoke method without a java.lang.invoke.WrongMethodType exception being thrown, the type descriptor of the method handle which represents the bootstrap method is arbitrary.
***
- relates to
-
JDK-8043191 5.5: Clarify that invokedynamic can trigger initialization
-
- Closed
-