001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.verifier.structurals; 019 020import org.apache.bcel.Const; 021import org.apache.bcel.classfile.Constant; 022import org.apache.bcel.classfile.ConstantClass; 023import org.apache.bcel.classfile.ConstantDouble; 024import org.apache.bcel.classfile.ConstantFloat; 025import org.apache.bcel.classfile.ConstantInteger; 026import org.apache.bcel.classfile.ConstantLong; 027import org.apache.bcel.classfile.ConstantString; 028// CHECKSTYLE:OFF (there are lots of references!) 029import org.apache.bcel.generic.*; 030//CHECKSTYLE:ON 031 032/** 033 * This Visitor class may be used for a type-based Java Virtual Machine simulation. 034 * 035 * <p> 036 * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are 037 * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type 038 * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this. 039 * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots 040 * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there 041 * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated. 042 * </p> 043 * 044 * <b>Conventions:</b> 045 * 046 * <p> 047 * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots 048 * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack 049 * here. 050 * </p> 051 * 052 * <p> 053 * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN. 054 * </p> 055 * 056 * @see #visitDSTORE(DSTORE o) 057 * @see InstConstraintVisitor 058 */ 059public class ExecutionVisitor extends EmptyVisitor { 060 061 /** 062 * The executionframe we're operating on. 063 */ 064 private Frame frame; 065 066 /** 067 * The ConstantPoolGen we're working with. 068 * 069 * @see #setConstantPoolGen(ConstantPoolGen) 070 */ 071 private ConstantPoolGen cpg; 072 073 /** 074 * Constructor. Constructs a new instance of this class. 075 */ 076 public ExecutionVisitor() { 077 } 078 079 /** 080 * The LocalVariables from the current Frame we're operating on. 081 * 082 * @see #setFrame(Frame) 083 */ 084 private LocalVariables locals() { 085 return frame.getLocals(); 086 } 087 088 /** 089 * Sets the ConstantPoolGen needed for symbolic execution. 090 */ 091 public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected? 092 this.cpg = cpg; 093 } 094 095 /** 096 * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this 097 * instance, <B>SET THE ConstantPoolGen FIRST</B>. 098 * 099 * @see #setConstantPoolGen(ConstantPoolGen) 100 */ 101 public void setFrame(final Frame f) { // TODO could be package-protected? 102 this.frame = f; 103 } 104 105 /** 106 * The OperandStack from the current Frame we're operating on. 107 * 108 * @see #setFrame(Frame) 109 */ 110 private OperandStack stack() { 111 return frame.getStack(); 112 } 113 114 /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */ 115 // public void visitWIDE(WIDE o) { 116 // The WIDE instruction is modelled as a flag 117 // of the embedded instructions in BCEL. 118 // Therefore BCEL checks for possible errors 119 // when parsing in the .class file: We don't 120 // have even the possibilty to care for WIDE 121 // here. 122 // } 123 124 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 125 @Override 126 public void visitAALOAD(final AALOAD o) { 127 stack().pop(); // pop the index int 128//System.out.print(stack().peek()); 129 final Type t = stack().pop(); // Pop Array type 130 if (t == Type.NULL) { 131 stack().push(Type.NULL); 132 } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time 133 else { 134 final ArrayType at = (ArrayType) t; 135 stack().push(at.getElementType()); 136 } 137 } 138 139 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 140 @Override 141 public void visitAASTORE(final AASTORE o) { 142 stack().pop(3); 143 } 144 145 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 146 @Override 147 public void visitACONST_NULL(final ACONST_NULL o) { 148 stack().push(Type.NULL); 149 } 150 151 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 152 @Override 153 public void visitALOAD(final ALOAD o) { 154 stack().push(locals().get(o.getIndex())); 155 } 156 157 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 158 @Override 159 public void visitANEWARRAY(final ANEWARRAY o) { 160 stack().pop(); // count 161 stack().push(new ArrayType(o.getType(cpg), 1)); 162 } 163 164 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 165 @Override 166 public void visitARETURN(final ARETURN o) { 167 stack().pop(); 168 } 169 170 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 171 @Override 172 public void visitARRAYLENGTH(final ARRAYLENGTH o) { 173 stack().pop(); 174 stack().push(Type.INT); 175 } 176 177 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 178 @Override 179 public void visitASTORE(final ASTORE o) { 180 locals().set(o.getIndex(), stack().pop()); 181 // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'."); 182 } 183 184 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 185 @Override 186 public void visitATHROW(final ATHROW o) { 187 final Type t = stack().pop(); 188 stack().clear(); 189 if (t.equals(Type.NULL)) { 190 stack().push(Type.getType("Ljava/lang/NullPointerException;")); 191 } else { 192 stack().push(t); 193 } 194 } 195 196 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 197 @Override 198 public void visitBALOAD(final BALOAD o) { 199 stack().pop(2); 200 stack().push(Type.INT); 201 } 202 203 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 204 @Override 205 public void visitBASTORE(final BASTORE o) { 206 stack().pop(3); 207 } 208 209 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 210 @Override 211 public void visitBIPUSH(final BIPUSH o) { 212 stack().push(Type.INT); 213 } 214 215 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 216 @Override 217 public void visitCALOAD(final CALOAD o) { 218 stack().pop(2); 219 stack().push(Type.INT); 220 } 221 222 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 223 @Override 224 public void visitCASTORE(final CASTORE o) { 225 stack().pop(3); 226 } 227 228 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 229 @Override 230 public void visitCHECKCAST(final CHECKCAST o) { 231 // It's possibly wrong to do so, but SUN's 232 // ByteCode verifier seems to do (only) this, too. 233 // TODO: One could use a sophisticated analysis here to check 234 // if a type cannot possibly be cated to another and by 235 // so doing predict the ClassCastException at run-time. 236 stack().pop(); 237 stack().push(o.getType(cpg)); 238 } 239 240 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 241 @Override 242 public void visitD2F(final D2F o) { 243 stack().pop(); 244 stack().push(Type.FLOAT); 245 } 246 247 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 248 @Override 249 public void visitD2I(final D2I o) { 250 stack().pop(); 251 stack().push(Type.INT); 252 } 253 254 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 255 @Override 256 public void visitD2L(final D2L o) { 257 stack().pop(); 258 stack().push(Type.LONG); 259 } 260 261 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 262 @Override 263 public void visitDADD(final DADD o) { 264 stack().pop(2); 265 stack().push(Type.DOUBLE); 266 } 267 268 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 269 @Override 270 public void visitDALOAD(final DALOAD o) { 271 stack().pop(2); 272 stack().push(Type.DOUBLE); 273 } 274 275 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 276 @Override 277 public void visitDASTORE(final DASTORE o) { 278 stack().pop(3); 279 } 280 281 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 282 @Override 283 public void visitDCMPG(final DCMPG o) { 284 stack().pop(2); 285 stack().push(Type.INT); 286 } 287 288 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 289 @Override 290 public void visitDCMPL(final DCMPL o) { 291 stack().pop(2); 292 stack().push(Type.INT); 293 } 294 295 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 296 @Override 297 public void visitDCONST(final DCONST o) { 298 stack().push(Type.DOUBLE); 299 } 300 301 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 302 @Override 303 public void visitDDIV(final DDIV o) { 304 stack().pop(2); 305 stack().push(Type.DOUBLE); 306 } 307 308 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 309 @Override 310 public void visitDLOAD(final DLOAD o) { 311 stack().push(Type.DOUBLE); 312 } 313 314 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 315 @Override 316 public void visitDMUL(final DMUL o) { 317 stack().pop(2); 318 stack().push(Type.DOUBLE); 319 } 320 321 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 322 @Override 323 public void visitDNEG(final DNEG o) { 324 stack().pop(); 325 stack().push(Type.DOUBLE); 326 } 327 328 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 329 @Override 330 public void visitDREM(final DREM o) { 331 stack().pop(2); 332 stack().push(Type.DOUBLE); 333 } 334 335 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 336 @Override 337 public void visitDRETURN(final DRETURN o) { 338 stack().pop(); 339 } 340 341 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 342 @Override 343 public void visitDSTORE(final DSTORE o) { 344 locals().set(o.getIndex(), stack().pop()); 345 locals().set(o.getIndex() + 1, Type.UNKNOWN); 346 } 347 348 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 349 @Override 350 public void visitDSUB(final DSUB o) { 351 stack().pop(2); 352 stack().push(Type.DOUBLE); 353 } 354 355 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 356 @Override 357 public void visitDUP(final DUP o) { 358 final Type t = stack().pop(); 359 stack().push(t); 360 stack().push(t); 361 } 362 363 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 364 @Override 365 public void visitDUP_X1(final DUP_X1 o) { 366 final Type w1 = stack().pop(); 367 final Type w2 = stack().pop(); 368 stack().push(w1); 369 stack().push(w2); 370 stack().push(w1); 371 } 372 373 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 374 @Override 375 public void visitDUP_X2(final DUP_X2 o) { 376 final Type w1 = stack().pop(); 377 final Type w2 = stack().pop(); 378 if (w2.getSize() == 2) { 379 stack().push(w1); 380 } else { 381 final Type w3 = stack().pop(); 382 stack().push(w1); 383 stack().push(w3); 384 } 385 stack().push(w2); 386 stack().push(w1); 387 } 388 389 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 390 @Override 391 public void visitDUP2(final DUP2 o) { 392 final Type t = stack().pop(); 393 if (t.getSize() == 2) { 394 stack().push(t); 395 } else { // t.getSize() is 1 396 final Type u = stack().pop(); 397 stack().push(u); 398 stack().push(t); 399 stack().push(u); 400 } 401 stack().push(t); 402 } 403 404 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 405 @Override 406 public void visitDUP2_X1(final DUP2_X1 o) { 407 final Type t = stack().pop(); 408 if (t.getSize() == 2) { 409 final Type u = stack().pop(); 410 stack().push(t); 411 stack().push(u); 412 } else { // t.getSize() is1 413 final Type u = stack().pop(); 414 final Type v = stack().pop(); 415 stack().push(u); 416 stack().push(t); 417 stack().push(v); 418 stack().push(u); 419 } 420 stack().push(t); 421 } 422 423 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 424 @Override 425 public void visitDUP2_X2(final DUP2_X2 o) { 426 final Type t = stack().pop(); 427 if (t.getSize() == 2) { 428 final Type u = stack().pop(); 429 if (u.getSize() == 2) { 430 stack().push(t); 431 } else { 432 final Type v = stack().pop(); 433 stack().push(t); 434 stack().push(v); 435 } 436 stack().push(u); 437 stack().push(t); 438 } else { // t.getSize() is 1 439 final Type u = stack().pop(); 440 final Type v = stack().pop(); 441 if (v.getSize() == 2) { 442 stack().push(u); 443 stack().push(t); 444 } else { 445 final Type w = stack().pop(); 446 stack().push(u); 447 stack().push(t); 448 stack().push(w); 449 } 450 stack().push(v); 451 stack().push(u); 452 stack().push(t); 453 } 454 } 455 456 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 457 @Override 458 public void visitF2D(final F2D o) { 459 stack().pop(); 460 stack().push(Type.DOUBLE); 461 } 462 463 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 464 @Override 465 public void visitF2I(final F2I o) { 466 stack().pop(); 467 stack().push(Type.INT); 468 } 469 470 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 471 @Override 472 public void visitF2L(final F2L o) { 473 stack().pop(); 474 stack().push(Type.LONG); 475 } 476 477 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 478 @Override 479 public void visitFADD(final FADD o) { 480 stack().pop(2); 481 stack().push(Type.FLOAT); 482 } 483 484 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 485 @Override 486 public void visitFALOAD(final FALOAD o) { 487 stack().pop(2); 488 stack().push(Type.FLOAT); 489 } 490 491 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 492 @Override 493 public void visitFASTORE(final FASTORE o) { 494 stack().pop(3); 495 } 496 497 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 498 @Override 499 public void visitFCMPG(final FCMPG o) { 500 stack().pop(2); 501 stack().push(Type.INT); 502 } 503 504 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 505 @Override 506 public void visitFCMPL(final FCMPL o) { 507 stack().pop(2); 508 stack().push(Type.INT); 509 } 510 511 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 512 @Override 513 public void visitFCONST(final FCONST o) { 514 stack().push(Type.FLOAT); 515 } 516 517 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 518 @Override 519 public void visitFDIV(final FDIV o) { 520 stack().pop(2); 521 stack().push(Type.FLOAT); 522 } 523 524 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 525 @Override 526 public void visitFLOAD(final FLOAD o) { 527 stack().push(Type.FLOAT); 528 } 529 530 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 531 @Override 532 public void visitFMUL(final FMUL o) { 533 stack().pop(2); 534 stack().push(Type.FLOAT); 535 } 536 537 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 538 @Override 539 public void visitFNEG(final FNEG o) { 540 stack().pop(); 541 stack().push(Type.FLOAT); 542 } 543 544 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 545 @Override 546 public void visitFREM(final FREM o) { 547 stack().pop(2); 548 stack().push(Type.FLOAT); 549 } 550 551 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 552 @Override 553 public void visitFRETURN(final FRETURN o) { 554 stack().pop(); 555 } 556 557 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 558 @Override 559 public void visitFSTORE(final FSTORE o) { 560 locals().set(o.getIndex(), stack().pop()); 561 } 562 563 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 564 @Override 565 public void visitFSUB(final FSUB o) { 566 stack().pop(2); 567 stack().push(Type.FLOAT); 568 } 569 570 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 571 @Override 572 public void visitGETFIELD(final GETFIELD o) { 573 stack().pop(); 574 Type t = o.getFieldType(cpg); 575 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 576 t = Type.INT; 577 } 578 stack().push(t); 579 } 580 581 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 582 @Override 583 public void visitGETSTATIC(final GETSTATIC o) { 584 Type t = o.getFieldType(cpg); 585 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 586 t = Type.INT; 587 } 588 stack().push(t); 589 } 590 591 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 592 @Override 593 public void visitGOTO(final GOTO o) { 594 // no stack changes. 595 } 596 597 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 598 @Override 599 public void visitGOTO_W(final GOTO_W o) { 600 // no stack changes. 601 } 602 603 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 604 @Override 605 public void visitI2B(final I2B o) { 606 stack().pop(); 607 stack().push(Type.INT); 608 } 609 610 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 611 @Override 612 public void visitI2C(final I2C o) { 613 stack().pop(); 614 stack().push(Type.INT); 615 } 616 617 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 618 @Override 619 public void visitI2D(final I2D o) { 620 stack().pop(); 621 stack().push(Type.DOUBLE); 622 } 623 624 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 625 @Override 626 public void visitI2F(final I2F o) { 627 stack().pop(); 628 stack().push(Type.FLOAT); 629 } 630 631 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 632 @Override 633 public void visitI2L(final I2L o) { 634 stack().pop(); 635 stack().push(Type.LONG); 636 } 637 638 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 639 @Override 640 public void visitI2S(final I2S o) { 641 stack().pop(); 642 stack().push(Type.INT); 643 } 644 645 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 646 @Override 647 public void visitIADD(final IADD o) { 648 stack().pop(2); 649 stack().push(Type.INT); 650 } 651 652 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 653 @Override 654 public void visitIALOAD(final IALOAD o) { 655 stack().pop(2); 656 stack().push(Type.INT); 657 } 658 659 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 660 @Override 661 public void visitIAND(final IAND o) { 662 stack().pop(2); 663 stack().push(Type.INT); 664 } 665 666 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 667 @Override 668 public void visitIASTORE(final IASTORE o) { 669 stack().pop(3); 670 } 671 672 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 673 @Override 674 public void visitICONST(final ICONST o) { 675 stack().push(Type.INT); 676 } 677 678 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 679 @Override 680 public void visitIDIV(final IDIV o) { 681 stack().pop(2); 682 stack().push(Type.INT); 683 } 684 685 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 686 @Override 687 public void visitIF_ACMPEQ(final IF_ACMPEQ o) { 688 stack().pop(2); 689 } 690 691 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 692 @Override 693 public void visitIF_ACMPNE(final IF_ACMPNE o) { 694 stack().pop(2); 695 } 696 697 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 698 @Override 699 public void visitIF_ICMPEQ(final IF_ICMPEQ o) { 700 stack().pop(2); 701 } 702 703 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 704 @Override 705 public void visitIF_ICMPGE(final IF_ICMPGE o) { 706 stack().pop(2); 707 } 708 709 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 710 @Override 711 public void visitIF_ICMPGT(final IF_ICMPGT o) { 712 stack().pop(2); 713 } 714 715 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 716 @Override 717 public void visitIF_ICMPLE(final IF_ICMPLE o) { 718 stack().pop(2); 719 } 720 721 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 722 @Override 723 public void visitIF_ICMPLT(final IF_ICMPLT o) { 724 stack().pop(2); 725 } 726 727 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 728 @Override 729 public void visitIF_ICMPNE(final IF_ICMPNE o) { 730 stack().pop(2); 731 } 732 733 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 734 @Override 735 public void visitIFEQ(final IFEQ o) { 736 stack().pop(); 737 } 738 739 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 740 @Override 741 public void visitIFGE(final IFGE o) { 742 stack().pop(); 743 } 744 745 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 746 @Override 747 public void visitIFGT(final IFGT o) { 748 stack().pop(); 749 } 750 751 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 752 @Override 753 public void visitIFLE(final IFLE o) { 754 stack().pop(); 755 } 756 757 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 758 @Override 759 public void visitIFLT(final IFLT o) { 760 stack().pop(); 761 } 762 763 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 764 @Override 765 public void visitIFNE(final IFNE o) { 766 stack().pop(); 767 } 768 769 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 770 @Override 771 public void visitIFNONNULL(final IFNONNULL o) { 772 stack().pop(); 773 } 774 775 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 776 @Override 777 public void visitIFNULL(final IFNULL o) { 778 stack().pop(); 779 } 780 781 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 782 @Override 783 public void visitIINC(final IINC o) { 784 // stack is not changed. 785 } 786 787 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 788 @Override 789 public void visitILOAD(final ILOAD o) { 790 stack().push(Type.INT); 791 } 792 793 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 794 @Override 795 public void visitIMUL(final IMUL o) { 796 stack().pop(2); 797 stack().push(Type.INT); 798 } 799 800 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 801 @Override 802 public void visitINEG(final INEG o) { 803 stack().pop(); 804 stack().push(Type.INT); 805 } 806 807 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 808 @Override 809 public void visitINSTANCEOF(final INSTANCEOF o) { 810 stack().pop(); 811 stack().push(Type.INT); 812 } 813 814 /** 815 * Symbolically executes the corresponding Java Virtual Machine instruction. 816 * 817 * @since 6.0 818 */ 819 @Override 820 public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) { 821 stack().pop(o.getArgumentTypes(cpg).length); 822 // We are sure the invoked method will xRETURN eventually 823 // We simulate xRETURNs functionality here because we 824 // don't really "jump into" and simulate the invoked 825 // method. 826 if (o.getReturnType(cpg) != Type.VOID) { 827 Type t = o.getReturnType(cpg); 828 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 829 t = Type.INT; 830 } 831 stack().push(t); 832 } 833 } 834 835 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 836 @Override 837 public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) { 838 stack().pop(); // objectref 839 stack().pop(o.getArgumentTypes(cpg).length); 840 // We are sure the invoked method will xRETURN eventually 841 // We simulate xRETURNs functionality here because we 842 // don't really "jump into" and simulate the invoked 843 // method. 844 if (o.getReturnType(cpg) != Type.VOID) { 845 Type t = o.getReturnType(cpg); 846 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 847 t = Type.INT; 848 } 849 stack().push(t); 850 } 851 } 852 853 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 854 @Override 855 public void visitINVOKESPECIAL(final INVOKESPECIAL o) { 856 if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) { 857 final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length); 858 if (t == Frame.getThis()) { 859 Frame.setThis(null); 860 } 861 stack().initializeObject(t); 862 locals().initializeObject(t); 863 } 864 stack().pop(); // objectref 865 stack().pop(o.getArgumentTypes(cpg).length); 866 // We are sure the invoked method will xRETURN eventually 867 // We simulate xRETURNs functionality here because we 868 // don't really "jump into" and simulate the invoked 869 // method. 870 if (o.getReturnType(cpg) != Type.VOID) { 871 Type t = o.getReturnType(cpg); 872 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 873 t = Type.INT; 874 } 875 stack().push(t); 876 } 877 } 878 879 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 880 @Override 881 public void visitINVOKESTATIC(final INVOKESTATIC o) { 882 stack().pop(o.getArgumentTypes(cpg).length); 883 // We are sure the invoked method will xRETURN eventually 884 // We simulate xRETURNs functionality here because we 885 // don't really "jump into" and simulate the invoked 886 // method. 887 if (o.getReturnType(cpg) != Type.VOID) { 888 Type t = o.getReturnType(cpg); 889 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 890 t = Type.INT; 891 } 892 stack().push(t); 893 } 894 } 895 896 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 897 @Override 898 public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) { 899 stack().pop(); // objectref 900 stack().pop(o.getArgumentTypes(cpg).length); 901 // We are sure the invoked method will xRETURN eventually 902 // We simulate xRETURNs functionality here because we 903 // don't really "jump into" and simulate the invoked 904 // method. 905 if (o.getReturnType(cpg) != Type.VOID) { 906 Type t = o.getReturnType(cpg); 907 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 908 t = Type.INT; 909 } 910 stack().push(t); 911 } 912 } 913 914 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 915 @Override 916 public void visitIOR(final IOR o) { 917 stack().pop(2); 918 stack().push(Type.INT); 919 } 920 921 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 922 @Override 923 public void visitIREM(final IREM o) { 924 stack().pop(2); 925 stack().push(Type.INT); 926 } 927 928 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 929 @Override 930 public void visitIRETURN(final IRETURN o) { 931 stack().pop(); 932 } 933 934 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 935 @Override 936 public void visitISHL(final ISHL o) { 937 stack().pop(2); 938 stack().push(Type.INT); 939 } 940 941 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 942 @Override 943 public void visitISHR(final ISHR o) { 944 stack().pop(2); 945 stack().push(Type.INT); 946 } 947 948 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 949 @Override 950 public void visitISTORE(final ISTORE o) { 951 locals().set(o.getIndex(), stack().pop()); 952 } 953 954 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 955 @Override 956 public void visitISUB(final ISUB o) { 957 stack().pop(2); 958 stack().push(Type.INT); 959 } 960 961 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 962 @Override 963 public void visitIUSHR(final IUSHR o) { 964 stack().pop(2); 965 stack().push(Type.INT); 966 } 967 968 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 969 @Override 970 public void visitIXOR(final IXOR o) { 971 stack().pop(2); 972 stack().push(Type.INT); 973 } 974 975 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 976 @Override 977 public void visitJSR(final JSR o) { 978 stack().push(new ReturnaddressType(o.physicalSuccessor())); 979//System.err.println("TODO-----------:"+o.physicalSuccessor()); 980 } 981 982 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 983 @Override 984 public void visitJSR_W(final JSR_W o) { 985 stack().push(new ReturnaddressType(o.physicalSuccessor())); 986 } 987 988 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 989 @Override 990 public void visitL2D(final L2D o) { 991 stack().pop(); 992 stack().push(Type.DOUBLE); 993 } 994 995 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 996 @Override 997 public void visitL2F(final L2F o) { 998 stack().pop(); 999 stack().push(Type.FLOAT); 1000 } 1001 1002 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1003 @Override 1004 public void visitL2I(final L2I o) { 1005 stack().pop(); 1006 stack().push(Type.INT); 1007 } 1008 1009 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1010 @Override 1011 public void visitLADD(final LADD o) { 1012 stack().pop(2); 1013 stack().push(Type.LONG); 1014 } 1015 1016 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1017 @Override 1018 public void visitLALOAD(final LALOAD o) { 1019 stack().pop(2); 1020 stack().push(Type.LONG); 1021 } 1022 1023 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1024 @Override 1025 public void visitLAND(final LAND o) { 1026 stack().pop(2); 1027 stack().push(Type.LONG); 1028 } 1029 1030 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1031 @Override 1032 public void visitLASTORE(final LASTORE o) { 1033 stack().pop(3); 1034 } 1035 1036 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1037 @Override 1038 public void visitLCMP(final LCMP o) { 1039 stack().pop(2); 1040 stack().push(Type.INT); 1041 } 1042 1043 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1044 @Override 1045 public void visitLCONST(final LCONST o) { 1046 stack().push(Type.LONG); 1047 } 1048 1049 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1050 @Override 1051 public void visitLDC(final LDC o) { 1052 final Constant c = cpg.getConstant(o.getIndex()); 1053 if (c instanceof ConstantInteger) { 1054 stack().push(Type.INT); 1055 } 1056 if (c instanceof ConstantFloat) { 1057 stack().push(Type.FLOAT); 1058 } 1059 if (c instanceof ConstantString) { 1060 stack().push(Type.STRING); 1061 } 1062 if (c instanceof ConstantClass) { 1063 stack().push(Type.CLASS); 1064 } 1065 } 1066 1067 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1068 public void visitLDC_W(final LDC_W o) { 1069 final Constant c = cpg.getConstant(o.getIndex()); 1070 if (c instanceof ConstantInteger) { 1071 stack().push(Type.INT); 1072 } 1073 if (c instanceof ConstantFloat) { 1074 stack().push(Type.FLOAT); 1075 } 1076 if (c instanceof ConstantString) { 1077 stack().push(Type.STRING); 1078 } 1079 if (c instanceof ConstantClass) { 1080 stack().push(Type.CLASS); 1081 } 1082 } 1083 1084 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1085 @Override 1086 public void visitLDC2_W(final LDC2_W o) { 1087 final Constant c = cpg.getConstant(o.getIndex()); 1088 if (c instanceof ConstantLong) { 1089 stack().push(Type.LONG); 1090 } 1091 if (c instanceof ConstantDouble) { 1092 stack().push(Type.DOUBLE); 1093 } 1094 } 1095 1096 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1097 @Override 1098 public void visitLDIV(final LDIV o) { 1099 stack().pop(2); 1100 stack().push(Type.LONG); 1101 } 1102 1103 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1104 @Override 1105 public void visitLLOAD(final LLOAD o) { 1106 stack().push(locals().get(o.getIndex())); 1107 } 1108 1109 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1110 @Override 1111 public void visitLMUL(final LMUL o) { 1112 stack().pop(2); 1113 stack().push(Type.LONG); 1114 } 1115 1116 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1117 @Override 1118 public void visitLNEG(final LNEG o) { 1119 stack().pop(); 1120 stack().push(Type.LONG); 1121 } 1122 1123 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1124 @Override 1125 public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) { 1126 stack().pop(); // key 1127 } 1128 1129 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1130 @Override 1131 public void visitLOR(final LOR o) { 1132 stack().pop(2); 1133 stack().push(Type.LONG); 1134 } 1135 1136 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1137 @Override 1138 public void visitLREM(final LREM o) { 1139 stack().pop(2); 1140 stack().push(Type.LONG); 1141 } 1142 1143 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1144 @Override 1145 public void visitLRETURN(final LRETURN o) { 1146 stack().pop(); 1147 } 1148 1149 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1150 @Override 1151 public void visitLSHL(final LSHL o) { 1152 stack().pop(2); 1153 stack().push(Type.LONG); 1154 } 1155 1156 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1157 @Override 1158 public void visitLSHR(final LSHR o) { 1159 stack().pop(2); 1160 stack().push(Type.LONG); 1161 } 1162 1163 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1164 @Override 1165 public void visitLSTORE(final LSTORE o) { 1166 locals().set(o.getIndex(), stack().pop()); 1167 locals().set(o.getIndex() + 1, Type.UNKNOWN); 1168 } 1169 1170 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1171 @Override 1172 public void visitLSUB(final LSUB o) { 1173 stack().pop(2); 1174 stack().push(Type.LONG); 1175 } 1176 1177 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1178 @Override 1179 public void visitLUSHR(final LUSHR o) { 1180 stack().pop(2); 1181 stack().push(Type.LONG); 1182 } 1183 1184 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1185 @Override 1186 public void visitLXOR(final LXOR o) { 1187 stack().pop(2); 1188 stack().push(Type.LONG); 1189 } 1190 1191 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1192 @Override 1193 public void visitMONITORENTER(final MONITORENTER o) { 1194 stack().pop(); 1195 } 1196 1197 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1198 @Override 1199 public void visitMONITOREXIT(final MONITOREXIT o) { 1200 stack().pop(); 1201 } 1202 1203 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1204 @Override 1205 public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) { 1206 stack().pop(o.getDimensions()); 1207 stack().push(o.getType(cpg)); 1208 } 1209 1210 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1211 @Override 1212 public void visitNEW(final NEW o) { 1213 stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg))); 1214 } 1215 1216 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1217 @Override 1218 public void visitNEWARRAY(final NEWARRAY o) { 1219 stack().pop(); 1220 stack().push(o.getType()); 1221 } 1222 1223 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1224 @Override 1225 public void visitNOP(final NOP o) { 1226 } 1227 1228 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1229 @Override 1230 public void visitPOP(final POP o) { 1231 stack().pop(); 1232 } 1233 1234 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1235 @Override 1236 public void visitPOP2(final POP2 o) { 1237 final Type t = stack().pop(); 1238 if (t.getSize() == 1) { 1239 stack().pop(); 1240 } 1241 } 1242 1243 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1244 @Override 1245 public void visitPUTFIELD(final PUTFIELD o) { 1246 stack().pop(2); 1247 } 1248 1249 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1250 @Override 1251 public void visitPUTSTATIC(final PUTSTATIC o) { 1252 stack().pop(); 1253 } 1254 1255 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1256 @Override 1257 public void visitRET(final RET o) { 1258 // do nothing, return address 1259 // is in the local variables. 1260 } 1261 1262 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1263 @Override 1264 public void visitRETURN(final RETURN o) { 1265 // do nothing. 1266 } 1267 1268 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1269 @Override 1270 public void visitSALOAD(final SALOAD o) { 1271 stack().pop(2); 1272 stack().push(Type.INT); 1273 } 1274 1275 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1276 @Override 1277 public void visitSASTORE(final SASTORE o) { 1278 stack().pop(3); 1279 } 1280 1281 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1282 @Override 1283 public void visitSIPUSH(final SIPUSH o) { 1284 stack().push(Type.INT); 1285 } 1286 1287 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1288 @Override 1289 public void visitSWAP(final SWAP o) { 1290 final Type t = stack().pop(); 1291 final Type u = stack().pop(); 1292 stack().push(t); 1293 stack().push(u); 1294 } 1295 1296 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1297 @Override 1298 public void visitTABLESWITCH(final TABLESWITCH o) { 1299 stack().pop(); 1300 } 1301}