1 package serp.bytecode;
2
3 import java.io.*;
4 import java.util.*;
5
6 import serp.bytecode.visitor.*;
7
8 /***
9 * An instruction that specifies a position in the code block to jump to.
10 * Examples include <code>go2, jsr</code>, etc.
11 *
12 * @author Abe White
13 */
14 public class GotoInstruction extends JumpInstruction {
15
16 GotoInstruction(Code owner, int opcode) {
17 super(owner, opcode);
18 }
19
20 public int getStackChange() {
21 if (getOpcode() == Constants.JSR)
22 return 1;
23 return 0;
24 }
25
26 int getLength() {
27 switch (getOpcode()) {
28 case Constants.GOTOW:
29 case Constants.JSRW:
30 return super.getLength() + 4;
31 default:
32 return super.getLength() + 2;
33 }
34 }
35
36 public void setOffset(int offset) {
37 super.setOffset(offset);
38 calculateOpcode();
39 }
40
41 /***
42 * Calculate our opcode based on the offset size.
43 */
44 private void calculateOpcode() {
45 int len = getLength();
46 int offset;
47 switch (getOpcode()) {
48 case Constants.GOTO:
49 case Constants.GOTOW:
50 offset = getOffset();
51 if (offset < (2 << 16))
52 setOpcode(Constants.GOTO);
53 else
54 setOpcode(Constants.GOTOW);
55 break;
56 case Constants.JSR:
57 case Constants.JSRW:
58 offset = getOffset();
59 if (offset < (2 << 16))
60 setOpcode(Constants.JSR);
61 else
62 setOpcode(Constants.JSRW);
63 break;
64 }
65 if (len != getLength())
66 invalidateByteIndexes();
67 }
68 }