001 package sysModel.classFile.code.instructions;
002
003 import sysModel.classFile.code.Opcode;
004 import junit.framework.TestCase;
005
006 import java.io.ByteArrayOutputStream;
007 import java.io.IOException;
008 import java.util.Arrays;
009 import java.util.LinkedList;
010
011 /**
012 * Unit tests for AInstruction classes.
013 *
014 * @author Mathias Ricken
015 */
016 public class AInstructionTest extends TestCase {
017 public void testFactory() throws IOException {
018 AInstruction i;
019 short pc = 0;
020 LinkedList<AInstruction> list = new LinkedList<AInstruction>();
021 ByteArrayOutputStream baos = new ByteArrayOutputStream();
022
023 byte[] code = new byte[]{
024 Opcode.ALOAD_0, // 0
025 Opcode.IFEQ, 0, 0, // 1
026 Opcode.GOTO, 0, 0, // 4
027 Opcode.GOTO_W, 0, 0, 0, 0, // 7
028 Opcode.ALOAD, 0, // 12
029 Opcode.WIDE, Opcode.ALOAD, 0, 0, // 14
030 Opcode.IINC, 0, 0, // 18
031 Opcode.WIDE, Opcode.IINC, 0, 0, 0, 0, // 21
032 Opcode.TABLESWITCH, /*default*/(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf1, /*low*/0, 0, 0, 5, /*high*/0, 0, 0, 7,
033 /*5*/(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf3, /*6*/(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf7, /*7*/(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfa, // 27
034 Opcode.LOOKUPSWITCH, /*pad*/ 0, 0, 0, /*default*/(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xe7, /*n*/0, 0, 0, 2, /*key*/0, 0, 0, 0,
035 /*offset*/0, 0, 0, 0, /*key*/ 0, 0, 0, 1, /*offset*/ (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xcc, // 52
036 Opcode.RETURN // 80
037 };
038 LineNumberTable lnt = new LineNumberTable(code);
039
040 i = AInstruction.makeInstruction(code, pc, pc, lnt);
041 assertEquals("Wrong instruction", GenericInstruction.class, i.getClass());
042 assertEquals("Wrong size", 1, i.getBytecodeLength(pc));
043 list.add(i);
044 pc += i.getBytecodeLength(pc);
045
046 i = AInstruction.makeInstruction(code, pc, pc, lnt);
047 assertEquals("Wrong instruction", BranchInstruction.class, i.getClass());
048 assertEquals("Wrong size", 3, i.getBytecodeLength(pc));
049 list.add(i);
050 pc += i.getBytecodeLength(pc);
051
052 i = AInstruction.makeInstruction(code, pc, pc, lnt);
053 assertEquals("Wrong instruction", BranchInstruction.class, i.getClass());
054 assertEquals("Wrong size", 3, i.getBytecodeLength(pc));
055 list.add(i);
056 pc += i.getBytecodeLength(pc);
057
058 i = AInstruction.makeInstruction(code, pc, pc, lnt);
059 assertEquals("Wrong instruction", WideBranchInstruction.class, i.getClass());
060 assertEquals("Wrong size", 5, i.getBytecodeLength(pc));
061 list.add(i);
062 pc += i.getBytecodeLength(pc);
063
064 i = AInstruction.makeInstruction(code, pc, pc, lnt);
065 assertEquals("Wrong instruction", GenericInstruction.class, i.getClass());
066 assertEquals("Wrong size", 2, i.getBytecodeLength(pc));
067 list.add(i);
068 pc += i.getBytecodeLength(pc);
069
070 i = AInstruction.makeInstruction(code, pc, pc, lnt);
071 assertEquals("Wrong instruction", WideInstruction.class, i.getClass());
072 assertEquals("Wrong size", 4, i.getBytecodeLength(pc));
073 list.add(i);
074 pc += i.getBytecodeLength(pc);
075
076 i = AInstruction.makeInstruction(code, pc, pc, lnt);
077 assertEquals("Wrong instruction", GenericInstruction.class, i.getClass());
078 assertEquals("Wrong size", 3, i.getBytecodeLength(pc));
079 list.add(i);
080 pc += i.getBytecodeLength(pc);
081
082 i = AInstruction.makeInstruction(code, pc, pc, lnt);
083 assertEquals("Wrong instruction", WideInstruction.class, i.getClass());
084 assertEquals("Wrong size", 6, i.getBytecodeLength(pc));
085 list.add(i);
086 pc += i.getBytecodeLength(pc);
087
088 i = AInstruction.makeInstruction(code, pc, pc, lnt);
089 assertEquals("Wrong instruction", TableSwitchInstruction.class, i.getClass());
090 assertEquals("Wrong size", 25, i.getBytecodeLength(pc));
091 list.add(i);
092 pc += i.getBytecodeLength(pc);
093
094 i = AInstruction.makeInstruction(code, pc, pc, lnt);
095 assertEquals("Wrong instruction", LookupSwitchInstruction.class, i.getClass());
096 assertEquals("Wrong size", 28, i.getBytecodeLength(pc));
097 list.add(i);
098 pc += i.getBytecodeLength(pc);
099
100 i = AInstruction.makeInstruction(code, pc, pc, lnt);
101 assertEquals("Wrong instruction", GenericInstruction.class, i.getClass());
102 assertEquals("Wrong size", 1, i.getBytecodeLength(pc));
103 list.add(i);
104
105 LineNumberTable reverseLnt = new LineNumberTable(list);
106 pc = 0;
107 for(AInstruction instr : list) {
108 baos.write(instr.getBytecode(pc, reverseLnt));
109 pc += instr.getBytecodeLength(pc);
110 }
111
112 byte[] generatedCode = baos.toByteArray();
113 assertTrue("Generated bytecode not the same", Arrays.equals(code, generatedCode));
114 }
115
116 public void testCorrespondingLoad() {
117 AInstruction i;
118
119 i = new GenericInstruction(new byte[] {Opcode.ISTORE_0});
120 assertEquals("Wrong load for ISTORE_0", "iload_0 ", AInstruction.getCorrespondingLoad(i).toString());
121
122 i = new GenericInstruction(new byte[] {Opcode.ASTORE_3});
123 assertEquals("Wrong load for ASTORE_3", "aload_3 ", AInstruction.getCorrespondingLoad(i).toString());
124
125 i = new GenericInstruction(new byte[] {Opcode.IASTORE});
126 assertEquals("Wrong load for IASTORE", "iaload ", AInstruction.getCorrespondingLoad(i).toString());
127
128 i = new GenericInstruction(new byte[] {Opcode.SASTORE});
129 assertEquals("Wrong load for SASTORE", "saload ", AInstruction.getCorrespondingLoad(i).toString());
130
131 i = new GenericInstruction(new byte[] {Opcode.ISTORE, 5});
132 assertEquals("Wrong load for ISTORE", "iload 05 ", AInstruction.getCorrespondingLoad(i).toString());
133
134 i = new GenericInstruction(new byte[] {Opcode.ASTORE, 5});
135 assertEquals("Wrong load for ASTORE", "aload 05 ", AInstruction.getCorrespondingLoad(i).toString());
136
137 i = new WideInstruction(new byte[] {Opcode.ISTORE, 0, 5});
138 assertEquals("Wrong load for WIDE ISTORE", "wide iload 00 05 ", AInstruction.getCorrespondingLoad(i).toString());
139
140 i = new WideInstruction(new byte[] {Opcode.ASTORE, 0, 5});
141 assertEquals("Wrong load for WIDE ASTORE", "wide aload 00 05 ", AInstruction.getCorrespondingLoad(i).toString());
142 }
143
144 public void testCorrespondingStore() {
145 AInstruction i;
146
147 i = new GenericInstruction(new byte[] {Opcode.ILOAD_0});
148 assertEquals("Wrong store for ILOAD_0", "istore_0 ", AInstruction.getCorrespondingStore(i).toString());
149
150 i = new GenericInstruction(new byte[] {Opcode.ALOAD_3});
151 assertEquals("Wrong store for ALOAD_3", "astore_3 ", AInstruction.getCorrespondingStore(i).toString());
152
153 i = new GenericInstruction(new byte[] {Opcode.IALOAD});
154 assertEquals("Wrong store for IALOAD", "iastore ", AInstruction.getCorrespondingStore(i).toString());
155
156 i = new GenericInstruction(new byte[] {Opcode.SALOAD});
157 assertEquals("Wrong store for SALOAD", "sastore ", AInstruction.getCorrespondingStore(i).toString());
158
159 i = new GenericInstruction(new byte[] {Opcode.ILOAD, 5});
160 assertEquals("Wrong store for ILOAD", "istore 05 ", AInstruction.getCorrespondingStore(i).toString());
161
162 i = new GenericInstruction(new byte[] {Opcode.ALOAD, 5});
163 assertEquals("Wrong store for ALOAD", "astore 05 ", AInstruction.getCorrespondingStore(i).toString());
164
165 i = new WideInstruction(new byte[] {Opcode.ILOAD, 0, 5});
166 assertEquals("Wrong store for WIDE ILOAD", "wide istore 00 05 ", AInstruction.getCorrespondingStore(i).toString());
167
168 i = new WideInstruction(new byte[] {Opcode.ALOAD, 0, 5});
169 assertEquals("Wrong store for WIDE ALOAD", "wide astore 00 05 ", AInstruction.getCorrespondingStore(i).toString());
170 }
171 }