This document proposes changes to the Java Virtual Machine Specification to introduce a new constant pool form, CONSTANT_Dynamic. See JEP 309 for an overview.

This version includes changes relative to an earlier version, taken 2017-10-24 from http://cr.openjdk.java.net/~dlsmith/constant-dynamic.html

4.4 The Constant Pool

Java Virtual Machine instructions do not rely on the run-time layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pool table.

All constant_pool table entries have the following general format:

cp_info {
    u1 tag;
    u1 info[];
}

Each entry in the constant_pool table must begin with a 1-byte tag indicating the type of constant denoted by the entry. The constant types and their corresponding tag values are listed in Table 4.4-A. Each constant type is accompanied by the first version of the class file format in which it was defined, and the corresponding version of the Java SE Platform. (For old class file versions, the JDK release is used instead of the Java SE Platform version.)

In a class file of version V, each item in the constant_pool table must have a tag that was first defined in version V or before.

The specification has previously failed to restrict the use of CONSTANT_MethodHandle, CONSTANT_MethodType, and CONSTANT_InvokeDynamic to version 51.0+ class files. This new rule addresses that bug.

Each tag byte must be followed by two or more bytes giving information about the specific constant. The format of the additional information depends on the tag byte, that is, the content of the info array varies with the value of tag.

A loadable constant structure is an entry in the constant_pool table that represents a primitive or reference value, or that represents a symbolic reference that can be resolved to a primitive or reference value (5.1).

Some tags in Table 4.4-A are accompanied by the first version of the class file format in which the type was considered loadable. In a class file of version V, an entry in the constant_pool table represents a loadable constant structure if and only if it has a tag that was first considered loadable in version V or before.

Table 4.4-A. Constant pool tags

Constant Type Value class File Java SE Loadable
CONSTANT_Class 7 45.3 1.0.2 49.0
CONSTANT_Fieldref 9 45.3 1.0.2
CONSTANT_Methodref 10 45.3 1.0.2
CONSTANT_InterfaceMethodref 11 45.3 1.0.2
CONSTANT_String 8 45.3 1.0.2 45.3
CONSTANT_Integer 3 45.3 1.0.2 45.3
CONSTANT_Float 4 45.3 1.0.2 45.3
CONSTANT_Long 5 45.3 1.0.2 45.3
CONSTANT_Double 6 45.3 1.0.2 45.3
CONSTANT_NameAndType 12 45.3 1.0.2
CONSTANT_Utf8 1 45.3 1.0.2
CONSTANT_MethodHandle 15 51.0 7 51.0
CONSTANT_MethodType 16 51.0 7 51.0
CONSTANT_InvokeDynamic CONSTANT_DynamicCallSite 18 51.0 7
CONSTANT_Module 19 53.0 9
CONSTANT_Package 20 53.0 9
CONSTANT_Dynamic 17 54.0 18.3 54.0

Some additional changes could help improve the presentation of Table 4.4-A and the similar tables in 4.7:

  • It adds a lot of noise to redundantly list class file version numbers and Java SE version numbers. (Should there be a "Loadable Java SE" column?) Suggest introducing a new table in 4.1 listing the correspondence between Java SE versions and class file versions, and then eliminating references to Java SE versions here and elsewhere.

  • Like the attributes table (4.7), it may be useful for the constants table to list section numbers where the constant is specified.

4.4.10 The CONSTANT_InvokeDynamic_info CONSTANT_DynamicCallSite_info Structure

The CONSTANT_InvokeDynamic_info structure is used by an invokedynamic instruction (invokedynamic) to specify a bootstrap method, the dynamic invocation name, the argument and return types of the call, and optionally, a sequence of additional constants called static arguments to the bootstrap method.

The CONSTANT_DynamicCallSite_info structure is used to describe a dynamically-computed call site, a java.lang.invoke.CallSite object produced by invocation of a bootstrap method (4.7.23) for use by the invokedynamic instruction (invokedynamic). The structure specifies i) a bootstrap method handle with an optional sequence of static arguments and ii) a referenced name and type, where the type represents the method type of the java.lang.invoke.CallSite.

In previous versions of the Java Virtual Machine Specification, CONSTANT_DynamicCallSite_info was referred to as CONSTANT_InvokeDynamic_info.

CONSTANT_DynamicCallSite_info {
   u1 tag;
   u2 bootstrap_method_attr_index;
   u2 name_and_type_index;
}

The items of the CONSTANT_InvokeDynamic_info CONSTANT_DynamicCallSite_info structure are as follows:

