| 1 30 31 package jbet; 32 import java.io.*; 33 import java.util.*; 34 35 57 58 public class Snippit { 59 60 public static String JbetLogFacility = "snippit"; 61 62 Instruction head, tail; 63 public Vector exVector; public Vector lvVector; public Vector lnVector; 67 68 70 71 int codelength; 72 Instruction [] pc2instr; 73 boolean stale; 74 boolean 75 emptyLocalTable = false, 76 emptyLineTable = false; 77 78 79 ExceptionRec findExceptionRec(Instruction instr, Type throwType) throws ClassFileException { 80 for (int i = 0; i < exVector.size(); i++) { 81 ExceptionRec ex = exAt(i); 82 Type catchType = new Type(ex.catchType, 0); 83 if (!throwType.isa(catchType)) continue; 84 for (Instruction j = ex.start.instr;; j = j.next) { 85 if (j == instr) return ex; 86 if (j == ex.end.instr) break; 87 } 88 } 89 return null; 90 } 91 92 94 95 public InstrEnum instrs() { 96 return new InstrEnum(head); 97 } 98 99 101 102 public void addLinesAsPCs(ConstantPool cp) { 103 resolveConstants(cp); 104 for (Instruction instr = head; instr != null; instr = instr.next) { 105 int pc = instr.pc(); 106 lnVector.addElement( new LineNumRec(instr, pc) ); 107 } 108 } 109 110 void relocate (Hashtable subs) { 111 for (Instruction instr = head; instr != null; instr = instr.next) { 112 if (instr.usesClass() || instr.usesMethod() || instr.usesField()) 113 instr.setClassRef( Util.relocate(instr.classRef(), subs) ); 114 115 if (instr.usesMethod()) 116 instr.setDescriptor( instr.descriptor().relocate_new(subs) ); 117 118 if (instr.usesField()) 119 instr.setType( instr.type().relocate_new(subs) ); 120 } 121 } 122 123 void setPcs() { 124 int i = 0; 125 for (Instruction instr = head; instr != null; instr = instr.next) 126 instr.setPc( i++ ); 127 } 128 129 131 public Snippit (Snippit s) { 132 head = tail = null; 133 134 Instruction [] pc2instrTemp = null; 135 if (s.pc2instr != null) { 136 codelength = s.codelength; 137 pc2instrTemp = new Instruction [ codelength ]; 138 } 139 else 140 pc2instrTemp = new Instruction [ s.maxcodesize() ]; 141 142 Vector ceVector = new Vector(); 143 int index = 0; 144 Instruction next; 145 for (Instruction instr = s.head; instr != null; instr = next) { 146 next = instr.next; 147 instr.setIndex(index++); 148 instr = instr.dup(); 149 pc2instrTemp[ instr.pc() ] = instr; 150 ceVector.addElement(instr); 151 push(instr); 152 } 153 pc2instr = pc2instrTemp; 154 155 exVector = new Vector( s.exVector.size() ); 156 lvVector = new Vector( s.lvVector.size() ); 157 lnVector = new Vector( s.lnVector.size() ); 158 159 for (int i = 0; i < ceVector.size(); i++) { 160 Instruction instr = (Instruction) ceVector.elementAt(i); 161 if (instr.usesBranch()) 162 instr.branchTarget().instr = (Instruction) ceVector.elementAt 163 (instr.branchTarget().instr.index()); 164 if (instr.isSwitch()) { 165 BranchTarget [] sa = instr.switchArray(); 166 for (int j = 0 ; j < sa.length; j++) 167 sa[j].instr = (Instruction) ceVector.elementAt( sa[j].instr.index()); 168 } 169 } 170 171 for (int i = 0; i < s.exVector.size(); i++) { 172 ExceptionRec ex = s.exAt(i); 173 exVector.addElement( new ExceptionRec 174 ( (Instruction) ceVector.elementAt (ex.start.instr.index()), 175 (Instruction) ceVector.elementAt (ex.end.instr.index()), 176 (Instruction) ceVector.elementAt (ex.handler.instr.index()), 177 ex.catchType) );; 178 } 179 180 for (int i = 0; i < s.lnVector.size(); i++) { 181 LineNumRec ln = s.lnAt(i); 182 lnVector.addElement( new LineNumRec( (Instruction) ceVector.elementAt 183 (ln.start.instr.index()), ln.lineNumber )); 184 } 185 186 187 for (int i = 0; i < s.lvVector.size(); i++) { 188 LocalVarRec lv = s.lvAt(i); 189 lvVector.addElement( new LocalVarRec 190 ( (Instruction) ceVector.elementAt (lv.start.instr.index()), 191 (Instruction) ceVector.elementAt (lv.end.instr.index()), 192 lv.name, lv.descriptor, lv.index ) ); 193 } 194 } 195 196 197 198 199 public Snippit () { 200 head = tail = null; 201 exVector = new Vector(); 202 lvVector = new Vector(); 203 lnVector = new Vector(); 204 } 205 206 void resolveConstants (ConstantPool constantPool) { 207 for (Instruction instr = head; instr != null; instr = instr.next) 208 instr.resolveConstants(constantPool); 209 for (int i = 0; i < lvVector.size(); i++) 210 ((LocalVarRec)lvVector.elementAt(i)).resolveConstants(constantPool); 211 for (int i = 0; i < exVector.size(); i++) 212 ((ExceptionRec)exVector.elementAt(i)).resolveConstants(constantPool); 213 resolveBranches(); 214 } 215 216 217 218 void addLines (LineNumRec [] lines) 219 throws ClassFileException { 220 221 if (lines != null) { 222 if (lines.length == 0) 223 emptyLineTable = true; 224 lnVector.ensureCapacity(lines.length); 225 for (int i = 0; i < lines.length; i++) { 226 lines[i].start.instr = pc2instr[ lines[i].start.offset ]; 227 lnVector.addElement (lines[i]); 228 } 229 } 230 } 231 232 233 234 void addLocals(LocalVarRec [] locals, ConstantPool constantPool) 235 throws ClassFileException { 236 237 if (locals != null) { 238 if (locals.length == 0) 239 emptyLocalTable = true; 240 lvVector.ensureCapacity(locals.length); 241 for (int i = 0; i < locals.length; i++) { 242 LocalVarRec rec = locals[i]; 243 rec.start.instr = pc2instr[ rec.start.offset ]; 244 if (rec.start.offset + rec.length == codelength) 245 rec.end.instr = tail; 246 else { 247 rec.end.instr = pc2instr[ rec.start.offset + rec.length ].prev; 248 if (rec.end.instr == null) throw new ClassFileException 249 ("end marker points to first instruction"); 250 } 251 lvVector.addElement (rec); 252 } 253 } 254 } 255 256 257 258 259 Snippit (byte [] code, ExceptionRec [] exceptions, ConstantPool constantPool) 260 throws ClassFileException, RuntimeException { 261 codelength = code.length; 262 263 head = tail = null; 264 exVector = new Vector (); 265 lvVector = new Vector (); 266 lnVector = new Vector (); 267 268 Instruction [] pc2instrTemp = new Instruction [ code.length ]; 269 270 DataInputStream dataIn = new DataInputStream ( new ByteArrayInputStream(code) ); 271 272 try { 273 for (int i = 0; i < code.length;) { 274 Instruction instr = new Instruction(); 275 int size = instr.readFile (dataIn, i, constantPool); 276 instr.setPc(i); 277 push(instr); 278 pc2instrTemp[i] = instr; 279 i += size; 280 281 } 282 } catch (IOException e) { 283 e.printStackTrace(Jbet.debug); 284 throw new RuntimeException ("caught an odd IOException: " + e.getMessage()); 285 } 286 pc2instr = pc2instrTemp; 287 288 for (int i = 0; i < exceptions.length; i++) { 289 ExceptionRec rec = exceptions[i]; 290 rec.start.instr = pc2instr[rec.start.offset]; 291 if (rec.end.offset == codelength) 292 rec.end.instr = tail; 293 else { 294 rec.end.instr = pc2instr[rec.end.offset].prev; 295 if (rec.end.instr == null) throw new ClassFileException 296 ("end marker points to first instruction"); 297 } 298 rec.handler.instr = pc2instr[rec.handler.offset]; 299 exVector.addElement(rec); 300 } 301 for (Instruction instr = head; instr != null; instr = instr.next) { 302 303 if (instr.usesBranch() ) { 304 308 int offset = instr.branchTarget().offset; 309 int tIndex = instr.pc() + offset; 310 Instruction target = pc2instr[tIndex]; 311 instr.branchTarget().instr = target; 312 } 313 314 if (instr.isSwitch() ) { 315 for (int i = 0; i < instr.switchArray().length; i++) { 316 int offset = instr.switchArray()[i].offset; 317 int tIndex = instr.pc() + offset; 318 Instruction target = pc2instr[tIndex]; 319 instr.switchArray()[i].instr = target; 320 } 321 } 322 } 323 } 324 325 333 334 void resolveBranches() { 335 if (unresolved.size() != 0) throw new IllegalStateException  336 ("this snippit contains unresolved branch targets: " + 337 ((BranchTarget)unresolved.elementAt(0)).label); 338 339 340 DataOutputStream devNull = new DataOutputStream( new DevNullStream() ); 341 codelength = 0; 342 for (Instruction instr = head; instr != null; instr = instr.next) { 343 instr.setPc( codelength ); 344 try { 345 codelength += instr.writeFile(devNull, codelength); 346 } catch (IOException e) { 347 throw new RuntimeException ("IOException caught from a DevNullStream!"); 348 } 349 } 350 351 while_loop: 352 while (true) { 353 for (Instruction instr = head; instr != null; instr = instr.next) { 354 if (instr.usesBranch()) { 355 int offset = instr.branchTarget().instr.pc() - instr.pc(); 356 instr.branchTarget().offset = offset; 357 if ((offset > Short.MAX_VALUE || offset < Short.MIN_VALUE) 358 && !instr.isLongjump()) { 359 instr.setLongjump(true); 360 for (Instruction i = instr.next; i != null; i = i.next) 361 i.setPc( i.pc() + 2 ); 362 codelength += 2; 363 continue while_loop; 364 } 365 } 366 if (instr.isSwitch()) 367 for (int j = 0; j < instr.switchArray().length; j++) { 368 instr.switchArray()[j].offset = 369 instr.switchArray()[j].instr.pc() - instr.pc(); 370 } 371 } 372 break while_loop; 373 } 374 375 for (int i = 0; i < exVector.size(); i++) { 376 ExceptionRec rec = (ExceptionRec) exVector.elementAt (i); 377 rec.start.offset = rec.start.instr.pc(); 378 if (rec.end.instr == tail) 379 rec.end.offset = codelength; 380 else 381 rec.end.offset = rec.end.instr.next.pc(); 382 rec.handler.offset = rec.handler.instr.pc(); 383 } 384 385 for (int i = 0; i < lnVector.size(); i++) { 386 LineNumRec rec = (LineNumRec) lnVector.elementAt(i); 387 rec.start.offset = rec.start.instr.pc(); 388 } 389 390 for (int i = 0; i < lvVector.size(); i++) { 391 LocalVarRec rec = (LocalVarRec) lvVector.elementAt(i); 392 rec.start.offset = rec.start.instr.pc(); 393 if (rec.end.instr == tail) 394 rec.length = codelength - rec.start.offset; 395 else 396 rec.length = rec.end.instr.next.pc() - rec.start.offset; 397 } 398 399 pc2instr = new Instruction [ codelength ]; 400 for (Instruction instr = head; instr != null; instr = instr.next) 401 pc2instr[ instr.pc() ] = instr; 402 } 403 404 405 406 407 void writeCodeAndExceptions(DataOutputStream dataOut) throws IOException { 408 409 if (codelength==0) 410 throw new IOException("attempt to write empty Snippit"); 411 412 dataOut.writeInt (codelength); 413 int index = 0; 414 for (Instruction instr = head; instr != null; instr = instr.next) 415 index += instr.writeFile( dataOut, index ); 416 417 dataOut.writeShort ( exVector.size() ); 418 for (int i=0; i < exVector.size(); i++) 419 ((ExceptionRec)exVector.elementAt(i)).writeFile( dataOut ); 420 } 421 422 423 boolean hasLocals() { 424 return lvVector.size() != 0 || emptyLocalTable; 425 } 426 427 428 boolean hasLineNums() { 429 return lnVector.size() != 0 || emptyLineTable; 430 } 431 432 433 434 void writeLineNums (DataOutputStream dataOut) throws IOException { 435 dataOut.writeShort ( lnVector.size() ); 436 for (int i = 0; i < lnVector.size(); i++) 437 ((LineNumRec)lnVector.elementAt(i)).writeFile (dataOut); 438 } 439 440 441 442 GenericAttribute genLineNumAttr(ConstantPool constantPool) { 443 if (lnVector.size() == 0 && !emptyLineTable) 444 return null; 445 GenericAttribute attr = new GenericAttribute ("LineNumberTable", 446 constantPool); 447 attr.writer = lineNumWriter(); 448 return attr; 449 } 450 451 452 453 AttributeWriter lineNumWriter() { 454 final int lnsize = lnVector.size(); 455 return new AttributeWriter() { 456 public void write (DataOutputStream dataOut) 457 throws IOException, RuntimeException { 458 dataOut.writeShort (lnsize); 459 for (int i = 0; i < lnsize; i++) 460 ((LineNumRec)lnVector.elementAt(i)).writeFile(dataOut); 461 } 462 public int size() { 463 return 2 + lnsize*4; 464 } 465 }; 466 } 467 468 469 int lineNumSize() { 470 return lnVector.size() * 4; 471 } 472 473 474 int localsSize() { 475 return lvVector.size() * 10; 476 } 477 478 479 int codeSize() { 480 return 4 + codelength; 481 } 482 483 484 int exceptionsSize() { 485 return 2 + 8*exVector.size(); 486 } 487 488 Instruction lookupPc(int pc) { 489 if (pc2instr == null) 490 throw new RuntimeException ("lookupPc called when pc2instr==null"); 491 else 492 return pc2instr[pc]; 493 } 494 495 496 void writeLocals(DataOutputStream dataOut) throws IOException { 497 dataOut.writeShort ( lvVector.size() ); 498 for (int i = 0; i < lvVector.size(); i++) 499 ((LocalVarRec)lvVector.elementAt(i)).writeFile (dataOut); 500 } 501 502 503 GenericAttribute genLocalsAttr(ConstantPool constantPool) { 504 if (lvVector.size() == 0 && !emptyLocalTable) 505 return null; 506 GenericAttribute attr = new GenericAttribute ("LocalVariableTable", 507 constantPool); 508 attr.writer = localsWriter(); 509 510 return attr; 511 } 512 513 514 AttributeWriter localsWriter() { 515 final int lvsize = lvVector.size(); 516 return new AttributeWriter() { 517 public void write (DataOutputStream dataOut) 518 throws IOException, RuntimeException { 519 dataOut.writeShort (lvsize); 520 for (int i = 0; i < lvsize; i++) 521 ((LocalVarRec)lvVector.elementAt(i)).writeFile(dataOut); 522 } 523 public int size() { 524 return 2 + lvsize*10; 525 } 526 }; 527 } 528 529 530 531 532 public ExceptionRec exAt (int i) { 533 return (ExceptionRec) exVector.elementAt(i); 534 } 535 536 public int numEx() { return exVector.size(); } 537 538 public LineNumRec lnAt (int i) { 539 return (LineNumRec) lnVector.elementAt(i); 540 } 541 542 public LocalVarRec lvAt (int i) { 543 return (LocalVarRec) lvVector.elementAt(i); 544 } 545 546 public Instruction first() { return head; }; 547 public Instruction last() { return tail; }; 548 549 void insertBefore(Instruction instr, Instruction newinst) { 550 pc2instr = null; 551 if (instr == head) 552 unshift(newinst); 553 else { 554 newinst.prev = instr.prev; 555 newinst.next = instr; 556 newinst.prev.next = newinst; 557 newinst.next.prev = newinst; 558 } 559 } 560 561 public boolean empty() { return head==null; } 562 563 568 public void insertAt(Instruction instr, Snippit snippit) { 569 pc2instr = null; 570 if (snippit.empty()) 571 return; 572 snippit.push( instr.dup() ); 573 instr.copy( snippit.shift_norec() ); 574 insertAfter(instr, snippit); 575 } 576 577 579 public void insertOver(Instruction instr, Snippit snippit) { 580 pc2instr = null; 581 if (snippit.empty()) 582 remove(instr); 583 instr.copy( snippit.shift_norec() ); 584 insertAfter(instr, snippit); 585 } 586 587 public void insertAfter(Instruction instr, Instruction newinst) { 588 pc2instr = null; 589 if (instr == tail) 590 push(newinst); 591 else { 592 newinst.prev = instr; 593 newinst.next = instr.next; 594 newinst.prev.next = newinst; 595 newinst.next.prev = newinst; 596 } 597 } 598 599 600 601 public void grabRecs(Snippit snippit) { 602 exVector.ensureCapacity ( exVector.size() + snippit.exVector.size() ); 603 lvVector.ensureCapacity ( lvVector.size() + snippit.lvVector.size() ); 604 lnVector.ensureCapacity ( lnVector.size() + snippit.lnVector.size() ); 605 for (int i = 0; i < snippit.exVector.size(); i++) 606 exVector.addElement( snippit.exVector.elementAt(i) ); 607 for (int i = 0; i < snippit.lvVector.size(); i++) 608 lvVector.addElement( snippit.lvVector.elementAt(i) ); 609 for (int i = 0; i < snippit.lnVector.size(); i++) 610 lnVector.addElement( snippit.lnVector.elementAt(i) ); 611 } 612 613 public void insertAfter(Instruction instr, Snippit snippit) { 614 pc2instr = null; 615 grabRecs(snippit); 616 Instruction next; 617 for (Instruction p = snippit.tail; p != null; p = next) { 618 next = p.prev; 619 insertAfter(instr, p); 620 } 621 } 622 623 public void insertBefore(Instruction instr, Snippit snippit) { 624 pc2instr = null; 625 grabRecs(snippit); 626 Instruction next; 627 for (Instruction p = snippit.head; p != null; p = next) { 628 next = p.next; 629 insertBefore(instr, p); 630 } 631 } 632 633 void redirect(Instruction from, Instruction to, BranchTarget bt) { 634 if (bt.instr == from) 635 bt.instr = to; 636 } 637 638 642 643 public void redirect(Instruction from, Instruction to) { 644 for(Instruction p = head; p != null; p = p.next) { 645 if (p.usesBranch()) 646 redirect(from, to, p.branchTarget()); 647 if (p.isSwitch()) 648 for (int j = 0; j < p.switchArray().length; j++) 649 redirect(from, to, p.switchArray()[j]); 650 } 651 for (int i = 0; i < exVector.size(); i++) { 652 redirect(from, to, exAt(i).start); 653 redirect(from, to, exAt(i).end); 654 redirect(from, to, exAt(i).handler); 655 } 656 for (int i = 0; i < lvVector.size(); i++) { 657 redirect(from, to, lvAt(i).start); 658 redirect(from, to, lvAt(i).end); 659 } 660 for (int i = 0; i < lnVector.size(); i++) 661 redirect(from, to, lnAt(i).start); 662 } 663 664 665 666 667 public void append (Snippit snippit) { 668 if (tail == null) { 669 grabRecs(snippit); 670 head = snippit.head; 671 tail = snippit.tail; 672 } else 673 insertAfter(tail, snippit); 674 } 675 676 677 public void prepend (Snippit snippit) { 678 if (head == null) { 679 grabRecs(snippit); 680 head = snippit.head; 681 tail = snippit.tail; 682 } else 683 insertBefore(head, snippit); 684 } 685 686 687 public void push(Instruction instr) { 688 pc2instr = null; 689 if (tail == null) { 690 head = tail = instr; 691 instr.next = instr.prev = null; 692 } else { 693 instr.next = null; 694 instr.prev = tail; 695 tail.next = instr; 696 tail = instr; 697 } 698 } 699 700 701 public void unshift(Instruction instr) { 702 pc2instr = null; 703 if (head == null) { 704 head = tail = instr; 705 instr.next = instr.prev = null; 706 } else { 707 instr.prev = null; 708 instr.next = head; 709 head.prev = instr; 710 head = instr; 711 } 712 } 713 714 715 public void remove(Instruction instr) { 716 pc2instr = null; 717 removeFromRecs(instr); 718 if (instr==head) 719 shift(); 720 else if (instr==tail) 721 pop(); 722 else { 723 instr.prev.next = instr.next; 724 instr.next.prev = instr.prev; 725 } 726 } 727 728 public Snippit splitAt (Instruction last) { 729 Snippit next = new Snippit(); 730 next.head = last.next; 731 next.tail = tail; 732 733 next.head.prev = null; 734 last.next = null; 736 tail = last; 737 tail.next = null; 738 739 return next; 740 } 741 742 void removeFromRecs (Instruction instr) { 743 for (int i = 0; i < lnVector.size(); i++) { 744 LineNumRec rec = lnAt(i); 745 if (rec.start.instr == instr) { 746 if (instr.next == null) 747 lnVector.removeElementAt(i); 748 else { 749 boolean keep = true; 750 for (int j = 0; j < lnVector.size() && keep; j++) 751 if (lnAt(j).start.instr == instr.next) 752 keep = false; 753 if (keep) 754 rec.start.instr = instr.next; 755 else 756 lnVector.removeElementAt(i); 757 } 758 } 759 } 760 761 } 762 763 public Instruction pop() throws ArrayIndexOutOfBoundsException { 764 if (tail == null) throw new ArrayIndexOutOfBoundsException  765 ("tried to pop an empty Snippit"); 766 removeFromRecs(tail); 767 return pop_norec(); 768 } 769 770 771 public Instruction pop_norec() throws ArrayIndexOutOfBoundsException { 772 pc2instr = null; 773 if (head == tail) 774 head = null; 775 Instruction ret = tail; 776 tail = ret.prev; 777 tail.next = null; 778 return ret; 779 } 780 781 public Instruction shift() throws ArrayIndexOutOfBoundsException { 782 if (head == null) 783 throw new ArrayIndexOutOfBoundsException  784 ("tried to shift an empty Snippit"); 785 removeFromRecs(head); 786 return shift_norec(); 787 } 788 789 790 public Instruction shift_norec() throws ArrayIndexOutOfBoundsException { 791 pc2instr = null; 792 if (tail == head) 793 tail = null; 794 Instruction ret = head; 795 head = ret.next; 796 if (head != null) 797 head.prev = null; 798 return ret; 799 } 800 801 public void comment (String s) { 802 if (!Jbet.compact) { 803 push ( new Instruction().setSpush(s)); 804 push ( new Instruction().setPop()); 805 } 806 } 807 808 814 815 public Snippit setDupX (Type t, int x) { 816 if (t.category() == 0) throw new 817 IllegalStateException ("dupX of category 0!"); 818 if (t.category() == 1) { 819 if (x == -1) { 820 push (new Instruction().setPop()); 821 } 822 else if (x > 2) { 823 push (new Instruction().setDup()); 824 if ((x & 1) == 0) { 825 push (new Instruction().setDup()); 826 } 827 828 for (int i = 0; i < ((x-1)>>1); i++) { 829 push (new Instruction().setDup2()); 830 } 831 } 832 else { 833 for (int i = 0; i < x; i++) 834 push (new Instruction().setDup()); 835 } 836 } 837 else { 838 if (x == -1) { 839 push (new Instruction().setPop2()); 840 } 841 for (int i = 0; i < x; i++) 842 push (new Instruction().setDup2()); 843 } 844 845 return this; 846 } 847 848 public Snippit setPopX (Type t, int x) { 849 int n = t.category() * x; 850 851 for (int i = 0; i < n >> 1; i++) 852 push (new Instruction().setPop2()); 853 854 if (n > 0 && (n & 1) != 0) { 855 push (new Instruction().setPop()); 856 } 857 858 return this; 859 } 860 861 862 public Snippit println (String s) { 863 push (new Instruction().setGetstatic ("java/lang/System", "out", Type.PRINTSTREAM)); 864 push (new Instruction().setSpush (s)); 865 push (new Instruction().setInvokeVirtual ("java/io/PrintStream", "println", new Descriptor (Type.STRING, Type.VOID))); 866 return this; 867 } 868 869 870 public Snippit println (Type t) { 871 t = t.compType(); 872 if (t.category() == 1) { 873 push (new Instruction().setDup()); 874 push (new Instruction().setGetstatic ("java/lang/System", "out", Type.PRINTSTREAM)); 875 push (new Instruction().setSwap ()); 876 push (new Instruction().setInvokeVirtual ("java/io/PrintStream", "println", new Descriptor (t, Type.VOID))); 877 } 878 else { 879 push (new Instruction().setDup2()); 880 push (new Instruction().setGetstatic ("java/lang/System", "out", Type.PRINTSTREAM)); 881 push (new Instruction().setDup_x2 ()); 882 push (new Instruction().setPop()); 883 push (new Instruction().setInvokeVirtual ("java/io/PrintStream", "println", new Descriptor (t, Type.VOID))); 884 } 885 return this; 886 } 887 888 public abstract static class Instructions 889 { 890 abstract void f (Snippit out); 891 Type type () { return Type.VOID; } 892 } 893 894 public static Instructions cString (final String s) { 895 return new Instructions() { 896 void f (Snippit out) { 897 out.push (new Instruction().setSpush (s)); 898 } 899 Type type() { return Type.STRING; } 900 }; 901 } 902 903 904 public Snippit println (Instructions[] strings) { 905 906 if (strings.length == 1) { 907 push (new Instruction().setGetstatic ("java/lang/System", "out", Type.PRINTSTREAM)); 908 strings[0].f (this); 909 push (new Instruction().setInvokeVirtual ("java/io/PrintStream", "println", 910 new Descriptor (strings[0].type(), Type.VOID))); 911 } 912 else { 913 push (new Instruction().setGetstatic ("java/lang/System", "out", Type.PRINTSTREAM)); 914 push (new Instruction().setNew ("java/lang/StringBuffer")); 915 push (new Instruction().setDup ()); 916 strings[0].f (this); 917 push (new Instruction().setInvokeSpecial ("java/lang/StringBuffer", "<init>", 918 new Descriptor (strings[0].type().compType(), Type.VOID))); 919 920 for (int i = 1; i < strings.length; i++) { 921 strings[i].f (this); 922 push (new Instruction().setInvokeVirtual ("java/lang/StringBuffer", "append", 923 new Descriptor (strings[i].type().compType(), Type.STRINGBUFFER))); 924 } 925 926 push (new Instruction().setInvokeVirtual ("java/lang/StringBuffer", "toString", new Descriptor (Type.STRING))); 927 push (new Instruction().setInvokeVirtual ("java/io/PrintStream", "println", new Descriptor (Type.STRING, Type.VOID))); 928 } 929 return this; 930 } 931 932 public Snippit println (Instructions a, Instructions b) { 933 Instructions[] A = new Instructions[2]; 934 A[0] = a; A[1] = b; 935 return println (A); 936 } 937 938 942 public void moveDown (Type top, Type[] ts) 943 { 944 int topc = top.category(); 945 int count = 0; 946 for (int i = 0; i < ts.length; i++) 947 count += ts[i].category(); 948 949 switch (count) { 950 case 1: 951 if (topc == 1) 952 push (new Instruction().setSwap()); 953 else { 954 push (new Instruction().setPop2()); 955 } 956 break; 957 958 case 2: 959 if (topc == 1) { 960 push (new Instruction().setPop()); 961 } else { 962 push (new Instruction().setPop2()); 963 } 964 break; 965 966 default: 967 throw new IllegalStateException ("moveDown isn't finished"); 968 } 969 } 970 971 972 973 void printExceptions (LineWriter out) { 974 int exsize = exVector.size(); 975 for (int i = 0; i < exsize; i++) 976 ((ExceptionRec)exVector.elementAt(i)).print(out); 977 } 978 979 void printLines (LineWriter out) { 980 int lnsize = lnVector.size(); 981 982 for (int i = 0; i < lnsize; i++) 983 out.println( "\t" + ((LineNumRec)lnVector.elementAt(i)).recString() ); 984 } 985 986 void printLocals (LineWriter out) { 987 int lvsize; 988 out.print(""); 989 lvsize = lvVector.size(); 990 991 for (int i = 0; i < lvsize; i++) 992 out.println( "\t" + ((LocalVarRec)lvVector.elementAt(i)).recString() ); 993 } 994 995 996 997 1002 void advanceLocals(Instruction instr, Hashtable locals) { 1003 for (int j = 0; j < lvVector.size(); j++) { 1004 LocalVarRec rec = (LocalVarRec) lvVector.elementAt(j); 1005 1006 if (rec.start.instr == instr || 1007 (instr.isStore() && instr.next == rec.start.instr)) 1008 locals.put( rec.integer(), rec ); 1009 1010 if (rec.end.instr.next == instr) { 1011 LocalVarRec curr = (LocalVarRec) locals.get(rec.integer()); 1012 if (curr == rec) 1013 locals.remove(rec.integer()); 1014 } 1015 } 1016 } 1017 1018 public void printCode (LineWriter out, boolean lines) { 1019 printCode (out, lines, false); 1020 } 1021 1022 public void printCode (LineWriter out, boolean lines, boolean counts) { 1023 int lvsize = lvVector.size(); 1024 int lnsize = lnVector.size(); 1025 1026 Hashtable locals = new Hashtable(); 1027 int line = -1; 1028 int n = 0; 1029 1030 for (Instruction instr = head; instr != null; instr = instr.next, n++) { 1031 if (instr.opCode() == Instruction.AOP_SPUSH && instr.next != null && 1033 instr.next.opCode() == Instruction.OP_POP) { 1034 out.print ("\t" + instr.pc()); 1035 if (lines) { 1036 out.print( "\t" ); 1037 if (line != -1) 1038 out.print( line ); 1039 } 1040 out.println("\t\t; " + instr.immediate_s()); 1041 instr = instr.next; 1042 n++; 1043 continue; 1044 } 1045 1046 advanceLocals(instr, locals); 1047 1048 if (lines) { 1049 for (int j = 0; j < lnsize; j++) { 1050 LineNumRec rec = (LineNumRec) lnVector.elementAt(j); 1051 if (rec.start.instr == instr) 1052 line = rec.lineNumber; 1053 } 1054 } 1055 1056 out.print( "\t" + instr.pc() ); 1057 if (lines) { 1058 out.print( "\t" ); 1059 if (line != -1) 1060 out.print( line ); 1061 } 1062 if (counts) { 1063 out.print ("\t"); 1064 out.print (n); 1065 } 1066 out.print( "\t" + instr.recString() ); 1067 1068 if (instr.usesLocals()) { 1069 int lvt = instr.lvtIndex(); 1070 LocalVarRec rec = (LocalVarRec) locals.get (new Integer (lvt)); 1071 if (rec != null) 1072 out.print (" " + rec.name + " " + rec.descriptor.toString() ); 1073 } 1074 1075 out.println(); 1076 } 1077 } 1078 1079 public int maxcodesize () 1080 { 1081 int size = 0; 1082 1083 for (Instruction instr = head; instr != null; instr = instr.next) 1084 size += instr.maxsize(); 1085 1086 return size; 1087 } 1088 1089 Hashtable labels = new Hashtable(); 1090 Vector unresolved = new Vector(); 1091 1092 1093 private String ins2lab(Hashtable tab, BranchTarget bt) { 1094 String ret = ins2lab(tab, bt.instr); 1095 return ret; 1096 } 1097 1098 1100 private String ins2lab(Hashtable tab, Instruction instr) { 1101 String label = (String ) tab.get(instr); 1102 if (label == null) { 1103 for (int i = 1;; i++) { 1104 label = ""+i; 1105 if (labels.get(label) == null) { 1106 labels.put(label, instr); 1107 break; 1108 } 1109 } 1110 tab.put(instr, label); 1111 } 1112 return label; 1113 } 1114 1115 1116 public void disassemble (LineWriter out, String prefix) { 1117 Hashtable tab = new Hashtable(); 1118 for (Enumeration e = labels.keys(); e.hasMoreElements();) { 1119 String label = (String ) e.nextElement(); 1120 Instruction instr = (Instruction) labels.get(label); 1121 tab.put(instr, label); 1122 } 1123 for (int i = 0; i < exVector.size(); i++) { 1124 ExceptionRec rec = exAt(i); 1125 out.println(prefix + ".exception " + ins2lab(tab, rec.start) + 1126 " " + ins2lab(tab, rec.end) + " " + rec.catchType 1127 + " " + ins2lab(tab, rec.handler)); 1128 } 1129 for (int i = 0; i < lvVector.size(); i++) { 1130 LocalVarRec rec = lvAt(i); 1131 out.println(prefix + ".local " + rec.index + " " + rec.name + " " 1132 + rec.descriptor + " " + ins2lab(tab, rec.start) + 1133 " " + ins2lab(tab, rec.end)); 1134 } 1135 1136 for (Instruction i = head; i != null; i = i.next) { 1137 if (i.usesBranch()) 1138 ins2lab(tab, i.branchTarget()); 1139 if (i.isSwitch()) 1140 for (int j = 0; j < i.switchArray().length; j++) 1141 ins2lab(tab,i.switchArray()[j]); 1142 } 1143 1144 for (Instruction i = head; i != null; i = i.next) { 1145 String label = (String ) tab.get(i); 1146 if (label != null) 1147 out.println(prefix + label + ":"); 1148 for (int j = 0; j < lnVector.size(); j++) 1149 if (lnAt(j).start.instr == i) 1150 out.println(prefix + ".line " + lnAt(j).lineNumber); 1151 if (i.usesBranch()) 1152 if (i.isSwitch()) { 1153 out.print(prefix + " " + i.recString(false) + " " + 1154 ins2lab(tab, i.branchTarget())); 1155 BranchTarget[] swa = i.switchArray(); 1156 if (i.opCode() == Instruction.OP_TABLESWITCH) 1157 for (int j = 0; j < swa.length; j++) 1158 out.print(" " + (i.immediate()+j) + ":" + ins2lab(tab,swa[j])); 1159 else 1160 for (int j = 0; j < swa.length; j++) 1161 out.print(" " + swa[j].key + ":" + ins2lab(tab,swa[j])); 1162 out.println(prefix); 1163 1164 } else 1165 out.println(prefix + " " + i.recString(false) + " " + 1166 ins2lab(tab, i.branchTarget())); 1167 else 1168 out.println(prefix + " " + i.recString()); 1169 } 1170 } 1171 1172 1173 1174 1175 Instruction getLabel(String label) { 1176 return (Instruction) labels.get(label); 1177 } 1178 1179 1180 void defineLabel(String label, Instruction instr) { 1181 for (int i = 0; i < unresolved.size();) { 1182 BranchTarget bt = (BranchTarget) unresolved.elementAt(i); 1183 if (bt.label.equals(label)) { 1184 bt.label = null; 1185 bt.instr = instr; 1186 unresolved.removeElementAt(i); 1187 } else 1188 i++; 1189 } 1190 labels.put(label, instr); 1191 } 1192 1193 1194 1195 public void assemble (String str) throws ClassFileException { 1196 assemble(new Lexer(new StringReader(str), "string"), null, 0, null); 1197 } 1198 1199 static final int INS_AT = 1; 1200 static final int INS_AFTER = 2; 1201 static final int INS_BEFORE = 3; 1202 static final int INS_OVER = 4; 1203 1204 1205 private void setupBranchTarget(BranchTarget bt, String label) { 1206 Instruction instr = getLabel(label); 1207 if (instr == null) { 1208 bt.label = label; 1209 unresolved.addElement(bt); 1210 } else 1211 bt.instr = instr; 1212 } 1213 1214 1215 static String parse_label(Lexer lexer) { 1216 lexer.push(Lexer.ST_ASM); 1217 String s = lexer.match(Token.TAG).text; 1218 lexer.pop(); 1219 return s; 1220 } 1221 1222 1232 1233 public void assemble (Lexer lexer, Instruction place, int state, MethodInfo mi) throws ClassFileException { 1234 Token tok; 1235 Vector curr = new Vector(); 1236 lexer.push(Lexer.ST_ASM); 1237 1238 while (true) { 1239 lexer.state = Lexer.ST_ASM; 1240 while ( lexer.peek().type == ';' ) lexer.read(); 1241 tok = lexer.peek(); 1242 lexer.state = Lexer.ST_ASM_ARG; 1243 if (tok.type == Token.LABEL) { 1244 lexer.read(); 1245 String label = tok.text; 1246 if ( labels.get(label) != null ) 1247 lexer.die("label allready defined: "+label); 1248 curr.addElement(label); 1249 continue; 1250 } 1251 if (tok.type == Token.TAG) { 1252 if (mi != null) { 1253 if (tok.text.equals(".maxstack")) { 1254 lexer.read(); 1255 int i = lexer.parse_int(); 1256 lexer.term(); 1257 mi.maxStack = i; 1258 continue; 1259 } 1260 if (tok.text.equals(".maxlocals")) { 1261 lexer.read(); 1262 int i = lexer.parse_int(); 1263 lexer.term(); 1264 mi.maxLocals = i; 1265 continue; 1266 } 1267 if (tok.text.equals(".throws")) { 1268 lexer.read(); 1269 String s = lexer.parse_name(); 1270 lexer.term(); 1271 mi.exceptions.addElement(s); 1272 continue; 1273 } 1274 if (tok.text.equals(".synthetic")) { 1275 lexer.read(); 1276 lexer.term(); 1277 mi.synthetic = true; 1278 continue; 1279 } 1280 if (tok.text.equals(".deprecated")) { 1281 lexer.read(); 1282 lexer.term(); 1283 mi.deprecated = true; 1284 continue; 1285 } 1286 if (tok.text.equals(".flags")) { 1287 lexer.read(); 1288 int flags = lexer.parse_flags(MethodInfo.ACC_ALL_MFLAGS); 1289 lexer.term(); 1290 mi.accessFlags = flags; 1291 continue; 1292 } 1293 } 1294 if (tok.text.equals(".exception")) { 1295 lexer.read(); 1296 String startlab = parse_label(lexer); 1297 String endlab = parse_label(lexer); 1298 String type = lexer.parse_name(); 1299 if (type.equals("null")) type = null; 1300 String handlerlab = parse_label(lexer); 1301 lexer.term(); 1302 ExceptionRec rec = new ExceptionRec(); 1303 setupBranchTarget(rec.start, startlab); 1304 setupBranchTarget(rec.end, endlab); 1305 setupBranchTarget(rec.handler, handlerlab); 1306 rec.catchType = type; 1307 exVector.addElement(rec); 1308 continue; 1309 } 1310 if (tok.text.equals(".local")) { 1311 lexer.read(); 1312 int index = lexer.parse_int(); 1313 String name = lexer.parse_name(); 1314 Type type = lexer.parse_type(); 1315 String startlab = parse_label(lexer); 1316 String endlab = parse_label(lexer); 1317 lexer.term(); 1318 LocalVarRec rec = new LocalVarRec(); 1319 setupBranchTarget(rec.start, startlab); 1320 setupBranchTarget(rec.end, endlab); 1321 rec.index = index; 1322 rec.name = name; 1323 rec.descriptor = type; 1324 lvVector.addElement(rec); 1325 continue; 1326 } 1327 if (tok.text.equals(".line")) { 1328 lexer.read(); 1329 int num = lexer.parse_int(); 1330 lexer.push(Lexer.ST_ASM); 1331 String lab = lexer.peek().type == ';' ? 1332 null : parse_label(lexer); 1333 lexer.pop(); 1334 lexer.term(); 1335 LineNumRec rec = new LineNumRec(); 1336 rec.lineNumber = num; 1337 if (lab == null) 1338 curr.addElement(rec); 1339 else 1340 setupBranchTarget(rec.start, lab); 1341 lnVector.addElement(rec); 1342 continue; 1343 } 1344 1345 1346 Instruction instr = parseInstruction(lexer); 1347 for (int i = 0; i < curr.size(); i++) { 1348 Object o = curr.elementAt(i); 1349 if (o instanceof LineNumRec) 1350 ((LineNumRec) o).start.instr = instr; 1351 else 1352 defineLabel((String ) o, instr); 1353 } 1354 curr.removeAllElements(); 1355 if (place==null) 1356 push(instr); 1357 else 1358 switch(state) { 1359 case INS_AT: 1360 insertAfter(place, place.dup()); 1361 case INS_OVER: 1362 place.copy( instr ); 1363 state = INS_AFTER; 1364 break; 1365 case INS_AFTER: 1366 insertAfter(place, instr); 1367 place = instr; 1368 break; 1369 case INS_BEFORE: 1370 insertBefore(place, instr); 1371 place = instr; 1372 state = INS_AFTER; 1373 break; 1374 } 1375 continue; 1376 } 1377 if (tok.type == Token.EOF || tok.type == '}') { 1378 if (curr.size() != 0) lexer.die 1379 ("label or .line without an instruction following"); 1380 lexer.pop(); 1381 return; 1382 } 1383 lexer.unexpected(tok); 1384 } 1385 } 1386 1387 1388 1389 Instruction parseInstruction (Lexer lexer) throws ClassFileException { 1390 String cname = null, name = null; 1391 Type type = null; 1392 Descriptor descriptor = null; 1393 Instruction ret= new Instruction(); 1394 ret.initialize(); 1395 int save, lvtIndex; 1396 1397 String op = lexer.match(Token.TAG).text; 1398 int opc = Instruction.mnemonic2opcode(op); 1399 int switchVal = opc; 1400 1401 while (true) switch (switchVal) { 1402 case Instruction.OP_IFEQ: 1403 case Instruction.OP_IFNE: 1404 case Instruction.OP_IFLT: 1405 case Instruction.OP_IFGE: 1406 case Instruction.OP_IFGT: 1407 case Instruction.OP_IFLE: 1408 case Instruction.OP_IF_ICMPEQ: 1409 case Instruction.OP_IF_ICMPNE: 1410 case Instruction.OP_IF_ICMPLT: 1411 case Instruction.OP_IF_ICMPGE: 1412 case Instruction.OP_IF_ICMPGT: 1413 case Instruction.OP_IF_ICMPLE: 1414 case Instruction.OP_IF_ACMPEQ: 1415 case Instruction.OP_IF_ACMPNE: 1416 case Instruction.OP_JSR: 1417 case Instruction.OP_IFNULL: 1418 case Instruction.OP_IFNONNULL: 1419 case Instruction.OP_GOTO: { 1420 String label = parse_label(lexer); 1421 lexer.term(); 1422 ret.setOpCode( opc ); 1423 ret.setBranchTarget( new BranchTarget() ); 1424 setupBranchTarget(ret.branchTarget(), label); 1425 return ret; 1426 } 1427 1428 case Instruction.OP_LOOKUPSWITCH: 1429 case Instruction.OP_TABLESWITCH: { 1430 String default_lab = parse_label(lexer); 1431 Vector sv = new Vector(); 1432 int base = 0; 1433 boolean first = true; 1434 for (int i = 0; lexer.peek().type != ';'; i++) { 1435 BranchTarget bt = new BranchTarget(); 1436 bt.key = lexer.parse_int(); 1437 if (opc == Instruction.OP_TABLESWITCH) 1438 if (first) { 1439 first = false; 1440 base = bt.key; 1441 } else if (bt.key != base + i) lexer.die 1442 ("tableswitch with non-contiguous cases"); 1443 lexer.match(':'); 1444 String label = parse_label(lexer); 1445 setupBranchTarget(bt, label); 1446 sv.addElement(bt); 1447 } 1448 lexer.term(); 1449 if (sv.size() == 0) lexer.die ("switch has no cases"); 1450 BranchTarget [] sa = new BranchTarget [ sv.size() ]; 1451 sv.copyInto(sa); 1452 1453 ret.setOpCode(opc); 1454 ret.setBranchTarget( new BranchTarget() ); 1455 setupBranchTarget( ret.branchTarget(), default_lab ); 1456 if (opc == Instruction.OP_TABLESWITCH) 1457 ret.setImmediate(base); 1458 ret.setSwitchArray( sa ); 1459 return ret; 1460 } 1461 1462 1463 case Instruction.OP_NOP: 1464 case Instruction.OP_MONITORENTER: 1465 case Instruction.OP_MONITOREXIT: 1466 case Instruction.OP_IRETURN: 1467 case Instruction.OP_LRETURN: 1468 case Instruction.OP_FRETURN: 1469 case Instruction.OP_DRETURN: 1470 case Instruction.OP_ARETURN: 1471 case Instruction.OP_RETURN: 1472 case Instruction.OP_ATHROW: 1473 case Instruction.OP_ACONST_NULL: 1474 case Instruction.OP_POP: 1475 case Instruction.OP_POP2: 1476 case Instruction.OP_DUP: 1477 case Instruction.OP_DUP_X1: 1478 case Instruction.OP_DUP_X2: 1479 case Instruction.OP_DUP2: 1480 case Instruction.OP_DUP2_X1: 1481 case Instruction.OP_DUP2_X2: 1482 case Instruction.OP_SWAP: 1483 case Instruction.OP_IADD: 1484 case Instruction.OP_LADD: 1485 case Instruction.OP_FADD: 1486 case Instruction.OP_DADD: 1487 case Instruction.OP_ISUB: 1488 case Instruction.OP_LSUB: 1489 case Instruction.OP_FSUB: 1490 case Instruction.OP_DSUB: 1491 case Instruction.OP_IMUL: 1492 case Instruction.OP_LMUL: 1493 case Instruction.OP_FMUL: 1494 case Instruction.OP_DMUL: 1495 case Instruction.OP_IDIV: 1496 case Instruction.OP_LDIV: 1497 case Instruction.OP_FDIV: 1498 case Instruction.OP_DDIV: 1499 case Instruction.OP_IREM: 1500 case Instruction.OP_LREM: 1501 case Instruction.OP_FREM: 1502 case Instruction.OP_DREM: 1503 case Instruction.OP_INEG: 1504 case Instruction.OP_LNEG: 1505 case Instruction.OP_FNEG: 1506 case Instruction.OP_DNEG: 1507 case Instruction.OP_ISHL: 1508 case Instruction.OP_LSHL: 1509 case Instruction.OP_ISHR: 1510 case Instruction.OP_LSHR: 1511 case Instruction.OP_IUSHR: 1512 case Instruction.OP_LUSHR: 1513 case Instruction.OP_IAND: 1514 case Instruction.OP_LAND: 1515 case Instruction.OP_IOR: 1516 case Instruction.OP_LOR: 1517 case Instruction.OP_IXOR: 1518 case Instruction.OP_LXOR: 1519 case Instruction.OP_LCMP: 1520 case Instruction.OP_FCMPG: 1521 case Instruction.OP_FCMPL: 1522 case Instruction.OP_DCMPG: 1523 case Instruction.OP_DCMPL: 1524 case Instruction.OP_I2B: 1525 case Instruction.OP_I2C: 1526 case Instruction.OP_I2D: 1527 case Instruction.OP_L2I: 1528 case Instruction.OP_L2F: 1529 case Instruction.OP_L2D: 1530 case Instruction.OP_F2I: 1531 case Instruction.OP_F2L: 1532 case Instruction.OP_F2D: 1533 case Instruction.OP_D2I: 1534 case Instruction.OP_D2L: 1535 case Instruction.OP_D2F: 1536 case Instruction.OP_I2F: 1537 case Instruction.OP_I2L: 1538 case Instruction.OP_I2S: 1539 case Instruction.OP_IALOAD: 1540 case Instruction.OP_LALOAD: 1541 case Instruction.OP_FALOAD: 1542 case Instruction.OP_DALOAD: 1543 case Instruction.OP_AALOAD: 1544 case Instruction.OP_CALOAD: 1545 case Instruction.OP_SALOAD: 1546 case Instruction.OP_BALOAD: 1547 case Instruction.OP_IASTORE: 1548 case Instruction.OP_LASTORE: 1549 case Instruction.OP_FASTORE: 1550 case Instruction.OP_DASTORE: 1551 case Instruction.OP_AASTORE: 1552 case Instruction.OP_BASTORE: 1553 case Instruction.OP_CASTORE: 1554 case Instruction.OP_SASTORE: 1555 case Instruction.OP_ARRAYLENGTH: 1556 lexer.term(); 1557 ret.setOpCode( opc ); 1558 return ret; 1559 1560 1561 1562 case Instruction.OP_ILOAD: 1563 case Instruction.OP_FLOAD: 1564 case Instruction.OP_LLOAD: 1565 case Instruction.OP_DLOAD: 1566 case Instruction.OP_ALOAD: 1567 case Instruction.OP_ISTORE: 1568 case Instruction.OP_FSTORE: 1569 case Instruction.OP_LSTORE: 1570 case Instruction.OP_DSTORE: 1571 case Instruction.OP_ASTORE: 1572 case Instruction.OP_RET: 1573 lexer.push(Lexer.ST_ASM_ARG); 1574 lvtIndex = (int) lexer.match(Token.INT).l; 1575 lexer.pop(); 1576 lexer.term(); 1577 ret.setOpCode( opc ); 1578 ret.setLvtIndex(lvtIndex); 1579 return ret; 1580 1581 case Instruction.OP_IINC: 1582 ret.setOpCode(opc); 1583 ret.setImmediate( lexer.parse_int() ); 1584 ret.setLvtIndex( lexer.parse_int() ); 1585 lexer.term(); 1586 return ret; 1587 1588 case Instruction.OP_NEWARRAY: 1589 ret.setOpCode(opc); 1590 ret.setOpCode(opc); 1591 ret.setImmediate( lexer.parse_int() ); 1592 lexer.term(); 1593 return ret; 1594 1595 case Instruction.OP_ILOAD_0: 1596 case Instruction.OP_ILOAD_1: 1597 case Instruction.OP_ILOAD_2: 1598 case Instruction.OP_ILOAD_3: 1599 case Instruction.OP_FLOAD_0: 1600 case Instruction.OP_FLOAD_1: 1601 case Instruction.OP_FLOAD_2: 1602 case Instruction.OP_FLOAD_3: 1603 case Instruction.OP_LLOAD_0: 1604 case Instruction.OP_LLOAD_1: 1605 case Instruction.OP_LLOAD_2: 1606 case Instruction.OP_LLOAD_3: 1607 case Instruction.OP_DLOAD_0: 1608 case Instruction.OP_DLOAD_1: 1609 case Instruction.OP_DLOAD_2: 1610 case Instruction.OP_DLOAD_3: 1611 case Instruction.OP_ALOAD_0: 1612 case Instruction.OP_ALOAD_1: 1613 case Instruction.OP_ALOAD_2: 1614 case Instruction.OP_ALOAD_3: 1615 case Instruction.OP_ISTORE_0: 1616 case Instruction.OP_ISTORE_1: 1617 case Instruction.OP_ISTORE_2: 1618 case Instruction.OP_ISTORE_3: 1619 case Instruction.OP_FSTORE_0: 1620 case Instruction.OP_FSTORE_1: 1621 case Instruction.OP_FSTORE_2: 1622 case Instruction.OP_FSTORE_3: 1623 case Instruction.OP_LSTORE_0: 1624 case Instruction.OP_LSTORE_1: 1625 case Instruction.OP_LSTORE_2: 1626 case Instruction.OP_LSTORE_3: 1627 case Instruction.OP_DSTORE_0: 1628 case Instruction.OP_DSTORE_1: 1629 case Instruction.OP_DSTORE_2: 1630 case Instruction.OP_DSTORE_3: 1631 case Instruction.OP_ASTORE_0: 1632 case Instruction.OP_ASTORE_1: 1633 case Instruction.OP_ASTORE_2: 1634 case Instruction.OP_ASTORE_3: 1635 lexer.term(); 1636 ret.setRealOpCode( opc ); 1637 ret.setVarAccess(opc); 1638 return ret; 1639 1640 1641 1642 case Instruction.OP_DCONST_0: 1643 case Instruction.OP_DCONST_1: 1644 ret.setImmediate_f( (float) (opc - Instruction.OP_DCONST_0) ); 1645 ret.setOpCode( Instruction.AOP_DPUSH ); 1646 ret.setRealOpCode( opc ); 1647 lexer.term(); 1648 return ret; 1649 1650 case Instruction.OP_FCONST_0: 1651 case Instruction.OP_FCONST_1: 1652 case Instruction.OP_FCONST_2: 1653 ret.setImmediate_f( (float) (opc - Instruction.OP_FCONST_0) ); 1654 ret.setOpCode( Instruction.AOP_FPUSH ); 1655 ret.setRealOpCode( opc ); 1656 lexer.term(); 1657 return ret; 1658 1659 case Instruction.OP_LCONST_0: 1660 case Instruction.OP_LCONST_1: 1661 ret.setImmediate( opc - Instruction.OP_LCONST_0 ); 1662 ret.setRealOpCode(opc); 1663 ret.setOpCode( Instruction.AOP_LPUSH ); 1664 lexer.term(); 1665 return ret; 1666 1667 case Instruction.OP_ICONST_M1: 1668 case Instruction.OP_ICONST_0: 1669 case Instruction.OP_ICONST_1: 1670 case Instruction.OP_ICONST_2: 1671 case Instruction.OP_ICONST_3: 1672 case Instruction.OP_ICONST_4: 1673 case Instruction.OP_ICONST_5: 1674 ret.setImmediate( opc - Instruction.OP_ICONST_0 ); 1675 ret.setRealOpCode(opc); 1676 ret.setOpCode( Instruction.AOP_IPUSH ); 1677 lexer.term(); 1678 return ret; 1679 1680 case Instruction.OP_BIPUSH: 1681 case Instruction.OP_SIPUSH: 1682 ret.setRealOpCode(opc); 1683 ret.setOpCode(Instruction.AOP_IPUSH); 1684 ret.setImmediate( lexer.parse_int() ); 1685 lexer.term(); 1686 return ret; 1687 1688 1689 case Instruction.OP_LDC2_W: 1690 ret.setRealOpCode(opc); 1691 if (lexer.peek().type == Token.FLOAT) { 1692 ret.setOpCode(Instruction.AOP_DPUSH); 1693 ret.setImmediate_f( lexer.parse_double() ); 1694 } else if (lexer.peek().type == Token.INT) { 1695 ret.setOpCode(Instruction.AOP_LPUSH); 1696 ret.setImmediate_l( lexer.parse_long() ); 1697 } else lexer.unexpected(lexer.read()); 1698 lexer.term(); 1699 return ret; 1700 1701 case Instruction.OP_LDC: 1702 case Instruction.OP_LDC_W: 1703 ret.setRealOpCode(opc); 1704 switch (lexer.peek().type) { 1705 case Token.STRING: 1706 ret.setOpCode(Instruction.AOP_SPUSH); 1707 ret.setImmediate_s(lexer.parse_string()); 1708 break; 1709 case Token.FLOAT: 1710 ret.setOpCode(Instruction.AOP_FPUSH); 1711 ret.setImmediate_f( lexer.parse_double() ); 1712 break; 1713 case Token.INT: 1714 ret.setOpCode(Instruction.AOP_IPUSH); 1715 ret.setImmediate_l( lexer.parse_long() ); 1716 break; 1717 default: 1718 lexer.unexpected(lexer.read()); 1719 } 1720 lexer.term(); 1721 return ret; 1722 1723 case Instruction.AOP_IPUSH: 1724 case Instruction.AOP_LPUSH: 1725 ret.setImmediate_l( lexer.parse_long() ); 1726 lexer.term(); 1727 ret.setOpCode(opc); 1728 return ret; 1729 1730 case Instruction.OP_INVOKESPECIAL: 1731 case Instruction.OP_INVOKESTATIC: 1732 case Instruction.OP_INVOKEVIRTUAL: 1733 case Instruction.OP_INVOKEINTERFACE: 1734 lexer.push(Lexer.ST_ASM_ARG); 1735 cname = lexer.parse_name(); 1736 lexer.match('.'); 1737 name = lexer.parse_name(); 1738 descriptor = lexer.parseOptDescriptor(cname, name); 1739 lexer.pop(); 1740 lexer.term(); 1741 ret.setOpCode(opc); 1742 ret.setClassRef(cname); 1743 ret.setElemName(name); 1744 ret.setDescriptor(descriptor); 1745 return ret; 1746 1747 case Instruction.OP_GETSTATIC: 1748 case Instruction.OP_PUTSTATIC: 1749 case Instruction.OP_GETFIELD: 1750 case Instruction.OP_PUTFIELD: 1751 lexer.push(Lexer.ST_ASM_ARG); 1752 cname = lexer.parse_name(); 1753 lexer.match('.'); 1754 name = lexer.parse_name(); 1755 type = lexer.parseOptType(cname, name); 1756 lexer.pop(); 1757 lexer.term(); 1758 ret.setOpCode(opc); 1759 ret.setClassRef(cname); 1760 ret.setElemName(name); 1761 ret.setType(type); 1762 return ret; 1763 1764 case Instruction.OP_NEW: 1765 case Instruction.OP_ANEWARRAY: 1766 case Instruction.OP_CHECKCAST: 1767 case Instruction.OP_INSTANCEOF: 1768 cname = lexer.parse_name(); 1769 lexer.term(); 1770 ret.setOpCode(opc); 1771 ret.setClassRef(cname); 1772 return ret; 1773 1774 case Instruction.OP_MULTIANEWARRAY: 1775 ret.setClassRef( lexer.parse_name() ); 1776 ret.setImmediate( lexer.parse_int() ); 1777 lexer.term(); 1778 ret.setOpCode(opc); 1779 return ret; 1780 1781 default: 1782 lexer.die("bad opcode " + op); 1783 } 1784 } 1785} 1786 | Popular Tags |