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 }