tag

The tag item of the CONSTANT_InvokeDynamic_info CONSTANT_DynamicCallSite_info structure has the value CONSTANT_InvokeDynamic CONSTANT_DynamicCallSite (18).

bootstrap_method_attr_index

The value of the bootstrap_method_attr_index item must be a valid index into the bootstrap_methods array of the bootstrap method table (4.7.23) of this class file.

name_and_type_index

The value of the name_and_type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (4.4.6) representing a method name and method descriptor (4.3.3).

The only substantial change to this section is to rename CONSTANT_InvokeDynamic_info to CONSTANT_DynamicCallSite_info. This aligns the tag name with the name of the entity it represents, a "call site specifier" (see, e.g., 5.4.3.6).

4.4.13 The CONSTANT_Dynamic_info Structure

The CONSTANT_Dynamic_info structure is used to describe a dynamically-computed constant, an arbitrary primitive or reference value produced by invocation of a bootstrap method (4.7.23). The structure specifies i) a bootstrap method handle with an optional sequence of static arguments and ii) a referenced name and type.

CONSTANT_Dynamic_info {
   u1 tag;
   u2 bootstrap_method_attr_index;
   u2 name_and_type_index;
}

The items of the CONSTANT_Dynamic_info structure are as follows:

tag

The tag item of the CONSTANT_Dynamic_info structure has the value CONSTANT_Dynamic (17).

bootstrap_method_attr_index

The value of the bootstrap_method_attr_index item must be a valid index into the bootstrap_methods array of the bootstrap method table (4.7.23) of this class file.

The referenced entry in the bootstrap_methods table must not refer, directly or indirectly, to this CONSTANT_Dynamic_info structure.

name_and_type_index

The value of the name_and_type_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_NameAndType_info structure (4.4.6) representing a name and field descriptor (4.3.2).

This section would be a more natural narrative fit if inserted after 4.4.9. But that may not be worth the trouble of renumbering subsequent sections.

4.7.23 The BootstrapMethods Attribute

The BootstrapMethods attribute is a variable-length attribute in the attributes table of a ClassFile structure (4.1). The BootstrapMethods attribute records bootstrap method specifiers referenced by invokedynamic instructions (invokedynamic) used to produce dynamically-computed call sites (4.4.10) and dynamically-computed constants (4.4.13).

There must be exactly one BootstrapMethods attribute in the attributes table of a ClassFile structure if the constant_pool table of the ClassFile structure has at least one CONSTANT_InvokeDynamic_info entry (4.4.10) CONSTANT_DynamicCallSite_info or CONSTANT_Dynamic_info entry.

There may be at most one BootstrapMethods attribute in the attributes table of a ClassFile structure.

The BootstrapMethods attribute has the following format:

BootstrapMethods_attribute { 
    u2 attribute_name_index;
    u4 attribute_length;
    u2 num_bootstrap_methods;
    {   u2 bootstrap_method_ref;
        u2 num_bootstrap_arguments;
        u2 bootstrap_arguments[num_bootstrap_arguments];
    } bootstrap_methods[num_bootstrap_methods];
}
attribute_name_index

The value of the attribute_name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info structure (4.4.7) representing the string "BootstrapMethods".

attribute_length

The value of the attribute_length item indicates the length of the attribute, excluding the initial six bytes.

The value of the attribute_length item is thus dependent on the number of invokedynamic instructions in this ClassFile structure.

This is assertion is false—invokedynamic instructions can share bootstrap methods—and not particularly useful.

num_bootstrap_methods

The value of the num_bootstrap_methods item determines the number of bootstrap method specifiers in the bootstrap_methods array.

bootstrap_methods[]

Each entry in the bootstrap_methods table contains an index to a CONSTANT_MethodHandle_info structure (4.4.8) which specifies a bootstrap method, and a sequence (perhaps empty) of indexes to static arguments for the bootstrap method.

Each bootstrap_methods entry must contain the following three items:

bootstrap_method_ref

The value of the bootstrap_method_ref item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_MethodHandle_info structure (4.4.8).

The form of the method handle is driven by the continuing resolution of the call site specifier in invokedynamic resolution of constant pool entries, where execution of invoke in java.lang.invoke.MethodHandle requires that the bootstrap method handle be adjustable to the actual arguments being passed, as if by a call to java.lang.invoke.MethodHandle.asType. Accordingly, the reference_kind item of the CONSTANT_MethodHandle_info structure should have the value 6 or 8 (5.4.3.5), 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, in that order. Otherwise, invocation of the bootstrap method handle during call site specifier resolution will complete abruptly.

