001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel.verifier.structurals; 020 021import org.apache.bcel.Const; 022import org.apache.bcel.classfile.Constant; 023import org.apache.bcel.classfile.ConstantClass; 024import org.apache.bcel.classfile.ConstantDouble; 025import org.apache.bcel.classfile.ConstantDynamic; 026import org.apache.bcel.classfile.ConstantFloat; 027import org.apache.bcel.classfile.ConstantInteger; 028import org.apache.bcel.classfile.ConstantLong; 029import org.apache.bcel.classfile.ConstantString; 030// CHECKSTYLE:OFF (there are lots of references!) 031import org.apache.bcel.generic.*; 032//CHECKSTYLE:ON 033 034/** 035 * This Visitor class may be used for a type-based Java Virtual Machine simulation. 036 * 037 * <p> 038 * It does not check for correct types on the OperandStack or in the LocalVariables; nor does it check their sizes are 039 * sufficiently big. Thus, to use this Visitor for bytecode verifying, you have to make sure externally that the type 040 * constraints of the Java Virtual Machine instructions are satisfied. An InstConstraintVisitor may be used for this. 041 * Anyway, this Visitor does not mandate it. For example, when you visitIADD(IADD o), then there are two stack slots 042 * popped and one stack slot containing a Type.INT is pushed (where you could also pop only one slot if you know there 043 * are two Type.INT on top of the stack). Monitor-specific behavior is not simulated. 044 * </p> 045 * 046 * <strong>Conventions:</strong> 047 * 048 * <p> 049 * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG that would normally take up two stack slots 050 * (like Double_HIGH and Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG object on the stack 051 * here. 052 * </p> 053 * 054 * <p> 055 * If a two-slot type is stored into a local variable, the next variable is given the type Type.UNKNOWN. 056 * </p> 057 * 058 * @see #visitDSTORE(DSTORE o) 059 * @see InstConstraintVisitor 060 */ 061public class ExecutionVisitor extends EmptyVisitor { 062 063 /** 064 * The executionframe we're operating on. 065 */ 066 private Frame frame; 067 068 /** 069 * The ConstantPoolGen we're working with. 070 * 071 * @see #setConstantPoolGen(ConstantPoolGen) 072 */ 073 private ConstantPoolGen cpg; 074 075 /** 076 * Constructs a new instance of this class. 077 */ 078 public ExecutionVisitor() { 079 } 080 081 /** 082 * The LocalVariables from the current Frame we're operating on. 083 * 084 * @see #setFrame(Frame) 085 */ 086 private LocalVariables locals() { 087 return frame.getLocals(); 088 } 089 090 /** 091 * Sets the ConstantPoolGen needed for symbolic execution. 092 */ 093 public void setConstantPoolGen(final ConstantPoolGen cpg) { // TODO could be package-protected? 094 this.cpg = cpg; 095 } 096 097 /** 098 * The only method granting access to the single instance of the ExecutionVisitor class. Before actively using this 099 * instance, <B>SET THE ConstantPoolGen FIRST</B>. 100 * 101 * @see #setConstantPoolGen(ConstantPoolGen) 102 */ 103 public void setFrame(final Frame f) { // TODO could be package-protected? 104 this.frame = f; 105 } 106 107 /** 108 * The OperandStack from the current Frame we're operating on. 109 * 110 * @see #setFrame(Frame) 111 */ 112 private OperandStack stack() { 113 return frame.getStack(); 114 } 115 116 /// ** Symbolically executes the corresponding Java Virtual Machine instruction. */ 117 // public void visitWIDE(WIDE o) { 118 // The WIDE instruction is modeled as a flag 119 // of the embedded instructions in BCEL. 120 // Therefore BCEL checks for possible errors 121 // when parsing in the .class file: We don't 122 // have even the possibility to care for WIDE 123 // here. 124 // } 125 126 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 127 @Override 128 public void visitAALOAD(final AALOAD o) { 129 stack().pop(); // pop the index int 130 // System.out.print(stack().peek()); 131 final Type t = stack().pop(); // Pop Array type 132 if (t == Type.NULL) { 133 stack().push(Type.NULL); 134 } else { 135 final ArrayType at = (ArrayType) t; 136 stack().push(at.getElementType()); 137 } 138 } 139 140 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 141 @Override 142 public void visitAASTORE(final AASTORE o) { 143 stack().pop(3); 144 } 145 146 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 147 @Override 148 public void visitACONST_NULL(final ACONST_NULL o) { 149 stack().push(Type.NULL); 150 } 151 152 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 153 @Override 154 public void visitALOAD(final ALOAD o) { 155 stack().push(locals().get(o.getIndex())); 156 } 157 158 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 159 @Override 160 public void visitANEWARRAY(final ANEWARRAY o) { 161 stack().pop(); // count 162 stack().push(new ArrayType(o.getType(cpg), 1)); 163 } 164 165 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 166 @Override 167 public void visitARETURN(final ARETURN o) { 168 stack().pop(); 169 } 170 171 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 172 @Override 173 public void visitARRAYLENGTH(final ARRAYLENGTH o) { 174 stack().pop(); 175 stack().push(Type.INT); 176 } 177 178 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 179 @Override 180 public void visitASTORE(final ASTORE o) { 181 locals().set(o.getIndex(), stack().pop()); 182 // System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'."); 183 } 184 185 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 186 @Override 187 public void visitATHROW(final ATHROW o) { 188 final Type t = stack().pop(); 189 stack().clear(); 190 if (t.equals(Type.NULL)) { 191 stack().push(Type.getType("Ljava/lang/NullPointerException;")); 192 } else { 193 stack().push(t); 194 } 195 } 196 197 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 198 @Override 199 public void visitBALOAD(final BALOAD o) { 200 stack().pop(2); 201 stack().push(Type.INT); 202 } 203 204 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 205 @Override 206 public void visitBASTORE(final BASTORE o) { 207 stack().pop(3); 208 } 209 210 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 211 @Override 212 public void visitBIPUSH(final BIPUSH o) { 213 stack().push(Type.INT); 214 } 215 216 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 217 @Override 218 public void visitCALOAD(final CALOAD o) { 219 stack().pop(2); 220 stack().push(Type.INT); 221 } 222 223 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 224 @Override 225 public void visitCASTORE(final CASTORE o) { 226 stack().pop(3); 227 } 228 229 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 230 @Override 231 public void visitCHECKCAST(final CHECKCAST o) { 232 // It's possibly wrong to do so, but SUN's 233 // ByteCode verifier seems to do (only) this, too. 234 // TODO: One could use a sophisticated analysis here to check 235 // if a type cannot possibly be cated to another and by 236 // so doing predict the ClassCastException at run-time. 237 stack().pop(); 238 stack().push(o.getType(cpg)); 239 } 240 241 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 242 @Override 243 public void visitD2F(final D2F o) { 244 stack().pop(); 245 stack().push(Type.FLOAT); 246 } 247 248 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 249 @Override 250 public void visitD2I(final D2I o) { 251 stack().pop(); 252 stack().push(Type.INT); 253 } 254 255 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 256 @Override 257 public void visitD2L(final D2L o) { 258 stack().pop(); 259 stack().push(Type.LONG); 260 } 261 262 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 263 @Override 264 public void visitDADD(final DADD o) { 265 stack().pop(2); 266 stack().push(Type.DOUBLE); 267 } 268 269 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 270 @Override 271 public void visitDALOAD(final DALOAD o) { 272 stack().pop(2); 273 stack().push(Type.DOUBLE); 274 } 275 276 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 277 @Override 278 public void visitDASTORE(final DASTORE o) { 279 stack().pop(3); 280 } 281 282 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 283 @Override 284 public void visitDCMPG(final DCMPG o) { 285 stack().pop(2); 286 stack().push(Type.INT); 287 } 288 289 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 290 @Override 291 public void visitDCMPL(final DCMPL o) { 292 stack().pop(2); 293 stack().push(Type.INT); 294 } 295 296 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 297 @Override 298 public void visitDCONST(final DCONST o) { 299 stack().push(Type.DOUBLE); 300 } 301 302 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 303 @Override 304 public void visitDDIV(final DDIV o) { 305 stack().pop(2); 306 stack().push(Type.DOUBLE); 307 } 308 309 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 310 @Override 311 public void visitDLOAD(final DLOAD o) { 312 stack().push(Type.DOUBLE); 313 } 314 315 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 316 @Override 317 public void visitDMUL(final DMUL o) { 318 stack().pop(2); 319 stack().push(Type.DOUBLE); 320 } 321 322 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 323 @Override 324 public void visitDNEG(final DNEG o) { 325 stack().pop(); 326 stack().push(Type.DOUBLE); 327 } 328 329 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 330 @Override 331 public void visitDREM(final DREM o) { 332 stack().pop(2); 333 stack().push(Type.DOUBLE); 334 } 335 336 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 337 @Override 338 public void visitDRETURN(final DRETURN o) { 339 stack().pop(); 340 } 341 342 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 343 @Override 344 public void visitDSTORE(final DSTORE o) { 345 locals().set(o.getIndex(), stack().pop()); 346 locals().set(o.getIndex() + 1, Type.UNKNOWN); 347 } 348 349 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 350 @Override 351 public void visitDSUB(final DSUB o) { 352 stack().pop(2); 353 stack().push(Type.DOUBLE); 354 } 355 356 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 357 @Override 358 public void visitDUP(final DUP o) { 359 final Type t = stack().pop(); 360 stack().push(t); 361 stack().push(t); 362 } 363 364 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 365 @Override 366 public void visitDUP_X1(final DUP_X1 o) { 367 final Type w1 = stack().pop(); 368 final Type w2 = stack().pop(); 369 stack().push(w1); 370 stack().push(w2); 371 stack().push(w1); 372 } 373 374 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 375 @Override 376 public void visitDUP_X2(final DUP_X2 o) { 377 final Type w1 = stack().pop(); 378 final Type w2 = stack().pop(); 379 if (w2.getSize() == 2) { 380 stack().push(w1); 381 } else { 382 final Type w3 = stack().pop(); 383 stack().push(w1); 384 stack().push(w3); 385 } 386 stack().push(w2); 387 stack().push(w1); 388 } 389 390 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 391 @Override 392 public void visitDUP2(final DUP2 o) { 393 final Type t = stack().pop(); 394 if (t.getSize() == 2) { 395 stack().push(t); 396 } else { // t.getSize() is 1 397 final Type u = stack().pop(); 398 stack().push(u); 399 stack().push(t); 400 stack().push(u); 401 } 402 stack().push(t); 403 } 404 405 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 406 @Override 407 public void visitDUP2_X1(final DUP2_X1 o) { 408 final Type t = stack().pop(); 409 if (t.getSize() == 2) { 410 final Type u = stack().pop(); 411 stack().push(t); 412 stack().push(u); 413 } else { // t.getSize() is1 414 final Type u = stack().pop(); 415 final Type v = stack().pop(); 416 stack().push(u); 417 stack().push(t); 418 stack().push(v); 419 stack().push(u); 420 } 421 stack().push(t); 422 } 423 424 /** Symbolically executes the corresponding Java Virtual Machine instruction. */ 425 @Override 426 public void visitDUP2_X2(final DUP2_X2 o) { 427 final Type t = stack().pop(); 428 if (t.getSize() == 2) { 429 final Type u = stack().pop(); 430 if (u.getSize() == 2) { 431 stack().push(t); 432 } else { 433 final Type v = stack().pop(); 434 stack().push(t); 435 stack().push(v); 436 } 437 stack().push(u); 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 } 453 stack().push(t); 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}