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