During resolution of a dynamically-computed call site or dynamically-computed constant (5.4.3.6), the method handle will be resolved (5.4.3.5) and invoked, as if by invocation of java.lang.invoke.MethodHandle.invokeinvokeWithArguments. The method handle must be adaptable to the arguments and return type determined by 5.4.3.6 for the call to invokeinvokeWithArguments, or resolution will complete abruptly.

The method handle typically has reference_kind REF_invokeStatic, pointing to a static method designed specifically to act as a bootstrap method.

num_bootstrap_arguments

The value of the num_bootstrap_arguments item gives the number of items in the bootstrap_arguments array.

bootstrap_arguments[]

Each entry in the bootstrap_arguments array must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_String_info, CONSTANT_Class_info, CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_MethodHandle_info, or CONSTANT_MethodType_info structure (4.4.3, 4.4.1, 4.4.4, 4.4.5, 4.4.8, 4.4.9) loadable constant structure (4.4).

4.10.1.3 Instruction Representation

Individual bytecode instructions are represented in Prolog as terms whose functor is the name of the instruction and whose arguments are its parsed operands.

For example, an aload instruction is represented as the term aload(N), which includes the index N that is the operand of the instruction.

The instructions as a whole are represented as a list of terms of the form:

instruction(Offset, AnInstruction)

For example, instruction(21, aload(1)).

The order of instructions in this list must be the same as in the class file.

A few instructions have operands that are constant pool entries representing fields, methods, and dynamic call sites, and dynamic constants. In the constant pool, a field is represented by a CONSTANT_Fieldref_info structure, a method is represented by a CONSTANT_InterfaceMethodref_info structure (for an interface's method) or a CONSTANT_Methodref_info structure (for a class's method), and a dynamic call site is represented by a CONSTANT_InvokeDynamic_info structure (4.4.2, 4.4.10). Such structures These are represented as functor applications of the form:

For clarity, we assume that field and method descriptors (4.3.2, 4.3.3) are mapped into more readable names: the leading L and trailing ; are dropped from class names, and the BaseType characters used for primitive types are mapped to the names of those types.

For example, a getfield instruction whose operand was an index into the constant pool that refers to a field foo of type F in class Bar would be represented as getfield(field('Bar', 'foo', 'F')).

Constant pool entries that refer to constant values, such as CONSTANT_String, CONSTANT_Integer, CONSTANT_Float, CONSTANT_Long, CONSTANT_Double, and CONSTANT_Class, are encoded via the functors whose names are string, int, float, long, double, and classConstant respectively.

For example, an An ldc instruction for loading the integer 91 would be encoded as ldc(int(91)).

This section previously failed to specify the predicates used to represent MethodHandle and MethodType constants used by ldc; that has been fixed.

As a matter of presentation, all relevant constant pool forms now appear in a uniform list, rather than trying to handle some of the more simple cases to the side.

4.10.1.9 Type Checking Instructions

...

ldc, ldc_w, ldc2_w

An ldc instruction with operand CP is type safe iff CP refers to a loadable constant pool entry denoting an entity of type Type, where Type is either int, float, String, Class, java.lang.invoke.MethodType, or java.lang.invoke.MethodHandle not long or double, and one can validly push Type onto the incoming operand stack yielding the outgoing type state.

instructionIsTypeSafe(ldc(CP), Environment, _Offset, StackFrame, NextStackFrame, ExceptionStackFrame) :-

functor(CP, Tag, _),
isBootstrapLoader(BL),
member([Tag, Type], [
[int, int],
[float, float],
[string, class('java/lang/String', BL)],
[classConst, class('java/lang/Class', BL)],
[methodTypeConst, class('java/lang/invoke/MethodType', BL)],
[methodHandleConst, class('java/lang/invoke/MethodHandle', BL)]
]),

loadableConstantType(CP, Type),
Type \= long,
Type \= double,
validTypeTransition(Environment, [], Type, StackFrame, NextStackFrame),
exceptionStackFrame(StackFrame, ExceptionStackFrame).

loadableConstantType(CP, Type) :-

functor(CP, Tag, _),
isBootstrapLoader(BL),
member([Tag, Type], [
[int, int],
[float, float],
[long, long],
[double, double],
[string, class('java/lang/String', BL)],
[classConst, class('java/lang/Class', BL)],
[methodType, class('java/lang/invoke/MethodType', BL)],
[methodHandle, class('java/lang/invoke/MethodHandle', BL)]
]).

