C H A P T E R 7 |
Java Card Virtual Machine Instruction Set |
A Java Card 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 Card virtual machine instruction and the operation it performs.
The description of each instruction is always given in the context of Java Card virtual machine code that satisfies the static and structural constraints of Chapter 6, "The CAP File Format".
In the description of individual Java Card 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 Chapter 6 "The CAP 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 Card virtual machine is undefined.
In addition to the opcodes of the instructions specified later this chapter, which are used in Java Card CAP files (see Chapter 6, "The CAP File Format"), two opcodes are reserved for internal use by a Java Card virtual machine implementation. If Sun Microsystems, Inc. extends the instruction set of the Java Card virtual machine in the future, these reserved opcodes are guaranteed not to be used.
The two 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.
Although these opcodes have been reserved, they may only be used inside a Java Card virtual machine implementation. They cannot appear in valid CAP files.
A Java Card virtual machine may encounter internal errors or resource limitations that prevent it from executing correctly written Java programs. While The Java Virtual Machine Specification allows reporting and handling of virtual machine errors, it also states that they cannot ordinarily be handled by application code. This Virtual Machine Specification for the Java Card Platform, v2.2.2 is more restrictive in that it does not allow for any reporting or handling of unrecoverable virtual machine errors at the application code level. A virtual machine error is considered unrecoverable if further execution could compromise the security or correct operation of the virtual machine or underlying system software. When an unrecoverable error occurs, the virtual machine will halt bytecode execution. Responses beyond halting the virtual machine are implementation-specific policies and are not mandated in this specification.
In the case where the virtual machine encounters a recoverable error, such as insufficient memory to allocate a new object, it will throw a SystemException with an error code describing the error condition. The Virtual Machine Specification for the Java Card Platform, v2.2.2 cannot predict where resource limitations or internal errors may be encountered and does not mandate precisely when they can be reported. Thus, a SystemException may be thrown at any time during the operation of the Java Card virtual machine.
Instructions of the Java Card virtual machine throw an instance of the class SecurityException when a security violation has been detected. The Java Card virtual machine does not mandate the complete set of security violations that can or will result in an exception being thrown. However, there is a minimum set that must be supported.
In the general case, any instruction that de-references an object reference must throw a SecurityException if the context (Section 3.4, Contexts) in which the instruction is executing is different than the owning context (Section 3.4, Contexts) of the referenced object. The list of instructions includes the instance field get and put instructions, the array load and store instructions, as well as the arraylength, invokeinterface, invokespecial, invokevirtual, checkcast, instanceof and athrow instructions.
There are several exceptions to this general rule that allow cross-context use of objects or arrays. These exceptions are detailed in Chapter 6 of the Runtime Environment Specification for the Java Card Platform, Version 2.2.2. An important detail to note is that any cross-context method invocation will result in a context switch (Section 3.4, Contexts).
The Java Card virtual machine may also throw a SecurityException if an instruction violates any of the static constraints of Chapter 6, "The CAP File Format". The Virtual Machine Specification for the Java Card Platform, Version 2.2.2 does not mandate which instructions must implement these additional security checks, or to what level. Therefore, a SecurityException may be thrown at any time during the operation of the Java Card virtual machine.
Java virtual machine instructions are represented in this chapter by entries of the form shown in TABLE 7-1, an example instruction page, in alphabetical order.
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 Card virtual machine code in a CAP file.
Keep in mind that there are "operands" generated at compile time and embedded within Java Card 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 Card 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 Card 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 sconst_<s> family of instructions, giving mnemonic and opcode information for the two instructions in that family (sconst_0 and sconst_1), is
Forms sconst_0 = 3 (0x3),
sconst_1 = 4 (0x4)
In the description of the Java Card virtual machine instructions, the effect of an instruction's execution on the operand stack (Section 3.5, Frames) of the current frame (Section 3.5, Frames) is represented textually, with the stack growing from left to right and each word represented separately. Thus,
Stack..., value1, value2 ->
..., result
shows an operation that begins by having a one-word value2 on top of the operand stack with a one-word 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 a one-word result, which has been calculated by the instruction. The remainder of the operand stack, represented by an ellipsis (...), is unaffected by the instruction's execution.
The type int takes two words on the operand stack. In the operand stack representation, each word is represented separately using a dot notation:
Stack..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
The Virtual Machine Specification for the Java Card Platform, v2.2.2 does not mandate how the two words are used to represent the 32-bit int value; it only requires that a particular implementation be internally consistent.
..., arrayref, index ->
..., value
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 short. 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 top of the operand stack.
If arrayref is null, aaload throws a NullPointerException.
Otherwise, if index is not within the bounds of the array referenced by arrayref, the aaload instruction throws an ArrayIndexOutOfBoundsException.
In some circumstances, the aaload instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
..., arrayref, index, value ->
...
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 short and the value must be of type reference. The arrayref, index and value are popped from the operand stack. The reference value is stored as the component of the array at index.
At runtime the type of value must be confirmed to be assignment compatible with the type of the components of the array referenced by arrayref. Assignment of a value of reference type S (source) to a variable of reference type T (target) is allowed only when the type S supports all of the operations defined on type T. The detailed rules follow:
TC and SC are the same primitive type (Section 3.1, Data Types and Values").
TC and SC are reference types[2] (Section 3.1, Data Types and Values) with type SC assignable to TC, by these rules.
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 value is not assignment compatible with the actual type of the component of the array, aastore throws an ArrayStoreException.
In some circumstances, the aastore instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
Push the null object reference onto the operand stack.
Load reference from local variable
The index is an unsigned byte that must be a valid index into the local variables of the current frame (Section 3.5, Frames). 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 is intentional.
Load reference from local variable
aload_0 = 24 (0x18)
aload_1 = 25 (0x19)
aload_2 = 26 (0x1a)
aload_3 = 27 (0x1b)
The <n> must be a valid index into the local variables of the current frame (Section 3.5, Frames). 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 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 short. 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 constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The item at that index in the constant pool must be of type CONSTANT_Classref (Section 6.7.1, CONSTANT_Classref), a reference to a class or interface type. The reference is resolved. A new array with components of that type, of length count, is allocated from the 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.
If count is less than zero, the anewarray instruction throws a NegativeArraySizeException.
The objectref must be of type reference. The objectref is popped from the operand stack of the current frame (Section 3.5, Frames) 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 virtual machine then reinstates the frame of the invoker and returns control to the invoker.
The arrayref must be of type reference and must refer to an array. It is popped from the operand stack. The length of the array it references is determined. That length is pushed onto the top of the operand stack as a short.
If arrayref is null, the arraylength instruction throws a NullPointerException.
In some circumstances, the arraylength instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
Store reference into local variable
The index is an unsigned byte that must be a valid index into the local variables of the current frame (Section 3.5, Frames). The objectref on the top of the operand stack must be of type returnAddress or of type reference. The objectref 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 Java's finally keyword. 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 is intentional.
Store reference into local variable
astore_0 = 43 (0x2b)
astore_1 = 44 (0x2c)
astore_2 = 45 (0x2d)
astore_3 = 46 (0x2e)
The <n> must be a valid index into the local variables of the current frame (Section 3.5, Frames). 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 Java's finally keyword. 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 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 frame (Section 3.5, Frames) for the most recent catch clause that catches the class of objectref or one of its superclasses.
If a catch clause 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 appropriate clause is found in the current frame, that frame is popped, the frame of its invoker is reinstated, and the objectref is rethrown.
If no catch clause is found that handles this exception, the virtual machine exits.
If objectref is null, athrow throws a NullPointerException instead of objectref.
In some circumstances, the athrow instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
Load byte or boolean from array
..., arrayref, index ->
..., value
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 short. 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 a short 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.
In some circumstances, the baload instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
Store into byte or boolean array
..., arrayref, index, value ->
...
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 value must both be of type short. The arrayref, index and value are popped from the operand stack. The short value is truncated to a byte and 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.
In some circumstances, the bastore instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
... ->
..., value.word1, value.word2
The immediate byte is sign-extended to an int, and the resulting value is pushed onto the operand stack.
Note - If a virtual machine does not support the int data type, the bipush instruction will not be available. |
The immediate byte is sign-extended to a short, and the resulting value is pushed onto the operand stack.
Check whether object is of given type
..., objectref ->
..., objectref
The unsigned byte atype is a code that indicates if the type against which the object is being checked is an array type or a class type. It must take one of the following values or zero:
If the value of atype is 10, 11, 12, or 13, the values of the indexbyte1 and indexbyte2 must be zero, and the value of atype indicates the array type against which to check the object. Otherwise the unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The item at that index in the constant pool must be of type CONSTANT_Classref (Section 6.7.1, CONSTANT_Classref), a reference to a class or interface type. The reference is resolved. If the value of atype is 14, the object is checked against an array type that is an array of object references of the type of the resolved class. If the value of atype is zero, the object is checked against a class or interface type that is the resolved class.
The objectref must be of type reference. If objectref is null or can be cast to the specified array type or the resolved class 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 class of the object referred to by objectref and T is the resolved class, array or interface type, checkcast determines whether objectref can be cast to type T as follows:
TC and SC are the same primitive type (Section 3.1, Data Types and Values).
TC and SC are reference types[4] (Section 3.1, Data Types and Values) with type SC assignable to TC, by these rules.
If objectref cannot be cast to the resolved class, array, or interface type, the checkcast instruction throws a ClassCastException.
The checkcast instruction is fundamentally very similar to the instanceof instruction. 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.
In some circumstances, the checkcast instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the value of atype may not be 13 (array type = T_INT).
Duplicate top operand stack word
The top word on the operand stack is duplicated and pushed onto the operand stack.
The dup instruction must not be used unless word contains a 16-bit data type.
Except for restrictions preserving the integrity of 32-bit data types, the dup instruction operates on an untyped word, ignoring the type of data it contains.
Duplicate top operand stack words and insert below
..., wordN, ..., wordM, ..., word1 ->
..., wordM, ..., word1, wordN, ..., wordM, ..., word1
The unsigned byte mn is used to construct two parameter values. The high nibble, (mn & 0xf0) >> 4, is used as the value m. The low nibble, (mn & 0xf), is used as the value n. Permissible values for m are 1 through 4. Permissible values for n are 0 and m through m+4.
For positive values of n, the top m words on the operand stack are duplicated and the copied words are inserted n words down in the operand stack. When n equals 0, the top m words are copied and placed on top of the stack.
The dup_x instruction must not be used unless the ranges of words 1 through m and words m+1 through n each contain either a 16-bit data type, two 16-bit data types, a 32-bit data type, a 16-bit data type and a 32-bit data type (in either order), or two 32-bit data types.
Except for restrictions preserving the integrity of 32-bit data types, the dup_x instruction operates on untyped words, ignoring the types of data they contain.
If a virtual machine does not support the int data type, the permissible values for m are 1 or 2, and permissible values for n are 0 and m through m+2.
Duplicate top two operand stack words
..., word2, word1 ->
..., word2, word1, word2, word1
The top two words on the operand stack are duplicated and pushed onto the operand stack, in the original order.
The dup2 instruction must not be used unless each of word1 and word2 is a word that contains a 16-bit data type or both together are the two words of a single 32-bit datum.
Except for restrictions preserving the integrity of 32-bit data types, the dup2 instruction operates on untyped words, ignoring the types of data they contain.
getfield_a = 131 (0x83)
getfield_b = 132 (0x84)
getfield_s = 133 (0x85)
getfield_i = 134 (0x86)
..., objectref ->
..., value.word1, value.word2
The objectref, which must be of type reference, is popped from the operand stack. The unsigned index is used as an index into the constant pool of the current package (Section 3.5, Frames). The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class.
The item must resolve to a field with a type that matches t, as follows:
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[5]. The value at that offset into the class instance referenced by objectref is fetched. If the value is of type byte or type boolean, it is sign-extended to a short. The value is pushed onto the operand stack.
If objectref is null, the getfield_<t> instruction throws a NullPointerException.
In some circumstances, the getfield_<t> instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the getfield_i instruction will not be available.
Fetch field from current object
getfield_a_this = 173 (0xad)
getfield_b_this = 174 (0xae)
getfield_s_this = 175 (0xaf)
getfield_i_this = 176 (0xb0)
... ->
..., value.word1, value.word2
The currently executing method must be an instance method. The local variable at index 0 must contain a reference objectref to the currently executing method's this parameter. The unsigned index is used as an index into the constant pool of the current package (Section 3.5, Frames). The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class.
The item must resolve to a field with a type that matches t, as follows:
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[6]. The value at that offset into the class instance referenced by objectref is fetched. If the value is of type byte or type boolean, it is sign-extended to a short. The value is pushed onto the operand stack.
If objectref is null, the getfield_<t>_this instruction throws a NullPointerException.
In some circumstances, the getfield_<t>_this instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the getfield_i_this instruction will not be available.
Fetch field from object (wide index)
getfield_a_w = 169 (0xa9)
getfield_b_w = 170 (0xaa)
getfield_s_w = 171 (0xab)
getfield_i_w = 172 (0xac)
..., objectref ->
..., value.word1, value.word2
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 constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token. The item must resolve to a field of type reference.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class.
The item must resolve to a field with a type that matches t, as follows:
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[7]. The value at that offset into the class instance referenced by objectref is fetched. If the value is of type byte or type boolean, it is sign-extended to a short. The value is pushed onto the operand stack.
If objectref is null, the getfield_<t>_w instruction throws a NullPointerException.
In some circumstances, the getfield_<t>_w instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the getfield_i_w instruction will not be available.
getstatic_a = 123 (0x7b)
getstatic_b = 124 (0x7c)
getstatic_s = 125 (0x7d)
getstatic_i = 126 (0x7e)
... ->
..., value.word1, value.word2
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at the index must be of type CONSTANT_StaticFieldref (Section 6.7.3, CONSTANT_StaticFieldref and CONSTANT_StaticMethodref), a reference to a static field.
The item must resolve to a field with a type that matches t, as follows:
The width of a class field is determined by the field type specified in the instruction. The item is resolved, determining the field offset. The item is resolved, determining the class field. The value of the class field is fetched. If the value is of type byte or boolean, it is sign-extended to a short. The value is pushed onto the operand stack.
If a virtual machine does not support the int data type, the getstatic_i instruction will not be available.
The value branch is used as a signed 8-bit offset. 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 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.
..., value.word1, value.word2 ->
..., result
The value on top of the operand stack must be of type int. It is popped from the operand stack and converted to a byte result by taking the low-order 16 bits of the int value, and discarding the high-order 16 bits. The low-order word is truncated to a byte, then sign-extended to a short result. The result is pushed onto the operand stack.
The i2b instruction performs a narrowing primitive conversion. It may lose information about the overall magnitude of value. The result may also not have the same sign as value.
If a virtual machine does not support the int data type, the i2b instruction will not be available.
..., value.word1, value.word2 ->
..., result
The value on top of the operand stack must be of type int. It is popped from the operand stack and converted to a short result by taking the low-order 16 bits of the int value and discarding the high-order 16 bits. The result is pushed onto the operand stack.
The i2s instruction performs a narrowing primitive conversion. It may lose information about the overall magnitude of value. The result may also not have the same sign as value.
If a virtual machine does not support the int data type, the i2s instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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.
If an iadd instruction overflows, then the result is the low-order bits of the true mathematical result in a sufficiently wide two's-complement format. 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.
If a virtual machine does not support the int data type, the iadd instruction will not be available.
..., arrayref, index ->
..., value.word1, value.word2
The arrayref must be of type reference and must refer to an array whose components are of type int. The index must be of type short. Both arrayref and index are popped from the operand stack. The int value in the component of the array at index is retrieved and pushed onto the top of the operand stack.
If arrayref is null, iaload throws a NullPointerException.
Otherwise, if index is not within the bounds of the array referenced by arrayref, the iaload instruction throws an ArrayIndexOutOfBoundsException.
In some circumstances, the iaload instruction may throw a SecurityException if the current context Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the iaload instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
Both value1 and value2 must be of type int. They are popped from the operand stack. An int result is calculated by taking the bitwise AND (conjunction) of value1 and value2. The result is pushed onto the operand stack.
If a virtual machine does not support the int data type, the iand instruction will not be available.
..., arrayref, index, value.word1, value.word2 ->
...
The arrayref must be of type reference and must refer to an array whose components are of type int. The index must be of type short and value must be of type int. The arrayref, index and value are popped from the operand stack. The int value is stored as the component of the array indexed by index.
If arrayref is null, iastore throws a NullPointerException.
Otherwise, if index is not within the bounds of the array referenced by arrayref, the iastore instruction throws an ArrayIndexOutOfBoundsException.
In some circumstances, the iastore instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the iastore instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result
Both value1 and value2 must be of type int. They are both popped from the operand stack, and a signed integer comparison is performed. If value1 is greater than value2, the short value 1 is pushed onto the operand stack. If value1 is equal to value2, the short value 0 is pushed onto the operand stack. If value1 is less than value2, the short value -1 is pushed onto the operand stack.
If a virtual machine does not support the int data type, the icmp instruction will not be available.
iconst_m1 = 10 (0x09)
iconst_0 = 11 (0xa)
iconst_1 = 12 (0xb)
iconst_2 = 13 (0xc)
iconst_3 = 14 (0xd)
iconst_4 = 15 (0xe)
iconst_5 = 16 (0xf)
... ->
..., <i>.word1, <i>.word2
Push the int constant <i> (-1, 0, 1, 2, 3, 4, or 5) onto the operand stack.
If a virtual machine does not support the int data type, the iconst_<i> instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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 expression value1 / value2. 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 a 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 the 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.
If the value of the divisor in an int division is 0, idiv throws an ArithmeticException.
If a virtual machine does not support the int data type, the idiv instruction will not be available.
Branch if reference comparison succeeds.
if_acmpeq = 104 (0x68)
if_acmpne = 105 (0x69)
Both value1 and value2 must be of type reference. They are both popped from the operand stack and compared. The results of the comparisons are as follows:
If the comparison succeeds, branch is used as signed 8-bit offset, and execution 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, execution proceeds at the address of the instruction following this if_acmp<cond> instruction.
Branch if reference comparison succeeds (wide index)
if_acmpeq_w = 160 (0xa0)
if_acmpne_w = 161 (0xa1)
Both value1 and value2 must be of type reference. They are both popped from the operand stack and compared. The results of the comparisons are as follows:
If the comparison succeeds, 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 if_acmp<cond>_w instruction. The target address must be that of an opcode of an instruction within the method that contains this if_acmp<cond>_w instruction.
Otherwise, execution proceeds at the address of the instruction following this if_acmp<cond>_w instruction.
Branch if short comparison succeeds
if_scmpeq = 106 (0x6a)
if_scmpne = 107 (0x6b)
if_scmplt = 108 (0x6c)
if_scmpge = 109 (0x6d)
if_scmpgt = 110 (0x6e)
if_scmple = 111 (0x6f)
Both value1 and value2 must be of type short. They are both popped from the operand stack and compared. All comparisons are signed. The results of the comparisons are as follows:
If the comparison succeeds, branch is used as signed 8-bit offset, and execution proceeds at that offset from the address of the opcode of this if_scmp<cond> instruction. The target address must be that of an opcode of an instruction within the method that contains this if_scmp<cond> instruction.
Otherwise, execution proceeds at the address of the instruction following this if_scmp<cond> instruction.
Branch if short comparison succeeds (wide index)
if_scmpeq_w = 162 (0xa2)
if_scmpne_w = 163 (0xa3)
if_scmplt_w = 164 (0xa4)
if_scmpge_w = 165 (0xa5)
if_scmpgt_w = 166 (0xa6)
if_scmple_w = 167 (0xa7)
Both value1 and value2 must be of type short. They are both popped from the operand stack and compared. All comparisons are signed. The results of the comparisons are as follows:
If the comparison succeeds, 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 if_scmp<cond>_w instruction. The target address must be that of an opcode of an instruction within the method that contains this if_scmp<cond>_w instruction.
Otherwise, execution proceeds at the address of the instruction following this if_scmp<cond>_w instruction.
Branch if short comparison with zero succeeds
ifeq = 96 (0x60)
ifne = 97 (0x61)
iflt = 98 (0x62)
ifge = 99 (0x63)
ifgt = 100 (0x64)
ifle = 101 (0x65)
The value must be of type short. 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, branch is used as signed 8-bit offset, and execution 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.
Branch if short comparison with zero succeeds (wide index)
ifeq_w = 152 (0x98)
ifne_w = 153 (0x99)
iflt_w = 154 (0x9a)
ifge_w = 155 (0x9b)
ifgt_w = 156 (0x9c)
ifle_w = 157 (0x9d)
The value must be of type short. 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 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 if<cond>_w instruction. The target address must be that of an opcode of an instruction within the method that contains this if<cond>_w instruction.
Otherwise, execution proceeds at the address of the instruction following this if<cond>_w instruction.
The value must be of type reference. It is popped from the operand stack. If the value is not null, branch is used as signed 8-bit offset, and execution 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.
Branch if reference not null (wide index)
The value must be of type reference. It is popped from the operand stack. If the value is not null, 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 ifnonnull_w instruction. The target address must be that of an opcode of an instruction within the method that contains this ifnonnull_w instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnonnull_w instruction.
The value must be of type reference. It is popped from the operand stack. If the value is null, branch is used as signed 8-bit offset, and execution 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.
Branch if reference is null (wide index)
The value must be of type reference. It is popped from the operand stack. If the value is null, 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 ifnull_w instruction. The target address must be that of an opcode of an instruction within the method that contains this ifnull_w instruction.
Otherwise, execution proceeds at the address of the instruction following this ifnull_w instruction.
Increment local int variable by constant
The index is an unsigned byte. Both index and index + 1 must be valid indices into the local variables of the current frame (Section 3.5, Frames). The local variables at index and index + 1 together must contain an int. The const is an immediate signed byte. The value const is first sign-extended to an int, then the int contained in the local variables at index and index + 1 is incremented by that amount.
If a virtual machine does not support the int data type, the iinc instruction will not be available.
Increment local int variable by constant
The index is an unsigned byte. Both index and index + 1 must be valid indices into the local variables of the current frame (Section 3.5, Frames). The local variables at index and index + 1 together must contain an int. The immediate unsigned byte1 and byte2 values are assembled into an intermediate short where the value of the short is (byte1 << 8) | byte2. The intermediate value is then sign-extended to an int const. The int contained in the local variables at index and index + 1 is incremented by const.
If a virtual machine does not support the int data type, the iinc_w instruction will not be available.
... ->
..., value1.word1, value1.word2
The immediate unsigned byte1, byte2, byte3, and byte4 values are assembled into a signed int where the value of the int is (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4. The resulting value is pushed onto the operand stack.
If a virtual machine does not support the int data type, the iipush instruction will not be available.
... ->
..., value1.word1, value1.word2
The index is an unsigned byte. Both index and index + 1 must be valid indices into the local variables of the current frame (Section 3.5, Frames). The local variables at index and index + 1 together must contain an int. The value of the local variables at index and index + 1 is pushed onto the operand stack.
If a virtual machine does not support the int data type, the iload instruction will not be available.
iload_0 = 32 (0x20)
iload_1 = 33 (0x21)
iload_2 = 34 (0x22)
iload_3 = 35 (0x23)
... ->
..., value1.word1, value1.word2
Both <n> and <n> + 1 must be a valid indices into the local variables of the current frame (Section 3.5, Frames). The local variables at <n> and <n> + 1 together must contain an int. The value of the local variables at <n> and <n> + 1 is pushed onto the operand stack.
Each of the iload_<n> instructions is the same as iload with an index of <n>, except that the operand <n> is implicit.
If a virtual machine does not support the int data type, the iload_<n> instruction will not be available.
Access jump table by key match and jump
..., key.word1, key.word2 ->
...
An ilookupswitch instruction is a variable-length instruction. Immediately after the ilookupswitch opcode follow a signed 16-bit value default, an unsigned 16-bit value npairs, and then npairs pairs. Each pair consists of an int match and a signed 16-bit offset. Each match is constructed from four unsigned bytes as (matchbyte1 << 24) | (matchbyte2 << 16) | (matchbyte3 << 8) | matchbyte4. Each offset is constructed from two unsigned bytes as (offsetbyte1 << 8) | offsetbyte2.
The table match-offset pairs of the ilookupswitch instruction must be sorted in increasing numerical order by match.
The key must be of type int and is popped from the operand stack and 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 ilookupswitch 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 ilookupswitch 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 ilookupswitch instruction.
The match-offset pairs are sorted to support lookup routines that are quicker than linear search.
If a virtual machine does not support the int data type, the ilookupswitch instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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.
If an imul instruction overflows, then the result is the low-order bits of the mathematical product as an int. If overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two values.
If a virtual machine does not support the int data type, the imul instruction will not be available.
..., value.word1, value.word2 ->
..., result.word1, result.word2
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 Card 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.
For all int values x, -x equals (~x) + 1.
If a virtual machine does not support the int data type, the ineg instruction will not be available.
Determine if object is of given type
The unsigned byte atype is a code that indicates if the type against which the object is being checked is an array type or a class type. It must take one of the following values or zero:
If the value of atype is 10, 11, 12, or 13, the values of the indexbyte1 and indexbyte2 must be zero, and the value of atype indicates the array type against which to check the object. Otherwise the unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The item at that index in the constant pool must be of type CONSTANT_Classref (Section 6.7.1, CONSTANT_Classref), a reference to a class or interface type. The reference is resolved. If the value of atype is 14, the object is checked against an array type that is an array of object references of the type of the resolved class. If the value of atype is zero, the object is checked against a class or interface type that is the resolved class.
The objectref must be of type reference. It is popped from the operand stack. If objectref is not null and is an instance of the resolved class, array or interface, the instanceof instruction pushes a short result of 1 on the operand stack. Otherwise it pushes a short 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 class of the object referred to by objectref and T is the resolved class, array or interface type, instanceof determines whether objectref is an instance of T as follows:
TC and SC are the same primitive type (Section 3.1, Data Types and Values).
TC and SC are reference types[9] (Section 3.1, Data Types and Values) with type SC assignable to TC, by these rules.
The instanceof instruction is fundamentally very similar to the checkcast instruction. 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.
In some circumstances, the instanceof instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the value of atype may not be 13 (array type = T_INT).
..., objectref, [arg1, [arg2 ...]] ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at that index must be of type CONSTANT_Classref (Section 6.7.1, CONSTANT_Classref), a reference to an interface class. The specified interface is resolved.
The nargs operand is an unsigned byte that must not be zero.
The method operand is an unsigned byte that is the interface method token for the method to be invoked. The interface method must not be <init> or an instance initialization method.
The objectref must be of type reference and must be followed on the operand stack by nargs - 1 words of arguments. The number of words of arguments and the type and order of the values they represent must be consistent with those of the selected interface method.
The interface table of the class of the type of objectref is determined. If objectref is an array type, then the interface table of class Object (Section 2.2.2.4, Classes) is used. The interface table is searched for the resolved interface. The result of the search is a table that is used to map the method token to a index.
The index is an unsigned byte that is used as an index into the method table of the class of the type of objectref. If the objectref is an array type, then the method table of class Object is used. The table entry at that index includes a direct reference to the method's code and modifier information.
The nargs - 1 words of arguments and objectref are popped from the operand stack. A new stack frame is created for the method being invoked, and objectref and the arguments are made the values of its first nargs words of local variables, with objectref in local variable 0, arg1 in local variable 1, and so on. The new stack frame is then made current, and the Java Card 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 objectref is null, the invokeinterface instruction throws a NullPointerException.
In some circumstances, the invokeinterface instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2. If the current context is not the object's context and the Java Card RE permits invocation of the method, the invokeinterface instruction will cause a context switch (Section 3.4, Contexts) to the object's context before invoking the method, and will cause a return context switch to the previous context when the invoked method returns.
Invoke instance method; special handling for superclass, private, and instance initialization method invocations
..., objectref, [arg1, [arg2 ...]] ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. If the invoked method is a private instance method or an instance initialization method, the constant pool item at index must be of type CONSTANT_StaticMethodref (Section 6.7.3, CONSTANT_StaticFieldref and CONSTANT_StaticMethodref), a reference to a statically linked instance method. If the invoked method is a superclass method, the constant pool item at index must be of type CONSTANT_SuperMethodref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to an instance method of a specified class. The reference is resolved. The resolved method must not be <clinit>, a class or interface initialization method. If the method is <init>, an instance initialization method, then the method must only be invoked once on an uninitialized object, and before the first backward branch following the execution of the new instruction that allocated the object. Finally, if the resolved method is protected, and it is a member of a superclass of the current class, and the method is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class.
The resolved method includes the code for the method, an unsigned byte nargs that must not be zero, and the method's modifier information.
The objectref must be of type reference, and must be followed on the operand stack by nargs - 1 words of arguments, where the number of words of arguments and the type and order of the values they represent must be consistent with those of the selected instance method.
The nargs - 1 words of arguments and objectref are popped from the operand stack. A new stack frame is created for the method being invoked, and objectref and the arguments are made the values of its first nargs words of local variables, with objectref in local variable 0, arg1 in local variable 1, and so on. The new stack frame is then made current, and the Java Card 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 objectref is null, the invokespecial instruction throws a NullPointerException.
Invoke a class (static) method
..., [arg1, [arg2 ...]] ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at that index must be of type CONSTANT_StaticMethodref (Section 6.7.3, CONSTANT_StaticFieldref and CONSTANT_StaticMethodref), a reference to a static method. The method must not be <init>, an instance initialization method, or <clinit>, a class or interface initialization method. It must be static, and therefore cannot be abstract.
The resolved method includes the code for the method, an unsigned byte nargs that may be zero, and the method's modifier information.
The operand stack must contain nargs words of arguments, where the number of words of arguments and the type and order of the values they represent must be consistent with those of the resolved method.
The nargs words of arguments are popped from the operand stack. A new stack frame is created for the method being invoked, and the words of arguments are made the values of its first nargs words of local variables, with arg1 in local variable 0, arg2 in local variable 1, and so on. The new stack frame is then made current, and the Java Card 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.
Invoke instance method; dispatch based on class
..., objectref, [arg1, [arg2 ...]] ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at that index must be of type CONSTANT_VirtualMethodref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a virtual method token. The specified method is resolved. The method must not be <init>, an instance initialization method, or <clinit>, a class or interface initialization method. Finally, if the resolved method is protected, and it is a member of a superclass of the current class, and the method is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class.
The resolved method reference includes an unsigned index into the method table of the resolved class and an unsigned byte nargs that must not be zero.
The objectref must be of type reference. The index is an unsigned byte that is used as an index into the method table of the class of the type of objectref. If the objectref is an array type, then the method table of class Object (Section 2.2.2.4, Classes) is used. The table entry at that index includes a direct reference to the method's code and modifier information.
The objectref must be followed on the operand stack by nargs - 1 words of arguments, where the number of words of arguments and the type and order of the values they represent must be consistent with those of the selected instance method.
The nargs - 1 words of arguments and objectref are popped from the operand stack. A new stack frame is created for the method being invoked, and objectref and the arguments are made the values of its first nargs words of local variables, with objectref in local variable 0, arg1 in local variable 1, and so on. The new stack frame is then made current, and the Java Card 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 objectref is null, the invokevirtual instruction throws a NullPointerException.
In some circumstances, the invokevirtual instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2. If the current context is not the object's context and the Java Card RE permits invocation of the method, the invokevirtual instruction will cause a context switch (Section 3.4, Contexts) to the object's context before invoking the method, and will cause a return context switch to the previous context when the invoked method returns.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
Both value1 and value2 must be of type int. The values are popped from the operand stack. An int result is calculated by taking the bitwise inclusive OR of value1 and value2. The result is pushed onto the operand stack.
If a virtual machine does not support the int data type, the ior instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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 expression 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 that 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.
If the value of the divisor for a short remainder operator is 0, irem throws an ArithmeticException.
If a virtual machine does not support the int data type, the irem instruction will not be available.
..., value.word1, value.word2 ->
[empty]
The value must be of type int. It is popped from the operand stack of the current frame (Section 3.5, Frames) 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 virtual machine then reinstates the frame of the invoker and returns control to the invoker.
If a virtual machine does not support the int data type, the ireturn instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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 left by s bit positions, where s is the value of the low five bits of value2. The result is pushed onto the operand stack.
This is equivalent (even if overflow occurs) to multiplication 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.
If a virtual machine does not support the int data type, the ishl instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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 five bits of value2. The result is pushed onto the operand stack.
The resulting value is Î(value1) / 2s°, where s is value2 & 0x1f. For nonnegative value1, this is equivalent (even if overflow occurs) 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.
If a virtual machine does not support the int data type, the ishr instruction will not be available.
..., value.word1, value.word2 ->
...
The index is an unsigned byte. Both index and index + 1 must be a valid index into the local variables of the current frame (Section 3.5, Frames). The value on top of the operand stack must be of type int. It is popped from the operand stack, and the local variables at index and index + 1 are set to value.
If a virtual machine does not support the int data type, the istore instruction will not be available.
istore_0 = 51 (0x33)
istore_1 = 52 (0x34)
istore_2 = 53 (0x35)
istore_3 = 54 (0x36)
..., value.word1, value.word2 ->
...
Both <n> and <n> + 1 must be a valid indices into the local variables of the current frame (Section 3.5, Frames). The value on top of the operand stack must be of type int. It is popped from the operand stack, and the local variables at index and index + 1 are set to value.
If a virtual machine does not support the int data type, the istore_<n> instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
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 zeros is the same as negation.
Despite the fact that overflow or underflow may occur, in which case the result may have a different sign than the true mathematical result, execution of an isub instruction never throws a runtime exception.
If a virtual machine does not support the int data type, the isub instruction will not be available.
Access jump table by int index and jump
An itableswitch instruction is a variable-length instruction. Immediately after the itableswitch opcode follow a signed 16-bit value default, a signed 32-bit value low, a signed 32-bit value high, and then high - low + 1 further signed 16-bit offsets. The value low must be less than or equal to high. The high - low + 1 signed 16-bit offsets are treated as a 0-based jump table. Each of the signed 16-bit values is constructed from two unsigned bytes as (byte1 << 8) | byte2. Each of the signed 32-bit values is constructed from four unsigned bytes as (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4.
The index must be of type int and is popped from the 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 itableswitch 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 itableswitch instruction. Execution then continues at the target address.
The target addresses that can be calculated from each jump table offset, as well as the one calculated from default, must be the address of an opcode of an instruction within the method that contains this itableswitch instruction.
If a virtual machine does not support the int data type, the itableswitch instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
Both value1 and value2 must be of type int. The values are popped from the operand stack. An int result is calculated by shifting the result right by s bit positions, with zero extension, where s is the value of the low five 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, as if value2 were subjected to a bitwise logical AND with the mask value 0x1f.
If a virtual machine does not support the int data type, the iushr instruction will not be available.
..., value1.word1, value1.word2, value2.word1, value2.word2 ->
..., result.word1, result.word2
Both value1 and value2 must be of type int. The values are popped from the operand stack. An int result is calculated by taking the bitwise exclusive OR of value1 and value2. The result is pushed onto the operand stack.
If a virtual machine does not support the int data type, the ixor instruction will not be available.
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.
The jsr instruction is used with the ret instruction in the implementation of the finally clause of the Java language. Note that jsr pushes the address onto the stack and ret gets it out of a local variable. This asymmetry is intentional.
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The item at that index in the constant pool must be of type CONSTANT_Classref (Section 6.7.1, CONSTANT_Classref), a reference to a class or interface type. The reference is resolved and must result in a class type (it must not result in an interface type). Memory for a new instance of that class is allocated from the heap, and the instance variables of the new object are initialized to their default initial values. The objectref, a reference to the instance, is pushed onto the operand stack.
The new instruction does not completely create a new instance; instance creation is not completed until an instance initialization method has been invoked on the uninitialized instance.
The count must be of type short. It is popped off the operand stack. The count represents the number of elements in the array to be created.
The unsigned byte atype is a code that indicates the type of array to create. It must take one of the following values:
A new array whose components are of type atype, of length count, is allocated from the heap. A reference arrayref to this new array object is pushed onto the operand stack. All of the elements of the new array are initialized to the default initial value for its type.
If count is less than zero, the newarray instruction throws a NegativeArraySizeException.
If a virtual machine does not support the int data type, the value of atype may not be 13 (array type = T_INT).
The top word is popped from the operand stack. The pop instruction must not be used unless the word contains a 16-bit data type.
The pop instruction operates on an untyped word, ignoring the type of data it contains.
Pop top two operand stack words
The top two words are popped from the operand stack.
The pop2 instruction must not be used unless each of word1 and word2 is a word that contains a 16-bit data type or both together are the two words of a single 32-bit datum.
Except for restrictions preserving the integrity of 32-bit data types, the pop2 instruction operates on an untyped word, ignoring the type of data it contains.
putfield_a = 135 (0x87)
putfield_b = 136 (0x88)
putfield_s = 137 (0x89)
putfield_i = 138 (0x8a)
..., objectref, value.word1, value.word2 ->
...
The unsigned index is used as an index into the constant pool of the current package (Section 3.5, Frames). The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class. If the field is final, it must be declared in the current class.
The item must resolve to a field with a type that matches t, as follows:
value must be of a type that is assignment compatible with the field descriptor (t) type.
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[10]. The objectref, which must be of type reference, and the value are popped from the operand stack. If the field is of type byte or type boolean, the value is truncated to a byte. The field at the offset from the start of the object referenced by objectref is set to the value.
If objectref is null, the putfield_<t> instruction throws a NullPointerException.
In some circumstances, the putfield_<t> instruction may throw a SecurityException if the current context Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the putfield_i instruction will not be available.
putfield_a_this = 181 (0xb5)
putfield_b_this = 182 (0xb6)
putfield_s_this = 183 (0xb7)
putfield_i_this = 184 (0xb8)
..., value.word1, value.word2 ->
...
The currently executing method must be an instance method that was invoked using the invokevirtual, invokeinterface or invokespecial instruction. The local variable at index 0 must contain a reference objectref to the currently executing method's this parameter. The unsigned index is used as an index into the constant pool of the current package (Section 3.5, Frames). The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class. If the field is final, it must be declared in the current class.
The item must resolve to a field with a type that matches t, as follows:
value must be of a type that is assignment compatible with the field descriptor (t) type.
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[11]. The value is popped from the operand stack. If the field is of type byte or type boolean, the value is truncated to a byte. The field at the offset from the start of the object referenced by objectref is set to the value.
If objectref is null, the putfield_<t>_this instruction throws a NullPointerException.
In some circumstances, the putfield_<t>_this instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the putfield_i_this instruction will not be available.
Set field in object (wide index)
putfield_a_w = 177 (0xb1)
putfield_b_w = 178 (0xb2)
putfield_s_w = 179 (0xb3)
putfield_i_w = 180 (0xb4)
..., objectref, value.word1, value.word2 ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at the index must be of type CONSTANT_InstanceFieldref (Section 6.7.2, CONSTANT_InstanceFieldref, CONSTANT_VirtualMethodref, and CONSTANT_SuperMethodref), a reference to a class and a field token.
The class of objectref must not be an array. If the field is protected, and it is a member of a superclass of the current class, and the field is not declared in the same package as the current class, then the class of objectref must be either the current class or a subclass of the current class. If the field is final, it must be declared in the current class.
The item must resolve to a field with a type that matches t, as follows:
value must be of a type that is assignment compatible with the field descriptor (t) type.
The width of a field in a class instance is determined by the field type specified in the instruction. The item is resolved, determining the field offset[12]. The objectref, which must be of type reference, and the value are popped from the operand stack. If the field is of type byte or type boolean, the value is truncated to a byte. The field at the offset from the start of the object referenced by objectref is set to the value.
If objectref is null, the putfield_<t>_w instruction throws a NullPointerException.
In some circumstances, the putfield_<t>_w instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object referenced by objectref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the putfield_i_w instruction will not be available.
putstatic_a = 127 (0x7f)
putstatic_b = 128 (0x80)
putstatic_s = 129 (0x81)
putstatic_i = 130 (0x82)
..., value.word1, value.word2 ->
...
The unsigned indexbyte1 and indexbyte2 are used to construct an index into the constant pool of the current package (Section 3.5, Frames), where the value of the index is (indexbyte1 << 8) | indexbyte2. The constant pool item at the index must be of type CONSTANT_StaticFieldref (Section 6.7.3, CONSTANT_StaticFieldref and CONSTANT_StaticMethodref), a reference to a static field. If the field is final, it must be declared in the current class.
The item must resolve to a field with a type that matches t, as follows:
value must be of a type that is assignment compatible with the field descriptor (t) type.
The width of a class field is determined by the field type specified in the instruction. The item is resolved, determining the class field. The value is popped from the operand stack. If the field is of type byte or type boolean, the value is truncated to a byte. The field is set to the value.
In some circumstances, the putstatic_a instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the object being stored in the field. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
If a virtual machine does not support the int data type, the putstatic_i instruction will not be available.
The index is an unsigned byte that must be a valid index into the local variables of the current frame (Section 3.5, Frames). The local variable at index must contain a value of type returnAddress. The contents of the local variable are written into the Java Card virtual machine's pc register, and execution continues there.
The ret instruction is used with the jsr instruction in the implementation of the finally keyword of the Java language. Note that jsr pushes the address onto the stack and ret gets it out of a local variable. This asymmetry is intentional.
The ret instruction should not be confused with the return instruction. A return instruction returns control from a Java method to its invoker, without passing any value back to the invoker.
Any values on the operand stack of the current method are discarded. The virtual machine then reinstates the frame of the invoker and returns control to the invoker.
The value on top of the operand stack must be of type short. It is popped from the top of the operand stack, truncated to a byte result, then sign-extended to a short result. The result is pushed onto the operand stack.
The s2b instruction performs a narrowing primitive conversion. It may lose information about the overall magnitude of value. The result may also not have the same sign as value.
..., value ->
..., result.word1, result.word2
The value on top of the operand stack must be of type short. It is popped from the operand stack and sign-extended to an int result. The result is pushed onto the operand stack.
The s2i instruction performs a widening primitive conversion. Because all values of type short are exactly representable by type int, the conversion is exact.
If a virtual machine does not support the int data type, the s2i instruction will not be available.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. The short result is value1 + value2. The result is pushed onto the operand stack.
If a sadd instruction overflows, then the result is the low-order bits of the true mathematical result in a sufficiently wide two's-complement format. 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.
..., arrayref, index ->
..., value
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 short. Both arrayref and index are popped from the operand stack. The short value in the component of the array at index is retrieved and pushed onto the top of the operand stack.
If arrayref is null, saload throws a NullPointerException.
Otherwise, if index is not within the bounds of the array referenced by arrayref, the saload instruction throws an ArrayIndexOutOfBoundsException.
In some circumstances, the saload instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
..., value1, value2 ->
..., result
Both value1 and value2 are popped from the operand stack. A short result is calculated by taking the bitwise AND (conjunction) of value1 and value2. The result is pushed onto the operand stack.
..., arrayref, index, value ->
...
The arrayref must be of type reference and must refer to an array whose components are of type short. The index and value must both be of type short. The arrayref, index and value are popped from the operand stack. The short value is stored as the component of the array indexed by index.
If arrayref is null, sastore throws a NullPointerException.
Otherwise, if index is not within the bounds of the array referenced by arrayref, the sastore instruction throws an ArrayIndexOutOfBoundsException.
In some circumstances, the sastore instruction may throw a SecurityException if the current context (Section 3.4, Contexts) is not the owning context (Section 3.4, Contexts) of the array referenced by arrayref. The exact circumstances when the exception will be thrown are specified in Chapter 6 of the Runtime Environment Specification, Java Card Platform, Version 2.2.2.
sconst_m1 = 2 (0x2)
sconst_0 = 3 (0x3)
sconst_1 = 4 (0x4)
sconst_2 = 5 (0x5)
sconst_3 = 6 (0x6)
sconst_4= 7 (0x7)
sconst_5 = 8 (0x8)
Push the short constant <s> (-1, 0, 1, 2, 3, 4, or 5) onto the operand stack.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. The short result is the value of the Java expression value1 / value2. The result is pushed onto the operand stack.
A short division rounds towards 0; that is, the quotient produced for short values in n/d is a short value q whose magnitude is as large as possible while satisfying | d · q | <= | n |. Moreover, q is a 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 the largest possible magnitude for the short 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.
If the value of the divisor in a short division is 0, sdiv throws an ArithmeticException.
Increment local short variable by constant
The index is an unsigned byte that must be a valid index into the local variable of the current frame (Section 3.5, Frames). The const is an immediate signed byte. The local variable at index must contain a short. The value const is first sign-extended to a short, then the local variable at index is incremented by that amount.
Increment local short variable by constant
The index is an unsigned byte that must be a valid index into the local variable of the current frame (Section 3.5, Frames). The immediate unsigned byte1 and byte2 values are assembled into a short const where the value of const is (byte1 << 8) | byte2. The local variable at index, which must contain a short, is incremented by const.
... ->
..., value1.word1, value1.word2
The immediate unsigned byte1 and byte2 values are assembled into a signed short where the value of the short is (byte1 << 8) | byte2. The intermediate value is then sign-extended to an int, and the resulting value is pushed onto the operand stack.
If a virtual machine does not support the int data type, the sipush instruction will not be available.
Load short from local variable
The index is an unsigned byte that must be a valid index into the local variables of the current frame (Section 3.5, Frames). The local variable at index must contain a short. The value in the local variable at index is pushed onto the operand stack.
Load short from local variable
sload_0 = 28 (0x1c)
sload_1 = 29 (0x1d)
sload_2 = 30 (0x1e)
sload_3 = 31 (0x1f)
The <n> must be a valid index into the local variables of the current frame (Section 3.5, Frames). The local variable at <n> must contain a short. The value in the local variable at <n> is pushed onto the operand stack.
Each of the sload_<n> instructions is the same as sload with an index of <n>, except that the operand <n> is implicit.
Access jump table by key match and jump
A slookupswitch instruction is a variable-length instruction. Immediately after the slookupswitch opcode follow a signed 16-bit value default, an unsigned 16-bit value npairs, and then npairs pairs. Each pair consists of a short match and a signed 16-bit offset. Each of the signed 16-bit values is constructed from two unsigned bytes as (byte1 << 8) | byte2.
The table match-offset pairs of the slookupswitch instruction must be sorted in increasing numerical order by match.
The key must be of type short and is popped from the operand stack and 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 slookupswitch 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 slookupswitch 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 slookupswitch instruction.
The match-offset pairs are sorted to support lookup routines that are quicker than linear search.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. The short result is value1 * value2. The result is pushed onto the operand stack.
If a smul instruction overflows, then the result is the low-order bits of the mathematical product as a short. If overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two values.
The value must be of type short. It is popped from the operand stack. The short result is the arithmetic negation of value, -value. The result is pushed onto the operand stack.
For short values, negation is the same as subtraction from zero. Because the Java Card 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 short results in that same maximum negative number. Despite the fact that overflow has occurred, no exception is thrown.
For all short values x, -x equals (~x) + 1.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. A short result is calculated by taking the bitwise inclusive OR of value1 and value2. The result is pushed onto the operand stack.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. The short result is the value of the Java expression 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 that the dividend is the negative short 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.
If the value of the divisor for a short remainder operator is 0, srem throws an ArithmeticException.
The value must be of type short. It is popped from the operand stack of the current frame (Section 3.5, Frames) 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 virtual machine then reinstates the frame of the invoker and returns control to the invoker.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. A short result is calculated by shifting value1 left by s bit positions, where s is the value of the low five bits of value2. The result is pushed onto the operand stack.
This is equivalent (even if overflow occurs) to multiplication 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 mask value of 0x1f allows shifting beyond the range of a 16-bit short value. It is used by this instruction, however, to ensure results equal to those generated by the Java instruction ishl.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. A short result is calculated by shifting value1 right by s bit positions, with sign extension, where s is the value of the low five bits of value2. The result is pushed onto the operand stack.
The resulting value is Î(value1) / 2s°, where s is value2 & 0x1f. For nonnegative value1, this is equivalent (even if overflow occurs) to truncating short 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 mask value of 0x1f allows shifting beyond the range of a 16-bit short value. It is used by this instruction, however, to ensure results equal to those generated by the Java instruction ishr.
The immediate unsigned byte1 and byte2 values are assembled into a signed short where the value of the short is (byte1 << 8) | byte2. The resulting value is pushed onto the operand stack.
Store short into local variable
The index is an unsigned byte that must be a valid index into the local variables of the current frame (Section 3.5, Frames). The value on top of the operand stack must be of type short. It is popped from the operand stack, and the value of the local variable at index is set to value.
Store short into local variable
sstore_0 = 47 (0x2f)
sstore_1 = 48 (0x30)
sstore_2 = 49 (0x31)
sstore_3 = 50 (0x32)
The <n> must be a valid index into the local variables of the current frame (Section 3.5, Frames). The value on top of the operand stack must be of type short. It is popped from the operand stack, and the value of the local variable at <n> is set to value.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. The short result is value1 - value2. The result is pushed onto the operand stack.
For short subtraction, a - b produces the same result as a + (-b). For short values, subtraction from zeros is the same as negation.
Despite the fact that overflow or underflow may occur, in which case the result may have a different sign than the true mathematical result, execution of a ssub instruction never throws a runtime exception.
Access jump table by short index and jump
A stableswitch instruction is a variable-length instruction. Immediately after the stableswitch opcode follow a signed 16-bit value default, a signed 16-bit value low, a signed 16-bit value high, and then high - low + 1 further signed 16-bit offsets. The value low must be less than or equal to high. The high - low + 1 signed 16-bit offsets are treated as a 0-based jump table. Each of the signed 16-bit values is constructed from two unsigned bytes as (byte1 << 8) | byte2.
The index must be of type short and is popped from the stack. If index is less than low or index is greater than high, than a target address is calculated by adding default to the address of the opcode of this stableswitch 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 stableswitch instruction. Execution then continues at the target address.
The target addresses that can be calculated from each jump table offset, as well as the one calculated from default, must be the address of an opcode of an instruction within the method that contains this stableswitch instruction.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. A short result is calculated by sign-extending value1 to 32 bits[13] and shifting the result right by s bit positions, with zero extension, where s is the value of the low five bits of value2. The resulting value is then truncated to a 16-bit result. 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, as if value2 were subjected to a bitwise logical AND with the mask value 0x1f.
The mask value of 0x1f allows shifting beyond the range of a 16-bit short value. It is used by this instruction, however, to ensure results equal to those generated by the Java instruction iushr.
Swap top two operand stack words
..., wordM+N, ..., wordM+1, wordM, ..., word1 ->
..., wordM, ..., word1, wordM+N, ..., wordM+1
The unsigned byte mn is used to construct two parameter values. The high nibble, (mn & 0xf0) >> 4, is used as the value m. The low nibble, (mn & 0xf), is used as the value n. Permissible values for both m and n are 1 and 2.
The top m words on the operand stack are swapped with the n words immediately below.
The swap_x instruction must not be used unless the ranges of words 1 through m and words m+1 through n each contain either a 16-bit data type, two 16-bit data types, a 32-bit data type, a 16-bit data type and a 32-bit data type (in either order), or two 32-bit data types.
Except for restrictions preserving the integrity of 32-bit data types, the swap_x instruction operates on untyped words, ignoring the types of data they contain.
If a virtual machine does not support the int data type, the only permissible value for both m and n is 1.
..., value1, value2 ->
..., result
Both value1 and value2 must be of type short. The values are popped from the operand stack. A short result is calculated by taking the bitwise exclusive OR of value1 and value2. The result is pushed onto the operand stack.
Copyright © 2005, Sun Microsystems, Inc. All Rights Reserved.