public class Instruction extends BytecodeContainer
CodeUnit
s, which
are created, populated, and organized by the Compiler
.
Each instruction may affect the depth of the current JVM operand stack.
The impact of each instruction type on the stack is recorded in the
stackMap
variable as an array of integer values. Each value
represents a single stack change caused by the instruction. A negative
number indicates that a value is popped from the runtime stack; a
positive number indicates that a value is pushed onto the runtime stack.
The magnitude of the number indicates the width of the value being
pushed or popped, with longs and doubles having a width of 2 and every
other type having a width of 1. A single instruction may conduct
multiple operations on the runtime stack. Each such operation is
represented by a separate number. Some instructions vary in their
interaction with the stack, such as those that invoke methods, where
the method's signature dictates the size and number of arguments popped
from the stack and the return type (if any) pushed onto the stack. For
these types of instructions, a custom stack change array must be
calculated by the compiler and provided via the specialized Instruction(int, int[])
constructor.
An instruction may have zero or more arguments. These are recorded as a list. The length of the instruction is one (for the bytecode instruction itself) plus the width of each of the arguments.
Modifier and Type | Field and Description |
---|---|
private java.util.List |
args
List of arguments to follow
|
private int |
opCode
Op code for the instruction
|
private static java.util.Map |
OPCODE_NAMES
Opcode to instruction name map
|
private int[] |
stackChange
Ordered array of stack depth changes caused by this instruction
|
private static java.util.Map |
stackMap
Map of stack depth change values, indexed by op code
|
length, offset
_aastore, _aconst_null, _aload_0, _aload_1, _aload_2, _aload_3, _anewarray, _areturn, _astore_1, _astore_2, _astore_3, _checkcast, _d2i, _d2l, _dadd, _dcmpg, _dconst_0, _dconst_1, _ddiv, _dmul, _dneg, _drem, _dreturn, _dsub, _dup, _getfield, _goto, _i2d, _i2l, _iadd, _iand, _iconst_0, _iconst_1, _iconst_2, _iconst_3, _iconst_4, _iconst_5, _idiv, _if_icmpeq, _if_icmpge, _if_icmpgt, _if_icmple, _if_icmplt, _if_icmpne, _ifeq, _ifge, _ifgt, _ifle, _iflt, _ifne, _ifnonnull, _ifnull, _imul, _ineg, _invokeinterface, _invokespecial, _invokestatic, _invokevirtual, _ior, _irem, _ireturn, _ishl, _ishr, _isub, _iushr, _ixor, _l2d, _l2i, _ladd, _land, _lcmp, _lconst_0, _lconst_1, _ldc_w, _ldc2_w, _ldiv, _lmul, _lneg, _lor, _lrem, _lshl, _lshr, _lsub, _lushr, _lxor, _new, _pop, _pop2, _return, _swap, CLASS_COMPILEDEXPRESSION, METHDESC_EXECUTE, METHNAME_EXECUTE, METHOD_INIT
Constructor and Description |
---|
Instruction(int opCode)
Constructor.
|
Instruction(int opCode,
int[] stackChange)
This constructor should be used for any instruction which has a
variable impact on the depth of the stack.
|
Modifier and Type | Method and Description |
---|---|
(package private) void |
addArgument(Argument arg)
Add an individual argument to the list of this instruction's arguments.
|
(package private) void |
fixupStack(java.util.Stack stack)
This method updates the state of the specified stack to reflect the
changes this instruction will make to the runtime stack when it is
executed.
|
(package private) int |
getOpCode()
This method returns the op code for this instruction.
|
int |
layout(int offset)
This method is called to set the offset position of this instruction
when laying out the bytecode instructions in a code unit.
|
void |
modifyStackDepth(Compiler compiler)
This method updates the current stack depth maintained by the specified
expression compiler, based upon the stack depth change required by this
instruction.
|
java.lang.String |
toString()
Generate a string representation of this instruction.
|
void |
write(java.io.DataOutput out)
Write the data represented by this instruction to the specified
output stream.
|
fixupBranchOffset, getLength, getOffset
private static java.util.Map OPCODE_NAMES
private static java.util.Map stackMap
private int opCode
private java.util.List args
private int[] stackChange
Instruction(int opCode)
opCode
- Op code for this instruction.Instruction(int opCode, int[] stackChange)
The stack change is represented as an array of positive or negative
widths (in 32-bit units) related to the popping of operands, if any,
and the subsequent pushing of a result, if any. Each array entry
represents one operand or result, listed in the order in which the
instruction will pop/push to/from the stack as it executes. All data
types take up one slot, except for double
and
long
, which each take up two.
opCode
- Op code for this instruction.stackChange
- Incremental change to the stack depth which will be caused
by this instruction at runtime. This array is not stored
directly; it is copied.public void modifyStackDepth(Compiler compiler)
modifyStackDepth
in class BytecodeContainer
compiler
- Expression compiler whose current stack depth must be changed.public int layout(int offset)
layout
in class BytecodeContainer
offset
- New offset of this instruction in its code array.public java.lang.String toString()
toString
in class java.lang.Object
Compiler.debug
public void write(java.io.DataOutput out) throws java.io.IOException
out
- Output stream to which the data will be written.java.io.IOException
- if any error occurs while writing.int getOpCode()
void addArgument(Argument arg)
arg
- Argument to be added.void fixupStack(java.util.Stack stack)
fixupStack
in class BytecodeContainer
stack
- Stack object which represents the state the runtime stack
will be in at the time the instructions in this bytecode
container are executed.java.util.EmptyStackException
- if stack is empty when popped. This indicates an incorrect
instruction was used when compiling the current expression.