loadableConstantType(CP, Type) :-

CP = dynamic(ConstantName, FieldDescriptor),
parseFieldDescriptor(FieldDescriptor, Type).

An ldc_w instruction is type safe iff the equivalent ldc instruction is type safe.

instructionHasEquivalentTypeRule(ldc_w(CP), ldc(CP)).

An ldc2_w instruction with operand CP is type safe iff CP refers to a loadable constant pool entry denoting an entity of type Tag Type, where Tag Type is either long or double, and one can validly push Tag Type onto the incoming operand stack yielding the outgoing type state.

instructionIsTypeSafe(ldc2_w(CP), Environment, _Offset, StackFrame, NextStackFrame, ExceptionStackFrame) :-

functor(CP, Tag, _),
member(Tag, [ long, double ]),
loadableConstantType(CP, Type),
(Type = long; Type = double),
validTypeTransition(Environment, [], Tag Type, StackFrame, NextStackFrame),
exceptionStackFrame(StackFrame, ExceptionStackFrame).

5.1 The Run-Time Constant Pool

The Java Virtual Machine maintains a per-type constant pool (2.5.5), a run-time data structure that serves many of the purposes of the symbol table of a conventional programming language implementation.

The constant_pool table (4.4) in the binary representation of a class or interface is used to construct the run-time constant pool upon class or interface creation (5.3). All references in the run-time constant pool are initially symbolic. The symbolic references in the run-time constant pool are derived from structures in the binary representation of the class or interface as follows:

In addition, certain run-time constant values which are not symbolic references are derived from items found in the constant_pool table:

The remaining structures in the constant_pool table of the binary representation of a class or interface—the CONSTANT_NameAndType_info and CONSTANT_Utf8_info structures (4.4.6, 4.4.7)—are only used indirectly when deriving symbolic references to classes, interfaces, methods, fields, method types, and method handles, and when deriving string literals and call site specifiers constructing the run-time constant pool.

The CONSTANT_Module_info and CONSTANT_Package_info structures do not appear at all in the constant_pool table of the binary representation of a class or interface, so are not relevant to this discussion.

This framing makes it a little clearer that there are three distinct types of run-time constant pool entries: symbolic references, which will later be resolved, constant values, which require no further processing, and supplementary structures, which have no run-time representation.

An entry in the run-time constant pool represents a loadable constant if it is derived from a loadable constant structure (4.4).

Loadable constants can be pushed onto the operand stack by the ldc, ldc_w, and ldc2_w instructions. The can also act as static arguments to a bootstrap method during resolution of dynamically-computed constants and dynamically-computed call sites (5.4.3.6).

5.4 Linking

Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces, and its element type (if it is an array type), if necessary. Resolution of symbolic references in the class or interface is an optional part of linking. Linking also includes resolution of symbolic references in the class or interface.

As the below discussion makes clear, resolution is "part of linking", whether it happens at the same time or later.

This specification allows an implementation flexibility as to when linking activities (and, because of recursion, loading) take place, provided that all of the following properties are maintained:

Because linking involves the allocation of new data structures, it may fail with an OutOfMemoryError. Because linking may involve recursive execution of Java code (for example, during class loading), it may fail with any kind of Error such as StackOverflowError or a recursive LinkageError. However, linking is defined in such a way that it will never fail with an Exception, either checked or unchecked.

The previous paragraph is a non-normative summary of linkage exception processing described elsewhere.

5.4.3 Resolution

The Java Virtual Machine instructions anewarray, checkcast, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, ldc2_w, multianewarray, new, putfield, and putstatic can make symbolic references to the run-time constant pool (5.4). Execution of any of these instructions requires resolution of its symbolic reference.

Resolution is the process of dynamically determining concrete values from symbolic references in the run-time constant pool.

Resolution of the symbolic reference of one occurrence of an invokedynamic instruction does not imply that the same symbolic reference is considered resolved for any other invokedynamic instruction.

For all other instructions above, resolution of the symbolic reference of one occurrence of an instruction does imply that the same symbolic reference is considered resolved for any other non-invokedynamic instruction.

(The above text implies that the concrete value determined by resolution for a specific invokedynamic instruction is a call site object bound to that specific invokedynamic instruction.)

Resolution can be attempted on a symbolic reference that has already been resolved. An attempt to resolve a symbolic reference that has already successfully been resolved always succeeds trivially and always results in the same entity produced by the initial resolution of that reference.

