Table of Contents
A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs.
The description of each
instruction is always given in the context of Java Virtual Machine code that
satisfies the static and structural constraints of
§4 (The class
File Format). In the description of individual Java Virtual Machine
instructions, we frequently state that some situation "must" or "must
not" be the case: "The value2 must be of type int
." The
constraints of §4 (The class
File Format) guarantee that all such
expectations will in fact be met. If some constraint (a "must" or
"must not") in an instruction description is not satisfied at run
time, the behavior of the Java Virtual Machine is undefined.
The Java Virtual Machine checks that Java Virtual Machine
code satisfies the static and structural constraints at link time
using a class
file verifier (§4.10). Thus, the
Java Virtual Machine will only attempt to execute code from valid class
files.
Performing verification at link time is attractive in that the checks
are performed just once, substantially reducing the amount of work
that must be done at run time. Other implementation strategies are
possible, provided that they comply with The Java Language Specification, Java SE 21 Edition and The Java Virtual Machine Specification, Java SE 21 Edition.
In addition to the opcodes of
the instructions specified later in this chapter, which are used in
class
files (§4 (The class
File Format)), three opcodes are reserved
for internal use by a Java Virtual Machine implementation. If the instruction set of
the Java Virtual Machine is extended in the future, these reserved opcodes are
guaranteed not to be used.
Two of the reserved opcodes, numbers 254 (0xfe) and 255 (0xff), have the mnemonics impdep1 and impdep2, respectively. These instructions are intended to provide "back doors" or traps to implementation-specific functionality implemented in software and hardware, respectively. The third reserved opcode, number 202 (0xca), has the mnemonic breakpoint and is intended to be used by debuggers to implement breakpoints.
Although these opcodes have
been reserved, they may be used only inside a Java Virtual Machine
implementation. They cannot appear in valid class
files. Tools such
as debuggers or JIT code generators (§2.13) that
might directly interact with Java Virtual Machine code that has been already loaded
and executed may encounter these opcodes. Such tools should attempt to
behave gracefully if they encounter any of these reserved
instructions.
A Java Virtual Machine implementation throws
an object that is an instance of a subclass of the class VirtualMachineError
when an
internal error or resource limitation prevents it from implementing
the semantics described in this chapter. This specification cannot
predict where internal errors or resource limitations may be
encountered and does not mandate precisely when they can be
reported. Thus, any of the VirtualMachineError
subclasses defined below may be
thrown at any time during the operation of the Java Virtual Machine:
InternalError
: An
internal error has occurred in the Java Virtual Machine implementation because of
a fault in the software implementing the virtual machine, a fault
in the underlying host system software, or a fault in the
hardware. This error is delivered asynchronously
(§2.10) when it is detected and may occur at
any point in a program.
OutOfMemoryError
: The Java Virtual Machine
implementation has run out of either virtual or physical memory,
and the automatic storage manager was unable to reclaim enough
memory to satisfy an object creation request.
StackOverflowError
: The Java Virtual Machine
implementation has run out of stack space for a thread, typically
because the thread is doing an unbounded number of recursive
invocations as a result of a fault in the executing
program.
UnknownError
: An
exception or error has occurred, but the Java Virtual Machine implementation is
unable to report the actual exception or error.
Java Virtual Machine instructions are represented in this chapter by entries of the form shown below, in alphabetical order and each beginning on a new page.
A longer description detailing constraints on operand stack contents or constant pool entries, the operation performed, the type of the results, etc.
If any linking exceptions may be thrown by the execution of this instruction, they are set off one to a line, in the order in which they must be thrown.
If any run-time exceptions can be thrown by the execution of an instruction, they are set off one to a line, in the order in which they must be thrown.
Other than the linking and run-time exceptions, if
any, listed for an instruction, that instruction must not throw any
run-time exceptions except for instances of VirtualMachineError
or its
subclasses.
Each cell in the instruction
format diagram represents a single 8-bit byte. The instruction's
mnemonic is its name. Its opcode is its numeric
representation and is given in both decimal and hexadecimal
forms. Only the numeric representation is actually present in the
Java Virtual Machine code in a class
file.
Keep in mind that there are "operands" generated at compile time and embedded within Java Virtual Machine instructions, as well as "operands" calculated at run time and supplied on the operand stack. Although they are supplied from several different areas, all these operands represent the same thing: values to be operated upon by the Java Virtual Machine instruction being executed. By implicitly taking many of its operands from its operand stack, rather than representing them explicitly in its compiled code as additional operand bytes, register numbers, etc., the Java Virtual Machine's code stays compact.
Some instructions are presented as members of a family of related instructions sharing a single description, format, and operand stack diagram. As such, a family of instructions includes several opcodes and opcode mnemonics; only the family mnemonic appears in the instruction format diagram, and a separate forms line lists all member mnemonics and opcodes. For example, the Forms line for the lconst_<l> family of instructions, giving mnemonic and opcode information for the two instructions in that family (lconst_0 and lconst_1), is
In the description of the Java Virtual Machine instructions, the effect of an instruction's execution on the operand stack (§2.6.2) of the current frame (§2.6) is represented textually, with the stack growing from left to right and each value represented separately. Thus,
shows an operation that begins by having value2 on top of the operand stack with value1 just beneath it. As a result of the execution of the instruction, value1 and value2 are popped from the operand stack and replaced by result value, which has been calculated by the instruction. The remainder of the operand stack, represented by an ellipsis (...), is unaffected by the instruction's execution.
Values of types long
and
double
are represented by a single entry on the operand
stack.
In the First Edition of The Java® Virtual Machine Specification, values on the
operand stack of types long
and double
were each represented in
the stack diagram by two entries.
The arrayref must be of type reference
and must refer to an array
whose components are of type reference
. The index must be of type
int
. Both arrayref and index are popped from the operand
stack. The reference
value in the component of the array at index
is retrieved and pushed onto the operand stack.
The arrayref must be of type reference
and must refer to an array
whose components are of type reference
. The index must be of type
int
, and value must be of type reference
. The arrayref, index,
and value are popped from the operand stack.
If value is null
, then value is stored as the component of
the array at index.
Otherwise, value is non-null
. If the type of value is
assignment compatible with the type of the components of the array
referenced by arrayref, then value is stored as the component
of the array at index.
The following rules are used to determine whether a value that
is not null
is assignment compatible with the array component
type. If S is the type of the object referred to by value, and
T is the reference type of the array components, then aastore
determines whether assignment is compatible as follows:
If arrayref is null
, aastore throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the aastore instruction throws an
ArrayIndexOutOfBoundsException
.
Otherwise, if arrayref is not null
and the actual type of the
non-null
value is not assignment compatible with the actual
type of the components of the array, aastore throws an
ArrayStoreException
.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local variable at index must
contain a reference
. The objectref in the local variable at index
is pushed onto the operand stack.
The aload instruction cannot be used to load a value of type
returnAddress
from a local variable onto the operand stack. This
asymmetry with the astore instruction
(§astore) is intentional.
The aload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain a reference
. The objectref
in the local variable at <n> is pushed onto the operand
stack.
An aload_<n> instruction cannot be used to load a value of type
returnAddress
from a local variable onto the operand stack. This
asymmetry with the corresponding astore_<n> instruction
(§astore_<n>) is intentional.
Each of the aload_<n> instructions is the same as aload with an index of <n>, except that the operand <n> is implicit.
The count must be of type int
. It is popped off the operand
stack. The count represents the number of components of the
array to be created. 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 entry at the index must be a symbolic
reference to a class, array, or interface type. The named class,
array, or interface type is resolved
(§5.4.3.1). A new array with components of
that type, of length count, is allocated from the
garbage-collected heap, and a reference
arrayref to this new array
object is pushed onto the operand stack. All components of the new
array are initialized to null
, the default value for reference
types
(§2.4).
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
The objectref must be of type reference
and must refer to an object
of a type that is assignment compatible (JLS §5.2) with the type
represented by the return descriptor
(§4.3.3) of the current method. If the
current method is a synchronized
method, the monitor entered or
reentered on invocation of the method is updated and possibly
exited as if by execution of a monitorexit instruction
(§monitorexit) in the current thread. If
no exception is thrown, objectref is popped from the operand
stack of the current frame (§2.6) and pushed
onto the operand stack of the frame of the invoker. Any other
values on the operand stack of the current method are
discarded.
The interpreter then reinstates the frame of the invoker and returns control to the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, areturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then areturn throws an
IllegalMonitorStateException
.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The objectref on the top of the
operand stack must be of type returnAddress
or of type reference
. It
is popped from the operand stack, and the value of the local
variable at index is set to objectref.
The astore instruction is used with an objectref of type
returnAddress
when implementing the finally
clause of the
Java programming language (§3.13).
The aload instruction (§aload) cannot
be used to load a value of type returnAddress
from a local
variable onto the operand stack. This asymmetry with the astore
instruction is intentional.
The astore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The objectref
on the top of the operand stack must be of type returnAddress
or
of type reference
. It is popped from the operand stack, and the value
of the local variable at <n> is set to
objectref.
An astore_<n> instruction is used with an objectref of type
returnAddress
when implementing the finally
clauses of the
Java programming language (§3.13).
An aload_<n> instruction (§aload_<n>)
cannot be used to load a value of type returnAddress
from a
local variable onto the operand stack. This asymmetry with the
corresponding astore_<n> instruction is intentional.
Each of the astore_<n> instructions is the same as astore with an index of <n>, except that the operand <n> is implicit.
The objectref must be of type reference
and must refer to an object
that is an instance of class Throwable
or of a subclass of
Throwable
. It is popped from the operand stack. The objectref
is then thrown by searching the current method
(§2.6) for the first exception handler that
matches the class of objectref, as given by the algorithm in
§2.10.
If an exception handler that matches objectref is found, it
contains the location of the code intended to handle this
exception. The pc
register is reset to that location, the
operand stack of the current frame is cleared, objectref is
pushed back onto the operand stack, and execution
continues.
If no matching exception handler is found in the current frame,
that frame is popped. If the current frame represents an
invocation of a synchronized
method, the monitor entered or
reentered on invocation of the method is exited as if by execution
of a monitorexit instruction
(§monitorexit). Finally, the frame of
its invoker is reinstated, if such a frame exists, and the
objectref is rethrown. If no such frame exists, the current
thread exits.
If objectref is null
, athrow throws a NullPointerException
instead of
objectref.
Otherwise, if the Java Virtual Machine implementation does not enforce the rules
on structured locking described in §2.11.10,
then if the method of the current frame is a synchronized
method
and the current thread is not the owner of the monitor entered or
reentered on invocation of the method, athrow throws an
IllegalMonitorStateException
instead of the object previously
being thrown. This can happen, for example, if an abruptly
completing synchronized
method contains a monitorexit
instruction, but no monitorenter instruction, on the object on
which the method is synchronized.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then athrow throws an
IllegalMonitorStateException
instead of the object previously
being thrown.
The operand stack diagram for the athrow instruction may be misleading: If a handler for this exception is matched in the current method, the athrow instruction discards all the values on the operand stack, then pushes the thrown object onto the operand stack. However, if no handler is matched in the current method and the exception is thrown farther up the method invocation chain, then the operand stack of the method (if any) that handles the exception is cleared and objectref is pushed onto that empty operand stack. All intervening frames from the method that threw the exception up to, but not including, the method that handles the exception are discarded.
The arrayref must be of type reference
and must refer to an array
whose components are of type byte
or of type boolean
. The
index must be of type int
. Both arrayref and index are
popped from the operand stack. The byte
value in the component
of the array at index is retrieved, sign-extended to an int
value, and pushed onto the top of the operand stack.
If arrayref is null
, baload throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the baload instruction throws an
ArrayIndexOutOfBoundsException
.
The baload instruction is used to load values from both byte
and boolean
arrays. In Oracle's Java Virtual Machine implementation, boolean
arrays - that is, arrays of type T_BOOLEAN
(§2.2, §newarray)
- are implemented as arrays of 8-bit values. Other implementations
may implement packed boolean
arrays; the baload instruction of
such implementations must be used to access those arrays.
The arrayref must be of type reference
and must refer to an array
whose components are of type byte
or of type boolean
. The
index and the value must both be of type int
. The arrayref,
index, and value are popped from the operand stack.
If the arrayref refers to an array whose components are of type byte
,
then the int
value is truncated to a byte
and stored as
the component of the array indexed by index.
If the arrayref refers to an array whose components are of type
boolean
, then the int
value is narrowed by taking the bitwise
AND of value and 1; the result is stored as the component of the
array indexed by index.
If arrayref is null
, bastore throws a NullPointerException
.
Otherwise, if index is not within the bounds of the array
referenced by arrayref, the bastore instruction throws an
ArrayIndexOutOfBoundsException
.
The bastore instruction is used to store values into both byte
and boolean
arrays. In Oracle's Java Virtual Machine implementation, boolean
arrays - that is, arrays of type T_BOOLEAN
(§2.2, §newarray)
- are implemented as arrays of 8-bit values. Other implementations
may implement packed boolean
arrays; in such implementations the
bastore instruction must be able to store boolean
values into
packed boolean
arrays as well as byte
values into byte
arrays.
The arrayref must be of type reference
and must refer to an array
whose components are of type char
. The index must be of type
int
. Both arrayref and index are popped from the operand
stack. The component of the array at index is retrieved and
zero-extended to an int
value. That value is pushed onto the
operand stack.
The arrayref must be of type reference
and must refer to an array
whose components are of type char
. The index and the value
must both be of type int
. The arrayref, index, and value
are popped from the operand stack. The int
value is truncated
to a char
and stored as the component of the array indexed by
index.
The objectref must be of type reference
. 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 entry at the index must be
a symbolic reference to a class, array, or interface type.
If objectref is null
, then the operand stack is unchanged.
Otherwise, the named class, array, or interface type is resolved
(§5.4.3.1). If objectref can be cast to
the resolved class, array, or interface type, the operand stack is
unchanged; otherwise, the checkcast instruction throws a
ClassCastException
.
The following rules are used to determine whether an objectref
that is not null
can be cast to the resolved type. If S is the
type of the object referred to by objectref, and T is the
resolved class, array, or interface type, then checkcast
determines whether objectref can be cast to type T as follows:
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
Otherwise, if objectref cannot be cast to the resolved class,
array, or interface type, the checkcast instruction throws a
ClassCastException
.
The checkcast instruction is very similar to the instanceof
instruction (§instanceof). It differs in
its treatment of null
, its behavior when its test fails
(checkcast throws an exception, instanceof pushes a result
code), and its effect on the operand stack.
The value on the top of the operand stack must be of type
double
. It is popped from the operand stack and converted to a float
result using
the round to nearest rounding
policy (§2.8). The result is pushed onto the
operand stack.
A finite value too small to be represented as a float
is
converted to a zero of the same sign; a finite value too large
to be represented as a float
is converted to an infinity of the
same sign. A double
NaN is converted to a float
NaN.
The value on the top of the operand stack must be of type
double
. It is popped from the operand stack and converted to an int
result.
The result is pushed onto the operand stack:
If the value is NaN, the result of the conversion is an
int
0.
Otherwise, if the value is not an infinity, it is rounded
to an integer value V using the round toward zero rounding
policy (§2.8). If this integer value V can be
represented as an int
, then the result is the int
value
V.
Otherwise, either the value must be too small (a negative
value of large magnitude or negative infinity), and the
result is the smallest representable value of type int
, or
the value must be too large (a positive value of large
magnitude or positive infinity), and the result is the
largest representable value of type int
.
The value on the top of the operand stack must be of type
double
. It is popped from the operand stack and converted to a long
. The result is
pushed onto the operand stack:
If the value is NaN, the result of the conversion is a
long
0.
Otherwise, if the value is not an infinity, it is rounded
to an integer value V using the round toward zero rounding
policy (§2.8). If this integer value V can be
represented as a long
, then the result is the long
value
V.
Otherwise, either the value must be too small (a negative
value of large magnitude or negative infinity), and the result
is the smallest representable value of type long
, or the
value must be too large (a positive value of large magnitude
or positive infinity), and the result is the largest
representable value of type long
.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack. The double
result is value1 + value2. The
result is pushed onto the operand stack.
The result of a dadd instruction is governed by the rules of IEEE 754 arithmetic:
The sum of two infinities of the same sign is the infinity of that sign.
The sum of an infinity and any finite value is equal to the infinity.
The sum of two zeroes of the same sign is the zero of that sign.
The sum of a zero and a nonzero finite value is equal to the nonzero value.
The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.
In the remaining cases, where neither operand is an infinity,
a zero, or NaN and the values have the same sign or have
different magnitudes, the sum is computed and rounded to the
nearest representable value using the round to nearest rounding policy
(§2.8). If the magnitude is too large to
represent as a double
, we say the operation overflows; the result
is then an infinity of appropriate sign. If the magnitude is too small
to represent as a double
, we say the operation underflows;
the result is then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dadd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type double
. The index must be of type
int
, and value must be of type double
. The arrayref,
index, and value are popped from the operand stack. The
double
value is
stored as the component of the array indexed by index.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack and a floating-point comparison is performed:
If value1 is greater than value2, the int
value 1 is
pushed onto the operand stack.
Otherwise, if value1 is equal to value2, the int
value
0 is pushed onto the operand stack.
Otherwise, if value1 is less than value2, the int
value -1 is pushed onto the operand stack.
Otherwise, at least one of value1 or value2 is NaN. The
dcmpg instruction pushes the int
value 1 onto the operand
stack and the dcmpl instruction pushes the int
value -1
onto the operand stack.
Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.
The dcmpg and dcmpl instructions differ only in their
treatment of a comparison involving NaN. NaN is unordered, so any
double
comparison fails if either or both of its operands are
NaN. With both dcmpg and dcmpl available, any double
comparison may be compiled to push the same result onto the
operand stack whether the comparison fails on non-NaN values or
fails because it encountered a NaN. For more information, see
§3.5.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack. The double
result is value1 / value2. The
result is pushed onto the operand stack.
The result of a ddiv instruction is governed by the rules of IEEE 754 arithmetic:
If neither value1 nor value2 is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.
Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.
Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither operand is an infinity,
a zero, or NaN, the quotient is computed and rounded to the
nearest double
using the
round to nearest rounding policy (§2.8).
If the magnitude is too large to represent as a double
, we say the
operation overflows; the result is then an infinity of
appropriate sign. If the magnitude is too small to represent
as a double
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of a ddiv instruction never throws a run-time exception.
The index is an unsigned byte. Both index and index+1 must
be indices into the local variable array of the current frame
(§2.6). The local variable at index must
contain a double
. The value of the local variable at index
is pushed onto the operand stack.
The dload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The local variable at <n>
must contain a double
. The value of the local variable at
<n> is pushed onto the operand stack.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack. The double
result is value1 * value2. The
result is pushed onto the operand stack.
The result of a dmul instruction is governed by the rules of IEEE 754 arithmetic:
If neither value1 nor value2 is NaN, the sign of the result is positive if both values have the same sign and negative if the values have different signs.
Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither an infinity nor NaN is
involved, the product is computed and rounded to the nearest
representable value using the
round to nearest rounding policy (§2.8). If
the magnitude is too large to represent as a double
, we say
the operation overflows; the result is then an infinity of
appropriate sign. If the magnitude is too small to represent
as a double
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dmul instruction never throws a run-time exception.
The value must be of type double
. It is popped from the operand
stack. The
double
result is the arithmetic negation of value. The
result is pushed onto the operand stack.
For double
values, negation is not the same as subtraction from
zero. If x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
. Unary
minus merely inverts the sign of a double
.
If the operand is NaN, the result is NaN (recall that NaN has no sign).
The Java Virtual Machine has not adopted the stronger requirement from the 2019 version of the IEEE 754 Standard that negation inverts the sign bit for all inputs, including NaN.
If the operand is an infinity, the result is the infinity of opposite sign.
If the operand is a zero, the result is the zero of opposite sign.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack. The double
result is calculated and pushed onto the
operand stack.
The result of a drem instruction is not the same as the result of
the remainder operation defined by IEEE 754, due to the choice of
rounding policy in the Java Virtual Machine (§2.8).
The IEEE 754 remainder operation computes the remainder from a rounding
division, not a truncating division, and so its behavior
is not analogous to that of the usual integer
remainder operator. Instead, the Java Virtual Machine defines drem to behave in
a manner analogous to that of the integer remainder
instructions irem and lrem, with an implied division using the
round toward zero rounding policy; this may be compared with the C
library function fmod
.
The result of a drem instruction is governed by the following rules, which match IEEE 754 arithmetic except for how the implied division is computed:
If neither value1 nor value2 is NaN, the sign of the result equals the sign of the dividend.
If the dividend is an infinity or the divisor is a zero or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend value1 and a divisor value2 is defined by the mathematical relation result = value1 - (value2 * q), where q is an integer that is negative only if value1 / value2 is negative, and positive only if value1 / value2 is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1 and value2.
Despite the fact that division by zero may occur, evaluation of a drem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.
The current method must have return type double
. The value
must be of type double
. If the current method is a
synchronized
method, the monitor entered or reentered on
invocation of the method is updated and possibly exited as if by
execution of a monitorexit instruction (§monitorexit) in the current thread. If no
exception is thrown, value is popped from the operand stack of
the current frame (§2.6) and pushed onto the operand stack of the
frame of the invoker. Any other values on the operand stack of the
current method are discarded.
The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, dreturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then dreturn throws an
IllegalMonitorStateException
.
The index is an unsigned byte. Both index and index+1 must
be indices into the local variable array of the current frame
(§2.6). The value on the top of the
operand stack must be of type double
. It is popped from the
operand stack.
The local variables at index and index+1 are set to value.
The dstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The value on the top of the
operand stack must be of type double
. It is popped from the
operand stack.
The local variables at <n> and <n>+1 are set to
value.
Both value1 and value2 must be of type double
. The values
are popped from the operand stack. The double
result is value1 - value2. The
result is pushed onto the operand stack.
For double
subtraction, it is always the case
that a-b
produces the same result
as a+(-b)
. However, for the dsub instruction,
subtraction from zero is not the same as negation, because
if x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of a dsub instruction never throws a run-time exception.
Duplicate the top value on the operand stack and push the duplicated value onto the operand stack.
The dup instruction must not be used unless value is a value of a category 1 computational type (§2.11.1).
Duplicate the top value on the operand stack and insert the duplicated value two values down in the operand stack.
The dup_x1 instruction must not be used unless both value1 and value2 are values of a category 1 computational type (§2.11.1).
Duplicate the top one or two operand stack values and insert two, three, or four values down
..., value4, value3, value2, value1 →
..., value2, value1, value4, value3, value2, value1
where value1, value2, value3, and value4 are all values of a category 1 computational type (§2.11.1).
..., value1, value3, value2, value1
where value1 is a value of a category 2 computational type and value2 and value3 are both values of a category 1 computational type (§2.11.1).
..., value2, value1, value3, value2, value1
where value1 and value2 are both values of a category 1 computational type and value3 is a value of a category 2 computational type (§2.11.1).
where value1 and value2 are both values of a category 2 computational type (§2.11.1).
The value on the top of the operand stack must be of type
float
. It is popped from the operand stack and converted to an int
result. The
result is pushed onto the operand stack:
If the value is NaN, the result of the conversion is an
int
0.
Otherwise, if the value is not an infinity, it is rounded
to an integer value V using the round toward zero rounding
policy (§2.8). If this integer value V can be
represented as an int
, then the result is the int
value
V.
Otherwise, either the value must be too small (a negative
value of large magnitude or negative infinity), and the
result is the smallest representable value of type int
, or
the value must be too large (a positive value of large
magnitude or positive infinity), and the result is the
largest representable value of type int
.
The value on the top of the operand stack must be of type
float
. It is popped from the operand stack and converted to a long
result. The
result is pushed onto the operand stack:
If the value is NaN, the result of the conversion is a
long
0.
Otherwise, if the value is not an infinity, it is rounded
to an integer value V using the round toward zero rounding
policy (§2.8). If this integer value V can be
represented as a long
, then the result is the long
value
V.
Otherwise, either the value must be too small (a negative
value of large magnitude or negative infinity), and the
result is the smallest representable value of type long
,
or the value must be too large (a positive value of large
magnitude or positive infinity), and the result is the
largest representable value of type long
.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack. The float
result is value1 + value2. The
result is pushed onto the operand stack.
The result of an fadd instruction is governed by the rules of IEEE 754 arithmetic:
The sum of two infinities of the same sign is the infinity of that sign.
The sum of an infinity and any finite value is equal to the infinity.
The sum of two zeroes of the same sign is the zero of that sign.
The sum of a zero and a nonzero finite value is equal to the nonzero value.
The sum of two nonzero finite values of the same magnitude and opposite sign is positive zero.
In the remaining cases, where neither operand is an infinity,
a zero, or NaN and the values have the same sign or have
different magnitudes, the sum is computed and rounded to the
nearest representable value using the round to nearest rounding policy
(§2.8). If the magnitude is too large
to represent as a float
, we say the operation overflows;
the result is then an infinity of appropriate sign.
If the magnitude is too small to represent as a float
,
we say the operation underflows; the result is then a
zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fadd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type float
. The index must be of type
int
, and the value must be of type float
. The arrayref,
index, and value are popped from the operand stack. The
float
value is
stored as the component of the array indexed by index.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack and a floating-point comparison is performed:
If value1 is greater than value2, the int
value 1 is
pushed onto the operand stack.
Otherwise, if value1 is equal to value2, the int
value
0 is pushed onto the operand stack.
Otherwise, if value1 is less than value2, the int
value -1 is pushed onto the operand stack.
Otherwise, at least one of value1 or value2 is NaN. The
fcmpg instruction pushes the int
value 1 onto the operand
stack and the fcmpl instruction pushes the int
value -1
onto the operand stack.
Floating-point comparison is performed in accordance with IEEE 754. All values other than NaN are ordered, with negative infinity less than all finite values and positive infinity greater than all finite values. Positive zero and negative zero are considered equal.
The fcmpg and fcmpl instructions differ only in their
treatment of a comparison involving NaN. NaN is unordered, so any
float
comparison fails if either or both of its operands are
NaN. With both fcmpg and fcmpl available, any float
comparison may be compiled to push the same result onto the
operand stack whether the comparison fails on non-NaN values or
fails because it encountered a NaN. For more information, see
§3.5.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack. The float
result is value1 / value2. The
result is pushed onto the operand stack.
The result of an fdiv instruction is governed by the rules of IEEE 754 arithmetic:
If neither value1 nor value2 is NaN, the sign of the result is positive if both values have the same sign, negative if the values have different signs.
Division of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
Division of a finite value by an infinity results in a signed zero, with the sign-producing rule just given.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero, with the sign-producing rule just given.
Division of a nonzero finite value by a zero results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither operand is an infinity,
a zero, or NaN, the quotient is computed and rounded to the
nearest float
using the
round to nearest rounding policy (§2.8). If the
magnitude is too large to represent as a float
, we say the
operation overflows; the result is then an infinity of
appropriate sign. If the magnitude is too small to represent
as a float
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, division by zero, or loss of precision may occur, execution of an fdiv instruction never throws a run-time exception.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local variable at index must
contain a float
. The value of the local variable at index is
pushed onto the operand stack.
The fload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain a float
. The value of
the local variable at <n> is pushed onto the operand
stack.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack. The float
result is value1 * value2. The
result is pushed onto the operand stack.
The result of an fmul instruction is governed by the rules of IEEE 754 arithmetic:
If neither value1 nor value2 is NaN, the sign of the result is positive if both values have the same sign, and negative if the values have different signs.
Multiplication of an infinity by a finite value results in a signed infinity, with the sign-producing rule just given.
In the remaining cases, where neither an infinity nor NaN is
involved, the product is computed and rounded to the nearest
representable value using
the round to nearest rounding policy (§2.8).
If the magnitude is too large to represent as a float
, we say
the operation overflows; the result is then an infinity of
appropriate sign. If the magnitude is too small to represent
as a float
, we say the operation underflows; the result is
then a zero of appropriate sign.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fmul instruction never throws a run-time exception.
The value must be of type float
. It is popped from the operand
stack. The float
result is the arithmetic negation of value. The result is
pushed onto the operand stack.
For float
values, negation is not the same as subtraction from
zero. If x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
. Unary
minus merely inverts the sign of a float
.
If the operand is NaN, the result is NaN (recall that NaN has no sign).
The Java Virtual Machine has not adopted the stronger requirement from the 2019 version of the IEEE 754 Standard that negation inverts the sign bit for all inputs, including NaN.
If the operand is an infinity, the result is the infinity of opposite sign.
If the operand is a zero, the result is the zero of opposite sign.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack. The float
result is calculated and pushed onto the
operand stack.
The result of an frem instruction is not the same as the result of
the remainder operation defined by IEEE 754, due to the choice of
rounding policy in the Java Virtual Machine (§2.8).
The IEEE 754 remainder operation computes the remainder from a rounding
division, not a truncating division, and so its behavior
is not analogous to that of the usual integer
remainder operator. Instead, the Java Virtual Machine defines frem to behave in
a manner analogous to that of the integer remainder
instructions irem and lrem, with an implied division using the
round toward zero rounding policy; this may be compared with the C
library function fmod
.
The result of an frem instruction is governed by the following rules, which match IEEE 754 arithmetic except for how the implied division is computed:
If neither value1 nor value2 is NaN, the sign of the result equals the sign of the dividend.
If the dividend is an infinity or the divisor is a zero or both, the result is NaN.
If the dividend is finite and the divisor is an infinity, the result equals the dividend.
If the dividend is a zero and the divisor is finite, the result equals the dividend.
In the remaining cases, where neither operand is an infinity, a zero, or NaN, the floating-point remainder result from a dividend value1 and a divisor value2 is defined by the mathematical relation result = value1 - (value2 * q), where q is an integer that is negative only if value1 / value2 is negative, and positive only if value1 / value2 is positive, and whose magnitude is as large as possible without exceeding the magnitude of the true mathematical quotient of value1 and value2.
Despite the fact that division by zero may occur, evaluation of an frem instruction never throws a run-time exception. Overflow, underflow, or loss of precision cannot occur.
The current method must have return type float
. The value must
be of type float
. If the current method is a synchronized
method, the monitor entered or reentered on invocation of the
method is updated and possibly exited as if by execution of a
monitorexit instruction (§monitorexit)
in the current thread. If no exception is thrown, value is
popped from the operand stack of the current frame (§2.6) and pushed onto the operand stack of the frame of the
invoker. Any other values on the operand stack of the current
method are discarded.
The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, freturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then freturn throws an
IllegalMonitorStateException
.
The index is an unsigned byte that must be an index into the
local variable array of the current frame (§2.6). The value on the top of the operand stack
must be of type float
. It is popped from the operand stack, and
the value of
the local variable at index is set to value.
The fstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The value on
the top of the operand stack must be of type float
. It is popped
from the operand stack, and the value
of the local variable at <n> is set to value.
Both value1 and value2 must be of type float
. The values are
popped from the operand stack. The float
result is value1 - value2. The
result is pushed onto the operand stack.
For float
subtraction, it is always the case
that a-b
produces the same result
as a+(-b)
. However, for the fsub instruction,
subtraction from zero is not the same as negation, because
if x
is +0.0
,
then 0.0-x
equals +0.0
,
but -x
equals -0.0
.
The Java Virtual Machine requires support of gradual underflow. Despite the fact that overflow, underflow, or loss of precision may occur, execution of an fsub instruction never throws a run-time exception.
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 entry at the index must be a symbolic reference to a field
(§5.1), which gives the name and descriptor
of the field as well as a symbolic reference to the class in which
the field is to be found. The referenced field is resolved
(§5.4.3.2).
The objectref, which must be
of type reference
but not an array type, is popped from the operand
stack. The value of the referenced field in objectref is fetched
and pushed onto the operand stack.
During resolution of the symbolic reference to the field, any of the errors pertaining to field resolution (§5.4.3.2) can be thrown.
Otherwise, if the resolved field is a static
field,
getfield throws an IncompatibleClassChangeError
.
The getfield instruction cannot be used to access the length
field of an array. The arraylength instruction
(§arraylength) is used instead.
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 entry at the index must be a symbolic reference to a field
(§5.1), which gives the name and descriptor
of the field as well as a symbolic reference to the class or
interface in which the field is to be found. The referenced field
is resolved (§5.4.3.2).
On successful resolution of the field, the class or interface that declared the resolved field is initialized if that class or interface has not already been initialized (§5.5).
The value of the class or interface field is fetched and pushed onto the operand stack.
During resolution of the symbolic reference to the class or interface field, any of the exceptions pertaining to field resolution (§5.4.3.2) can be thrown.
Otherwise, if the resolved field is not a static
(class) field
or an interface field, getstatic throws an IncompatibleClassChangeError
.
Otherwise, if execution of this getstatic instruction causes
initialization of the referenced class or interface, getstatic
may throw an Error
as detailed in §5.5.
The unsigned bytes branchbyte1 and branchbyte2 are used to
construct a signed 16-bit branchoffset, where branchoffset is
(branchbyte1 <<
8) | branchbyte2. Execution proceeds at
that offset from the address of the opcode of this goto
instruction. The target address must be that of an opcode of an
instruction within the method that contains this goto
instruction.
The unsigned bytes branchbyte1, branchbyte2, branchbyte3,
and branchbyte4 are used to construct a signed 32-bit
branchoffset, where branchoffset is (branchbyte1 <<
24) | (branchbyte2 <<
16) | (branchbyte3 <<
8) |
branchbyte4. Execution proceeds at that offset from the address
of the opcode of this goto_w instruction. The target address
must be that of an opcode of an instruction within the method that
contains this goto_w instruction.
Although the goto_w instruction takes a 4-byte branch offset, other factors limit the size of a method to 65535 bytes (§4.11). This limit may be raised in a future release of the Java Virtual Machine.
The value on the top of the operand stack must be of type
int
. It is popped from the operand stack and converted to a
float
result using the
round to nearest rounding policy (§2.8).
The result is pushed onto the operand stack.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. The int
result is value1 +
value2. The result is pushed onto the operand stack.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the mathematical sum of
the two values.
Despite the fact that overflow may occur, execution of an iadd instruction never throws a run-time exception.
iconst_m1 = 2 (0x2)
iconst_0 = 3 (0x3)
iconst_1 = 4 (0x4)
iconst_2 = 5 (0x5)
iconst_3 = 6 (0x6)
iconst_4 = 7 (0x7)
iconst_5 = 8 (0x8)
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. The int
result is the value of
the Java programming language expression value1 / value2 (JLS §15.17.2).
The result is pushed onto the operand stack.
An int
division rounds towards 0; that is, the quotient produced
for int
values in n/d is an int
value q whose
magnitude is as large as possible while satisfying |d ⋅
q| ≤ |n|. Moreover, q is positive when |n|
≥ |d| and n and d have the same sign, but
q is negative when |n| ≥ |d| and n and
d have opposite signs.
There is one special case that does not satisfy this rule: if the
dividend is the negative integer of largest possible magnitude for
the int
type, and the divisor is -1, then overflow occurs, and
the result is equal to the dividend. Despite the overflow, no
exception is thrown in this case.
Both value1 and value2 must be of type reference
. They are both
popped from the operand stack and compared. The results of the
comparison are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if_acmp<cond> instruction. The
target address must be that of an opcode of an instruction within
the method that contains this if_acmp<cond> instruction.
Otherwise, if the comparison fails, execution proceeds at the address of the instruction following this if_acmp<cond> instruction.
if_icmpeq = 159 (0x9f)
if_icmpne = 160 (0xa0)
if_icmplt = 161 (0xa1)
if_icmpge = 162 (0xa2)
if_icmpgt = 163 (0xa3)
if_icmple = 164 (0xa4)
Both value1 and value2 must be of type int
. They are both
popped from the operand stack and compared. All comparisons are
signed. The results of the comparison are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if_icmp<cond> instruction. The
target address must be that of an opcode of an instruction within
the method that contains this if_icmp<cond> instruction.
Otherwise, execution proceeds at the address of the instruction following this if_icmp<cond> instruction.
ifeq = 153 (0x99)
ifne = 154 (0x9a)
iflt = 155 (0x9b)
ifge = 156 (0x9c)
ifgt = 157 (0x9d)
ifle = 158 (0x9e)
The value must be of type int
. It is popped from the operand
stack and compared against zero. All comparisons are signed. The
results of the comparisons are as follows:
If the comparison succeeds, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this if<cond> instruction. The target
address must be that of an opcode of an instruction within the
method that contains this if<cond> instruction.
Otherwise, execution proceeds at the address of the instruction following this if<cond> instruction.
The value must be of type reference
. It is popped from the operand
stack. If value is not null
, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this ifnonnull instruction. The target
address must be that of an opcode of an instruction within the
method that contains this ifnonnull instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnonnull instruction.
The value must of type reference
. It is popped from the operand
stack. If value is null
, the unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is calculated to be (branchbyte1 <<
8) |
branchbyte2. Execution then proceeds at that offset from the
address of the opcode of this ifnull instruction. The target
address must be that of an opcode of an instruction within the
method that contains this ifnull instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnull instruction.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The const is an
immediate signed byte. The local variable at index must contain
an int
. The value const is first
sign-extended to an int
, and then the local variable at index
is incremented by that amount.
The iinc opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index and to increment it by a two-byte immediate signed value.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The local variable at index must
contain an int
. The value of the local variable at index is
pushed onto the operand stack.
The iload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The local
variable at <n> must contain an int
. The value of
the local variable at <n> is pushed onto the operand
stack.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. The int
result is value1 *
value2. The result is pushed onto the operand stack.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the
mathematical multiplication of the two values.
Despite the fact that overflow may occur, execution of an imul instruction never throws a run-time exception.
The value must be of type int
. It is popped from the operand
stack. The int
result is the arithmetic negation of value,
-value. The result is pushed onto the operand stack.
For int
values, negation is the same as subtraction from
zero. Because the Java Virtual Machine uses two's-complement representation for
integers and the range of two's-complement values is not
symmetric, the negation of the maximum negative int
results in
that same maximum negative number. Despite the fact that overflow
has occurred, no exception is thrown.
The objectref, which must be of type reference
, is popped from the
operand stack. 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 entry at the index must be a symbolic reference to a
class, array, or interface type.
If objectref is null
, the instanceof instruction pushes an
int
result of 0 as an int
onto the operand stack.
Otherwise, the named class, array, or interface type is resolved
(§5.4.3.1). If objectref is an instance of
the resolved class or array type, or implements the resolved
interface, the instanceof instruction pushes an int
result
of 1 as an int
onto the operand stack; otherwise, it pushes an
int
result of 0.
The following rules are used to determine whether an objectref
that is not null
is an instance of the resolved type. If S is
the type of the object referred to by objectref, and T is the
resolved class, array, or interface type, then instanceof
determines whether objectref is an instance of T as follows:
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
The instanceof instruction is very similar to the checkcast
instruction (§checkcast). It differs in
its treatment of null
, its behavior when its test fails
(checkcast throws an exception, instanceof pushes a result
code), and its effect on the operand stack.
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 entry at the index must be a symbolic reference to a
dynamically-computed call site (§5.1). The
values of the third and fourth operand bytes must always be
zero.
The symbolic reference is resolved (§5.4.3.6)
for this specific invokedynamic
instruction to obtain a reference
to an instance
of java.lang.invoke.CallSite
. The instance of java.lang.invoke.CallSite
is considered "bound"
to this specific invokedynamic instruction.
The instance of java.lang.invoke.CallSite
indicates a target method
handle. The nargs argument values are popped from the
operand stack, and the target method handle 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 R where:
and where it is as if the following items were pushed, in order, onto the operand stack:
During resolution of the symbolic reference to a dynamically-computed call site, any of the exceptions pertaining to dynamically-computed call site resolution can be thrown.
If the symbolic reference to the dynamically-computed call site
can be resolved, it implies that a non-null
reference
to an instance
of java.lang.invoke.CallSite
is bound to the invokedynamic instruction.
Therefore, the target method handle, indicated by the instance of
java.lang.invoke.CallSite
, is non-null
.
Similarly, successful resolution implies that the method descriptor in the symbolic reference is semantically equal to the type descriptor of the target method handle.
Together, these invariants mean that an invokedynamic
instruction which is bound to an instance of java.lang.invoke.CallSite
never
throws a NullPointerException
or a java.lang.invoke.WrongMethodTypeException
.
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 entry at the index must be a symbolic reference to an
interface method (§5.1), which gives the
name and descriptor (§4.3.3) of the
interface method as well as a symbolic reference to the interface
in which the interface method is to be found. The named interface
method is resolved (§5.4.3.4).
The resolved interface method must not be an instance initialization method, or the class or interface initialization method (§2.9.1, §2.9.2).
The count operand is an unsigned byte that must not be zero. The
objectref must be of type reference
and must be followed on the
operand stack by nargs argument values, where the number, type,
and order of the values must be consistent with the descriptor of
the resolved interface method. The value of the fourth operand
byte must always be zero.
Let C be the class of objectref. A method is selected with respect to C and the resolved method (§5.4.6). This is the method to be invoked.
If the method to be invoked is synchronized
, the monitor
associated with objectref is entered or reentered as if by
execution of a monitorenter instruction
(§monitorenter) in the current
thread.
If the method to be invoked is not native
, the nargs argument values and
objectref are popped from the operand stack. A new frame is
created on the Java Virtual Machine stack for the method being invoked. The
objectref and the argument values are consecutively made the
values of local variables of the new frame, with objectref in
local variable 0, arg1 in local variable 1 (or, if arg1 is of
type long
or double
, in local variables 1 and 2), and so
on. The new frame is then made current,
and the Java Virtual Machine pc
is set to the opcode of the first instruction
of the method to be invoked. Execution continues with the first
instruction of the method.
If the method to be invoked is native
and the platform-dependent
code that implements it has not yet been bound
(§5.6) into the Java Virtual Machine, then that is
done. The nargs argument values and objectref are popped from
the operand stack and are passed as parameters to the code that
implements the method. The parameters are passed and the code is invoked in an
implementation-dependent manner. When the platform-dependent code
returns:
If the native
method is synchronized
, the monitor
associated with objectref is updated and possibly exited as
if by execution of a monitorexit instruction
(§monitorexit) in the current thread.
If the native
method returns a value, the return value of
the platform-dependent code is converted in an
implementation-dependent way to the return type of the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the interface method, any of the exceptions pertaining to interface method resolution (§5.4.3.4) can be thrown.
Otherwise, if the resolved method is static
,
the invokeinterface instruction throws an IncompatibleClassChangeError
.
Note that invokeinterface may refer to private
methods
declared in interfaces, including nestmate interfaces.
Otherwise, if objectref is null
, the invokeinterface
instruction throws a NullPointerException
.
Otherwise, if the class of objectref does not implement the
resolved interface, invokeinterface throws an IncompatibleClassChangeError
.
Otherwise, if the selected method is neither public
nor private
,
invokeinterface throws an IllegalAccessError
.
Otherwise, if the selected method is abstract
,
invokeinterface throws an AbstractMethodError
.
Otherwise, if the selected method is native
and the code that implements the method cannot be bound,
invokeinterface throws an UnsatisfiedLinkError
.
Otherwise, if no method is selected, and there are multiple
maximally-specific superinterface methods of C that match the
resolved method's name and descriptor and are not abstract
,
invokeinterface throws an IncompatibleClassChangeError
Otherwise, if no method is selected, and there are no
maximally-specific superinterface methods of C that match the
resolved method's name and descriptor and are not abstract
,
invokeinterface throws an AbstractMethodError
.
The count operand of the invokeinterface instruction records a
measure of the number of argument values, where an argument value
of type long
or type double
contributes two units to the
count value and an argument of any other type contributes one
unit. This information can also be derived from the descriptor of
the selected method. The redundancy is historical.
The fourth operand byte exists to reserve space for an additional operand used in certain of Oracle's Java Virtual Machine implementations, which replace the invokeinterface instruction by a specialized pseudo-instruction at run time. It must be retained for backwards compatibility.
The nargs argument values and objectref are not one-to-one
with the first nargs+1 local variables. Argument values of types
long
and double
must be stored in two consecutive local
variables, thus more than nargs local variables may be required
to pass nargs argument values to the invoked method.
The selection logic allows a non-abstract
method declared in a
superinterface to be selected. Methods in interfaces are only
considered if there is no matching method in the class
hierarchy. In the event that there are two non-abstract
methods
in the superinterface hierarchy, with neither more specific than
the other, an error occurs; there is no attempt to disambiguate
(for example, one may be the referenced method and one may be
unrelated, but we do not prefer the referenced method). On the
other hand, if there are many abstract
methods but only one
non-abstract
method, the non-abstract
method is selected
(unless an abstract
method is more specific).
Invoke instance method; direct invocation of instance initialization methods and methods of the current class and its supertypes
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 entry at the index must be a symbolic reference to a method
or an interface method (§5.1), which gives
the name and descriptor (§4.3.3) of the
method or interface method as well as a symbolic reference to the
class or interface in which the method or interface method is to
be found. The named method is resolved
(§5.4.3.3, §5.4.3.4).
If all of the following are true, let C be the direct superclass of the current class:
Otherwise, let C be the class or interface named by the symbolic reference.
The actual method to be invoked is selected by the following lookup procedure:
If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.
Otherwise, if C is a class and has a superclass, a search for a declaration of an instance method with the same name and descriptor as the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a match is found or no further superclasses exist. If a match is found, then it is the method to be invoked.
Otherwise, if C is an interface and the class Object
contains a declaration of a public
instance method with the
same name and descriptor as the resolved method, then it is
the method to be invoked.
Otherwise, if there is exactly one maximally-specific method
(§5.4.3.3) in the superinterfaces of C
that matches the resolved method's name and descriptor and is
not abstract
, then it is the method to be invoked.
The objectref must be of type reference
and must be followed on the
operand stack by nargs argument values, where the number, type,
and order of the values must be consistent with the descriptor of
the selected instance method.
If the method is synchronized
, the monitor associated with
objectref is entered or reentered as if by execution of a
monitorenter instruction
(§monitorenter) in the current
thread.
If the method is not native
, the nargs argument values and
objectref are popped from the operand stack. A new frame is
created on the Java Virtual Machine stack for the method being invoked. The
objectref and the argument values are consecutively made the
values of local variables of the new frame, with objectref in
local variable 0, arg1 in local variable 1 (or, if arg1 is of
type long
or double
, in local variables 1 and 2), and so
on. The new frame is then made current,
and the Java Virtual Machine pc
is set to the opcode of the first instruction
of the method to be invoked. Execution continues with the first
instruction of the method.
If the method is native
and the platform-dependent code that
implements it has not yet been bound (§5.6)
into the Java Virtual Machine, that is done. The nargs argument values and
objectref are popped from the operand stack and are passed as
parameters to the code that implements the method. The parameters are passed and the code is invoked in
an implementation-dependent manner. When the platform-dependent
code returns, the following take place:
If the native
method is synchronized
, the monitor
associated with objectref is updated and possibly exited as
if by execution of a monitorexit instruction
(§monitorexit) in the current
thread.
If the native
method returns a value, the return value of
the platform-dependent code is converted in an
implementation-dependent way to the return type of the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§5.4.3.3) can be thrown.
Otherwise, if the resolved method is an instance initialization
method, and the class in which it is declared is not the class
symbolically referenced by the instruction, a NoSuchMethodError
is
thrown.
Otherwise, if the resolved method is a class (static
) method,
the invokespecial instruction throws an IncompatibleClassChangeError
.
Otherwise, if objectref is null
, the invokespecial
instruction throws a NullPointerException
.
Otherwise, if step 1, step 2, or step 3 of the lookup procedure
selects an abstract
method, invokespecial throws an AbstractMethodError
.
Otherwise, if step 1, step 2, or step 3 of the lookup procedure
selects a native
method and the code that implements the method
cannot be bound, invokespecial throws an UnsatisfiedLinkError
.
Otherwise, if step 4 of the lookup procedure determines there are
multiple maximally-specific superinterface methods of C that
match the resolved method's name and descriptor and are not
abstract
, invokespecial throws an IncompatibleClassChangeError
Otherwise, if step 4 of the lookup procedure determines there are
no maximally-specific superinterface methods of C that match the
resolved method's name and descriptor and are not abstract
,
invokespecial throws an AbstractMethodError
.
The difference between the invokespecial instruction and the invokevirtual instruction (§invokevirtual) is that invokevirtual invokes a method based on the class of the object. The invokespecial instruction is used to directly invoke instance initialization methods (§2.9.1) as well as methods of the current class and its supertypes.
The invokespecial instruction was named
invokenonvirtual
prior to JDK release 1.0.2.
The nargs argument values and objectref are not one-to-one
with the first nargs+1 local variables. Argument values of types
long
and double
must be stored in two consecutive local
variables, thus more than nargs local variables may be required
to pass nargs argument values to the invoked method.
The invokespecial instruction handles invocation of a non-abstract
interface method,
referenced either via a direct superinterface or via a superclass.
In these cases, the rules for selection are essentially the same
as those for invokeinterface (except that the search starts from
a different class).
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 entry at the index must be a symbolic reference to a method
or an interface method (§5.1), which gives
the name and descriptor (§4.3.3) of the
method or interface method as well as a symbolic reference to the
class or interface in which the method or interface method is to
be found. The named method is resolved
(§5.4.3.3, §5.4.3.4).
The resolved method must not be an instance initialization method, or the class or interface initialization method (§2.9.1, §2.9.2).
The resolved method must be static
, and therefore cannot be
abstract
.
On successful resolution of the method, the class or interface that declared the resolved method is initialized if that class or interface has not already been initialized (§5.5).
The operand stack must contain nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the resolved method.
If the method is synchronized
, the monitor associated with the
resolved Class
object is entered or reentered as if by execution
of a monitorenter instruction
(§monitorenter) in the current
thread.
If the method is not native
, the nargs argument values are
popped from the operand stack. A new frame is created on the Java Virtual Machine
stack for the method being invoked. The nargs argument values
are consecutively made the values of local variables of the new
frame, with arg1 in local variable 0 (or, if arg1 is of type
long
or double
, in local variables 0 and 1) and so on. The new frame is then made current,
and the Java Virtual Machine pc
is set to the opcode of the first instruction
of the method to be invoked. Execution continues with the first
instruction of the method.
If the method is native
and the platform-dependent code that
implements it has not yet been bound (§5.6)
into the Java Virtual Machine, that is done. The nargs argument values are
popped from the operand stack and are passed as parameters to the
code that implements the method. The parameters are passed and the code is invoked in an
implementation-dependent manner. When the platform-dependent code
returns, the following take place:
If the native
method is synchronized
, the monitor
associated with the resolved Class
object is updated and
possibly exited as if by execution of a monitorexit
instruction (§monitorexit) in the
current thread.
If the native
method returns a value, the return value of
the platform-dependent code is converted in an
implementation-dependent way to the return type of the
native
method and pushed onto the operand stack.
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§5.4.3.3) can be thrown.
Otherwise, if the resolved method is an instance method, the
invokestatic instruction throws an IncompatibleClassChangeError
.
Otherwise, if execution of this invokestatic instruction causes
initialization of the referenced class or interface,
invokestatic may throw an Error
as detailed in
§5.5.
Otherwise, if the resolved method is native
and the code that
implements the method cannot be bound, invokestatic throws an
UnsatisfiedLinkError
.
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 entry at the index must be a symbolic reference to a method
(§5.1), which gives the name and descriptor
(§4.3.3) of the method as well as a symbolic
reference to the class in which the method is to be found. The
named method is resolved (§5.4.3.3).
If the resolved method is not signature polymorphic (§2.9.3), then the invokevirtual instruction proceeds as follows.
Let C be the class of objectref. A method is selected with respect to C and the resolved method (§5.4.6). This is the method to be invoked.
The objectref must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the descriptor of the selected instance method.
If the method to be invoked is synchronized
, the monitor
associated with objectref is entered or reentered as if by
execution of a monitorenter instruction
(§monitorenter) in the current
thread.
If the method to be invoked is not native
, the nargs argument
values and objectref are popped from the operand stack. A new
frame is created on the Java Virtual Machine stack for the method being
invoked. The objectref and the argument values are consecutively
made the values of local variables of the new frame, with
objectref in local variable 0, arg1 in local variable 1 (or,
if arg1 is of type long
or double
, in local variables 1 and
2), and so on. The new frame is
then made current, and the Java Virtual Machine pc
is set to the opcode of the
first instruction of the method to be invoked. Execution continues
with the first instruction of the method.
If the method to be invoked is native
and the platform-dependent
code that implements it has not yet been bound (§5.6) into the Java Virtual Machine, that is done. The nargs
argument values and objectref are popped from the operand stack
and are passed as parameters to the code that implements the
method. The parameters are
passed and the code is invoked in an implementation-dependent
manner. When the platform-dependent code returns, the following
take place:
If the native
method is synchronized
, the monitor
associated with objectref is updated and possibly exited as
if by execution of a monitorexit instruction
(§monitorexit) in the current thread.
If the native
method returns a value, the return value of
the platform-dependent code is converted in an
implementation-dependent way to the return type of the
native
method and pushed onto the operand stack.
If the resolved method is signature polymorphic
(§2.9.3),
and declared in the java.lang.invoke.MethodHandle
class,
then the invokevirtual instruction proceeds as follows, where D is
the descriptor of the method symbolically referenced by the instruction.
First, 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.4.3.5) with the same parameter and
return types as D.
If the named method is invokeExact
, the instance of
java.lang.invoke.MethodType
must be semantically equal to the type descriptor
of the receiving method handle objectref. The
method handle to be invoked is objectref.
If the named method is invoke
, and the instance of
java.lang.invoke.MethodType
is semantically equal to the type descriptor of
the receiving method handle objectref, then
the method handle to be invoked is objectref.
If the named method is invoke
, and the instance of
java.lang.invoke.MethodType
is not semantically equal to the type descriptor
of the receiving method handle objectref, then the Java Virtual Machine
attempts to adjust the type descriptor of the receiving method
handle, as if by invocation of the asType
method of java.lang.invoke.MethodHandle
,
to obtain an exactly invokable method handle m
. The
method handle to be invoked is m
.
The objectref must be followed on the operand stack by nargs argument values, where the number, type, and order of the values must be consistent with the type descriptor of the method handle to be invoked. (This type descriptor will correspond to the method descriptor appropriate for the kind of the method handle to be invoked, as specified in §5.4.3.5.)
Then, if the method handle to be invoked has bytecode behavior,
the Java Virtual Machine invokes the method handle as if by execution of the
bytecode behavior associated with the method handle's kind. If the
kind is 5 (REF_invokeVirtual
), 6 (REF_invokeStatic
), 7
(REF_invokeSpecial
), 8 (REF_newInvokeSpecial
), or 9
(REF_invokeInterface
), then a frame will be created and made
current in the course of executing the bytecode
behavior; however, this frame is not visible, and when
the method invoked by the bytecode behavior completes (normally or
abruptly), the frame of its invoker is
considered to be the frame for the method containing this
invokevirtual instruction.
Otherwise, if the method handle to be invoked has no bytecode behavior, the Java Virtual Machine invokes it in an implementation-dependent manner.
If the resolved method is signature polymorphic and
declared in the java.lang.invoke.VarHandle
class, then the
invokevirtual instruction proceeds as follows, where N
and
D are the name and descriptor of the method symbolically
referenced by the instruction.
First, a reference
to an instance of java.lang.invoke.VarHandle.AccessMode
is obtained
as if by invocation of the valueFromMethodName
method
of java.lang.invoke.VarHandle.AccessMode
with a String
argument denoting N
.
Second, a reference
to an instance of java.lang.invoke.MethodType
is obtained as if
by invocation of the accessModeType
method of java.lang.invoke.VarHandle
on the instance objectref, with the instance of
java.lang.invoke.VarHandle.AccessMode
as the argument.
Third, a reference
to an instance of java.lang.invoke.MethodHandle
is obtained as if
by invocation of the varHandleExactInvoker
method of java.lang.invoke.MethodHandles
with the instance of java.lang.invoke.VarHandle.AccessMode
as the first argument
and the instance of java.lang.invoke.MethodType
as the second argument. The resulting
instance is called the invoker method handle.
Finally, the nargs argument values and objectref are popped from the operand stack, and the invoker method handle 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 R where:
for the symbolic reference to the class in which the method is
to be found, R specifies java.lang.invoke.MethodHandle
;
for the descriptor of the method, R specifies a return type
indicated by the return descriptor of D, and specifies a
first parameter type of java.lang.invoke.VarHandle
followed by the parameter
types indicated by the parameter descriptors of D (if any)
in order.
and where it is as if the following items were pushed, in order, onto the operand stack:
During resolution of the symbolic reference to the method, any of the exceptions pertaining to method resolution (§5.4.3.3) can be thrown.
Otherwise, if the resolved method is a class (static
) method,
the invokevirtual instruction throws an IncompatibleClassChangeError
.
Otherwise, if the resolved method is signature polymorphic
and declared in the java.lang.invoke.MethodHandle
class, then
during resolution of the method type derived from the descriptor
in the symbolic reference to the method, any of the exceptions
pertaining to method type resolution
(§5.4.3.5) can be thrown.
Otherwise, if the resolved method is signature polymorphic and
declared in the java.lang.invoke.VarHandle
class, then any linking exception that
may arise from invocation of the invoker method handle can be
thrown. No linking exceptions are thrown from invocation of the
valueFromMethodName
, accessModeType
, and
varHandleExactInvoker
methods.
Otherwise, if objectref is null
, the invokevirtual
instruction throws a NullPointerException
.
Otherwise, if the resolved method is not signature polymorphic:
If the selected method is abstract
,
invokevirtual throws an AbstractMethodError
.
Otherwise, if the selected method is native
and the code that implements the method cannot be bound,
invokevirtual throws an UnsatisfiedLinkError
.
Otherwise, if no method is selected, and there are multiple
maximally-specific superinterface methods of C that match
the resolved method's name and descriptor and are not
abstract
, invokevirtual throws an IncompatibleClassChangeError
Otherwise, if no method is selected, and there are no
maximally-specific superinterface methods of C that match
the resolved method's name and descriptor and are not
abstract
, invokevirtual throws an AbstractMethodError
.
Otherwise, if the resolved method is signature polymorphic
and declared in the java.lang.invoke.MethodHandle
class, then:
If the method name is invokeExact
, and the obtained instance
of java.lang.invoke.MethodType
is not semantically equal to the type
descriptor of the receiving method handle objectref,
the invokevirtual instruction throws a java.lang.invoke.WrongMethodTypeException
.
If the method name is invoke
, and the obtained instance of
java.lang.invoke.MethodType
is not a valid argument to the asType
method of
java.lang.invoke.MethodHandle
invoked on the receiving method handle objectref,
the invokevirtual instruction throws a java.lang.invoke.WrongMethodTypeException
.
Otherwise, if the resolved method is signature polymorphic and
declared in the java.lang.invoke.VarHandle
class, then any run-time exception
that may arise from invocation of the invoker method handle can be
thrown. No run-time exceptions are thrown from invocation of the
valueFromMethodName
, accessModeType
, and varHandleExactInvoker
methods, except NullPointerException
if objectref is null
.
The nargs argument values and objectref are not one-to-one
with the first nargs+1 local variables. Argument values of types
long
and double
must be stored in two consecutive local
variables, thus more than nargs local variables may be required
to pass nargs argument values to the invoked method.
It is possible that the symbolic reference of an invokevirtual
instruction resolves to an interface method. In this case, it is
possible that there is no overriding method in the class
hierarchy, but that a non-abstract
interface method matches the
resolved method's descriptor. The selection logic matches such a
method, using the same rules as for invokeinterface.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. The int
result is value1 -
(value1 / value2) * value2. The result is pushed onto the
operand stack.
The result of the irem instruction is such that (a/b)*b
+ (a%b)
is equal to a
. This identity
holds even in the special case in which the dividend is the
negative int
of largest possible magnitude for its type and the
divisor is -1 (the remainder is 0). It follows from this rule that
the result of the remainder operation can be negative only if the
dividend is negative and can be positive only if the dividend is
positive. Moreover, the magnitude of the result is always less
than the magnitude of the divisor.
The current method must have return type boolean
, byte
,
char
, short
, or int
. The value must be of type int
. If
the current method is a synchronized
method, the monitor entered
or reentered on invocation of the method is updated and possibly
exited as if by execution of a monitorexit instruction
(§monitorexit) in the current thread. If
no exception is thrown, value is popped from the operand stack
of the current frame (§2.6) and pushed onto
the operand stack of the frame of the invoker. Any other values on
the operand stack of the current method are discarded.
Prior to pushing value onto the operand stack of the frame of
the invoker, it may have to be converted. If the return type of
the invoked method was byte
, char
, or short
, then value is
converted from int
to the return type as if by execution of
i2b, i2c, or i2s, respectively. If the return type of the
invoked method was boolean
, then value is narrowed from int
to
boolean
by taking the bitwise AND of value and 1.
The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, ireturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then ireturn throws an
IllegalMonitorStateException
.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. An int
result is calculated by
shifting value1 right by s bit positions, with sign
extension, where s is the value of the low 5 bits of
value2. The result is pushed onto the operand stack.
The resulting value is floor(value1 /
2s), where s is value2
& 0x1f. For non-negative value1, this is equivalent to
truncating int
division by 2 to the power s. The shift
distance actually used is always in the range 0 to 31, inclusive,
as if value2 were subjected to a bitwise logical AND with the
mask value 0x1f.
The index is an unsigned byte that must be an index into the
local variable array of the current frame
(§2.6). The value on the top of the
operand stack must be of type int
. It is popped from the operand
stack, and the value of the local variable at index is set to
value.
The istore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The <n> must be an index into the local variable array
of the current frame (§2.6). The value on
the top of the operand stack must be of type int
. It is popped
from the operand stack, and the value of the local variable at
<n> is set to value.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. The int
result is value1 -
value2. The result is pushed onto the operand stack.
For int
subtraction, a-b
produces the same
result as a+(-b)
. For int
values, subtraction
from zero is the same as negation.
The result is the 32 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type int
. If overflow occurs, then the sign of the
result may not be the same as the sign of the mathematical
difference of the two values.
Despite the fact that overflow may occur, execution of an isub instruction never throws a run-time exception.
Both value1 and value2 must be of type int
. The values are
popped from the operand stack. An int
result is calculated by
shifting value1 right by s bit positions, with zero
extension, where s is the value of the low 5 bits of
value2. The result is pushed onto the operand stack.
If value1 is positive and s is value2 & 0x1f, the
result is the same as that of value1 >>
s; if
value1 is negative, the result is equal to the value of the
expression (value1 >>
s) + (2 <<
~s). The
addition of the (2 <<
~s) term cancels out the
propagated sign bit. The shift distance actually used is always in
the range 0 to 31, inclusive.
The address of the opcode of the instruction immediately
following this jsr instruction is pushed onto the operand stack
as a value of type returnAddress
. The unsigned branchbyte1 and
branchbyte2 are used to construct a signed 16-bit offset, where
the offset is (branchbyte1 <<
8) |
branchbyte2. Execution proceeds at that offset from the address
of this jsr instruction. The target address must be that of an
opcode of an instruction within the method that contains this
jsr instruction.
Note that jsr pushes the address onto the operand stack and ret (§ret) gets it out of a local variable. This asymmetry is intentional.
In Oracle's implementation of a compiler for the Java programming language prior
to Java SE 6, the jsr instruction was used with the ret
instruction in the implementation of the finally
clause
(§3.13, §4.10.2.5).
The address of the opcode of the instruction immediately
following this jsr_w instruction is pushed onto the operand
stack as a value of type returnAddress
. The unsigned
branchbyte1, branchbyte2, branchbyte3, and branchbyte4 are
used to construct a signed 32-bit offset, where the offset is
(branchbyte1 <<
24) | (branchbyte2 <<
16) |
(branchbyte3 <<
8) | branchbyte4. Execution proceeds at
that offset from the address of this jsr_w instruction. The
target address must be that of an opcode of an instruction within
the method that contains this jsr_w instruction.
Note that jsr_w pushes the address onto the operand stack and ret (§ret) gets it out of a local variable. This asymmetry is intentional.
In Oracle's implementation of a compiler for the Java programming language prior
to Java SE 6, the jsr_w instruction was used with the ret
instruction in the implementation of the finally
clause
(§3.13,
§4.10.2.5).
Although the jsr_w instruction takes a 4-byte branch offset, other factors limit the size of a method to 65535 bytes (§4.11). This limit may be raised in a future release of the Java Virtual Machine.
The value on the top of the operand stack must be of type
long
. It is popped from the operand stack and converted to a
double
result using the
round to nearest rounding policy (§2.8).
The result is pushed onto the operand stack.
The value on the top of the operand stack must be of type
long
. It is popped from the operand stack and converted to a
float
result using the
round to nearest rounding policy (§2.8).
The result is pushed onto the operand stack.
Both value1 and value2 must be of type long
. The values are
popped from the operand stack. The long
result is value1 +
value2. The result is pushed onto the operand stack.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, the sign of the
result may not be the same as the sign of the mathematical sum of
the two values.
Despite the fact that overflow may occur, execution of an ladd instruction never throws a run-time exception.
The arrayref must be of type reference
and must refer to an array
whose components are of type long
. The index must be of type
int
, and value must be of type long
. The arrayref,
index, and value are popped from the operand stack. The long
value is stored as the component of the array indexed by
index.
Both value1 and value2 must be of type long
. They are both
popped from the operand stack, and a signed integer comparison is
performed. If value1 is greater than value2, the int
value 1
is pushed onto the operand stack. If value1 is equal to
value2, the int
value 0 is pushed onto the operand stack. If
value1 is less than value2, the int
value -1 is pushed onto
the operand stack.
The index is an unsigned byte that must be a valid index into the run-time constant pool of the current class (§2.5.5). The run-time constant pool entry at index must be loadable (§5.1), and not any of the following:
If the run-time constant pool entry is a numeric constant of type
int
or float
, then the value of that numeric constant is
pushed onto the operand stack as an int
or float
, respectively.
Otherwise, if the run-time constant pool entry is a string
constant, that is, a reference
to an instance of class String
, then
value, a reference
to that instance, is pushed onto the operand stack.
Otherwise, if the run-time constant pool entry is a symbolic
reference to a class or interface, then the named class or
interface is resolved (§5.4.3.1) and
value, a reference
to the Class
object representing that class or
interface, is pushed onto the operand stack.
Otherwise, the run-time constant pool entry is a symbolic reference to a method type, a method handle, or a dynamically-computed constant. The symbolic reference is resolved (§5.4.3.5, §5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.
The unsigned indexbyte1 and indexbyte2 are assembled into an
unsigned 16-bit index into the run-time constant pool of the
current class (§2.5.5), 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 the
index must be loadable
(§5.1), and not any of the following:
If the run-time constant pool entry is a numeric constant of type
int
or float
, or a string constant, then value is determined
and pushed onto the operand stack according to the rules given for
the ldc instruction.
Otherwise, the run-time constant pool entry is a symbolic reference to a class, interface, method type, method handle, or dynamically-computed constant. It is resolved and value is determined and pushed onto the operand stack according to the rules given for the ldc instruction.
During resolution of a symbolic reference, any of the exceptions pertaining to resolution of that kind of symbolic reference can be thrown.
The ldc_w instruction is identical to the ldc instruction (§ldc) except for its wider run-time constant pool index.
The unsigned indexbyte1 and indexbyte2 are assembled into an
unsigned 16-bit index into the run-time constant pool of the
current class (§2.5.5), 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 the index must be loadable (§5.1),
and in particular one of the following:
If the run-time constant pool entry is a numeric constant of type
long
or double
, then the value of that numeric constant is
pushed onto the operand stack as a long
or double
, respectively.
Otherwise, the run-time constant pool entry is a symbolic reference to a dynamically-computed constant. The symbolic reference is resolved (§5.4.3.6) and value, the result of resolution, is pushed onto the operand stack.
Both value1 and value2 must be of type long
. The values are
popped from the operand stack. The long
result is the value of
the Java programming language expression value1 / value2. The result is
pushed onto the operand stack.
A long
division rounds towards 0; that is, the quotient produced
for long
values in n / d is a long
value q
whose magnitude is as large as possible while satisfying |d
⋅ q| ≤ |n|. Moreover, q is positive when
|n| ≥ |d| and n and d have the same sign,
but q is negative when |n| ≥ |d| and n and
d have opposite signs.
There is one special case that does not satisfy this rule: if the
dividend is the negative integer of largest possible magnitude for
the long
type and the divisor is -1, then overflow occurs and
the result is equal to the dividend; despite the overflow, no
exception is thrown in this case.
The index is an unsigned byte. Both index and index+1 must
be indices into the local variable array of the current frame
(§2.6). The local variable at index must
contain a long
. The value of the local variable at index is
pushed onto the operand stack.
The lload opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The local variable at <n>
must contain a long
. The value of the local variable at
<n> is pushed onto the operand stack.
Both value1 and value2 must be of type long
. The values are
popped from the operand stack. The long
result is value1 *
value2. The result is pushed onto the operand stack.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, the sign of the
result may not be the same as the sign of the
mathematical multiplication of the two values.
Despite the fact that overflow may occur, execution of an lmul instruction never throws a run-time exception.
The value must be of type long
. It is popped from the operand
stack. The long
result is the arithmetic negation of value,
-value. The result is pushed onto the operand stack.
For long
values, negation is the same as subtraction from
zero. Because the Java Virtual Machine uses two's-complement representation for
integers and the range of two's-complement values is not
symmetric, the negation of the maximum negative long
results in
that same maximum negative number. Despite the fact that overflow
has occurred, no exception is thrown.
lookupswitch
<0-3 byte pad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
npairs1
npairs2
npairs3
npairs4
match-offset pairs...
A lookupswitch is a variable-length instruction. Immediately
after the lookupswitch opcode, between zero and three bytes must
act as padding, such that defaultbyte1 begins
at an address that is a multiple of four bytes from the start of
the current method (the opcode of its first
instruction). Immediately after the padding follow a series of
signed 32-bit
values: default, npairs,
and then npairs pairs of signed 32-bit
values. The npairs must be greater than or
equal to 0. Each of the npairs pairs consists
of an int
match and a signed
32-bit offset. Each of these signed 32-bit
values is constructed from four unsigned bytes as
(byte1 <<
24) |
(byte2 <<
16) |
(byte3 <<
8)
| byte4.
The table match-offset pairs of the lookupswitch instruction must be sorted in increasing numerical order by match.
The key must be of type int
and is popped
from the operand stack. The key is compared
against the match values. If it is equal to
one of them, then a target address is calculated by adding the
corresponding offset to the address of the
opcode of this lookupswitch instruction. If
the key does not match any of
the match values, the target address is
calculated by adding default to the address
of the opcode of this lookupswitch instruction. Execution then
continues at the target address.
The target address that can be calculated from the offset of each match-offset pair, as well as the one calculated from default, must be the address of an opcode of an instruction within the method that contains this lookupswitch instruction.
The alignment required of the 4-byte operands of the lookupswitch instruction guarantees 4-byte alignment of those operands if and only if the method that contains the lookupswitch is positioned on a 4-byte boundary.
The match-offset pairs are sorted to support lookup routines that are quicker than linear search.
Both value1 and value2 must be of type long
. The values are
popped from the operand stack. The long
result is value1 -
(value1 / value2) * value2. The result is pushed onto the
operand stack.
The result of the lrem instruction is such that
(a/b)*b + (a%b)
is equal
to a
. This identity holds even in the special
case in which the dividend is the negative long
of largest
possible magnitude for its type and the divisor is -1 (the
remainder is 0). It follows from this rule that the result of the
remainder operation can be negative only if the dividend is
negative and can be positive only if the dividend is positive;
moreover, the magnitude of the result is always less than the
magnitude of the divisor.
The current method must have return type long
. The value must
be of type long
. If the current method is a synchronized
method, the monitor entered or reentered on invocation of the
method is updated and possibly exited as if by execution of a
monitorexit instruction (§monitorexit)
in the current thread. If no exception is thrown, value is
popped from the operand stack of the current frame
(§2.6) and pushed onto the operand stack of
the frame of the invoker. Any other values on the operand stack of
the current method are discarded.
The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, lreturn throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized
.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then lreturn throws an
IllegalMonitorStateException
.
The value1 must be of type long
, and value2 must be of type
int
. The values are popped from the operand stack. A long
result is calculated by shifting value1 right by s bit
positions, with sign extension, where s is the value of the
low 6 bits of value2. The result is pushed onto the operand
stack.
The resulting value is floor(value1 /
2s), where s is value2
& 0x3f. For non-negative value1, this is equivalent to
truncating long
division by 2 to the power s. The shift
distance actually used is therefore always in the range 0 to 63,
inclusive, as if value2 were subjected to a bitwise logical AND
with the mask value 0x3f.
The index is an unsigned byte. Both index and index+1 must
be indices into the local variable array of the current frame
(§2.6). The value on the top of the
operand stack must be of type long
. It is popped from the
operand stack, and the local variables at index and index+1
are set to value.
The lstore opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
Both <n> and <n>+1 must be indices into the
local variable array of the current frame
(§2.6). The value on the top of the
operand stack must be of type long
. It is popped from the
operand stack, and the local variables at <n> and
<n>+1 are set to value.
Both value1 and value2 must be of type long
. The values are
popped from the operand stack. The long
result is value1 -
value2. The result is pushed onto the operand stack.
For long
subtraction, a-b
produces the same
result as a+(-b)
. For long
values,
subtraction from zero is the same as negation.
The result is the 64 low-order bits of the true mathematical
result in a sufficiently wide two's-complement format, represented
as a value of type long
. If overflow occurs, then the sign of
the result may not be the same as the sign of the
mathematical difference of the two values.
Despite the fact that overflow may occur, execution of an lsub instruction never throws a run-time exception.
The value1 must be of type long
, and value2 must be of type
int
. The values are popped from the operand stack. A long
result is calculated by shifting value1 right
logically by s bit positions, with zero
extension, where s is the value of the low 6 bits of
value2. The result is pushed onto the operand stack.
If value1 is positive and s is value2 & 0x3f, the
result is the same as that of value1 >>
s; if
value1 is negative, the result is equal to the value of the
expression (value1 >>
s) + (2L <<
~s). The
addition of the (2L <<
~s) term cancels out the
propagated sign bit. The shift distance actually used is always in
the range 0 to 63, inclusive.
The objectref must be of type reference
.
Each object is associated with a monitor. A monitor is locked if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of the monitor associated with objectref, as follows:
If the entry count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
If the thread already owns the monitor associated with objectref, it reenters the monitor, incrementing its entry count.
If another thread already owns the monitor associated with objectref, the thread blocks until the monitor's entry count is zero, then tries again to gain ownership.
A monitorenter instruction may be used with one or more
monitorexit instructions
(§monitorexit) to implement a
synchronized
statement in the Java programming language
(§3.14). The monitorenter and
monitorexit instructions are not used in the implementation of
synchronized
methods, although they can be used to provide
equivalent locking semantics. Monitor entry on invocation of a
synchronized
method, and monitor exit on its return, are handled
implicitly by the Java Virtual Machine's method invocation and return
instructions, as if monitorenter and monitorexit were
used.
The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object.
The synchronization constructs of the Java programming language require support
for operations on monitors besides entry and exit. These include
waiting on a monitor (Object.wait
) and
notifying other threads waiting on a monitor
(Object.notifyAll
and Object.notify
). These operations are
supported in the standard package java.lang
supplied with the Java Virtual Machine. No explicit support for these operations
appears in the instruction set of the Java Virtual Machine.
The objectref must be of type reference
.
The thread that executes monitorexit must be the owner of the monitor associated with the instance referenced by objectref.
The thread decrements the entry count of the monitor associated with objectref. If as a result the value of the entry count is zero, the thread exits the monitor and is no longer its owner. Other threads that are blocking to enter the monitor are allowed to attempt to do so.
If objectref is null
, monitorexit throws a NullPointerException
.
Otherwise, if the thread that executes monitorexit is not the
owner of the monitor associated with the instance referenced by
objectref, monitorexit throws an
IllegalMonitorStateException
.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the second of those rules is violated by the execution of this
monitorexit instruction, then monitorexit throws an
IllegalMonitorStateException
.
One or more monitorexit instructions may be used with a
monitorenter instruction
(§monitorenter) to implement a
synchronized
statement in the Java programming language
(§3.14). The monitorenter and
monitorexit instructions are not used in the implementation of
synchronized
methods, although they can be used to provide
equivalent locking semantics.
The Java Virtual Machine supports exceptions thrown within synchronized
methods
and synchronized
statements differently:
Monitor exit on normal synchronized
method completion is
handled by the Java Virtual Machine's return instructions. Monitor exit on
abrupt synchronized
method completion is handled implicitly
by the Java Virtual Machine's athrow instruction.
When an exception is thrown from within a synchronized
statement, exit from the monitor entered prior to the
execution of the synchronized
statement is achieved using
the Java Virtual Machine's exception handling mechanism
(§3.14).
The dimensions operand is an unsigned byte
that must be greater than or equal to 1. It represents the number
of dimensions of the array to be created. The operand stack must
contain dimensions values. Each such value
represents the number of components in a dimension of the array to
be created, must be of type int
, and must be
non-negative. The count1 is the desired
length in the first dimension, count2 in the
second, etc.
All of the count values are popped off the
operand stack. 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 entry at the index must be a symbolic reference to a
class, array, or interface type. The named class, array, or
interface type is resolved (§5.4.3.1). The
resulting entry must be an array class type of dimensionality
greater than or equal to dimensions.
A new multidimensional array of the array type is allocated from
the garbage-collected heap. If any count
value is zero, no subsequent dimensions are allocated. The
components of the array in the first dimension are initialized to
subarrays of the type of the second dimension, and so on. The
components of the last allocated dimension of the array are
initialized to the default initial value
(§2.3, §2.4) for the
element type of the array type. A reference
arrayref to the new
array is pushed onto the operand stack.
During resolution of the symbolic reference to the class, array, or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
Otherwise, if the current class does not have permission to access
the element type of the resolved array class, multianewarray
throws an IllegalAccessError
.
Otherwise, if any of the dimensions values on
the operand stack are less than zero, the multianewarray
instruction throws a NegativeArraySizeException
.
It may be more efficient to use newarray or anewarray (§newarray, §anewarray) when creating an array of a single dimension.
The array class referenced via the run-time constant pool may have more dimensions than the dimensions operand of the multianewarray instruction. In that case, only the first dimensions of the dimensions of the array are created.
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 entry at the index must be a symbolic reference to a class or
interface type. The named class or interface type is resolved
(§5.4.3.1) and should result in a class
type. Memory for a new instance of that class is allocated from
the garbage-collected heap, and the instance variables of the new
object are initialized to their default initial values
(§2.3, §2.4). The
objectref, a reference
to the instance, is pushed onto the operand
stack.
On successful resolution of the class, it is initialized if it has not already been initialized (§5.5).
During resolution of the symbolic reference to the class or interface type, any of the exceptions documented in §5.4.3.1 can be thrown.
Otherwise, if the symbolic reference to the class or interface
type resolves to an interface or an abstract
class, new throws
an InstantiationError
.
Otherwise, if execution of this new instruction causes
initialization of the referenced class, new may throw an Error
as detailed in JLS §15.9.4.
The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method (§2.9.1) has been invoked on the uninitialized instance.
The count must be of type int
. It is popped off the operand
stack. The count represents the number of elements in the array
to be created.
The atype is a code that indicates the type of array to create. It must take one of the following values:
Table 6.5.newarray-A. Array type codes
Array Type | atype |
---|---|
T_BOOLEAN |
4 |
T_CHAR |
5 |
T_FLOAT |
6 |
T_DOUBLE |
7 |
T_BYTE |
8 |
T_SHORT |
9 |
T_INT |
10 |
T_LONG |
11 |
A new array whose components are of
type atype and of length count is allocated
from the garbage-collected heap. A reference
arrayref to this new
array object is pushed into the operand stack. Each of the
elements of the new array is initialized to the default initial
value (§2.3, §2.4) for
the element type of the array type.
In Oracle's Java Virtual Machine implementation, arrays of type boolean
(atype is T_BOOLEAN
) are stored as arrays
of 8-bit values and are manipulated using the baload and
bastore instructions (§baload,
§bastore) which also access arrays of
type byte
. Other implementations may implement packed boolean
arrays; the baload and bastore instructions must still be used
to access those arrays.
Pop the top value from the operand stack.
The pop instruction must not be used unless value is a value of a category 1 computational type (§2.11.1).
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 entry at the index must be a symbolic reference to a field
(§5.1), which gives the name and descriptor
of the field as well as a symbolic reference to the class in which
the field is to be found. The referenced field is resolved
(§5.4.3.2).
The type of a value stored by a putfield instruction must be
compatible with the descriptor of the referenced field (§4.3.2). If the field descriptor type is
boolean
, byte
, char
, short
, or int
, then the value
must be an int
. If the field descriptor type is float
, long
,
or double
, then the value must be a float
, long
, or
double
, respectively. If the field descriptor type is a
reference type, then the value must be of a type that is
assignment compatible (JLS §5.2) with the field descriptor
type. If the field is final
, it must be declared in the current
class, and the instruction must occur in an instance
initialization method of the current class (§2.9.1).
The value and objectref are popped from the operand stack.
The objectref must be of type reference
but not an array type.
If the value is of type int
and the field descriptor type is
boolean
, then the int
value is narrowed by taking the
bitwise AND of value and 1, resulting in value'. The referenced
field in objectref is set to value'.
Otherwise, the referenced field in objectref is set to value.
During resolution of the symbolic reference to the field, any of the exceptions pertaining to field resolution (§5.4.3.2) can be thrown.
Otherwise, if the resolved field is a static
field,
putfield throws an IncompatibleClassChangeError
.
Otherwise, if the resolved field is final
, it must be declared
in the current class, and the instruction must occur in an
instance initialization method of the current class.
Otherwise, an IllegalAccessError
is thrown.
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 entry at the index must be a symbolic reference to a field
(§5.1), which gives the name and descriptor
of the field as well as a symbolic reference to the class or
interface in which the field is to be found. The referenced field
is resolved (§5.4.3.2).
On successful resolution of the field, the class or interface that declared the resolved field is initialized if that class or interface has not already been initialized (§5.5).
The type of a value stored by a putstatic instruction must be
compatible with the descriptor of the referenced field
(§4.3.2). If the field descriptor type is
boolean
, byte
, char
, short
, or int
, then the value
must be an int
. If the field descriptor type is float
, long
,
or double
, then the value must be a float
, long
, or
double
, respectively. If the field descriptor type is a
reference type, then the value must be of a type that is
assignment compatible (JLS §5.2) with the field descriptor
type. If the field is final
, it must be declared in the current
class or interface, and the instruction must occur in the class or
interface initialization method of the current class or interface
(§2.9.2).
The value is popped from the operand stack.
If the value is of type int
and the field descriptor type is
boolean
, then the int
value is narrowed by taking the
bitwise AND of value and 1, resulting in value'. The referenced
field in the class or interface is set to value'.
Otherwise, the referenced field in the class or interface is set to value.
During resolution of the symbolic reference to the class or interface field, any of the exceptions pertaining to field resolution (§5.4.3.2) can be thrown.
Otherwise, if the resolved field is not a static
(class) field
or an interface field, putstatic throws an IncompatibleClassChangeError
.
Otherwise, if the resolved field is final
, it must be declared in the
current class or interface, and the instruction must occur in the class
or interface initialization method of the current class or interface.
Otherwise, an IllegalAccessError
is thrown.
Otherwise, if execution of this putstatic instruction causes
initialization of the referenced class or interface, putstatic
may throw an Error
as detailed in §5.5.
A putstatic instruction may be used only to set the value of an interface field on the initialization of that field. Interface fields may be assigned to only once, on execution of an interface variable initialization expression when the interface is initialized (§5.5, JLS §9.3.1).
The index is an unsigned byte between 0 and 255, inclusive. The
local variable at index in the current frame
(§2.6) must contain a value of type
returnAddress
. The contents of the local variable are written
into the Java Virtual Machine's pc
register, and execution continues
there.
Note that jsr (§jsr) pushes the address onto the operand stack and ret gets it out of a local variable. This asymmetry is intentional.
In Oracle's implementation of a compiler for the Java programming language prior
to Java SE 6, the ret instruction was used with the jsr and
jsr_w instructions (§jsr,
§jsr_w) in the implementation of the
finally
clause (§3.13,
§4.10.2.5).
The ret instruction should not be confused with the return instruction (§return). A return instruction returns control from a method to its invoker, without passing any value back to the invoker.
The ret opcode can be used in conjunction with the wide instruction (§wide) to access a local variable using a two-byte unsigned index.
The current method must have return type void
. If the current
method is a synchronized
method, the monitor entered or
reentered on invocation of the method is updated and possibly
exited as if by execution of a monitorexit instruction
(§monitorexit) in the current thread. If
no exception is thrown, any values on the operand stack of the
current frame (§2.6) are discarded.
The interpreter then returns control to the invoker of the method, reinstating the frame of the invoker.
If the Java Virtual Machine implementation does not enforce the rules on
structured locking described in §2.11.10,
then if the current method is a synchronized
method and the
current thread is not the owner of the monitor entered or
reentered on invocation of the method, return throws an
IllegalMonitorStateException
. This can happen, for example, if a
synchronized
method contains a monitorexit instruction, but no
monitorenter instruction, on the object on which the method is
synchronized
.
Otherwise, if the Java Virtual Machine implementation enforces the rules on
structured locking described in §2.11.10 and
if the first of those rules is violated during invocation of the
current method, then return throws an
IllegalMonitorStateException
.
The arrayref must be of type reference
and must refer to an array
whose components are of type short
. The index must be of type
int
. Both arrayref and index are popped from the operand
stack. The component of the array at index is retrieved and
sign-extended to an int
value. That value is pushed onto the
operand stack.
The arrayref must be of type reference
and must refer to an array
whose components are of type short
. Both index and value
must be of type int
. The arrayref, index, and value are
popped from the operand stack. The int
value is truncated to a
short
and stored as the component of the array indexed by
index.
Swap the top two values on the operand stack.
The swap instruction must not be used unless value1 and value2 are both values of a category 1 computational type (§2.11.1).
tableswitch
<0-3 byte pad>
defaultbyte1
defaultbyte2
defaultbyte3
defaultbyte4
lowbyte1
lowbyte2
lowbyte3
lowbyte4
highbyte1
highbyte2
highbyte3
highbyte4
jump offsets...
A tableswitch is a variable-length instruction. Immediately
after the tableswitch opcode, between zero and three bytes must
act as padding, such that defaultbyte1 begins
at an address that is a multiple of four bytes from the start of
the current method (the opcode of its first
instruction). Immediately after the padding are bytes constituting
three signed 32-bit values: default,
low, and high.
Immediately following are bytes constituting a series
of high - low + 1 signed
32-bit offsets. The value low must be less
than or equal to high.
The high - low + 1
signed 32-bit offsets are treated as a 0-based jump table. Each of
these signed 32-bit values is constructed as
(byte1 <<
24) |
(byte2 <<
16) |
(byte3 <<
8)
| byte4.
The index must be of type int
and is popped from the operand
stack. If index is less than low or index
is greater than high, then a target address
is calculated by adding default to the
address of the opcode of this tableswitch
instruction. Otherwise, the offset at position
index - low of the jump
table is extracted. The target address is calculated by adding
that offset to the address of the opcode of this tableswitch
instruction. Execution then continues at the target
address.
The target address that can be calculated from each jump table offset, as well as the one that can be calculated from default, must be the address of an opcode of an instruction within the method that contains this tableswitch instruction.
wide
<opcode>
indexbyte1
indexbyte2
where <opcode> is one of iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret
The wide instruction modifies the behavior of another instruction. It takes one of two formats, depending on the instruction being modified. The first form of the wide instruction modifies one of the instructions iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret (§iload, §fload, §aload, §lload, §dload, §istore, §fstore, §astore, §lstore, §dstore, §ret). The second form applies only to the iinc instruction (§iinc).
In either case, the wide opcode itself is followed in the
compiled code by the opcode of the instruction wide modifies. In
either form, two unsigned bytes indexbyte1 and indexbyte2
follow the modified opcode and are assembled into a 16-bit
unsigned index to a local variable in the current frame
(§2.6), where the value of the index is
(indexbyte1 <<
8) | indexbyte2. The calculated index
must be an index into the local variable array of the current
frame. Where the wide instruction modifies an lload, dload,
lstore, or dstore instruction, the index following the
calculated index (index + 1) must also be an index into the local
variable array. In the second form, two immediate unsigned bytes
constbyte1
and constbyte2 follow indexbyte1 and
indexbyte2 in the code stream. Those bytes are also assembled
into a signed 16-bit constant, where the constant is
(constbyte1 <<
8)
| constbyte2.
The widened bytecode operates as normal, except for the use of the wider index and, in the case of the second form, the larger increment range.
Although we say that wide "modifies the behavior of another instruction," the wide instruction effectively treats the bytes constituting the modified instruction as operands, denaturing the embedded instruction in the process. In the case of a modified iinc instruction, one of the logical operands of the iinc is not even at the normal offset from the opcode. The embedded instruction must never be executed directly; its opcode must never be the target of any control transfer instruction.