3.10 Stack Manipulations

The instructions pop and pop2 remove the top slot of the stack. The pop instruction removes a single slot value (int, float, or reference) from the stack. The pop2 instruction removes two slots from the stack, which can be either a double-slot value (long or double) or two one-slot values.

The pop instructions are most often used to pop off the results of method calls where you were more interested in the side effect of a method call than in what the method returns:

 aload_0          ; Push a FileInputStream ldc2_w      ; Skip up to 128 bytes, leaving the actual                  ; number skipped on the stack invokevirtual java/io/FileInputStream/skip (L)L pop2             ; But I don't care about the result 

The swap instruction swaps the top two slots on the stack, independent of their types:

                  ; The stack: ldc "A String"   ; "A String" iconst_3         ; "A String"     3 swap             ; 3              "A String" 

The swap instruction can be used only on ints, floats, and references. If either of the top two entries is a double or a long, this operation is meaningless (since it will try to break up a two-slot type), and the verification algorithm will reject the program.

Another set of stack-manipulating instructions is the dup instructions. The most basic of these, dup, just duplicates the value on top of the stack:

                  ; The stack: ldc 2.71728      ; 2.71828 dup              ; 2.71828 2.71828 

More complicated is dup_x1, which creates a duplicate of the word on top of the stack and places the duplicate on the stack below the top two slots:

 ldc "O"          ; "O" ldc "S"          ; "O"    "S" dup_x1           ; "S"    "O"      "S" 

When a reference is duplicated, you get two references to the same object, not two different objects. At the end of this sequence, the operand stack and heap look like Figure 3.1. There's also dup_x2, which puts the copy below the top three slots:

                  ; The stack: ldc 3.14159      ; 3.14159 bipush 2         ; 3.14159      2 dup_x1           ; 2            3.14159       2 aconst_null      ; 2            3.14159       2        null dup_x2           ; 2            null          3.14159  2    null 
Figure 3.1. (a) Before dup_x1 (b) After dup_x1


These instructions can work interchangeably on floats, ints, and references. To duplicate two-slot values (long and double), there are the dup2, dup2_x1, and dup2_x2 instructions. These work just like the corresponding dup instructions, but they duplicate the top two slots of the stack instead of the top one:

                           ; The stack: ldc "Pi"                  ; "Pi" ldc2_w 3.1415926368979    ; "Pi"            3.1415926368979 dup2_x1                   ; 3.1415926368979 "Pi"  3.1415926368979 

Table 3.9 summarizes these instructions. (The top of the stack is towards the right.)

Recall that long and double values take up two positions on the stack. You are not allowed to use the pop and pop2 instructions to try to split up a long or double value. For example, it is illegal to use a pop instruction when a double-slot value is on top of the stack:

 ldc 2345789L          ; Push a long value pop                   ; ILLEGAL! Attempt to remove                       ; half of the value 

Similarly, it is illegal to use pop2 like this:

 lconst_1              ; Push a long value bipush 6              ; Push an int pop2                  ; ILLEGAL! 

Table 3.9. Pop instructions
Mnemonic Stack Result
pop word empty
pop2 word1 word2 empty
swap word1 word2 word2 word1
dup word1 word1 word1
dup_x1 word1 word2 word2 word1 word2
dup_x2 word1 word2 word3 word3 word1 word2 word3
dup2 word1 word2 word1 word2 word1 word2
dup2_x1 word1 word2 word3 word2 word3 word1 word2 word3
dup2_x2 word1 word2 word3 word4 word3 word4 word1 word2 word3 word4

This illegality is illustrated in Figure 3.2. Before the pop2, the top two slots are the int 6 and half of the long 1. Removing them would leave half the long on the stack, an invalid state.

Figure 3.2. Illegal pop2 instruction


It is your responsibility to make sure you use the right kind of instruction in the right place. If you use the wrong kind of pop instruction, the JVM will detect it during verification and refuse to load the class.

Exercise 3.9

What should the .limit stack directive be for this code fragment? What about the .limit locals? How high is the stack at the end?

 aload_3 iload 9 swap dup astore_2 sipush 99 bipush 101 imul imul 

Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net