If an error occurs during resolution of a symbolic reference, then an instance of IncompatibleClassChangeError (or a subclass) must be thrown at a point in the program that (directly or indirectly) uses the symbolic reference.

If an attempt by the Java Virtual Machine to resolve a symbolic reference fails because an error is thrown that is an instance of LinkageError (or a subclass), then subsequent attempts to resolve the reference always fail with the same error that was thrown as a result of the initial resolution attempt.

Resolution of a symbolic reference proceeds as follows:

A symbolic reference to a call site specifier by a specific invokedynamic instruction must not be resolved prior to execution of that instruction.

This rule has been moved to 5.4.

In the case of failed resolution of an invokedynamic instruction, the bootstrap method is not re-executed on subsequent resolution attempts.

Certain of the instructions above require additional linking checks when resolving symbolic references. For instance, in order for a getfield instruction to successfully resolve the symbolic reference to the field on which it operates, it must not only complete the field resolution steps given in 5.4.3.2 but also check that the field is not static. If it is a static field, a linking exception must be thrown.

Notably, in order for an invokedynamic instruction to successfully resolve the symbolic reference to a call site specifier, the bootstrap method specified therein must complete normally and return a suitable call site object. If the bootstrap method completes abruptly or returns an unsuitable call site object, a linking exception must be thrown.

Linking exceptions generated by checks that are specific to the execution of a particular Java Virtual Machine instruction are given in the description of that instruction and are not covered in this general discussion of resolution. Note that such exceptions, although described as part of the execution of Java Virtual Machine instructions rather than resolution, are still properly considered failures of resolution.

The following sections describe the initial process of resolving a symbolic reference in the run-time constant pool (5.1) of a class or interface D. Details of resolution differ with the kind of symbolic reference to be resolved.

As this section has evolved, it has developed an unclear structure and unnecessary redundancy. The rewritten version above presents the same content more precisely and concisely. No change in specified behavior is intended, other than to allow for the resolution of dynamically-computed constants.

5.4.3.5 Method Type and Method Handle Resolution

To resolve an unresolved symbolic reference to a method type, it is as if resolution occurs of unresolved symbolic references to classes and interfaces (5.4.3.1) whose names correspond to the types a reference to an instance of Class is produced for each parameter type and return type given in the method descriptor (4.3.3).

For each type named in the descriptor, if the type is a primitive type or void, an instance of Class representing that type is produced directly. Otherwise, an instance of Class corresponding to the type is produced as if by resolution of an unresolved symbolic reference to a class or interface with the given name (5.4.3.1).

Any exception that can be thrown as a result of failure of resolution of a class reference can thus be thrown as a result of failure of method type resolution.

The result of successful method type resolution is a reference to an instance of java.lang.invoke.MethodType which represents the method descriptor.

Method type resolution occurs regardless of whether the run time constant pool actually contains symbolic references to classes and interfaces indicated in the method descriptor. Also, the resolution is deemed to occur 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 later time.

This change clarifies how primitive types appearing in method descriptors are handled, and aligns the rules with the treatment of field descriptors of dynamically-computed constants (5.4.3.6).

...

5.4.3.6 Dynamically-Computed Constant and Call Site Specifier Resolution

To resolve an unresolved symbolic reference to a call site specifier dynamically-computed constant or call site, involves three four five steps are performed:

The vague words about "may terminate immediately" and "must eventually throw" reflect the current implementation of circularity detection. This part of the spec. should be strengthened in a future release, to require a more prompt and deterministic BootstrapMethodError, probably by saying "must terminate immediately", and maybe even with a specified new subclass BootstrapMethodCircularityError.

The result of call site specifier resolution is a tuple consisting of:

Rather than stop here, we continue with invocation of the bootstrap method handle in order to produce a resolution result. In what follows, this section incorporates the rules for "continuing resolution of the call site specifier" from invokedynamic, generalizing them for dynamically-computed constants.

During resolution of the symbolic reference to the method handle in the call site specifier, or resolution of the symbolic reference to the method type for the method descriptor in the call site specifier, or resolution of a symbolic reference to any static argument, any of the exceptions pertaining to method type or method handle resolution may be thrown (5.4.3.5).

This rule is now stated explicitly at the end of each step.

