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 }