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