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.ConstantDynamic; 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 * 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 modeled 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 possibility 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 private void visitInvokedInternals(final InvokeInstruction o) { 815 stack().pop(o.getArgumentTypes(cpg).length); 816 // We are sure the invoked method will xRETURN eventually 817 // We simulate xRETURNs functionality here because we 818 // don't really "jump into" and simulate the invoked 819 // method. 820 if (o.getReturnType(cpg) != Type.VOID) { 821 Type t = o.getReturnType(cpg); 822 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 823 t = Type.INT; 824 } 825 stack().push(t); 826 } 827 } 828 829 /** 830 * Symbolically executes the corresponding Java Virtual Machine instruction. 831 * 832 * @since 6.0 833 */ 834 @Override 835 public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC o) { 836 visitInvokedInternals(o); 837 } 838 839 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 840 @Override 841 public void visitINVOKEINTERFACE(final INVOKEINTERFACE o) { 842 stack().pop(); // objectref 843 stack().pop(o.getArgumentTypes(cpg).length); 844 // We are sure the invoked method will xRETURN eventually 845 // We simulate xRETURNs functionality here because we 846 // don't really "jump into" and simulate the invoked 847 // method. 848 if (o.getReturnType(cpg) != Type.VOID) { 849 Type t = o.getReturnType(cpg); 850 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 851 t = Type.INT; 852 } 853 stack().push(t); 854 } 855 } 856 857 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 858 @Override 859 public void visitINVOKESPECIAL(final INVOKESPECIAL o) { 860 if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) { 861 final UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length); 862 if (t == Frame.getThis()) { 863 Frame.setThis(null); 864 } 865 stack().initializeObject(t); 866 locals().initializeObject(t); 867 } 868 stack().pop(); // objectref 869 stack().pop(o.getArgumentTypes(cpg).length); 870 // We are sure the invoked method will xRETURN eventually 871 // We simulate xRETURNs functionality here because we 872 // don't really "jump into" and simulate the invoked 873 // method. 874 if (o.getReturnType(cpg) != Type.VOID) { 875 Type t = o.getReturnType(cpg); 876 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 877 t = Type.INT; 878 } 879 stack().push(t); 880 } 881 } 882 883 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 884 @Override 885 public void visitINVOKESTATIC(final INVOKESTATIC o) { 886 visitInvokedInternals(o); 887 } 888 889 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 890 @Override 891 public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL o) { 892 stack().pop(); // objectref 893 stack().pop(o.getArgumentTypes(cpg).length); 894 // We are sure the invoked method will xRETURN eventually 895 // We simulate xRETURNs functionality here because we 896 // don't really "jump into" and simulate the invoked 897 // method. 898 if (o.getReturnType(cpg) != Type.VOID) { 899 Type t = o.getReturnType(cpg); 900 if (t.equals(Type.BOOLEAN) || t.equals(Type.CHAR) || t.equals(Type.BYTE) || t.equals(Type.SHORT)) { 901 t = Type.INT; 902 } 903 stack().push(t); 904 } 905 } 906 907 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 908 @Override 909 public void visitIOR(final IOR o) { 910 stack().pop(2); 911 stack().push(Type.INT); 912 } 913 914 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 915 @Override 916 public void visitIREM(final IREM 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 visitIRETURN(final IRETURN o) { 924 stack().pop(); 925 } 926 927 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 928 @Override 929 public void visitISHL(final ISHL o) { 930 stack().pop(2); 931 stack().push(Type.INT); 932 } 933 934 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 935 @Override 936 public void visitISHR(final ISHR 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 visitISTORE(final ISTORE o) { 944 locals().set(o.getIndex(), stack().pop()); 945 } 946 947 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 948 @Override 949 public void visitISUB(final ISUB o) { 950 stack().pop(2); 951 stack().push(Type.INT); 952 } 953 954 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 955 @Override 956 public void visitIUSHR(final IUSHR 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 visitIXOR(final IXOR 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 visitJSR(final JSR o) { 971 stack().push(new ReturnaddressType(o.physicalSuccessor())); 972//System.err.println("TODO-----------:"+o.physicalSuccessor()); 973 } 974 975 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 976 @Override 977 public void visitJSR_W(final JSR_W o) { 978 stack().push(new ReturnaddressType(o.physicalSuccessor())); 979 } 980 981 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 982 @Override 983 public void visitL2D(final L2D o) { 984 stack().pop(); 985 stack().push(Type.DOUBLE); 986 } 987 988 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 989 @Override 990 public void visitL2F(final L2F o) { 991 stack().pop(); 992 stack().push(Type.FLOAT); 993 } 994 995 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 996 @Override 997 public void visitL2I(final L2I o) { 998 stack().pop(); 999 stack().push(Type.INT); 1000 } 1001 1002 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1003 @Override 1004 public void visitLADD(final LADD o) { 1005 stack().pop(2); 1006 stack().push(Type.LONG); 1007 } 1008 1009 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1010 @Override 1011 public void visitLALOAD(final LALOAD 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 visitLAND(final LAND 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 visitLASTORE(final LASTORE o) { 1026 stack().pop(3); 1027 } 1028 1029 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1030 @Override 1031 public void visitLCMP(final LCMP o) { 1032 stack().pop(2); 1033 stack().push(Type.INT); 1034 } 1035 1036 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1037 @Override 1038 public void visitLCONST(final LCONST o) { 1039 stack().push(Type.LONG); 1040 } 1041 1042 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1043 @Override 1044 public void visitLDC(final LDC o) { 1045 final Constant c = cpg.getConstant(o.getIndex()); 1046 if (c instanceof ConstantInteger) { 1047 stack().push(Type.INT); 1048 } 1049 if (c instanceof ConstantFloat) { 1050 stack().push(Type.FLOAT); 1051 } 1052 if (c instanceof ConstantString) { 1053 stack().push(Type.STRING); 1054 } 1055 if (c instanceof ConstantClass) { 1056 stack().push(Type.CLASS); 1057 } 1058 if (c instanceof ConstantDynamic) { 1059 stack().push(Type.OBJECT); 1060 } 1061 } 1062 1063 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1064 public void visitLDC_W(final LDC_W o) { 1065 final Constant c = cpg.getConstant(o.getIndex()); 1066 if (c instanceof ConstantInteger) { 1067 stack().push(Type.INT); 1068 } 1069 if (c instanceof ConstantFloat) { 1070 stack().push(Type.FLOAT); 1071 } 1072 if (c instanceof ConstantString) { 1073 stack().push(Type.STRING); 1074 } 1075 if (c instanceof ConstantClass) { 1076 stack().push(Type.CLASS); 1077 } 1078 } 1079 1080 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1081 @Override 1082 public void visitLDC2_W(final LDC2_W o) { 1083 final Constant c = cpg.getConstant(o.getIndex()); 1084 if (c instanceof ConstantLong) { 1085 stack().push(Type.LONG); 1086 } 1087 if (c instanceof ConstantDouble) { 1088 stack().push(Type.DOUBLE); 1089 } 1090 } 1091 1092 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1093 @Override 1094 public void visitLDIV(final LDIV o) { 1095 stack().pop(2); 1096 stack().push(Type.LONG); 1097 } 1098 1099 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1100 @Override 1101 public void visitLLOAD(final LLOAD o) { 1102 stack().push(locals().get(o.getIndex())); 1103 } 1104 1105 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1106 @Override 1107 public void visitLMUL(final LMUL o) { 1108 stack().pop(2); 1109 stack().push(Type.LONG); 1110 } 1111 1112 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1113 @Override 1114 public void visitLNEG(final LNEG o) { 1115 stack().pop(); 1116 stack().push(Type.LONG); 1117 } 1118 1119 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1120 @Override 1121 public void visitLOOKUPSWITCH(final LOOKUPSWITCH o) { 1122 stack().pop(); // key 1123 } 1124 1125 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1126 @Override 1127 public void visitLOR(final LOR o) { 1128 stack().pop(2); 1129 stack().push(Type.LONG); 1130 } 1131 1132 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1133 @Override 1134 public void visitLREM(final LREM o) { 1135 stack().pop(2); 1136 stack().push(Type.LONG); 1137 } 1138 1139 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1140 @Override 1141 public void visitLRETURN(final LRETURN o) { 1142 stack().pop(); 1143 } 1144 1145 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1146 @Override 1147 public void visitLSHL(final LSHL o) { 1148 stack().pop(2); 1149 stack().push(Type.LONG); 1150 } 1151 1152 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1153 @Override 1154 public void visitLSHR(final LSHR o) { 1155 stack().pop(2); 1156 stack().push(Type.LONG); 1157 } 1158 1159 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1160 @Override 1161 public void visitLSTORE(final LSTORE o) { 1162 locals().set(o.getIndex(), stack().pop()); 1163 locals().set(o.getIndex() + 1, Type.UNKNOWN); 1164 } 1165 1166 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1167 @Override 1168 public void visitLSUB(final LSUB o) { 1169 stack().pop(2); 1170 stack().push(Type.LONG); 1171 } 1172 1173 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1174 @Override 1175 public void visitLUSHR(final LUSHR o) { 1176 stack().pop(2); 1177 stack().push(Type.LONG); 1178 } 1179 1180 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1181 @Override 1182 public void visitLXOR(final LXOR o) { 1183 stack().pop(2); 1184 stack().push(Type.LONG); 1185 } 1186 1187 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1188 @Override 1189 public void visitMONITORENTER(final MONITORENTER o) { 1190 stack().pop(); 1191 } 1192 1193 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1194 @Override 1195 public void visitMONITOREXIT(final MONITOREXIT o) { 1196 stack().pop(); 1197 } 1198 1199 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1200 @Override 1201 public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) { 1202 stack().pop(o.getDimensions()); 1203 stack().push(o.getType(cpg)); 1204 } 1205 1206 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1207 @Override 1208 public void visitNEW(final NEW o) { 1209 stack().push(new UninitializedObjectType((ObjectType) o.getType(cpg))); 1210 } 1211 1212 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1213 @Override 1214 public void visitNEWARRAY(final NEWARRAY o) { 1215 stack().pop(); 1216 stack().push(o.getType()); 1217 } 1218 1219 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1220 @Override 1221 public void visitNOP(final NOP o) { 1222 } 1223 1224 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1225 @Override 1226 public void visitPOP(final POP o) { 1227 stack().pop(); 1228 } 1229 1230 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1231 @Override 1232 public void visitPOP2(final POP2 o) { 1233 final Type t = stack().pop(); 1234 if (t.getSize() == 1) { 1235 stack().pop(); 1236 } 1237 } 1238 1239 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1240 @Override 1241 public void visitPUTFIELD(final PUTFIELD o) { 1242 stack().pop(2); 1243 } 1244 1245 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1246 @Override 1247 public void visitPUTSTATIC(final PUTSTATIC o) { 1248 stack().pop(); 1249 } 1250 1251 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1252 @Override 1253 public void visitRET(final RET o) { 1254 // do nothing, return address 1255 // is in the local variables. 1256 } 1257 1258 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1259 @Override 1260 public void visitRETURN(final RETURN o) { 1261 // do nothing. 1262 } 1263 1264 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1265 @Override 1266 public void visitSALOAD(final SALOAD o) { 1267 stack().pop(2); 1268 stack().push(Type.INT); 1269 } 1270 1271 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1272 @Override 1273 public void visitSASTORE(final SASTORE o) { 1274 stack().pop(3); 1275 } 1276 1277 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1278 @Override 1279 public void visitSIPUSH(final SIPUSH o) { 1280 stack().push(Type.INT); 1281 } 1282 1283 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1284 @Override 1285 public void visitSWAP(final SWAP o) { 1286 final Type t = stack().pop(); 1287 final Type u = stack().pop(); 1288 stack().push(t); 1289 stack().push(u); 1290 } 1291 1292 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 1293 @Override 1294 public void visitTABLESWITCH(final TABLESWITCH o) { 1295 stack().pop(); 1296 } 1297}