1 #!/usr/bin/env python 2 3 """ 4 Java bytecode conversion. Specification found at the following URL: 5 http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc.html 6 7 NOTE: Synchronized constructs are not actually supported. 8 """ 9 10 import dis # for access to Python bytecode values 11 12 # Bytecode production classes. 13 14 class BytecodeWriter: 15 def __init__(self): 16 self.loops = [] 17 self.jumps = [] 18 self.output = [] 19 self.position = 0 20 21 # Special methods. 22 23 def end_loop(self): 24 current_loop_start = self.loops.pop() 25 self.jump_absolute(current_loop_start) 26 self.output[current_loop_start + 1] = self.position 27 self.pop_block() 28 29 def jump_to_next(self, status): 30 self.jumps.push(self.position) 31 if status: 32 self.jump_if_true() 33 else: 34 self.jump_if_false() 35 36 def start_next(self): 37 current_jump_start = self.jumps.pop() 38 self.output[current_jump_start + 1] = self.position 39 40 # Normal bytecode generators. 41 42 def for_iter(self): 43 self.loops.push(self.position) 44 self.output.append(opmap["FOR_ITER"]) 45 self.output.append(None) # To be filled in later 46 self.position += 2 47 48 def jump_if_false(self, offset=None): 49 self.output.append(opmap["JUMP_IF_FALSE"]) 50 self.output.append(offset) # May be filled in later 51 self.position += 2 52 53 def jump_if_true(self, offset=None): 54 self.output.append(opmap["JUMP_IF_TRUE"]) 55 self.output.append(offset) # May be filled in later 56 self.position += 2 57 58 # Bytecode conversion. 59 60 class BytecodeReader: 61 def __init__(self, class_file): 62 self.class_file = class_file 63 self.position_mapping = {} 64 65 def process(self, code, program): 66 self.java_position = 0 67 while self.java_position < len(code): 68 self.position_mapping[self.java_position] = program.position 69 bytecode = ord(code[self.java_position]) 70 mnemonic, number_of_arguments = self.java_bytecodes[bytecode] 71 self.process_bytecode(mnemonic, number_of_arguments) 72 73 def process_bytecode(self, mnemonic, number_of_arguments): 74 if number_of_arguments is not None: 75 arguments = [] 76 for j in range(0, number_of_arguments): 77 arguments.append(ord(code[self.java_position + 1 + j])) 78 79 # Call the handler. 80 getattr(self, mnemonic)(arguments, program) 81 else: 82 # Call the handler. 83 number_of_arguments = getattr(self, mnemonic)(code[self.java_position+1:], program) 84 85 self.java_position = self.java_position + 1 + number_of_arguments 86 87 def nop(self, arguments, program): 88 pass 89 90 def aaload(self, arguments, program): 91 # NOTE: No type checking performed. 92 program.binary_subscr() 93 94 def aastore(self, arguments, program): 95 # NOTE: No type checking performed. 96 # Stack: arrayref, index, value 97 program.rot_three() # Stack: value, arrayref, index 98 program.store_subscr() 99 100 def aconst_null(self, arguments, program): 101 program.load_global(None) 102 103 def aload(self, arguments, program): 104 program.load_fast(arguments[0]) 105 106 def aload_0(self, arguments, program): 107 program.load_fast(0) 108 109 def aload_1(self, arguments, program): 110 program.load_fast(1) 111 112 def aload_2(self, arguments, program): 113 program.load_fast(2) 114 115 def aload_3(self, arguments, program): 116 program.load_fast(3) 117 118 def anewarray(self, arguments, program): 119 # NOTE: Does not raise NegativeArraySizeException. 120 # NOTE: Not using the index to type the list/array. 121 index = arguments[0] << 8 + arguments[1] 122 123 program.build_list() 124 program.setup_loop() 125 program.load_global("range") 126 program.load_const(0) # Stack: list, count, range, 0 127 program.rot_three() # Stack: list, 0, count, range 128 program.rot_three() # Stack: list, range, 0, count 129 program.call_function(2) # Stack: list, range_list 130 program.get_iter() # Stack: list, iter 131 program.for_iter() # Stack: list, iter, value 132 program.pop_top() # Stack: list, iter 133 program.rot_two() # Stack: iter, list 134 program.dup_top() # Stack: iter, list, list 135 program.load_attr("append") # Stack: iter, list, append 136 program.load_global(None) # Stack: iter, list, append, None 137 program.call_function(1) # Stack: iter, list, None 138 program.pop_top() # Stack: iter, list 139 program.rot_two() # Stack: list, iter 140 program.end_loop() # Back to for_iter above 141 142 def areturn(self, arguments, program): 143 program.return_value() 144 145 def arraylength(self, arguments, program): 146 program.load_global("len") # Stack: arrayref, len 147 program.rot_two() # Stack: len, arrayref 148 program.call_function(1) 149 150 def astore(self, arguments, program): 151 program.store_fast(arguments[0]) 152 153 def astore_0(self, arguments, program): 154 program.store_fast(0) 155 156 def astore_1(self, arguments, program): 157 program.store_fast(1) 158 159 def astore_2(self, arguments, program): 160 program.store_fast(2) 161 162 def astore_3(self, arguments, program): 163 program.store_fast(3) 164 165 def athrow(self, arguments, program): 166 # NOTE: NullPointerException not raised where null/None is found on the stack. 167 program.raise_varargs(1) 168 169 baload = aaload 170 bastore = aastore 171 172 def bipush(self, arguments, program): 173 program.load_const(arguments[0]) 174 175 caload = aaload 176 castore = aastore 177 178 def checkcast(self, arguments, program): 179 index = arguments[0] << 8 + arguments[1] 180 target_name = self.class_file.constants[index - 1].get_name() 181 target_components = target_name.split("/") 182 183 program.dup_top() # Stack: objectref, objectref 184 program.load_global("isinstance") # Stack: objectref, objectref, isinstance 185 program.rot_two() # Stack: objectref, isinstance, objectref 186 program.load_global(target_components[0]) 187 for target_component in target_components[1:]: 188 program.load_attr(target_component) 189 program.call_function(2) # Stack: objectref 190 191 def d2f(self, arguments, program): 192 pass 193 194 def d2i(self, arguments, program): 195 program.load_global("int") # Stack: value, int 196 program.rot_two() # Stack: int, value 197 program.call_function(1) # Stack: result 198 199 d2l = d2i # Preserving Java semantics 200 201 def dadd(self, arguments, program): 202 # NOTE: No type checking performed. 203 program.binary_add() 204 205 daload = aaload 206 dastore = aastore 207 208 def dcmpg(self, arguments, program): 209 # NOTE: No type checking performed. 210 program.compare_op(">") 211 212 def dcmpl(self, arguments, program): 213 # NOTE: No type checking performed. 214 program.compare_op("<") 215 216 def dconst_0(self, arguments, program): 217 program.load_const(0.0) 218 219 def dconst_1(self, arguments, program): 220 program.load_const(1.0) 221 222 def ddiv(self, arguments, program): 223 # NOTE: No type checking performed. 224 program.binary_divide() 225 226 dload = aload 227 dload_0 = aload_0 228 dload_1 = aload_1 229 dload_2 = aload_2 230 dload_3 = aload_3 231 232 def dmul(self, arguments, program): 233 # NOTE: No type checking performed. 234 program.binary_multiply() 235 236 def dneg(self, arguments, program): 237 # NOTE: No type checking performed. 238 program.unary_negative() 239 240 def drem(self, arguments, program): 241 # NOTE: No type checking performed. 242 program.binary_modulo() 243 244 dreturn = areturn 245 dstore = astore 246 dstore_0 = astore_0 247 dstore_1 = astore_1 248 dstore_2 = astore_2 249 dstore_3 = astore_3 250 251 def dsub(self, arguments, program): 252 # NOTE: No type checking performed. 253 program.binary_subtract() 254 255 def dup(self, arguments, program): 256 program.dup_top() 257 258 def dup_x1(self, arguments, program): 259 # Ignoring computational type categories. 260 program.dup_top() 261 program.rot_three() 262 263 def dup_x2(self, arguments, program): 264 # Ignoring computational type categories. 265 program.dup_top() 266 program.rot_four() 267 268 dup2 = dup # Ignoring computational type categories 269 dup2_x1 = dup_x1 # Ignoring computational type categories 270 dup2_x2 = dup_x2 # Ignoring computational type categories 271 272 def f2d(self, arguments, program): 273 pass # Preserving Java semantics 274 275 def f2i(self, arguments, program): 276 program.load_global("int") # Stack: value, int 277 program.rot_two() # Stack: int, value 278 program.call_function(1) # Stack: result 279 280 f2l = f2i # Preserving Java semantics 281 fadd = dadd 282 faload = daload 283 fastore = dastore 284 fcmpg = dcmpg 285 fcmpl = dcmpl 286 fconst_0 = dconst_0 287 fconst_1 = dconst_1 288 289 def fconst_2(self, arguments, program): 290 program.load_const(2.0) 291 292 fdiv = ddiv 293 fload = dload 294 fload_0 = dload_0 295 fload_1 = dload_1 296 fload_2 = dload_2 297 fload_3 = dload_3 298 fmul = dmul 299 fneg = dneg 300 frem = drem 301 freturn = dreturn 302 fstore = dstore 303 fstore_0 = dstore_0 304 fstore_1 = dstore_1 305 fstore_2 = dstore_2 306 fstore_3 = dstore_3 307 fsub = dsub 308 309 def getfield(self, arguments, program): 310 index = arguments[0] << 8 + arguments[1] 311 target_name = self.class_file.constants[index - 1].get_name() 312 # NOTE: Using the string version of the name which may contain incompatible characters. 313 program.load_attr(str(target_name)) 314 315 getstatic = getfield # Ignoring Java restrictions 316 317 def goto(self, arguments, program): 318 offset = arguments[0] << 8 + arguments[1] 319 java_absolute = self.java_position + offset 320 program.jump_absolute(self.position_mapping[java_absolute]) 321 322 def goto_w(self, arguments, program): 323 offset = arguments[0] << 24 + arguments[1] << 16 + arguments[2] << 8 + arguments[3] 324 java_absolute = self.java_position + offset 325 program.jump_absolute(self.position_mapping[java_absolute]) 326 327 def i2b(self, arguments, program): 328 pass 329 330 def i2c(self, arguments, program): 331 program.load_global("chr") # Stack: value, chr 332 program.rot_two() # Stack: chr, value 333 program.call_function(1) # Stack: result 334 335 def i2d(self, arguments, program): 336 program.load_global("float") # Stack: value, float 337 program.rot_two() # Stack: float, value 338 program.call_function(1) # Stack: result 339 340 i2f = i2d # Not distinguishing between float and double 341 342 def i2l(self, arguments, program): 343 pass # Preserving Java semantics 344 345 def i2s(self, arguments, program): 346 pass # Not distinguishing between int and short 347 348 iadd = fadd 349 iaload = faload 350 351 def iand(self, arguments, program): 352 # NOTE: No type checking performed. 353 program.binary_and() 354 355 iastore = fastore 356 357 def iconst_m1(self, arguments, program): 358 program.load_const(-1) 359 360 def iconst_0(self, arguments, program): 361 program.load_const(0) 362 363 def iconst_1(self, arguments, program): 364 program.load_const(1) 365 366 def iconst_2(self, arguments, program): 367 program.load_const(2) 368 369 def iconst_3(self, arguments, program): 370 program.load_const(3) 371 372 def iconst_4(self, arguments, program): 373 program.load_const(4) 374 375 def iconst_5(self, arguments, program): 376 program.load_const(5) 377 378 idiv = fdiv 379 380 def _if_xcmpx(self, arguments, program, op): 381 offset = arguments[0] << 8 + arguments[1] 382 java_absolute = self.java_position + offset 383 program.compare_op(op) 384 program.jump_to_next(0) # skip if false 385 program.goto(offset) 386 program.start_next() 387 388 def if_acmpeq(self, arguments, program): 389 # NOTE: No type checking performed. 390 self._if_xcmpx(arguments, program, "is") 391 392 def if_acmpne(self, arguments, program): 393 # NOTE: No type checking performed. 394 self._if_xcmpx(arguments, program, "is not") 395 396 def if_icmpeq(self, arguments, program): 397 # NOTE: No type checking performed. 398 self._if_xcmpx(arguments, program, "==") 399 400 def if_icmpne(self, arguments, program): 401 # NOTE: No type checking performed. 402 self._if_xcmpx(arguments, program, "!=") 403 404 def if_icmplt(self, arguments, program): 405 # NOTE: No type checking performed. 406 self._if_xcmpx(arguments, program, "<") 407 408 def if_icmpge(self, arguments, program): 409 # NOTE: No type checking performed. 410 self._if_xcmpx(arguments, program, ">=") 411 412 def if_icmpgt(self, arguments, program): 413 # NOTE: No type checking performed. 414 self._if_xcmpx(arguments, program, ">") 415 416 def if_icmple(self, arguments, program): 417 # NOTE: No type checking performed. 418 self._if_xcmpx(arguments, program, "<=") 419 420 def ifeq(self, arguments, program): 421 # NOTE: No type checking performed. 422 program.load_const(0) 423 self._if_xcmpx(arguments, program, "==") 424 425 def ifne(self, arguments, program): 426 # NOTE: No type checking performed. 427 program.load_const(0) 428 self._if_xcmpx(arguments, program, "!=") 429 430 def iflt(self, arguments, program): 431 # NOTE: No type checking performed. 432 program.load_const(0) 433 self._if_xcmpx(arguments, program, "<") 434 435 def ifge(self, arguments, program): 436 # NOTE: No type checking performed. 437 program.load_const(0) 438 self._if_xcmpx(arguments, program, ">=") 439 440 def ifgt(self, arguments, program): 441 # NOTE: No type checking performed. 442 program.load_const(0) 443 self._if_xcmpx(arguments, program, ">") 444 445 def ifle(self, arguments, program): 446 # NOTE: No type checking performed. 447 program.load_const(0) 448 self._if_xcmpx(arguments, program, "<=") 449 450 def ifnonnull(self, arguments, program): 451 # NOTE: No type checking performed. 452 program.load_const(None) 453 self._if_xcmpx(arguments, program, "is not") 454 455 def ifnull(self, arguments, program): 456 # NOTE: No type checking performed. 457 program.load_const(None) 458 self._if_xcmpx(arguments, program, "is") 459 460 def iinc(self, arguments, program): 461 # NOTE: No type checking performed. 462 program.load_fast(arguments[0]) 463 program.load_const(arguments[1]) 464 program.binary_add() 465 466 iload = fload 467 iload_0 = fload_0 468 iload_1 = fload_1 469 iload_2 = fload_2 470 iload_3 = fload_3 471 imul = fmul 472 ineg = fneg 473 474 def instanceof(self, arguments, program): 475 index = arguments[0] << 8 + arguments[1] 476 target_name = self.class_file.constants[index - 1].get_name() 477 target_components = target_name.split("/") 478 479 program.load_global("isinstance") # Stack: objectref, isinstance 480 program.rot_two() # Stack: isinstance, objectref 481 program.load_global(target_components[0]) 482 for target_component in target_components[1:]: 483 program.load_attr(target_component) 484 program.call_function(2) # Stack: result 485 486 def _invoke(self, target_name, program): 487 program.rot_two() # Stack: tuple, objectref 488 # NOTE: Using the string version of the name which may contain incompatible characters. 489 program.load_attr(str(target_name)) # Stack: tuple, method 490 program.rot_two() # Stack: method, tuple 491 program.load_global("apply") # Stack: method, tuple, apply 492 program.rot_three() # Stack: apply, method, tuple 493 program.call_function(2) 494 495 def invokeinterface(self, arguments, program): 496 # NOTE: This implementation does not perform the necessary checks for 497 # NOTE: signature-based polymorphism. 498 # NOTE: Java rules not specifically obeyed. 499 index = arguments[0] << 8 + arguments[1] 500 count = arguments[2] 501 target_name = self.class_file.constants[index - 1].get_name() 502 # Stack: objectref, arg1, arg2, ... 503 program.build_tuple(count) # Stack: objectref, tuple 504 self._invoke(target_name, program) 505 506 def invokespecial(self, arguments, program): 507 # NOTE: This implementation does not perform the necessary checks for 508 # NOTE: signature-based polymorphism. 509 # NOTE: Java rules not specifically obeyed. 510 index = arguments[0] << 8 + arguments[1] 511 target = self.class_file.constants[index - 1] 512 target_name = target.get_name() 513 # Get the number of parameters from the descriptor. 514 count = len(target.get_descriptor()[0]) 515 # Stack: objectref, arg1, arg2, ... 516 program.build_tuple(count) # Stack: objectref, tuple 517 self._invoke(target_name, program) 518 519 def invokestatic(self, arguments, program): 520 # NOTE: This implementation does not perform the necessary checks for 521 # NOTE: signature-based polymorphism. 522 # NOTE: Java rules not specifically obeyed. 523 index = arguments[0] << 8 + arguments[1] 524 target = self.class_file.constants[index - 1] 525 target_name = target.get_name() 526 # Get the number of parameters from the descriptor. 527 count = len(target.get_descriptor()[0]) 528 # Stack: arg1, arg2, ... 529 program.build_tuple(count) # Stack: tuple 530 # NOTE: Should probably use Python static methods. 531 program.load_name("self") # Stack: tuple, self 532 self._invoke(target_name, program) 533 534 invokevirtual = invokeinterface # Ignoring Java rules 535 536 def ior(self, arguments, program): 537 # NOTE: No type checking performed. 538 program.binary_or() 539 540 irem = frem 541 ireturn = freturn 542 543 def ishl(self, arguments, program): 544 # NOTE: No type checking performed. 545 # NOTE: Not verified. 546 program.binary_lshift() 547 548 def ishr(self, arguments, program): 549 # NOTE: No type checking performed. 550 # NOTE: Not verified. 551 program.binary_rshift() 552 553 istore = fstore 554 istore_0 = fstore_0 555 istore_1 = fstore_1 556 istore_2 = fstore_2 557 istore_3 = fstore_3 558 isub = fsub 559 iushr = ishr # Ignoring distinctions between arithmetic and logical shifts 560 561 def ishr(self, arguments, program): 562 # NOTE: No type checking performed. 563 program.binary_xor() 564 565 def jsr(self, arguments, program): 566 offset = arguments[0] << 8 + arguments[1] 567 java_absolute = self.java_position + offset 568 # NOTE: To be implemented. 569 570 def wide(self, code, program): 571 # NOTE: To be implemented. 572 return number_of_arguments 573 574 java_bytecodes = { 575 # code : (mnemonic, number of following bytes, change in stack) 576 0 : ("nop", 0), 577 1 : ("aconst_null", 0), 578 2 : ("iconst_m1", 0), 579 3 : ("iconst_0", 0), 580 4 : ("iconst_1", 0), 581 5 : ("iconst_2", 0), 582 6 : ("iconst_3", 0), 583 7 : ("iconst_4", 0), 584 8 : ("iconst_5", 0), 585 9 : ("lconst_0", 0), 586 10 : ("lconst_1", 0), 587 11 : ("fconst_0", 0), 588 12 : ("fconst_1", 0), 589 13 : ("fconst_2", 0), 590 14 : ("dconst_0", 0), 591 15 : ("dconst_1", 0), 592 16 : ("bipush", 1), 593 17 : ("sipush", 2), 594 18 : ("ldc", 1), 595 19 : ("ldc_w", 2), 596 20 : ("ldc2_w", 2), 597 21 : ("iload", 1), 598 22 : ("lload", 1), 599 23 : ("fload", 1), 600 24 : ("dload", 1), 601 25 : ("aload", 1), 602 26 : ("iload_0", 0), 603 27 : ("iload_1", 0), 604 28 : ("iload_2", 0), 605 29 : ("iload_3", 0), 606 30 : ("lload_0", 0), 607 31 : ("lload_1", 0), 608 32 : ("lload_2", 0), 609 33 : ("lload_3", 0), 610 34 : ("fload_0", 0), 611 35 : ("fload_1", 0), 612 36 : ("fload_2", 0), 613 37 : ("fload_3", 0), 614 38 : ("dload_0", 0), 615 39 : ("dload_1", 0), 616 40 : ("dload_2", 0), 617 41 : ("dload_3", 0), 618 42 : ("aload_0", 0), 619 43 : ("aload_1", 0), 620 44 : ("aload_2", 0), 621 45 : ("aload_3", 0), 622 46 : ("iaload", 0), 623 47 : ("laload", 0), 624 48 : ("faload", 0), 625 49 : ("daload", 0), 626 50 : ("aaload", 0), 627 51 : ("baload", 0), 628 52 : ("caload", 0), 629 53 : ("saload", 0), 630 54 : ("istore", 1), 631 55 : ("lstore", 1), 632 56 : ("fstore", 1), 633 57 : ("dstore", 1), 634 58 : ("astore", 1), 635 59 : ("istore_0", 0), 636 60 : ("istore_1", 0), 637 61 : ("istore_2", 0), 638 62 : ("istore_3", 0), 639 63 : ("lstore_0", 0), 640 64 : ("lstore_1", 0), 641 65 : ("lstore_2", 0), 642 66 : ("lstore_3", 0), 643 67 : ("fstore_0", 0), 644 68 : ("fstore_1", 0), 645 69 : ("fstore_2", 0), 646 70 : ("fstore_3", 0), 647 71 : ("dstore_0", 0), 648 72 : ("dstore_1", 0), 649 73 : ("dstore_2", 0), 650 74 : ("dstore_3", 0), 651 75 : ("astore_0", 0), 652 76 : ("astore_1", 0), 653 77 : ("astore_2", 0), 654 78 : ("astore_3", 0), 655 79 : ("iastore", 0), 656 80 : ("lastore", 0), 657 81 : ("fastore", 0), 658 82 : ("dastore", 0), 659 83 : ("aastore", 0), 660 84 : ("bastore", 0), 661 85 : ("castore", 0), 662 86 : ("sastore", 0), 663 87 : ("pop", 0), 664 88 : ("pop2", 0), 665 89 : ("dup", 0), 666 90 : ("dup_x1", 0), 667 91 : ("dup_x2", 0), 668 92 : ("dup2", 0), 669 93 : ("dup2_x1", 0), 670 94 : ("dup2_x2", 0), 671 95 : ("swap", 0), 672 96 : ("iadd", 0), 673 97 : ("ladd", 0), 674 98 : ("fadd", 0), 675 99 : ("dadd", 0), 676 100 : ("isub", 0), 677 101 : ("lsub", 0), 678 102 : ("fsub", 0), 679 103 : ("dsub", 0), 680 104 : ("imul", 0), 681 105 : ("lmul", 0), 682 106 : ("fmul", 0), 683 107 : ("dmul", 0), 684 108 : ("idiv", 0), 685 109 : ("ldiv", 0), 686 110 : ("fdiv", 0), 687 111 : ("ddiv", 0), 688 112 : ("irem", 0), 689 113 : ("lrem", 0), 690 114 : ("frem", 0), 691 115 : ("drem", 0), 692 116 : ("ineg", 0), 693 117 : ("lneg", 0), 694 118 : ("fneg", 0), 695 119 : ("dneg", 0), 696 120 : ("ishl", 0), 697 121 : ("lshl", 0), 698 122 : ("ishr", 0), 699 123 : ("lshr", 0), 700 124 : ("iushr", 0), 701 125 : ("lushr", 0), 702 126 : ("iand", 0), 703 127 : ("land", 0), 704 128 : ("ior", 0), 705 129 : ("lor", 0), 706 130 : ("ixor", 0), 707 131 : ("lxor", 0), 708 132 : ("iinc", 2), 709 133 : ("i2l", 0), 710 134 : ("i2f", 0), 711 135 : ("i2d", 0), 712 136 : ("l2i", 0), 713 137 : ("l2f", 0), 714 138 : ("l2d", 0), 715 139 : ("f2i", 0), 716 140 : ("f2l", 0), 717 141 : ("f2d", 0), 718 142 : ("d2i", 0), 719 143 : ("d2l", 0), 720 144 : ("d2f", 0), 721 145 : ("i2b", 0), 722 146 : ("i2c", 0), 723 147 : ("i2s", 0), 724 148 : ("lcmp", 0), 725 149 : ("fcmpl", 0), 726 150 : ("fcmpg", 0), 727 151 : ("dcmpl", 0), 728 152 : ("dcmpg", 0), 729 153 : ("ifeq", 2), 730 154 : ("ifne", 2), 731 155 : ("iflt", 2), 732 156 : ("ifge", 2), 733 157 : ("ifgt", 2), 734 158 : ("ifle", 2), 735 159 : ("if_icmpeq", 2), 736 160 : ("if_icmpne", 2), 737 161 : ("if_icmplt", 2), 738 162 : ("if_icmpge", 2), 739 163 : ("if_icmpgt", 2), 740 164 : ("if_icmple", 2), 741 165 : ("if_acmpeq", 2), 742 166 : ("if_acmpne", 2), 743 167 : ("goto", 2), 744 168 : ("jsr", 2), 745 169 : ("ret", 1), 746 170 : ("tableswitch", None), # variable number of arguments 747 171 : ("lookupswitch", None), # variable number of arguments 748 172 : ("ireturn", 0), 749 173 : ("lreturn", 0), 750 174 : ("freturn", 0), 751 175 : ("dreturn", 0), 752 176 : ("areturn", 0), 753 177 : ("return", 0), 754 178 : ("getstatic", 2), 755 179 : ("putstatic", 2), 756 180 : ("getfield", 2), 757 181 : ("putfield", 2), 758 182 : ("invokevirtual", 2), 759 183 : ("invokespecial", 2), 760 184 : ("invokestatic", 2), 761 185 : ("invokeinterface", 4), 762 187 : ("new", 2), 763 188 : ("newarray", 1), 764 189 : ("anewarray", 2), 765 190 : ("arraylength", 0), 766 191 : ("athrow", 0), 767 192 : ("checkcast", 2), 768 193 : ("instanceof", 2), 769 194 : ("monitorenter", 0), 770 195 : ("monitorexit", 0), 771 196 : ("wide", None), # 3 or 5 arguments, stack changes according to modified element 772 197 : ("multianewarray", 3), 773 198 : ("ifnull", 2), 774 199 : ("ifnonnull", 2), 775 200 : ("goto_w", 4), 776 201 : ("jsr_w", 4), 777 } 778 779 if __name__ == "__main__": 780 import sys 781 from classfile import ClassFile 782 f = open(sys.argv[1]) 783 c = ClassFile(f.read()) 784 785 # vim: tabstop=4 expandtab shiftwidth=4