001 package serp.bytecode; 002 003 import java.io.*; 004 import java.util.*; 005 006 import serp.bytecode.visitor.*; 007 008 /** 009 * An instruction that specifies a position in the code block to jump to. 010 * Examples include <code>go2, jsr</code>, etc. 011 * 012 * @author Abe White 013 */ 014 public class GotoInstruction extends JumpInstruction { 015 016 GotoInstruction(Code owner, int opcode) { 017 super(owner, opcode); 018 } 019 020 public int getStackChange() { 021 if (getOpcode() == Constants.JSR) 022 return 1; 023 return 0; 024 } 025 026 int getLength() { 027 switch (getOpcode()) { 028 case Constants.GOTOW: 029 case Constants.JSRW: 030 return super.getLength() + 4; 031 default: 032 return super.getLength() + 2; 033 } 034 } 035 036 public void setOffset(int offset) { 037 super.setOffset(offset); 038 calculateOpcode(); 039 } 040 041 /** 042 * Calculate our opcode based on the offset size. 043 */ 044 private void calculateOpcode() { 045 int len = getLength(); 046 int offset; 047 switch (getOpcode()) { 048 case Constants.GOTO: 049 case Constants.GOTOW: 050 offset = getOffset(); 051 if (offset < (2 << 16)) 052 setOpcode(Constants.GOTO); 053 else 054 setOpcode(Constants.GOTOW); 055 break; 056 case Constants.JSR: 057 case Constants.JSRW: 058 offset = getOffset(); 059 if (offset < (2 << 16)) 060 setOpcode(Constants.JSR); 061 else 062 setOpcode(Constants.JSRW); 063 break; 064 } 065 if (len != getLength()) 066 invalidateByteIndexes(); 067 } 068 }