1 34 package jarg; 35 36 import java.io.IOException ; 37 38 import org.apache.bcel.classfile.*; 39 import org.apache.bcel.generic.*; 40 import org.apache.bcel.Constants; 41 import org.apache.bcel.util.*; 42 43 49 class OpecodeCounter { 50 static int countOpcode(byte[] code) { 51 int count = 0; 52 boolean wide = false; 53 ByteSequence stream = new ByteSequence(code); 54 55 try { 56 for (int i=0; stream.available() > 0; count++) { 57 wide = fetchOpcode(stream, wide); 58 } 59 } catch(IOException ex) { 60 ex.printStackTrace(); 61 throw new ClassFormatError ("Byte code error: " + ex); 62 } 63 64 return count; 65 } 66 67 private static final boolean fetchOpcode(ByteSequence bytes, boolean wide) throws IOException { 68 short opcode = (short)bytes.readUnsignedByte(); 69 int default_offset=0, low, high, npairs; 70 int index, vindex, constant; 71 int[] match, jump_table; 72 int no_pad_bytes=0, offset; 73 74 if ((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { 77 int remainder = bytes.getIndex() % 4; 78 no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; 79 80 for (int i=0; i < no_pad_bytes; i++) { 81 byte b = bytes.readByte(); 82 if (b != 0) { 83 System.err.println("Warning: Padding byte != 0 in " + 84 Constants.OPCODE_NAMES[opcode] + ":" + b); 85 } 86 } 87 88 default_offset = bytes.readInt(); 90 } 91 92 switch(opcode) { 93 case Constants.TABLESWITCH: 95 low = bytes.readInt(); 96 high = bytes.readInt(); 97 98 for (int i=0; i < (high - low + 1); i++) { 99 bytes.readInt(); 100 } 101 break; 102 103 case Constants.LOOKUPSWITCH: { 105 npairs = bytes.readInt(); 106 offset = bytes.getIndex() - 8 - no_pad_bytes - 1; 107 108 for (int i=0; i < npairs; i++) { 109 bytes.readInt(); bytes.readInt(); } 112 } 113 break; 114 115 case Constants.GOTO: case Constants.IFEQ: case Constants.IFGE: case Constants.IFGT: 117 case Constants.IFLE: case Constants.IFLT: case Constants.JSR: case Constants.IFNE: 118 case Constants.IFNONNULL: case Constants.IFNULL: case Constants.IF_ACMPEQ: 119 case Constants.IF_ACMPNE: case Constants.IF_ICMPEQ: case Constants.IF_ICMPGE: case Constants.IF_ICMPGT: 120 case Constants.IF_ICMPLE: case Constants.IF_ICMPLT: case Constants.IF_ICMPNE: 121 bytes.readShort(); 122 break; 123 124 case Constants.GOTO_W: case Constants.JSR_W: 126 bytes.readInt(); 127 break; 128 129 case Constants.ALOAD: case Constants.ASTORE: case Constants.DLOAD: case Constants.DSTORE: case Constants.FLOAD: 131 case Constants.FSTORE: case Constants.ILOAD: case Constants.ISTORE: case Constants.LLOAD: case Constants.LSTORE: 132 case Constants.RET: 133 if (wide) { 134 vindex = bytes.readUnsignedShort(); 135 wide=false; } else { 137 vindex = bytes.readUnsignedByte(); 138 } 139 break; 140 141 146 case Constants.WIDE: 147 wide = true; 148 break; 149 150 case Constants.NEWARRAY: 152 bytes.readByte(); 153 break; 154 155 case Constants.GETFIELD: case Constants.GETSTATIC: case Constants.PUTFIELD: case Constants.PUTSTATIC: 157 index = bytes.readUnsignedShort(); 158 break; 159 160 case Constants.NEW: 162 case Constants.CHECKCAST: 163 case Constants.INSTANCEOF: 164 index = bytes.readUnsignedShort(); 165 break; 166 167 case Constants.INVOKESPECIAL: case Constants.INVOKESTATIC: case Constants.INVOKEVIRTUAL: 169 index = bytes.readUnsignedShort(); 170 break; 171 172 case Constants.INVOKEINTERFACE: 173 index = bytes.readUnsignedShort(); 174 int nargs = bytes.readUnsignedByte(); bytes.readUnsignedByte(); break; 177 178 case Constants.LDC_W: case Constants.LDC2_W: 180 index = bytes.readUnsignedShort(); 181 break; 182 183 case Constants.LDC: 184 index = bytes.readUnsignedByte(); 185 break; 186 187 case Constants.ANEWARRAY: 189 index = bytes.readUnsignedShort(); 190 break; 191 192 case Constants.MULTIANEWARRAY: { 194 index = bytes.readUnsignedShort(); 195 int dimensions = bytes.readUnsignedByte(); 196 } 197 break; 198 199 case Constants.IINC: 201 if (wide) { 202 vindex = bytes.readUnsignedShort(); 203 constant = bytes.readShort(); 204 wide = false; 205 } else { 206 vindex = bytes.readUnsignedByte(); 207 constant = bytes.readByte(); 208 } 209 break; 210 211 default: 212 if (Constants.NO_OF_OPERANDS[opcode] > 0) { 213 for (int i=0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { 214 switch(Constants.TYPE_OF_OPERANDS[opcode][i]) { 215 case Constants.T_BYTE: bytes.readByte(); break; 216 case Constants.T_SHORT: bytes.readShort(); break; 217 case Constants.T_INT: bytes.readInt(); break; 218 default: System.err.println("Unreachable default case reached!"); 220 System.exit(-1); 221 } 222 } 223 } 224 } 225 return wide; 226 } 227 } 228 | Popular Tags |