Due to the behavior of the java.lang.invoke.MethodHandle.invoke method, note that the method type of the bootstrap method handle need not be semantically equal to the method descriptor of the invocation. For example, the first parameter type of the bootstrap method handle could be Object instead of java.lang.invoke.MethodHandles.Lookup, and the return type could be Object. If the bootstrap method handle is variable arity, then some or all of the arguments may be collected into a trailing array parameter.

As part of the process of invoking a bootstrap method, it is sometimes necessary to convert from a primitive constant value of type PT to a reference, or vice versa, from a non-null reference to a primitive type PT. (These steps are refered to as "boxing" and "unboxing".) Such conversions are carried out as if by the creation and invocation of an adapted method handle that consumes the value to be converted and returns the converted value. The supposed method handle used by this conversion is obtained by first obtaining a unary method handle that implements the identity function over the type PT, and then adapting it as if by asType, converting the return type (if boxing) or the parameter type (if unboxing) to java.lang.Object. (The identity method handle behaves as if it were obtained from java.lang.invoke.MethodHandles.identity.) In the case of an unboxing operation, the supposed invocation of the method handle may throw an exception, in which case the conversion of the value is considered impossible and the resolution of the dynamically-computed constant must fail.

The invocation of the bootstrap method handle occurs within a thread that is attempting resolution of the symbolic reference. If there are several such threads, the bootstrap method may be invoked in several threads concurrently.

Thus, bootstrap methods which access global application data must take precautions against race conditions.

Despite performing the invocation of the bootstrap method handle "as if by execution of an invokevirtual instruction", no particular method's operand stack is necessarily used, and the value of the max_stack item of any method's Code attribute is not enforced for the invocation.

Likewise, although the invocation is defined "as if" performed by a direct call to invokeWithArguments, implementations are free to use any means of method handle invocation that leads to the same effect, such as calling invoke or invokeExact. In particular, implementations are not required to create a full varargs array of boxed arguments, if there is a more efficient alternative with the same effect. On the other hand, if an implementation chooses to use boxed arguments and varargs arrays, they must be appear identical to boxes and arrays created by adapters produced by MethodHandle.asType. Implementations may store static arguments in either boxed or unboxed forms, since, during method handle invocation, argument values may be freely converted between those forms.

When resolving a symbolic reference to a dynamically-computed call site, if the invocation succeeds, but the resulting java.lang.invoke.CallSite object has a type that is not equal to the java.lang.invoke.MethodType object derived from the method descriptor of the symbolic reference, resolution fails with a BootstrapMethodError.

The old invokedynamic specification asserts that an error also occurs if the result is not a CallSite. But this should be impossible: the invoke call would not succeed if the result were not an instance of the invoked return type, CallSite.

Otherwise, if the invocation succeeds, the result is popped from the operand stack. This is the result of resolution.

If the invocation fails by throwing an instance of Error or a subclass of Error, resolution fails with that exception.

If the invocation fails by throwing an exception that is not an instance of Error or a subclass of Error, resolution fails with a BootstrapMethodError whose cause is the thrown exception.

For example, if the bootstrap method handle has the wrong arity or an incompatible parameter or return type, resolution will fail with a BootstrapMethodError whose cause is a java.lang.invoke.WrongMethodTypeException.

The old invokedynamic specification suggests that wrapping in a BootstrapMethodError may need to occur during earlier steps of resolution as well, but I don't think it is possible for those steps to throw something other than an Error.

6.5 invokedynamic

Operation

Invoke dynamic method a dynamically-computed call site

Format

getfield indexbyte1 indexbyte2 0 0

Forms

invokedynamic = 186 (0xba)

Operand Stack

..., [arg1, [arg2 ... ]] →
...

Description

Each specific lexical occurrence of an invokedynamic instruction is called a dynamic call site.

