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