1 19 package org.netbeans.modules.java.source.usages; 20 21 import java.util.Iterator ; 22 import org.netbeans.modules.classfile.ByteCodes; 23 24 28 public class BytecodeDecoder implements Iterator <byte[]>, Iterable <byte[]> { 29 30 static final int opcodeLengths[] = { 31 1, 32 1, 33 1, 34 1, 35 1, 36 1, 37 1, 38 1, 39 1, 40 1, 41 1, 42 1, 43 1, 44 1, 45 1, 46 1, 47 2, 48 3, 49 2, 50 3, 51 3, 52 2, 53 2, 54 2, 55 2, 56 2, 57 1, 58 1, 59 1, 60 1, 61 1, 62 1, 63 1, 64 1, 65 1, 66 1, 67 1, 68 1, 69 1, 70 1, 71 1, 72 1, 73 1, 74 1, 75 1, 76 1, 77 1, 78 1, 79 1, 80 1, 81 1, 82 1, 83 1, 84 1, 85 2, 86 2, 87 2, 88 2, 89 2, 90 1, 91 1, 92 1, 93 1, 94 1, 95 1, 96 1, 97 1, 98 1, 99 1, 100 1, 101 1, 102 1, 103 1, 104 1, 105 1, 106 1, 107 1, 108 1, 109 1, 110 1, 111 1, 112 1, 113 1, 114 1, 115 1, 116 1, 117 1, 118 1, 119 1, 120 1, 121 1, 122 1, 123 1, 124 1, 125 1, 126 1, 127 1, 128 1, 129 1, 130 1, 131 1, 132 1, 133 1, 134 1, 135 1, 136 1, 137 1, 138 1, 139 1, 140 1, 141 1, 142 1, 143 1, 144 1, 145 1, 146 1, 147 1, 148 1, 149 1, 150 1, 151 1, 152 1, 153 1, 154 1, 155 1, 156 1, 157 1, 158 1, 159 1, 160 1, 161 1, 162 1, 163 3, 164 1, 165 1, 166 1, 167 1, 168 1, 169 1, 170 1, 171 1, 172 1, 173 1, 174 1, 175 1, 176 1, 177 1, 178 1, 179 1, 180 1, 181 1, 182 1, 183 1, 184 3, 185 3, 186 3, 187 3, 188 3, 189 3, 190 3, 191 3, 192 3, 193 3, 194 3, 195 3, 196 3, 197 3, 198 3, 199 3, 200 2, 201 99, 202 99, 203 1, 204 1, 205 1, 206 1, 207 1, 208 1, 209 3, 210 3, 211 3, 212 3, 213 3, 214 3, 215 3, 216 5, 217 0, 218 3, 219 2, 220 3, 221 1, 222 1, 223 3, 224 3, 225 1, 226 1, 227 0, 228 4, 229 3, 230 3, 231 5, 232 5, 233 1, 234 2, 235 3, 236 3, 237 3, 238 3, 239 3, 240 3, 241 3, 242 3, 243 3, 244 3, 245 3, 246 3, 247 3, 248 3, 249 5, 250 3, 251 3, 252 3, 253 3, 254 4, 255 3, 256 3, 257 3, 258 3, 259 3, 260 1, 261 1, 262 -1, 263 -1, 264 -1, 265 -1, 266 -1, 267 -1, 268 -1, 269 -1, 270 -1, 271 -1, 272 -1, 273 -1, 274 -1, 275 -1, 276 -1, 277 -1, 278 -1, 279 -1, 280 -1, 281 -1, 282 -1, 283 -1, 284 -1, 285 -1, 286 -1, 287 }; 288 289 private byte[] code; 290 291 int currentIndex; 292 293 294 public BytecodeDecoder( byte[] code ) { 295 this.code = code; 296 this.currentIndex = 0; 297 } 298 299 300 public Iterator <byte[]> iterator() { 301 return this; 302 } 303 304 305 306 public boolean hasNext() { 307 if ( currentIndex < code.length ) { 308 return true; 309 } 310 if ( currentIndex != code.length ) { 311 throw new IllegalStateException ( "Bad end " + currentIndex + " vs. " + code.length ); 312 } 313 return false; 314 315 } 316 317 public byte[] next() { 318 int opCode = toInt( code[currentIndex]); 319 int length; 320 321 if (opCode == 196) { 322 int wideInstruction = toInt( code[currentIndex+1]); 326 switch (wideInstruction) { 327 case 132: length = 6; 329 break; 330 case 21: case 22: case 23: case 24: case 25: case 54: case 55: case 56: case 57: case 58: case 169: length = 4; 342 break; 343 default: 344 throw new IllegalArgumentException ("Bad wide instruction at index " + currentIndex + " wide instruction " + wideInstruction); 345 } 346 } 347 else { 348 length = opcodeLengths[opCode]; 349 } 350 351 if ( length == -1 ) { 352 throw new IllegalArgumentException ( "Bad bytecode at index " + currentIndex + " opcode " + opCode); 353 } 354 355 if ( length == 99 ) { 356 switch ( opCode ) { 357 case ByteCodes.bc_lookupswitch: { 358 int padd = 4 - ( currentIndex % 4 ); 359 int start = currentIndex + padd + 4; 360 int npairs = toInt(code[start], code[start + 1], code[start + 2], code[start + 3] ); 361 length = padd + 8 + npairs * 8; 362 367 break; 368 } 369 case ByteCodes.bc_tableswitch: { 370 int padd = 4 - ( currentIndex % 4 ); 371 int start = currentIndex + padd + 4; 372 int low = toInt(code[start], code[start + 1], code[start + 2], code[start + 3] ); 373 int high = toInt(code[start + 4], code[start + 5], code[start + 6], code[start + 7] ); 374 length = padd + 12 + (high - low + 1) * 4; 375 376 385 break; 386 } 387 default: 388 throw new IllegalArgumentException ( "Bad bytecode at index " + currentIndex ); 389 } 390 } 391 392 byte currCode[] = new byte[length]; 393 for( int i = 0; i < length; i++ ) { 394 currCode[i] = code[ currentIndex + i ]; 395 } 396 397 currentIndex += length; 398 399 return currCode; 400 } 401 402 public void remove() { 403 throw new UnsupportedOperationException ( "Byte code is read only" ); 404 } 405 406 static int toInt( byte b ) { 407 return ((int)b) & 0xFF; 408 } 409 410 static int toInt( byte b1, byte b2 ) { 411 return ( (toInt(b1) << 8) | toInt(b2) ); 412 } 413 414 static int toInt( byte b1, byte b2, byte b3, byte b4 ) { 415 return (toInt(b1) << 24) | (toInt(b2) << 16) | (toInt(b3) << 8) | toInt(b4); 416 } 417 418 } 419 | Popular Tags |