We've used the term "dynamically-computed call site" to refer to the CallSite object produced by resolution. Thus, it's confusing to use "dynamic call site" to refer to an instruction. The term "call site" has already been claimed by the API, so it seems best to avoid re-using it here. (It might be more appropriate to say that an invokedynamic instruction has a call site, but there's no need to formalize that in the specification.)

First, the unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (2.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The run-time constant pool item at that index must be a symbolic reference to a dynamically-computed call site specifier (5.1). The values of the third and fourth operand bytes must always be zero.

The call site specifier symbolic reference is resolved (5.4.3, 5.4.3.6) for this specific dynamic call site invokedynamic instruction to obtain a reference to an instance of java.lang.invoke.MethodHandle that will serve as the bootstrap method, a reference to an instance of java.lang.invoke.MethodType, and references to static arguments a CallSite object.

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 (invokevirtual) that indicates a run-time constant pool index to a symbolic reference R where:

and where it is as if the following items were pushed, in order, onto the operand stack:

The symbolic reference R describes a method which is signature polymorphic (2.9.3). Due to the operation of invokevirtual on a signature polymorphic method called invoke, the type descriptor of the receiving method handle (representing the bootstrap method) need not be semantically equal to the method descriptor specified by R. For example, the first parameter type specified by R could be Object instead of java.lang.invoke.MethodHandles.Lookup, and the return type specified by R 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.WrongMethodTypeException being thrown, the type descriptor of the method handle which represents the bootstrap method is arbitrary.

If the bootstrap method is a variable arity method, then some or all of the arguments on the operand stack specified above may be collected into a trailing array parameter.

The invocation of a bootstrap method occurs within a thread that is attempting resolution of the symbolic reference to the call site specifier of this dynamic call site. If there are several such threads, the bootstrap method may be invoked in several threads concurrently. Therefore, bootstrap methods which access global application data must take the usual precautions against race conditions.

The result returned by the bootstrap method must be a reference to an object whose class is java.lang.invoke.CallSite or a subclass of java.lang.invoke.CallSite. This object is known as the call site object. The reference is popped from the operand stack used as if in the execution of an invokevirtual instruction.

If several threads simultaneously execute the bootstrap method for the same dynamic call site, the Java Virtual Machine must choose one returned call site object and install it visibly to all threads. Any other bootstrap methods executing for the dynamic call site are allowed to complete, but their results are ignored, and the threads' execution of the dynamic call site proceeds with the chosen call site object.

The call site object has a type descriptor (an instance of java.lang.invoke.MethodType) which must be semantically equal to the java.lang.invoke.MethodType object obtained for the method descriptor in the call site specifier.

The result of successful call site specifier resolution is a call site object which is permanently bound to the dynamic call site.

All of the above rules regarding "continuing resolution of the call site specifier" have been moved to 5.4.3.6 and generalized to also support resolution of dynamically-computed constants.

The nargs argument values are popped from the operand stack. The method handle represented by the target of the bound call site object is invoked. The invocation occurs as if by execution of an invokevirtual instruction that indicates a run-time constant pool index to a symbolic reference T where:

and where it is as if the following items were pushed, in order, onto the operand stack:

Linking Exceptions

If resolution of the symbolic reference to the call site specifier throws an exception E, the invokedynamic instruction throws E if the type of E is Error or a subclass, else throws a BootstrapMethodError that wraps E.

Otherwise, during the continuing resolution of the call site specifier, if invocation of the bootstrap method completes abruptly ([2.6.5]) because of a throw of an exception E, the invokedynamic instruction throws E if the type of E is Error or a subclass, else throws a BootstrapMethodError that wraps E. (The latter can occur if the bootstrap method has the wrong arity, parameter type, or return type, causing java.lang.invoke.MethodHandle.invoke to throw java.lang.invoke.WrongMethodTypeException.)

Otherwise, during the continuing resolution of the call site specifier, if the result from the bootstrap method invocation is not a reference to an instance of java.lang.invoke.CallSite, the invokedynamic instruction throws a BootstrapMethodError.

Otherwise, during the continuing resolution of the call site specifier, if the type descriptor of the target of the call site object is not semantically equal to the method descriptor in the call site specifier, the invokedynamic instruction throws a BootstrapMethodError.

During resolution of the symbolic reference to a dynamically-computed call site, any of the exceptions pertaining to dynamically-computed call site resolution (5.4.3.6) can be thrown.

Run-time Exceptions Notes

If this specific dynamic call site completed resolution of its call site specifier, it implies that a non-null reference to an instance of java.lang.invoke.CallSite is bound to this dynamic call site. Therefore, the operand stack item which represents a reference to the target of the call site object is never null. Similarly, it implies that the method descriptor in the call site specifier is semantically equal to the type descriptor of the method handle to be invoked as if by execution of an invokevirtual instruction. Together, these invariants mean that an invokedynamic instruction which is bound to a call site object never throws a NullPointerException or a java.lang.invoke.WrongMethodTypeException.

This paragraph is merely informative—it does not specify any exceptions to be thrown. Thus, it belongs in the "Notes" section.

6.5 ldc

Operation

Push item from run-time constant pool

Format

ldc index

Forms

ldc = 18 (0x12)

Operand Stack

... →
..., value

Description

The index is an unsigned byte that must be a valid index into the run-time constant pool of the current class (2.6). The run-time constant pool entry at index either must be a run-time constant of type int or float, or a reference to a string literal, or a symbolic reference to a class, method type, or method handle (5.1) loadable constant (5.1), and must not have type long or double.

If the run-time constant pool entry is a run-time constant of type int or float, the numeric value of that run-time constant is pushed onto the operand stack as an int or float, respectively constant value, that value is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a reference to an instance of class String representing a string literal (5.1), then a reference to that instance, value, is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a symbolic reference to a class (5.1), then the named class is resolved (5.4.3.1) and a reference to the Class object representing that class, value, is pushed onto the operand stack.

Otherwise, the run-time constant pool entry must be a symbolic reference to a method type or a method handle (5.1). The method type or method handle symbolic reference is resolved (5.4.3.5 5.4.3) and a reference to the resulting instance of java.lang.invoke.MethodType or java.lang.invoke.MethodHandle, value, the resulting value is pushed onto the operand stack.

Linking Exceptions

During resolution of a symbolic reference to a class, any of the exceptions pertaining to class resolution (5.4.3.1 5.4.3) can be thrown.

During resolution of a symbolic reference to a method type or method handle, any of the exception pertaining to method type or method handle resolution (5.4.3.5) can be thrown.

Notes

The ldc instruction can only be used to push a value of type float taken from the float value set (2.3.2) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

6.5 ldc_w

Operation

Push item from run-time constant pool (wide index)

Format

ldc_w indexbyte1 indexbyte2

Forms

ldc_w = 19 (0x13)

Operand Stack

... →
..., value

Description

The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.6), where the value of the index is calculated as (indexbyte1 << 8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at index either must be a run-time constant of type int or float, or a reference to a string literal, or a symbolic reference to a class, method type, or method handle (5.1) loadable constant (5.1), and must not have type long or double.

If the run-time constant pool entry is a run-time constant of type int or float, the numeric value of that run-time constant is pushed onto the operand stack as an int or float, respectively constant value, that value is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a reference to an instance of class String representing a string literal (5.1), then a reference to that instance, value, is pushed onto the operand stack.

Otherwise, if the run-time constant pool entry is a symbolic reference to a class (5.1), then the named class is resolved (5.4.3.1) and a reference to the Class object representing that class, value, is pushed onto the operand stack.

Otherwise, the run-time constant pool entry must be a symbolic reference to a method type or a method handle (5.1). The method type or method handle symbolic reference is resolved (5.4.3.5 5.4.3) and a reference to the resulting instance of java.lang.invoke.MethodType or java.lang.invoke.MethodHandle, value, the resulting value is pushed onto the operand stack.

Linking Exceptions

During resolution of a symbolic reference to a class, any of the exceptions pertaining to class resolution (5.4.3.1 5.4.3) can be thrown.

During resolution of a symbolic reference to a method type or method handle, any of the exception pertaining to method type or method handle resolution (5.4.3.5) can be thrown.

Notes

The ldc_w instruction is identical to the ldc instruction (ldc) except for its wider run-time constant pool index.

The ldc_w instruction can only be used to push a value of type float taken from the float value set (2.3.2) because a constant of type float in the constant pool (4.4.4) must be taken from the float value set.

6.5 ldc2_w

Operation

Push long or double from run-time constant pool (wide index)

Format

ldc2_w indexbyte1 indexbyte2

Forms

ldc2_w = 20 (0x14)

Operand Stack

... →
..., value

Description

The unsigned indexbyte1 and indexbyte2 are assembled into an unsigned 16-bit index into the run-time constant pool of the current class (2.6), where the value of the index is calculated as (indexbyte1 << 8) | indexbyte2. The index must be a valid index into the run-time constant pool of the current class. The run-time constant pool entry at index must be a run-time constant of type long or double loadable constant (5.1), and must have type long or double. The numeric value of that run-time constant is pushed onto the operand stack as a long or double, respectively.

If the run-time constant pool entry is a constant value, that value is pushed onto the operand stack.

Otherwise, the run-time constant pool entry must be a symbolic reference. The symbolic reference is resolved (5.4.3) and the resulting value is pushed onto the operand stack.

Notes

Only a wide-index version of the ldc2_w instruction exists; there is no ldc2 instruction that pushes a long or double with a single-byte index.

The ldc2_w instruction can only be used to push a value of type double taken from the double value set (2.3.2) because a constant of type double in the constant pool (4.4.5) must be taken from the double value set.