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 }