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