-
Notifications
You must be signed in to change notification settings - Fork 0
JVM ASM
Pushes the int value held in a local variable onto the operand stack. The ILOAD instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable to use. The single-word int value held in that local variable is retrieved and placed on the stack.
[...] -> [... , a]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.INT_TYPE, null, l1, l2)
LABEL(l1)
ILOAD(v1)
LABEL(l2)
Pushes the long value held in a local variable onto the operand stack. The LLOAD instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable to use. The double-word long value held in that local variable is retrieved and placed on the stack.
[...] -> [... , a1 , a2]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.LONG_TYPE, null, l1, l2)
LABEL(l1)
ILOAD(v1)
LABEL(l2)
Pushes the float value held in a local variable onto the operand stack. The FLOAD instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable to use. The single-word float value held in that local variable is retrieved and placed on the stack.
[...] -> [... , a]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.FLOAT_TYPE, null, l1, l2)
LABEL(l1)
ILOAD(v1)
LABEL(l2)
Pushes the double value held in a local variable onto the operand stack. The DLOAD instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable to use. The double-word long value held in that local variable is retrieved and placed on the stack.
[...] -> [... , a1 , a2]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.DOUBLE_TYPE, null, l1, l2)
LABEL(l1)
ILOAD(v1)
LABEL(l2)
Pushes the object reference held in a local variable onto the operand stack. The ALOAD instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable to use. The single-word object reference held in that local variable is retrieved and placed on the stack.
[...] -> [... , o]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.INT_TYPE, null, l1, l2)
LABEL(l1)
ILOAD(v1)
LABEL(l2)
Pops an integer (single-word) off the stack and stores it in local variable var. The ISTORE instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable should be used.
[... , a] -> [...]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.INT_TYPE, null, l1, l2)
LABEL(l1)
ICONST(1)
ISTORE(v1)
LABEL(l2)
Pops a long (double-word) off the stack and stores it in local variable var. The LSTORE instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable should be used.
[... , a1 , a2] -> [...]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.LONG_TYPE, null, l1, l2)
LABEL(l1)
LCONST(1)
LSTORE(v1)
LABEL(l2)
Pops a double (double-word) off the stack and stores it in local variable var. The DSTORE instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable should be used.
[... , a1 , a2] -> [...]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.DOUBLE_TYPE, null, l1, l2)
LABEL(l1)
DCONST(1)
DSTORE(v1)
LABEL(l2)
Pops a float (single-word) off the stack and stores it in local variable var. The FSTORE instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable should be used.
[... , a] -> [...]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.FLOAT_TYPE, null, l1, l2)
LABEL(l1)
FCONST(1)
FSTORE(v1)
LABEL(l2)
Pops an object reference (single-word) off the stack and stores it in local variable var. The ASTORE instruction takes a single parameter, var, created by VAR() instruction, which indicates which local variable should be used.
[... , o] -> [...]
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.getType("java/lang/String"), null, l1, l2)
LABEL(l1)
LDC("string")
ASTORE(v1)
LABEL(l2)
Increments the integer held in the local variable var by . The IINC instruction takes two parameters: var, created by VAR() instruction, which indicates which local variable should be used. is the integer amount to increment or decrement the variable by.
No effect
var l1 = LABEL()
var l2 = LABEL()
var v1 = VAR("v1", Type.INT_TYPE, null, l1, l2)
LABEL(l1)
LCONST(1)
LSTORE(v1)
IINC(v1, 2)
LABEL(l2)
Pops the top single-word item off the stack and discards it
[... , a] -> [...]
POP()
Removes two single-word items from the stack (e.g. two integers, or an integer and an object reference) or one two-word item (i.e. a double or a long).
[... , a1, a2] -> [...]
POP2()
This pops the top single-word value off the operand stack, and then pushes that value twice - i.e. it makes an extra copy of the top item on the stack.
This instruction cannot be used to duplicate two-word items (longs or doubles) - use DUP2 instead.
[... , a] -> [... , a , a]
DUP()
Duplicates the top two words on the stack and pushes the duplicates onto the stack in the same order. You can use this to duplicate two single-word items (e.g. two integers, or an integer and an object reference) or one two-word item (i.e. a double or a long).
[... , a1 , a2] -> [... , a1 , a2, a1 , a2]
DUP2()
Swaps the top two single-word items on the stack. a1/a2 cannot belong to a long or double.
[... , a1 , a2] -> [... , a2 , a1]
SWAP()
Duplicates the top item on the stack and inserts the duplicate below the second-from-top item. Both items must be single-word items.
[... , a1 , a2] -> [... , a2 , a1 , a2]
DUP_X1()
Duplicates the top single-word stack item inserts the duplicate three words down.
[... , a1 , a2 , a3] -> [... , a3 , a1 , a2 , a3]
DUP_X2()
Duplicates the top two-word item on the stack and inserts the duplicate before the previous (single-word) item on the stack. Alternatively, this instruction could also be used to duplicate two single-word items and insert them before the third single-word item on the stack.
[... , a1 , a2 , a3] -> [... , a2 , a3 , a1 , a2 , a3]
DUP2_X1()
Duplicates the top two-word item on the stack and inserts the duplicate before the previous (two-word) item on the stack. Alternatively, this instruction could be used to duplicate two single-word items and insert them before the before the third two-word (or fourth single-word) item on the stack.
[... , a1 , a2 , a3 , a4] -> [... , a3 , a4 , a1 , a2 , a3 , a4]
DUP2_X2()
Pushes an integer constant on stack
[...] -> [... , a]
ICONST(10)
Pushes a long (double-word) constant on stack
[...] -> [... , a1 , a2]
LCONST(10)
Pushes a float constant on stack
[...] -> [... , a]
ICONST(10.0)
Pushes a double (double-word) constant on stack
[...] -> [... , a1 , a2]
DCONST(10.0)
Pushes a one-word constant onto the operand stack. ldc takes a single parameter, , which is the value to push. The following Java types can be pushed using LDC:
- int
- float
- String
Pushing a String causes a reference to a java.lang.String object to be constructed and pushed onto the operand stack. Pushing an int or a float causes a primitive value to be pushed onto the stack.
[...] -> [... , a]
LDC("Testing")
Pushes the special null object reference onto the stack. null is a reference to no object, and has no type (null can be cast to any reference type). null conventionally represents an invalid or uncreated object. Fields, variables and the elements of object reference arrays have null as their initial value.
[...] -> [... , a]
ACONST_NULL()
Pops two integers from the operand stack, adds them, and pushes the integer result back onto the stack. On overflow, IADD produces a result whose low order bits are correct, but whose sign bit may be incorrect.
[... , a , b] -> [... , c]
ICONST(1)
ICONST(2)
IADD()
Pops two long integers from the operand stack, adds them and then pushes the result back onto the stack. On overflow, LADD produces a result whose low order bits are correct, but whose sign bit may be incorrect.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
LCONST(1)
LCONST(2)
LADD()
Pops two single-precision floating point numbers off the operand stack, adds them, and pushes the result back onto the stack. Floating point addition follows IEEE rules.
[... , a , b] -> [... , c]
FCONST(1.0)
FCONST(2.0)
FADD()
Takes the two top double-precision floating point numbers off of the operand stack, adds them, and pushes the result back onto the stack.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
DCONST(1.0)
DCONST(2.0)
DADD()
Pops two ints off the operand stack, subtracts the top one from the second (i.e. computes value2 - value1), and pushes the int result back onto the stack.
[... , a , b] -> [... , c]
ICONST(2)
ICONST(1)
ISUB()
Pops two long integers from the stack, subtracts the top one from the second (i.e. computes value2 - value1), and pushes the result back onto the stack.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
LCONST(2)
LCONST(1)
LSUB()
Pops two single-precision floating point numbers off the operand stack, subtracts the top one from the second (i.e. computes value2 - value1), and pushes the single-precision result back onto the stack. Subtraction is done according to IEEE 754 rules for single precision floating point numbers.
[... , a , b] -> [... , c]
FCONST(2.0)
FCONST(1.0)
FSUB()
Takes the top two double-precision floating point numbers from the stack, subtracts the top one from the second (i.e. computes value2 - value1), and pushes the double-precision result back onto the stack. Subtraction is done according to IEEE 754 rules for double precision floating point numbers.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
DCONST(2.0)
DCONST(1.0)
DSUB()
Pops the top two integers from the operand stack, multiplies them, and pushes the integer result back onto the stack. On overflow, IMUL produces a result whose low order bits are correct, but whose sign bit may be incorrect.
[... , a , b] -> [... , c]
ICONST(2)
ICONST(1)
IMUL()
Pops the top two long integers from the operand stack, multiplies them, and then pushes the long integer result back onto the stack. On overflow, LMUL produces a result whose low order bits are correct, but whose sign bit may be incorrect.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
LCONST(2)
LCONST(1)
LMUL()
Pops two single-precision floating point numbers off of the stack, multiplies them, and pushes the single precision result back onto the stack. IEEE 754 rules for floating point arithmetic are used.
[... , a , b] -> [... , c]
FCONST(2.0)
FCONST(1.0)
FMUL()
Pops the top two double-precision floating point numbers off the stack, multiplies them, and pushes the double-precision result back onto the stack. Multiplication is performed using the standard IEEE rules for double precision floating point arithmetic.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
DCONST(2.0)
DCONST(1.0)
DMUL()
Pops the top two integers from the operand stack and divides the second-from top integer (value2) by the top integer (value1), i.e. computes (value2 div value1). The quotient result is truncated to the nearest integer (with rounding going towards zero, so 1.7 becomes 1) and placed on the stack.
Throws ArithmeticException on attempt to divide by 0 (i.e. value1 is 0)
[... , a , b] -> [... , c]
ICONST(2)
ICONST(1)
IDIV()
Pops the top two two-word long integers from the stack and divides by the top long integer (i.e. computes value2 / value1). The result is rounded to the nearest integer, with rounding going towards 0. The long integer quotient result is pushed back onto the stack.
Throws ArithmeticException on attempt to divide by 0 (i.e. value1 is 0)
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
LCONST(2)
LCONST(1)
LDIV()
Pops two single-precision floats from the stack, divide by the top float, and push the single-precision quotient result back onto the stack (i.e. computes value2 / value1). Division is carried out using IEEE 754 rules.
Divide by zero results in the value NaN to be pushed onto the stack.
[... , a , b] -> [... , c]
FCONST(2.0)
FCONST(1.0)
FDIV()
Pops the top two double-precision floating point numbers off of the stack, divides by the top number (i.e. computes value2 / value1), and pushes the double precision quotient result back onto the stack.
Division by zero will result in an infinity result. The division is computed using IEEE 754 round-to-nearest mode and gradual underflow. Standard IEEE arithmetic rules are used for the special NaN, infinity, and zero values.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
DCONST(2.0)
DCONST(1.0)
DDIV()
Pops two ints off the operand stack, divides value2 by value1 (i.e. value2 / value1), computes the remainder and pushes the int remainder back onto the stack. The remainder is (value2 - ((value1 / value2) * value2)). This is used by the % operator in Java.
Throws ArithmeticException on attempt to divide by 0 (i.e. value1 is 0)
[... , a , b] -> [... , c]
ICONST(3)
ICONST(2)
IREM()
Pops two long integers off the operand stack, divides value2 by value1, computes the remainder and pushes the long integer remainder back onto the stack. The remainder is (value2 - ((value1 / value2) * value2)). This is used by the % operator in Java.
Throws ArithmeticException on attempt to divide by 0 (i.e. value1 is 0)
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
LCONST(3)
LCONST(2)
LREM()
Pops two single-precision numbers off the operand stack, divides by the top float, computes the remainder and pushes the single-precision result back onto the stack. This is like the C function fmod. The remainder is computed using the equation:
remainder = value2 - (intof( value2 / value1 ) * value1)
where intof () rounds towards the nearest integer, or towards the nearest even integer if the number is half way between two integers.
Divide by zero results in the value NaN to be pushed onto the stack.
This operation is not the same as the IEEE-defined remainder operation, which uses slightly different rules for rounding. Use the Java library routine Math.IEEEremainder if you want the IEEE behavior.
[... , a , b] -> [... , c]
FCONST(3.0)
FCONST(2.0)
FREM()
Pops two double-precision numbers off the operand stack, divides by the top double, computes the remainder and pushes the double-precision result back onto the stack. This is like the C function fmod.
Divide by zero results in the value NaN to be pushed onto the stack.
This operation is not the same as the IEEE-defined remainder operation, which uses slightly different rules for rounding. Use the Java library routine Math.IEEEremainder if you want the IEEE behavior.
[... , a1 , a2 , b1 , b2] -> [... , c1 , c2]
DCONST(3.0)
DCONST(2.0)
DREM()
Pops an int off the stack, negates it, and pushes the negated integer value back onto the stack. This is the same as multiplying the integer by -1.
[... , a] -> [... , -a]
ICONST(3)
INEG()
Removes the top long integer from the operand stack, negates it, and pushes the negated result back onto the stack. This is the same as multiplying the long integer by -1, which is the same as (~value) + 1.
Because of the two's-complement representation used for negative numbers, negating Long.MIN_VALUE actually produces Long.MIN_VALUE, not Long.MAX_VALUE as you might expect.
[... , a1 , a2] -> [... ,b1 , b2]
LCONST(3)
LNEG()
Removes the top single-precision float from the operand stack, negates it (i.e. inverts its sign), and pushes the negated result back onto the stack.
Note that, in IEEE floating point arithmetic, negation is not quite the same as subtracting from 0. IEEE has two zeros, +0.0 and -0.0. FNEG applied to +0.0 is -0.0, whereas (+0.0 minus +0.0) is +0.0.
[... , a] -> [... , b]
FCONST(3.0)
FNEG()
Removes the top double-precision float from the operand stack, negates it (i.e. inverts its sign), and pushes the negated result back onto the stack.
Note that, in IEEE double precision floating point arithmetic, negation is not quite the same as subtracting from 0. IEEE has two zeros, +0.0 and -0.0, and dneg applied to +0.0 is -0.0, whereas (+0.0 minus +0.0) is +0.0.
[... , a1 , a2] -> [... , b1 , b2]
DCONST(3.0)
DNEG()
Pops two ints off the stack. Shifts a left by the amount indicated in the five low bits of b. The int result is then pushed back onto the stack.
This is the same as computing the expression:
a * 2^b
[... , a, b] -> [... , c]
ICONST(1)
ICONST(3)
ISHL()
Pops a long integer and an int from the stack. Shifts a (the long integer) left by the amount indicated in the low six bits of b (an int). The long integer result is then pushed back onto the stack.
This is the same as computing the expression:
a * 2^b
[... , a1 , a2, b] -> [... , c1 , c2]
LCONST(1)
ICONST(3)
LSHL()
Pops two ints off the stack. Shifts a right by the amount indicated in the five low bits of b. The int result is then pushed back onto the stack. a is shifted arithmetically (preserving the sign extension).
This is the same as computing the expression:
a / 2^b
[... , a, b] -> [... , c]
ICONST(34)
ICONST(3)
ISHR()
Pops a long integer and an int from the stack. Shifts a (the long integer) right by the amount indicated in the low six bits of b (an int). The long integer result is then pushed back onto the stack. The value is shifted arithmetically (preserving the sign extension).
This is the same as computing the expression:
a / 2^b
[... , a1 , a2, b] -> [... , c1 , c2]
LCONST(34)
ICONST(3)
LSHR()
Pops two ints off the stack. Shifts a right by the amount indicated in the five low bits of b. The int result is then pushed back onto the stack. a is shifted logically (ignoring the sign extension - useful for unsigned values).
[... , a, b] -> [... , c]
ICONST(34)
ICONST(3)
IUSHR()
Pops a long integer and an int from the stack. Shifts a (the long integer) right by the amount indicated in the low six bits of b (an int). The long integer result is then pushed back onto the stack. a is shifted logically (ignoring the sign extension - useful for unsigned values).
[... , a1 , a2, b] -> [... , c1 , c2]
LCONST(34)
ICONST(3)
LUSHR()
Computes the bitwise and of value1 and value2 (which must be ints). The int result replaces value1 and value2 on the stack.
[... , a , b] -> [... , c]
ICONST(3)
ICONST(2)
IAND()
Pops two long integers off the stack. Computes the bitwise and of value1 and value2. The long integer result replaces value1 and value2 on the stack.
[... , a1 , a2, b1 , b2] -> [... , c1 , c2]
LCONST(3)
LCONST(2)
LAND()
Computes the bitwise or of value1 and value2 (which must be ints). The int result replaces value1 and value2 on the stack.
[... , a , b] -> [... , c]
ICONST(3)
ICONST(2)
IOR()
Pops two long integers off the stack. Computes the bitwise or of value1 and value2. The long integer result replaces value1 and value2 on the stack.
[... , a1 , a2, b1 , b2] -> [... , c1 , c2]
LCONST(3)
LCONST(2)
LOR()
Computes the bitwise xor of value1 and value2 (which must be ints). The int result replaces value1 and value2 on the stack.
[... , a , b] -> [... , c]
ICONST(3)
ICONST(2)
IXOR()
Pops two long integers off the stack. Computes the bitwise xor of value1 and value2. The long integer result replaces value1 and value2 on the stack.
[... , a1 , a2, b1 , b2] -> [... , c1 , c2]
LCONST(3)
LCONST(2)
LXOR()
Takes two two-word long integers off the stack and compares them. If the two integers are the same, the int 0 is pushed onto the stack. If a is greater than b, the int 1 is pushed onto the stack. If b is greater than a, the int -1 is pushed onto the stack.
[... , a1 , a2, b1 , b2] -> [... , c]
LCONST(3)
LCONST(2)
LCMP()
This takes two single-precision floating point numbers off the stack and compares them, using IEEE 754 rules.
If the two numbers are the same, the integer 0 is pushed onto the stack. If a is greater than b, the integer 1 is pushed onto the stack. If b is greater than a, the integer -1 is pushed onto the stack. If either number is NaN, the integer -1 is pushed onto the stack. +0.0 and -0.0 are treated as equal.
[... , a , b] -> [... , c]
FCONST(3.0)
FCONST(2.0)
FCMPL()
This takes two single-precision floating point numbers off the stack and compares them, using IEEE 754 rules.
If the two numbers are the same, the integer 0 is pushed onto the stack. If a is greater than b, the integer 1 is pushed onto the stack. If b is greater than a, the integer -1 is pushed onto the stack. If either number is NaN, the integer 1 is pushed onto the stack. +0.0 and -0.0 are treated as equal.
[... , a , b] -> [... , c]
FCONST(3.0)
FCONST(2.0)
FCMPG()
This takes two double-precision floating point numbers off the operand stack and compares them, using IEEE 754 rules.
If the two numbers are the same, the 32-bit integer 0 is pushed onto the stack. If a is greater than b, the integer 1 is pushed onto the stack. If b is greater than a, -1 is pushed onto the stack. If either numbers is NaN, the integer -1 is pushed onto the stack. +0.0 and -0.0 are treated as equal.
[... , a1 , a2, b1 , b2] -> [... , c]
DCONST(3.0)
DCONST(2)
DCMPL()
This takes two double-precision floating point numbers off the operand stack and compares them, using IEEE 754 rules.
If the two numbers are the same, the 32-bit integer 0 is pushed onto the stack. If a is greater than b, the integer 1 is pushed onto the stack. If b is greater than a, -1 is pushed onto the stack. If either numbers is NaN, the integer 1 is pushed onto the stack. +0.0 and -0.0 are treated as equal.
[... , a1 , a2, b1 , b2] -> [... , c]
DCONST(3.0)
DCONST(2)
DCMPG()
Converts an integer to a signed byte. A 32-bit int is popped off the stack, the top 24 bits are discarded (they are set to zero), then the resulting value is signed extended to an int. The int result is pushed back onto the stack.
I2B is used in Java where there is a cast between an int and a byte. Notice that I2B can cause a change in sign. For example, in the code:
int x = -134;
byte b = (byte)x;
The value of b is positive 122 - the sign bit of x is lost in the conversion.
[... , a] -> [... , b]
ICONST(-134)
I2B()
Converts an integer to a 16-bit unsigned char. A 32-bit int is popped off the stack, the top 16 bits are set to zero and the resulting int value is pushed back onto the stack.
I2C is used in Java when there is an explicit cast between an int and a char. Notice that I2C produces an unsigned value - any sign bit for the original number is lost. For example, in the code:
int x = -1;
char c = (char)x;
The value of c is positive 0xFFFF.
[... , a] -> [... , b]
ICONST(-1)
I2C()
Converts an integer to a signed short. A 32-bit int is popped off the stack, the top 16 bits are set to zero, and the resulting value is then sign extended to an int. The int result is pushed back onto the stack.
I2S is used in Java where there is an explicit case between an int and a short. Notice that I2S can cause a change in sign. For example, in the code:
int x = -40000;
short s = (short)x;
The value of s is positive 25536, since the sign bit of x is lost in the conversion.
[... , a] -> [... , b]
ICONST(-40000)
I2S()
Pops a long integer off of the stack, discards the most significant 32 bits, and pushes the low 32 bits onto the stack as an int. This may cause the magnitude or sign of the value to change.
[... , a1 , a2] -> [... , b]
LCONST(40000)
L2I()
Pops a single precision float off of the stack, casts it to a 32-bit int, and pushes the int value back onto the stack.
Rounding is done using IEEE 754 round-to-nearest mode. The fractional part is lost by rounding towards zero, so (int)-3.14 becomes -3.
If the original float value is NaN, the result is 0. If the value is too large to be represented as an integer, or if it is positive infinity, the result is the largest possible integer 0x7FFFFFFF. If the value is too small (i.e. a negative value of large magnitude, or negative infinity) then the result is the most negative integer 0x80000000.
[... , a] -> [... , b]
FCONST(13.4)
F2I()
Pops a two-word double precision floating point number off of the operand stack, casts it into a 32-bit int, and pushes the resulting int onto the stack.
Rounding is done using IEEE 754 round-to-nearest mode. The fractional part is lost by rounding towards zero, so (int)-3.14 becomes -3.
If the original double value is NaN, the result is 0. If the value is too large to be represented as an integer, or if it is positive infinity, the result is the largest possible integer 0x7FFFFFFF. If the value is too small (i.e. a negative value of large magnitude, or negative infinity) then the result is the most negative integer 0x80000000.
[... , a1 , a2] -> [... , b]
DCONST(-3.14)
D2I()
Pops an integer off the operand stack, sign extends it into a long integer, and pushes the two-word long back onto the stack.
[... , a] -> [... , b1 , b2]
ICONST(2)
I2L()
This is used to cast a single precision float value into a 64-bit long integer value. f2l removes a float from the stack, converts it to a long integer, and pushes the two-word long integer back onto the stack.
Rounding is done using IEEE 754 round-to-nearest mode. The fractional part is lost by rounding towards zero, so (long)-3.14 becomes -3.
If the original value is NaN, the result is 0. If the value is too large to be represented as an integer, or if it is positive infinity, the result is the largest possible long integer Long.MAX_VALUE. If the value is too small (i.e. a negative value of large magnitude, or negative infinity) then the result is the most negative long integer Long.MIN_VALUE.
[... , a] -> [... , b1 , b2]
FCONST(2.0)
F2L()
Pops a two-word double precision floating point number off of the operand stack, converts it into a 64-bit long integer, and pushes the resulting two-word long onto the stack.
Rounding is done using IEEE 754 round-to-nearest mode. The fractional part is lost by rounding towards zero, so (long)-3.14 becomes -3.
If the original double value is NaN, the result is 0. If the value is too large to be represented as an integer, or if it is positive infinity, the result is the largest possible long integer Long.MAX_VALUE. If the value is too small (i.e. a negative value of large magnitude, or negative infinity) then the result is the most negative long integer Long.MIN_VALUE.
In some implementations, this may be coded using the C casting mechanism, e.g.
void d2l(double d, int &l_high, int &l_low)
{
l_low = (unsigned int)d;
l_high = (unsigned int)(d / 2**32);
}
where l_low and l_high are respectively the least significant and most significant 32-bit words of the long.
[... , a1 , a2] -> [... , b1 , b2]
DCONST(-3.14)
D2L()
Pops an int off the operand stack, casts it into a single-precision float, and pushes the float back onto the stack. Notice that there is may be a loss of precision (floats have 24 bits of significance, as compared to 32 bits for an int, so the least significant bits of int are lost). However, the magnitude of the result will be preserved (the range of a float is greater than the range of an int). Rounding is done using the IEEE 754 round-to-nearest mode.
[... , a] -> [... , b]
ICONST(2)
I2F()
Pops a long integer off of the stack, casts it into a single precision floating point number, and pushes the single float back onto the stack. Notice that this can cause loss of precision (the significance in a float is 24 bits, compared to 64 bits for the long) though not loss of magnitude (since the range of a float is greater than the range of a long). Rounding is done using the IEEE 754 round-to-nearest mode.
[... , a1 , a2] -> [... , b]
LCONST(2)
L2F()
Pops a two-word double precision floating point number off of the operand stack, casts it into a single precision float, and pushes the resulting float back onto the stack. There is a loss of precision and range in the result.
This conversion is done in accordance with IEEE 754 specifications, with rounding using IEEE 754 round-to-nearest mode.
The sign of the value if preserved. A value which is too small to be represented as a float is converted to positive or negative zero. A value that is too large to be represented as a float is converted to positive infinity or negative infinity. If the value was NaN, the result is NaN.
[... , a1 , a2] -> [... , b]
DCONST(2.0)
D2F()
Pops an int off the operand stack, casts it into a double precision floating point number, and pushes the two-word double precision result back onto the stack. This conversion is exact, since doubles have enough precision to represent all int values.
[... , a] -> [... , b1 , b2]
ICONST(2)
I2D()
Pops a long integer off of the stack, casts it into a double precision floating point number, and pushes the double back onto the stack. Notice that this can cause loss of precision (the significand in a double is 54 bits, compared to 64 bits for the long) though not loss of magnitude (since the range of a double is greater than the range of a long). Rounding is done using the IEEE 754 round-to-nearest mode.
[... , a1 , a2] -> [... , b1 , b2]
LCONST(2)
L2D()
Pops a single precision float off of the stack, casts it to a double, and pushes the double-precision floating point number back onto the stack. This conversion is done in accordance with IEEE 754 specifications. Note that nothing is lost in this conversion. If the original value is NaN, the result will be NaN. Similarly, if the original value is an infinity, the result will be the same infinity.
[... , a] -> [... , b1 , b2]
FCONST(2.0)
F2D()
Checks that the top item on the operand stack (a reference to an object or array) can be cast to a given type.
clz - the class type; can be specified as string (eg. java.lang.String)
[... , o] -> [... , o]
ALOAD(0)
CHECKCAST("pkg.MyClass")
NEW is used to create object instances. A reference to the new object is pushed onto the operand stack.
Note that the new object is uninitialized - before the new object can be used, one of its methods must be called using invokespecial.
clz - the class type; can be specified as string (eg. java.lang.String) or using the Type reference
[...] -> [... , o]
NEW("pkg.MyClass")
INVOKESPECIAL("pkg.MyClass", "") // invoking pkg.MyClass() constructor
Pops objectref (a reference to an object) from the stack, retrieves the value of the field identified by [clz, name, type] from objectref, and pushes the one-word or two-word value onto the operand stack.
Throws NullPointerException if objectref is null
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference name - the field name type - the field type; can be specified as string (eg. java.util.List) or using the Type reference
[... , o] -> [... , v] [... , o] -> [... , v1 , v2]
ALOAD(0)
GETFIELD("pkg.MyClass", "counter", Type.INT_TYPE)
Sets the value of the field identified by [clz, name, type] in objectref (a reference to an object) to the single or double word value on the operand stack.
Throws NullPointerException if objectref is null
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference name - the field name type - the field type; can be specified as string (eg. java.util.List) or using the Type reference
[... , o , v] -> [...] [... , o , v1 , v2] -> [...]
ALOAD(0)
ICONST(120)
PUTFIELD("pkg.MyClass", "counter", Type.INT_TYPE)
Retrieves the value of the static field (also known as a class field) identified by [clz, name, type] from the class, and pushes the one-word or two-word value onto the operand stack.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference name - the field name type - the field type; can be specified as string (eg. java.util.List) or using the Type reference
[...] -> [... , v] [...] -> [... , v1 , v2]
GETSTATIC("pkg.MyClass", "s_counter", Type.INT_TYPE)
Sets the value of the field identified by [clz, name, type] to the single or double word value on the operand stack.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference name - the field name type - the field type; can be specified as string (eg. java.util.List) or using the Type reference
[... , v] -> [...] [... , v1 , v2] -> [...]
ICONST(10)
PUTSTATIC("pkg.MyClass", "s_counter", Type.INT_TYPE)
INVOKEVIRTUAL dispatches a Java method. It is used in Java to invoke all methods except interface methods (which use INVOKEINTERFACE), static methods (which use INVOKESTATIC), and the few special cases handled by INVOKESPECIAL.
Throws NullPointerException if objectref is null and StackOverflowError when no more space in callstack for a new stack frame.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference method - the method name argTypeArray - the argument type array; types can be specified as string (eg. java.util.List) or using the Type reference retType - the return type; can be specified as string (eg. java.util.List) or using the Type reference
[... , o , arg1 ... argN] -> [... , r]
ALOAD(0)
ICONST(10)
INVOKEVIRTUAL("pkg.MyClass", "count", [Type.INT_TYPE])
Calls a static method (also known as a class method)
StackOverflowError when no more space in callstack for a new stack frame.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference method - the method name argTypeArray - the argument type array; types can be specified as string (eg. java.util.List) or using the Type reference retType - the return type; can be specified as string (eg. java.util.List) or using the Type reference
[... , arg1 ... argN] -> [... , r]
ICONST(10)
INVOKESTATIC("pkg.MyClass", "s_count", [Type.INT_TYPE])
INVOKEINTERFACE is used to invoke a method declared within a Java interface.
Throws NullPointerException if objectref is null and StackOverflowError when no more space in callstack for a new stack frame.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference method - the method name argTypeArray - the argument type array; types can be specified as string (eg. java.util.List) or using the Type reference retType - the return type; can be specified as string (eg. java.util.List) or using the Type reference
[... , o , arg1 ... argN] -> [... , r]
ALOAD(0)
INVOKEVIRTUAL("java.util.Collection", "size", null, Type.INT_TYPE)
INVOKESPECIAL is used in certain special cases to invoke a method. Specifically, INVOKESPECIAL is used to invoke:
- the instance initialization method,
- a private method of this
- a method in a superclass of this
The main use of INVOKESPECIAL is to invoke an object's instance initialization method, , during the construction phase for a new object.
Throws NullPointerException if objectref is null and StackOverflowError when no more space in callstack for a new stack frame.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference method - the method name argTypeArray - the argument type array; types can be specified as string (eg. java.util.List) or using the Type reference retType - the return type; can be specified as string (eg. java.util.List) or using the Type reference
[... , o , arg1 ... argN] -> [... , r]
NEW("pkg.MyClass")
ICONST(1)
INVOKESPECIAL("pkg.MyClass", "", [Type.INT_TYPE])
Not yet implemented
The INSTANCEOF instruction is used to implement the Java language's instanceof operator, which tests whether an object reference or array belongs to a given class.
It pops objectref (a reference to an object) off the top of the operand stack. If objectref is an instance of [clz] or one of [clz]'s subclasses, the int 1 is pushed onto the stack, otherwise the int 0 is pushed onto the stack. If objectref is null, the result is always 0. If [clz] is an interface, int-result will be 1 if objectref implements that interface, and 0 if objectref does not implement the interface.
clz - the declaring class type; can be specified as string (eg. java.lang.String) or using the Type reference
[... , o] -> [... , r]
ALOAD(0)
INSTANCEOF("java.lang.String")
The monitorenter/monitorexit mechanism is used by the Java synchronized statement to coordinate access to an object among multiple threads.
MONITORENTER obtains an exclusive lock on the object referenced by objectref. There are three possible scenarios: If no other thread has locked the object, a new lock is established on the object, and execution continues at the next instruction.
If the object is currently locked by another thread, MONITORENTER blocks, waiting for the other thread to unlock the object.
If the current thread already owns a lock on the object, a counter is incremented - the lock will only be released when the counter returns to zero.
Throws NullPointerException when the object reference on the stack is null.
[... , o] -> [...]
ALOAD(0)
MONITORENTER()
This releases an exclusive lock that was previously obtained using MONITORENTER for the object objectref. If other threads are waiting for the object to become unlocked, one of the waiting threads will be able to acquire a lock on the object and proceed.
Note that a single thread can lock an object several times - the runtime system maintains a count of the number of times that the object was locked by the current thread, and only unlocks the object when the counter reaches zero (i.e. when the number of monitorenters and monitorexits applied to a given object are equal).
The monitorenter/monitorexit mechanism is used by the Java synchronized statement to coordinate access to an object among multiple threads.
Throws NullPointerException when the object reference on the stack is null and IllegalMonitorStateException when objectref was not previously locked by the current thread.
[... , o] -> [...]
ALOAD(0)
MONITOREXIT()
NEWARRAY is used to allocate single-dimension arrays of booleans, chars, floats, doubles, bytes, shorts, ints or longs.
NEWARRAY pops a positive int, n, off the stack, and constructs an array for holding n elements of the type given by [primitiveType]. Initially the elements in the array are set to zero. A reference to the new array object is left on the stack.
Throws NegativeArraySizeException when n is less than zero and OutOfMemoryError when insufficient memory to allocate the array.
- primitiveType - a type specified using the Type reference eg. Type.INT_TYPE
[... , n] -> [... , a]
ICONST(10)
NEWARRAY(Type.INT_TYPE)
ANEWARRAY allocates a new array for holding object references. It pops an int, size, off the stack and constructs a new array capable of holding size object references of the type indicated by [clz].
A reference to the new array is pushed onto the stack. Entries in the new array are initially set to null.
Throws NegativeArraySizeException when n is less than zero and OutOfMemoryError when insufficient memory to allocate the array.
- clz - a type specified using string (eg. "java.lang.String") or the Type reference eg. Type.INT_TYPE
[... , n] -> [... , a]
ICONST(10)
ANEWARRAY("java.lang.String")
Allocates a multi-dimensional array. In Java, a multi-dimensional array is structured an array of arrays, i.e. an array whose elements are references to array objects.
The lengths of each array within the multi-dimensional array are given as positive ints on the operand stack. The number of ints taken from the stack is specified by the unsigned byte parameter [n]. The type of the array is given as an array type descriptor by the [clz] parameter.
The elements within the array are initialized to zero (for numeric and boolean arrays), or null for arrays of references. MULTIANEWARRAY leaves a reference to the newly constructed array on the operand stack.
A reference to the new array is pushed onto the stack.
Throws NegativeArraySizeException when n is less than zero and OutOfMemoryError when insufficient memory to allocate the array.
- clz - a type specified using string (eg. "java.lang.String") or the Type reference eg. Type.INT_TYPE
- n - the dimensions count
[... , d1 ... dn] -> [... , a]
ICONST(3)
ICONST(2)
ICONST(1)
MULTIANEWARRAY(Type.INT_TYPE, 3)
Retrieves a byte from a byte array, expands it to an integer and places it on the operand stack. arrayref is a reference to an array of bytes. index is an int. The arrayref and index are removed from the stack, and the 8-bit signed byte at the given index in the array is retrieved, sign-extended to a 32-bit int, and pushed onto the stack.
BALOAD is also used to retrieve values from boolean arrays. In this case, arrayref is a reference to an array of booleans (see the newarray instruction) . If the entry at the given index is true, then the int 1 is pushed onto the stack, otherwise the int 0 is pushed onto the stack. In Sun's implementation, boolean arrays are actually stored as byte arrays, using one byte per boolean value. Other implementations might use packed arrays - or even int arrays - this is invisible to programs running on the JVM, which always use BALOAD and BASTORE to access and store values in boolean arrays.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
BALOAD()
Retrieves a character from an array of characters and pushes it on the operand stack. arrayref is a reference to an array of chars. index is an int. The arrayref and index are removed from the stack, and the 16-bit unsigned Unicode character at the given index in the array is retrieved, zero extended to a 32-bit int, and pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
CALOAD()
Retrieves a short from an array of shorts and places it on the stack. arrayref is a reference to an array of shorts. index is an int. The arrayref and index are removed from the stack, and the 16-bit signed short at the given index in the array is retrieved, sign-extended to an int, and pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
SALOAD()
Retrieves an entry from a int array and places it on the stack. arrayref is a reference to an array of ints. index is an int. The arrayref and index are removed from the stack, and the int value at the given index in the array is pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
IALOAD()
Retrieves a long integer from a long integer array and places it on the stack. arrayref is a reference to an array of long integers. index is an int. The arrayref and index are removed from the stack, and the long integer entry at the given index in the array is pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value1 , value2]
ALOAD(2)
ICONST(1)
LALOAD()
Retrieves an entry from a float array and places it on the stack. arrayref is a reference to an array of single-precision floats. index is an int. The arrayref and index are removed from the stack, and the single-precision float entry at the given index in the array is pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
FALOAD()
Retrieves an entry from a double precision float array and places it on the stack. arrayref is a reference to an array of double-precision floating point numbers. index is an int. The arrayref and index are removed from the stack, and the two-word value at the given index in the array is pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value1 , value2]
ALOAD(2)
ICONST(1)
DALOAD()
Retrieves an object reference from an array of objects and places it on the stack. arrayref is a reference to an array of objects. index is an int. The arrayref and index are removed from the stack, and the object reference at the given index in the array is pushed onto the stack.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index] -> [... , value]
ALOAD(2)
ICONST(1)
AALOAD()
Takes a 32-bit int from the stack, truncates it to an 8-bit signed byte, and stores it in an array of bytes. arrayref is a reference to an array of bytes. index is an int. value is the int value to be stored in the array. arrayref, index and value are removed from the stack, and value is truncated to 8 bits and stored in the array at the given index.
BASTORE is also used to store values in boolean arrays. In this case, arrayref is a reference to an array of booleans (see the NEWARRAY instruction) . If value is zero, false is stored at the given index in the array, otherwise true is stored at the given index. In Sun's implementation, boolean arrays are actually stored as byte arrays, using one byte per boolean value. Other implementations might use packed arrays - or even int arrays - this is invisible to programs running on the JVM, which always use BALOAD and BASTORE to access and store values in boolean arrays.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
ICONST(10)
BASTORE()
Pops a 32-bit integer from the stack, truncates it to a 16-bit unsigned value, and stores it in an array of characters. arrayref is a reference to an array of 16-bit Unicode characters. index is an int. value is the int value to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
ICONST(10)
CASTORE()
Takes an int from the stack, truncates it to a signed 16-bit short, and stores it in an array of shorts. arrayref is a reference to an array of 16-bit signed shorts. index is an int. value is the int to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
ICONST(10)
SASTORE()
Takes an int from the stack and stores it in an array of ints. arrayref is a reference to an array of ints. index is an int. value is the int value to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
ICONST(10)
IASTORE()
Takes a two-word long integer from the stack and stores it in an array of long integers. arrayref is a reference to an array of long integers. index is an int. value is the long integer value to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value1 , value2] -> [...]
ALOAD(2)
ICONST(1)
LCONST(10)
LASTORE()
Takes a single-precision float from the stack and stores it in an array of floats. arrayref is a reference to an array of single-precision floats. index is an int. value is the single-precision float value to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
FCONST(10)
FASTORE()
Pops a two-word double precision floating point number from the stack and stores it in an array of doubles. arrayref is a reference to an array of doubles. index is an int. value is the double to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value1 , value2] -> [...]
ALOAD(2)
ICONST(1)
DCONST(10)
DASTORE()
This stores an object reference it in an array of objects. arrayref is a reference to an array of object references. index is an int. value is the object reference to be stored in the array. arrayref, index and value are removed from the stack, and value is stored in the array at the given index.
The runtime type of value must be assignment-compatible with the type of the array. For example, if the array is declared as an array of Threads, then value must either be null or an instance of Thread or one of its subclasses. An ArrayStoreException is generated if you attempt to store an incompatible type of object in an array.
Throws NullPointerException when arrayref is null and ArrayIndexOutOfBoundsException when index is < 0 or >= arrayref.length
[... , arrayref , index, value] -> [...]
ALOAD(2)
ICONST(1)
ALOAD(4)
AASTORE()
Removes arrayref (a reference to an array) from the stack and replaces it with the length of the array (an int). For multi-dimensional arrays, the length of the first dimension is returned.
Throws NullPointerException when arrayref is null
[... , arrayref] -> [... , length]
ALOAD(2)
ARRAYLENGTH()
IFEQ pops the top int off the operand stack. If the int equals zero, execution branches to the [label]. If the int on the stack does not equal zero, execution continues at the next instruction.
[... , value] -> [...]
ICONST(0)
IFEQ(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFNE pops the top int off the operand stack. If the int does not equal zero, execution branches to the [label]. If the int on the stack equals zero, execution continues at the next instruction.
[... , value] -> [...]
ICONST(2)
IFNE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFLE pops the top int off the operand stack. If the int is less than zero or equals zero, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value] -> [...]
ICONST(0)
IFLE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFLT pops the top int off the operand stack. If the int is less than zero, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value] -> [...]
ICONST(-1)
IFLT(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFGE pops the top int off the operand stack. If the int is greater than zero or equals zero, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value] -> [...]
ICONST(0)
IFGE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFGT pops the top int off the operand stack. If the int is greater than zero, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value] -> [...]
ICONST(1)
IFGT(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPEQ pops the top two ints off the stack and compares them. If the two integers are equal, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(1)
ICONST(1)
IF_ICMPEQ(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPNE pops the top two ints off the stack and compares them. If the two integers are not equal, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(1)
ICONST(2)
IF_ICMPNE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPLE pops the top two ints off the stack and compares them. If value1 is less than value2 or euqals value2, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(1)
ICONST(1)
IF_ICMPLE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPLT pops the top two ints off the stack and compares them. If value1 is less than value2, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(1)
ICONST(2)
IF_ICMPLT(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPGE pops the top two ints off the stack and compares them. If value1 is greater than value2 or equals value2, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(1)
ICONST(1)
IF_ICMPLT(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ICMPGT pops the top two ints off the stack and compares them. If value1 is greater than value2, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , value1 , value2] -> [...]
ICONST(2)
ICONST(1)
IF_ICMPGT(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ACMPEQ pops the top two object references off the stack and compares them. If two object references are equal, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , ref1 , ref2] -> [...]
ALOAD(1)
ALOAD1(1)
IF_ACMPEQ(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IF_ACMPNE pops the top two object references off the stack and compares them. If two object references are not equal, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , ref1 , ref2] -> [...]
ALOAD(2)
ALOAD1(1)
IF_ACMPNE(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFNULL pops the top object reference off the operand stack. If the object reference is to the special object null, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , ref] -> [...]
ACONST_NULL()
IFNULL(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
IFNONNULL pops the top object reference off the operand stack. If the object reference is not to the special object null, execution branches to the [label]. Otherwise execution continues at the next instruction.
[... , ref] -> [...]
ALOAD(1)
IFNULL(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
Causes execution to branch to the instruction specified by the [label].
[...] -> [...]
GOTO(l1)
ICONST(1)
LABEL(l1)
ICONST(2)
TABLESWITCH is used to perform computed jump. The jump table used by tableswitch is given in the bytecode after the tableswitch opcode.
An integer, val, is popped off the top of the operand stack. If this value is less than [low], or if it is greater than [high], execution branches to [defaultLabel].
If val is in the range to , execution branches to the i'th entry in the [labelArray], where i is (val - ) and the first entry in the table is index 0.
[... , val] -> [...]
ILOAD(1)
TABLESWITCH(0, 2, DefaultLabel, [ZeroLabel, OneLabel, TwoLabel])
LABEL(ZeroLabel)
...
LABEL(OneLabel)
...
LABEL(TwoLabel)
...
LABEL(DefaultLabel)
...
This is used to perform an efficient compare-and-jump, as might be needed for a switch statement. The table used by LOOKUPSWITCH is given after the LOOKUPSWITCH opcode in bytecode.
LOOKUPSWITCH works as follows. First, an int, item, is taken from the top of the stack. Then, LOOKUPSWITCH searches the [valArray] table looking for an entry whose [key] field matches item. If a match is found at position pos, execution branches to the address of the corresponding [labelArray[pos]] label. If no match is found, execution branches to [labelDefault].
[... , item] -> [...]
ILOAD(1)
LOOKUPSWITCH(DefaultLabel, [1, 10], [Label_1, Label_10])
LABEL(Label_1)
...
LABEL(Label_10)
...
LABEL(DefaultLabel)
...
Pops an int from the top of the stack and pushes it onto the operand stack of the invoker (i.e. the method which used INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE to call the currently executing method). All other items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is int.
[... , ret] -> [?]
ILOAD(1)
IRETURN()
Pops a long integer from the top of the stack and pushes it onto the operand stack of the invoker (i.e. the method which used INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE to call the currently executing method). All other items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is long.
[... , ret1 , ret2] -> [?]
LLOAD(1)
LRETURN()
Pops a float from the top of the stack and pushes it onto the operand stack of the invoker (i.e. the method which used INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE to call the currently executing method). All other items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is float.
[... , ret] -> [?]
FLOAD(1)
FRETURN()
Pops a double precision float from the top of the stack and pushes it onto the operand stack of the invoker (i.e. the method which used INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE to call the currently executing method). All other items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is double.
[... , ret1 , ret2] -> [?]
DLOAD(1)
DRETURN()
Pops an object reference from the top of the stack and pushes it onto the operand stack of the invoker (i.e. the method which used INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE to call the currently executing method). All other items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is an object reference.
[... , ret] -> [?]
ALOAD(1)
ARETURN()
All items on the current method's operand stack are discarded. If the current method is marked as synchronized, then an implicit monitorexit instruction is executed. Then the current method's frame is discarded, the invoker's frame is reinstated, and control returns to the invoker. This instruction can only be used in methods whose return type is void.
[...] -> [?]
RETURN()
Removes objectref (a reference to an object) from the operand stack, and 'throws' the exception represented by that object. objectref is an instance of Throwable or one of its subclasses.
To throw an exception, the system searches for a handler for objectref's class in the exception table of the currently active method.
If no handler is found, the current method's frame is discarded, its invoker's frame is reinstated, and the exception is immediately rethrown. This process is repeated until a handler is found or until there are no more procedures on the callstack (at which point, the current thread dies, typically printing out an error message).
If a handler is found, the operand stack of the active method is cleared, objectref is pushed on the operand stack of the current method, and execution continues at the first instruction of the handler.
[... , objectref] -> [?]
NEW("java.lang.IllegalArgumentException")
DUP()
INVOKESPECIAL("java.lang.IllegalArgumentException", "")
ATHROW()
Generates a new (when the [label] argument is not provided) or places an existing [label].
var l1 = LABEL()
ICONST(10)
IFNE(l1)
ICONST(2)
LABEL(l1)
Generates a try/catch block description. The block starts at [startLabel], ends at [endLabel] and has its handler at [handlerLabel]. The handler can handle exceptions of [type] type (can be specified as string - eg. "java.lang.IllegalArgumentException")
Creates a new local variable definition
- name - the variable name
- type - the variable type; specified as a string (eg. "java.lang.String") or using the Type reference (eg. Type.INT_TYPE)
- genericSig - signature (eg. ) if the type is generified, null otherwise
- startLabel - start of the local variable scope
- endLabel - end of the local variable scope
var start = LABEL()
var end = LABEL()
var x1 = VAR("x1", Type.INT_TYPE, null, start, end)
LABEL(l1)
ICONST(10)
ASTORE(x1)
LABEL(l2)