1. package com.sun.org.apache.bcel.internal.verifier.structurals;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <http://www.apache.org/>.
  54. */
  55. import com.sun.org.apache.bcel.internal.Constants;
  56. import com.sun.org.apache.bcel.internal.Repository;
  57. import com.sun.org.apache.bcel.internal.generic.*;
  58. import com.sun.org.apache.bcel.internal.classfile.JavaClass;
  59. import com.sun.org.apache.bcel.internal.classfile.Constant;
  60. import com.sun.org.apache.bcel.internal.classfile.ConstantDouble;
  61. import com.sun.org.apache.bcel.internal.classfile.ConstantFloat;
  62. import com.sun.org.apache.bcel.internal.classfile.ConstantInteger;
  63. import com.sun.org.apache.bcel.internal.classfile.ConstantLong;
  64. import com.sun.org.apache.bcel.internal.classfile.ConstantString;
  65. import com.sun.org.apache.bcel.internal.verifier.Verifier;
  66. import com.sun.org.apache.bcel.internal.verifier.exc.*;
  67. import java.util.ArrayList;
  68. import java.util.Hashtable;
  69. /**
  70. * This Visitor class may be used for a type-based Java Virtual Machine
  71. * simulation.
  72. * It does not check for correct types on the OperandStack or in the
  73. * LocalVariables; nor does it check their sizes are sufficiently big.
  74. * Thus, to use this Visitor for bytecode verifying, you have to make sure
  75. * externally that the type constraints of the Java Virtual Machine instructions
  76. * are satisfied. An InstConstraintVisitor may be used for this.
  77. * Anyway, this Visitor does not mandate it. For example, when you
  78. * visitIADD(IADD o), then there are two stack slots popped and one
  79. * stack slot containing a Type.INT is pushed (where you could also
  80. * pop only one slot if you know there are two Type.INT on top of the
  81. * stack). Monitor-specific behaviour is not simulated.
  82. *
  83. * </P><B>Conventions:</B>
  84. *
  85. * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG
  86. * that would normally take up two stack slots (like Double_HIGH and
  87. * Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG
  88. * object on the stack here.
  89. * If a two-slot type is stored into a local variable, the next variable
  90. * is given the type Type.UNKNOWN.
  91. *
  92. * @version $Id: ExecutionVisitor.java,v 1.1.1.1 2001/10/29 20:00:39 jvanzyl Exp $
  93. * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
  94. * @see #visitDSTORE(DSTORE o)
  95. * @see InstConstraintVisitor
  96. */
  97. public class ExecutionVisitor extends EmptyVisitor implements Visitor{
  98. /**
  99. * The executionframe we're operating on.
  100. */
  101. private Frame frame = null;
  102. /**
  103. * The ConstantPoolGen we're working with.
  104. * @see #setConstantPoolGen(ConstantPoolGen)
  105. */
  106. private ConstantPoolGen cpg = null;
  107. /**
  108. * Constructor. Constructs a new instance of this class.
  109. */
  110. public ExecutionVisitor(){}
  111. /**
  112. * The OperandStack from the current Frame we're operating on.
  113. * @see #setFrame(Frame)
  114. */
  115. private OperandStack stack(){
  116. return frame.getStack();
  117. }
  118. /**
  119. * The LocalVariables from the current Frame we're operating on.
  120. * @see #setFrame(Frame)
  121. */
  122. private LocalVariables locals(){
  123. return frame.getLocals();
  124. }
  125. /**
  126. * Sets the ConstantPoolGen needed for symbolic execution.
  127. */
  128. public void setConstantPoolGen(ConstantPoolGen cpg){
  129. this.cpg = cpg;
  130. }
  131. /**
  132. * The only method granting access to the single instance of
  133. * the ExecutionVisitor class. Before actively using this
  134. * instance, <B>SET THE ConstantPoolGen FIRST</B>.
  135. * @see #setConstantPoolGen(ConstantPoolGen)
  136. */
  137. public void setFrame(Frame f){
  138. this.frame = f;
  139. }
  140. ///** Symbolically executes the corresponding Java Virtual Machine instruction. */
  141. //public void visitWIDE(WIDE o){
  142. // The WIDE instruction is modelled as a flag
  143. // of the embedded instructions in BCEL.
  144. // Therefore BCEL checks for possible errors
  145. // when parsing in the .class file: We don't
  146. // have even the possibilty to care for WIDE
  147. // here.
  148. //}
  149. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  150. public void visitAALOAD(AALOAD o){
  151. stack().pop(); // pop the index int
  152. //System.out.print(stack().peek());
  153. Type t = stack().pop(); // Pop Array type
  154. if (t == Type.NULL){
  155. stack().push(Type.NULL);
  156. } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time
  157. else{
  158. ArrayType at = (ArrayType) t;
  159. stack().push(at.getElementType());
  160. }
  161. }
  162. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  163. public void visitAASTORE(AASTORE o){
  164. stack().pop();
  165. stack().pop();
  166. stack().pop();
  167. }
  168. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  169. public void visitACONST_NULL(ACONST_NULL o){
  170. stack().push(Type.NULL);
  171. }
  172. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  173. public void visitALOAD(ALOAD o){
  174. stack().push(locals().get(o.getIndex()));
  175. }
  176. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  177. public void visitANEWARRAY(ANEWARRAY o){
  178. stack().pop(); //count
  179. stack().push( new ArrayType(o.getType(cpg), 1) );
  180. }
  181. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  182. public void visitARETURN(ARETURN o){
  183. stack().pop();
  184. }
  185. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  186. public void visitARRAYLENGTH(ARRAYLENGTH o){
  187. stack().pop();
  188. stack().push(Type.INT);
  189. }
  190. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  191. public void visitASTORE(ASTORE o){
  192. locals().set(o.getIndex(), stack().pop());
  193. //System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'.");
  194. }
  195. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  196. public void visitATHROW(ATHROW o){
  197. Type t = stack().pop();
  198. stack().clear();
  199. if (t.equals(Type.NULL))
  200. stack().push(Type.getType("Ljava/lang/NullPointerException;"));
  201. else
  202. stack().push(t);
  203. }
  204. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  205. public void visitBALOAD(BALOAD o){
  206. stack().pop();
  207. stack().pop();
  208. stack().push(Type.INT);
  209. }
  210. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  211. public void visitBASTORE(BASTORE o){
  212. stack().pop();
  213. stack().pop();
  214. stack().pop();
  215. }
  216. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  217. public void visitBIPUSH(BIPUSH o){
  218. stack().push(Type.INT);
  219. }
  220. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  221. public void visitCALOAD(CALOAD o){
  222. stack().pop();
  223. stack().pop();
  224. stack().push(Type.INT);
  225. }
  226. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  227. public void visitCASTORE(CASTORE o){
  228. stack().pop();
  229. stack().pop();
  230. stack().pop();
  231. }
  232. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  233. public void visitCHECKCAST(CHECKCAST o){
  234. // It's possibly wrong to do so, but SUN's
  235. // ByteCode verifier seems to do (only) this, too.
  236. // TODO: One could use a sophisticated analysis here to check
  237. // if a type cannot possibly be cated to another and by
  238. // so doing predict the ClassCastException at run-time.
  239. stack().pop();
  240. stack().push(o.getType(cpg));
  241. }
  242. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  243. public void visitD2F(D2F o){
  244. stack().pop();
  245. stack().push(Type.FLOAT);
  246. }
  247. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  248. public void visitD2I(D2I o){
  249. stack().pop();
  250. stack().push(Type.INT);
  251. }
  252. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  253. public void visitD2L(D2L o){
  254. stack().pop();
  255. stack().push(Type.LONG);
  256. }
  257. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  258. public void visitDADD(DADD o){
  259. stack().pop();
  260. stack().pop();
  261. stack().push(Type.DOUBLE);
  262. }
  263. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  264. public void visitDALOAD(DALOAD o){
  265. stack().pop();
  266. stack().pop();
  267. stack().push(Type.DOUBLE);
  268. }
  269. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  270. public void visitDASTORE(DASTORE o){
  271. stack().pop();
  272. stack().pop();
  273. stack().pop();
  274. }
  275. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  276. public void visitDCMPG(DCMPG o){
  277. stack().pop();
  278. stack().pop();
  279. stack().push(Type.INT);
  280. }
  281. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  282. public void visitDCMPL(DCMPL o){
  283. stack().pop();
  284. stack().pop();
  285. stack().push(Type.INT);
  286. }
  287. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  288. public void visitDCONST(DCONST o){
  289. stack().push(Type.DOUBLE);
  290. }
  291. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  292. public void visitDDIV(DDIV o){
  293. stack().pop();
  294. stack().pop();
  295. stack().push(Type.DOUBLE);
  296. }
  297. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  298. public void visitDLOAD(DLOAD o){
  299. stack().push(Type.DOUBLE);
  300. }
  301. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  302. public void visitDMUL(DMUL o){
  303. stack().pop();
  304. stack().pop();
  305. stack().push(Type.DOUBLE);
  306. }
  307. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  308. public void visitDNEG(DNEG o){
  309. stack().pop();
  310. stack().push(Type.DOUBLE);
  311. }
  312. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  313. public void visitDREM(DREM o){
  314. stack().pop();
  315. stack().pop();
  316. stack().push(Type.DOUBLE);
  317. }
  318. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  319. public void visitDRETURN(DRETURN o){
  320. stack().pop();
  321. }
  322. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  323. public void visitDSTORE(DSTORE o){
  324. locals().set(o.getIndex(), stack().pop());
  325. locals().set(o.getIndex()+1, Type.UNKNOWN);
  326. }
  327. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  328. public void visitDSUB(DSUB o){
  329. stack().pop();
  330. stack().pop();
  331. stack().push(Type.DOUBLE);
  332. }
  333. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  334. public void visitDUP(DUP o){
  335. Type t = stack().pop();
  336. stack().push(t);
  337. stack().push(t);
  338. }
  339. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  340. public void visitDUP_X1(DUP_X1 o){
  341. Type w1 = stack().pop();
  342. Type w2 = stack().pop();
  343. stack().push(w1);
  344. stack().push(w2);
  345. stack().push(w1);
  346. }
  347. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  348. public void visitDUP_X2(DUP_X2 o){
  349. Type w1 = stack().pop();
  350. Type w2 = stack().pop();
  351. if (w2.getSize() == 2){
  352. stack().push(w1);
  353. stack().push(w2);
  354. stack().push(w1);
  355. }
  356. else{
  357. Type w3 = stack().pop();
  358. stack().push(w1);
  359. stack().push(w3);
  360. stack().push(w2);
  361. stack().push(w1);
  362. }
  363. }
  364. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  365. public void visitDUP2(DUP2 o){
  366. Type t = stack().pop();
  367. if (t.getSize() == 2){
  368. stack().push(t);
  369. stack().push(t);
  370. }
  371. else{ // t.getSize() is 1
  372. Type u = stack().pop();
  373. stack().push(u);
  374. stack().push(t);
  375. stack().push(u);
  376. stack().push(t);
  377. }
  378. }
  379. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  380. public void visitDUP2_X1(DUP2_X1 o){
  381. Type t = stack().pop();
  382. if (t.getSize() == 2){
  383. Type u = stack().pop();
  384. stack().push(t);
  385. stack().push(u);
  386. stack().push(t);
  387. }
  388. else{ //t.getSize() is1
  389. Type u = stack().pop();
  390. Type v = stack().pop();
  391. stack().push(u);
  392. stack().push(t);
  393. stack().push(v);
  394. stack().push(u);
  395. stack().push(t);
  396. }
  397. }
  398. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  399. public void visitDUP2_X2(DUP2_X2 o){
  400. Type t = stack().pop();
  401. if (t.getSize() == 2){
  402. Type u = stack().pop();
  403. if (u.getSize() == 2){
  404. stack().push(t);
  405. stack().push(u);
  406. stack().push(t);
  407. }else{
  408. Type v = stack().pop();
  409. stack().push(t);
  410. stack().push(v);
  411. stack().push(u);
  412. stack().push(t);
  413. }
  414. }
  415. else{ //t.getSize() is 1
  416. Type u = stack().pop();
  417. Type v = stack().pop();
  418. if (v.getSize() == 2){
  419. stack().push(u);
  420. stack().push(t);
  421. stack().push(v);
  422. stack().push(u);
  423. stack().push(t);
  424. }else{
  425. Type w = stack().pop();
  426. stack().push(u);
  427. stack().push(t);
  428. stack().push(w);
  429. stack().push(v);
  430. stack().push(u);
  431. stack().push(t);
  432. }
  433. }
  434. }
  435. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  436. public void visitF2D(F2D o){
  437. stack().pop();
  438. stack().push(Type.DOUBLE);
  439. }
  440. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  441. public void visitF2I(F2I o){
  442. stack().pop();
  443. stack().push(Type.INT);
  444. }
  445. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  446. public void visitF2L(F2L o){
  447. stack().pop();
  448. stack().push(Type.LONG);
  449. }
  450. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  451. public void visitFADD(FADD o){
  452. stack().pop();
  453. stack().pop();
  454. stack().push(Type.FLOAT);
  455. }
  456. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  457. public void visitFALOAD(FALOAD o){
  458. stack().pop();
  459. stack().pop();
  460. stack().push(Type.FLOAT);
  461. }
  462. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  463. public void visitFASTORE(FASTORE o){
  464. stack().pop();
  465. stack().pop();
  466. stack().pop();
  467. }
  468. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  469. public void visitFCMPG(FCMPG o){
  470. stack().pop();
  471. stack().pop();
  472. stack().push(Type.INT);
  473. }
  474. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  475. public void visitFCMPL(FCMPL o){
  476. stack().pop();
  477. stack().pop();
  478. stack().push(Type.INT);
  479. }
  480. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  481. public void visitFCONST(FCONST o){
  482. stack().push(Type.FLOAT);
  483. }
  484. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  485. public void visitFDIV(FDIV o){
  486. stack().pop();
  487. stack().pop();
  488. stack().push(Type.FLOAT);
  489. }
  490. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  491. public void visitFLOAD(FLOAD o){
  492. stack().push(Type.FLOAT);
  493. }
  494. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  495. public void visitFMUL(FMUL o){
  496. stack().pop();
  497. stack().pop();
  498. stack().push(Type.FLOAT);
  499. }
  500. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  501. public void visitFNEG(FNEG o){
  502. stack().pop();
  503. stack().push(Type.FLOAT);
  504. }
  505. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  506. public void visitFREM(FREM o){
  507. stack().pop();
  508. stack().pop();
  509. stack().push(Type.FLOAT);
  510. }
  511. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  512. public void visitFRETURN(FRETURN o){
  513. stack().pop();
  514. }
  515. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  516. public void visitFSTORE(FSTORE o){
  517. locals().set(o.getIndex(), stack().pop());
  518. }
  519. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  520. public void visitFSUB(FSUB o){
  521. stack().pop();
  522. stack().pop();
  523. stack().push(Type.FLOAT);
  524. }
  525. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  526. public void visitGETFIELD(GETFIELD o){
  527. stack().pop();
  528. Type t = o.getFieldType(cpg);
  529. if ( t.equals(Type.BOOLEAN) ||
  530. t.equals(Type.CHAR) ||
  531. t.equals(Type.BYTE) ||
  532. t.equals(Type.SHORT) )
  533. t = Type.INT;
  534. stack().push(t);
  535. }
  536. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  537. public void visitGETSTATIC(GETSTATIC o){
  538. Type t = o.getFieldType(cpg);
  539. if ( t.equals(Type.BOOLEAN) ||
  540. t.equals(Type.CHAR) ||
  541. t.equals(Type.BYTE) ||
  542. t.equals(Type.SHORT) )
  543. t = Type.INT;
  544. stack().push(t);
  545. }
  546. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  547. public void visitGOTO(GOTO o){
  548. // no stack changes.
  549. }
  550. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  551. public void visitGOTO_W(GOTO_W o){
  552. // no stack changes.
  553. }
  554. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  555. public void visitI2B(I2B o){
  556. stack().pop();
  557. stack().push(Type.INT);
  558. }
  559. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  560. public void visitI2C(I2C o){
  561. stack().pop();
  562. stack().push(Type.INT);
  563. }
  564. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  565. public void visitI2D(I2D o){
  566. stack().pop();
  567. stack().push(Type.DOUBLE);
  568. }
  569. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  570. public void visitI2F(I2F o){
  571. stack().pop();
  572. stack().push(Type.FLOAT);
  573. }
  574. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  575. public void visitI2L(I2L o){
  576. stack().pop();
  577. stack().push(Type.LONG);
  578. }
  579. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  580. public void visitI2S(I2S o){
  581. stack().pop();
  582. stack().push(Type.INT);
  583. }
  584. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  585. public void visitIADD(IADD o){
  586. stack().pop();
  587. stack().pop();
  588. stack().push(Type.INT);
  589. }
  590. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  591. public void visitIALOAD(IALOAD o){
  592. stack().pop();
  593. stack().pop();
  594. stack().push(Type.INT);
  595. }
  596. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  597. public void visitIAND(IAND o){
  598. stack().pop();
  599. stack().pop();
  600. stack().push(Type.INT);
  601. }
  602. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  603. public void visitIASTORE(IASTORE o){
  604. stack().pop();
  605. stack().pop();
  606. stack().pop();
  607. }
  608. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  609. public void visitICONST(ICONST o){
  610. stack().push(Type.INT);
  611. }
  612. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  613. public void visitIDIV(IDIV o){
  614. stack().pop();
  615. stack().pop();
  616. stack().push(Type.INT);
  617. }
  618. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  619. public void visitIF_ACMPEQ(IF_ACMPEQ o){
  620. stack().pop();
  621. stack().pop();
  622. }
  623. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  624. public void visitIF_ACMPNE(IF_ACMPNE o){
  625. stack().pop();
  626. stack().pop();
  627. }
  628. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  629. public void visitIF_ICMPEQ(IF_ICMPEQ o){
  630. stack().pop();
  631. stack().pop();
  632. }
  633. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  634. public void visitIF_ICMPGE(IF_ICMPGE o){
  635. stack().pop();
  636. stack().pop();
  637. }
  638. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  639. public void visitIF_ICMPGT(IF_ICMPGT o){
  640. stack().pop();
  641. stack().pop();
  642. }
  643. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  644. public void visitIF_ICMPLE(IF_ICMPLE o){
  645. stack().pop();
  646. stack().pop();
  647. }
  648. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  649. public void visitIF_ICMPLT(IF_ICMPLT o){
  650. stack().pop();
  651. stack().pop();
  652. }
  653. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  654. public void visitIF_ICMPNE(IF_ICMPNE o){
  655. stack().pop();
  656. stack().pop();
  657. }
  658. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  659. public void visitIFEQ(IFEQ o){
  660. stack().pop();
  661. }
  662. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  663. public void visitIFGE(IFGE o){
  664. stack().pop();
  665. }
  666. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  667. public void visitIFGT(IFGT o){
  668. stack().pop();
  669. }
  670. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  671. public void visitIFLE(IFLE o){
  672. stack().pop();
  673. }
  674. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  675. public void visitIFLT(IFLT o){
  676. stack().pop();
  677. }
  678. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  679. public void visitIFNE(IFNE o){
  680. stack().pop();
  681. }
  682. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  683. public void visitIFNONNULL(IFNONNULL o){
  684. stack().pop();
  685. }
  686. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  687. public void visitIFNULL(IFNULL o){
  688. stack().pop();
  689. }
  690. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  691. public void visitIINC(IINC o){
  692. // stack is not changed.
  693. }
  694. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  695. public void visitILOAD(ILOAD o){
  696. stack().push(Type.INT);
  697. }
  698. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  699. public void visitIMUL(IMUL o){
  700. stack().pop();
  701. stack().pop();
  702. stack().push(Type.INT);
  703. }
  704. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  705. public void visitINEG(INEG o){
  706. stack().pop();
  707. stack().push(Type.INT);
  708. }
  709. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  710. public void visitINSTANCEOF(INSTANCEOF o){
  711. stack().pop();
  712. stack().push(Type.INT);
  713. }
  714. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  715. public void visitINVOKEINTERFACE(INVOKEINTERFACE o){
  716. stack().pop(); //objectref
  717. for (int i=0; i<o.getArgumentTypes(cpg).length; i++){
  718. stack().pop();
  719. }
  720. // We are sure the invoked method will xRETURN eventually
  721. // We simulate xRETURNs functionality here because we
  722. // don't really "jump into" and simulate the invoked
  723. // method.
  724. if (o.getReturnType(cpg) != Type.VOID){
  725. Type t = o.getReturnType(cpg);
  726. if ( t.equals(Type.BOOLEAN) ||
  727. t.equals(Type.CHAR) ||
  728. t.equals(Type.BYTE) ||
  729. t.equals(Type.SHORT) )
  730. t = Type.INT;
  731. stack().push(t);
  732. }
  733. }
  734. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  735. public void visitINVOKESPECIAL(INVOKESPECIAL o){
  736. if (o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME)){
  737. UninitializedObjectType t = (UninitializedObjectType) stack().peek(o.getArgumentTypes(cpg).length);
  738. if (t == frame._this){
  739. frame._this = null;
  740. }
  741. stack().initializeObject(t);
  742. locals().initializeObject(t);
  743. }
  744. stack().pop(); //objectref
  745. for (int i=0; i<o.getArgumentTypes(cpg).length; i++){
  746. stack().pop();
  747. }
  748. // We are sure the invoked method will xRETURN eventually
  749. // We simulate xRETURNs functionality here because we
  750. // don't really "jump into" and simulate the invoked
  751. // method.
  752. if (o.getReturnType(cpg) != Type.VOID){
  753. Type t = o.getReturnType(cpg);
  754. if ( t.equals(Type.BOOLEAN) ||
  755. t.equals(Type.CHAR) ||
  756. t.equals(Type.BYTE) ||
  757. t.equals(Type.SHORT) )
  758. t = Type.INT;
  759. stack().push(t);
  760. }
  761. }
  762. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  763. public void visitINVOKESTATIC(INVOKESTATIC o){
  764. for (int i=0; i<o.getArgumentTypes(cpg).length; i++){
  765. stack().pop();
  766. }
  767. // We are sure the invoked method will xRETURN eventually
  768. // We simulate xRETURNs functionality here because we
  769. // don't really "jump into" and simulate the invoked
  770. // method.
  771. if (o.getReturnType(cpg) != Type.VOID){
  772. Type t = o.getReturnType(cpg);
  773. if ( t.equals(Type.BOOLEAN) ||
  774. t.equals(Type.CHAR) ||
  775. t.equals(Type.BYTE) ||
  776. t.equals(Type.SHORT) )
  777. t = Type.INT;
  778. stack().push(t);
  779. }
  780. }
  781. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  782. public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){
  783. stack().pop(); //objectref
  784. for (int i=0; i<o.getArgumentTypes(cpg).length; i++){
  785. stack().pop();
  786. }
  787. // We are sure the invoked method will xRETURN eventually
  788. // We simulate xRETURNs functionality here because we
  789. // don't really "jump into" and simulate the invoked
  790. // method.
  791. if (o.getReturnType(cpg) != Type.VOID){
  792. Type t = o.getReturnType(cpg);
  793. if ( t.equals(Type.BOOLEAN) ||
  794. t.equals(Type.CHAR) ||
  795. t.equals(Type.BYTE) ||
  796. t.equals(Type.SHORT) )
  797. t = Type.INT;
  798. stack().push(t);
  799. }
  800. }
  801. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  802. public void visitIOR(IOR o){
  803. stack().pop();
  804. stack().pop();
  805. stack().push(Type.INT);
  806. }
  807. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  808. public void visitIREM(IREM o){
  809. stack().pop();
  810. stack().pop();
  811. stack().push(Type.INT);
  812. }
  813. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  814. public void visitIRETURN(IRETURN o){
  815. stack().pop();
  816. }
  817. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  818. public void visitISHL(ISHL o){
  819. stack().pop();
  820. stack().pop();
  821. stack().push(Type.INT);
  822. }
  823. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  824. public void visitISHR(ISHR o){
  825. stack().pop();
  826. stack().pop();
  827. stack().push(Type.INT);
  828. }
  829. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  830. public void visitISTORE(ISTORE o){
  831. locals().set(o.getIndex(), stack().pop());
  832. }
  833. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  834. public void visitISUB(ISUB o){
  835. stack().pop();
  836. stack().pop();
  837. stack().push(Type.INT);
  838. }
  839. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  840. public void visitIUSHR(IUSHR o){
  841. stack().pop();
  842. stack().pop();
  843. stack().push(Type.INT);
  844. }
  845. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  846. public void visitIXOR(IXOR o){
  847. stack().pop();
  848. stack().pop();
  849. stack().push(Type.INT);
  850. }
  851. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  852. public void visitJSR(JSR o){
  853. stack().push(new ReturnaddressType(o.physicalSuccessor()));
  854. //System.err.println("TODO-----------:"+o.physicalSuccessor());
  855. }
  856. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  857. public void visitJSR_W(JSR_W o){
  858. stack().push(new ReturnaddressType(o.physicalSuccessor()));
  859. }
  860. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  861. public void visitL2D(L2D o){
  862. stack().pop();
  863. stack().push(Type.DOUBLE);
  864. }
  865. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  866. public void visitL2F(L2F o){
  867. stack().pop();
  868. stack().push(Type.FLOAT);
  869. }
  870. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  871. public void visitL2I(L2I o){
  872. stack().pop();
  873. stack().push(Type.INT);
  874. }
  875. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  876. public void visitLADD(LADD o){
  877. stack().pop();
  878. stack().pop();
  879. stack().push(Type.LONG);
  880. }
  881. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  882. public void visitLALOAD(LALOAD o){
  883. stack().pop();
  884. stack().pop();
  885. stack().push(Type.LONG);
  886. }
  887. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  888. public void visitLAND(LAND o){
  889. stack().pop();
  890. stack().pop();
  891. stack().push(Type.LONG);
  892. }
  893. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  894. public void visitLASTORE(LASTORE o){
  895. stack().pop();
  896. stack().pop();
  897. stack().pop();
  898. }
  899. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  900. public void visitLCMP(LCMP o){
  901. stack().pop();
  902. stack().pop();
  903. stack().push(Type.INT);
  904. }
  905. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  906. public void visitLCONST(LCONST o){
  907. stack().push(Type.LONG);
  908. }
  909. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  910. public void visitLDC(LDC o){
  911. Constant c = cpg.getConstant(o.getIndex());
  912. if (c instanceof ConstantInteger){
  913. stack().push(Type.INT);
  914. }
  915. if (c instanceof ConstantFloat){
  916. stack().push(Type.FLOAT);
  917. }
  918. if (c instanceof ConstantString){
  919. stack().push(Type.STRING);
  920. }
  921. }
  922. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  923. public void visitLDC_W(LDC_W o){
  924. Constant c = cpg.getConstant(o.getIndex());
  925. if (c instanceof ConstantInteger){
  926. stack().push(Type.INT);
  927. }
  928. if (c instanceof ConstantFloat){
  929. stack().push(Type.FLOAT);
  930. }
  931. if (c instanceof ConstantString){
  932. stack().push(Type.STRING);
  933. }
  934. }
  935. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  936. public void visitLDC2_W(LDC2_W o){
  937. Constant c = cpg.getConstant(o.getIndex());
  938. if (c instanceof ConstantLong){
  939. stack().push(Type.LONG);
  940. }
  941. if (c instanceof ConstantDouble){
  942. stack().push(Type.DOUBLE);
  943. }
  944. }
  945. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  946. public void visitLDIV(LDIV o){
  947. stack().pop();
  948. stack().pop();
  949. stack().push(Type.LONG);
  950. }
  951. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  952. public void visitLLOAD(LLOAD o){
  953. stack().push(locals().get(o.getIndex()));
  954. }
  955. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  956. public void visitLMUL(LMUL o){
  957. stack().pop();
  958. stack().pop();
  959. stack().push(Type.LONG);
  960. }
  961. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  962. public void visitLNEG(LNEG o){
  963. stack().pop();
  964. stack().push(Type.LONG);
  965. }
  966. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  967. public void visitLOOKUPSWITCH(LOOKUPSWITCH o){
  968. stack().pop(); //key
  969. }
  970. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  971. public void visitLOR(LOR o){
  972. stack().pop();
  973. stack().pop();
  974. stack().push(Type.LONG);
  975. }
  976. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  977. public void visitLREM(LREM o){
  978. stack().pop();
  979. stack().pop();
  980. stack().push(Type.LONG);
  981. }
  982. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  983. public void visitLRETURN(LRETURN o){
  984. stack().pop();
  985. }
  986. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  987. public void visitLSHL(LSHL o){
  988. stack().pop();
  989. stack().pop();
  990. stack().push(Type.LONG);
  991. }
  992. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  993. public void visitLSHR(LSHR o){
  994. stack().pop();
  995. stack().pop();
  996. stack().push(Type.LONG);
  997. }
  998. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  999. public void visitLSTORE(LSTORE o){
  1000. locals().set(o.getIndex(), stack().pop());
  1001. locals().set(o.getIndex()+1, Type.UNKNOWN);
  1002. }
  1003. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1004. public void visitLSUB(LSUB o){
  1005. stack().pop();
  1006. stack().pop();
  1007. stack().push(Type.LONG);
  1008. }
  1009. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1010. public void visitLUSHR(LUSHR o){
  1011. stack().pop();
  1012. stack().pop();
  1013. stack().push(Type.LONG);
  1014. }
  1015. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1016. public void visitLXOR(LXOR o){
  1017. stack().pop();
  1018. stack().pop();
  1019. stack().push(Type.LONG);
  1020. }
  1021. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1022. public void visitMONITORENTER(MONITORENTER o){
  1023. stack().pop();
  1024. }
  1025. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1026. public void visitMONITOREXIT(MONITOREXIT o){
  1027. stack().pop();
  1028. }
  1029. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1030. public void visitMULTIANEWARRAY(MULTIANEWARRAY o){
  1031. for (int i=0; i<o.getDimensions(); i++){
  1032. stack().pop();
  1033. }
  1034. stack().push(o.getType(cpg));
  1035. }
  1036. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1037. public void visitNEW(NEW o){
  1038. stack().push(new UninitializedObjectType((ObjectType) (o.getType(cpg))));
  1039. }
  1040. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1041. public void visitNEWARRAY(NEWARRAY o){
  1042. stack().pop();
  1043. stack().push(o.getType());
  1044. }
  1045. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1046. public void visitNOP(NOP o){
  1047. }
  1048. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1049. public void visitPOP(POP o){
  1050. stack().pop();
  1051. }
  1052. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1053. public void visitPOP2(POP2 o){
  1054. Type t = stack().pop();
  1055. if (t.getSize() == 1){
  1056. stack().pop();
  1057. }
  1058. }
  1059. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1060. public void visitPUTFIELD(PUTFIELD o){
  1061. stack().pop();
  1062. stack().pop();
  1063. }
  1064. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1065. public void visitPUTSTATIC(PUTSTATIC o){
  1066. stack().pop();
  1067. }
  1068. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1069. public void visitRET(RET o){
  1070. // do nothing, return address
  1071. // is in in the local variables.
  1072. }
  1073. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1074. public void visitRETURN(RETURN o){
  1075. // do nothing.
  1076. }
  1077. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1078. public void visitSALOAD(SALOAD o){
  1079. stack().pop();
  1080. stack().pop();
  1081. stack().push(Type.INT);
  1082. }
  1083. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1084. public void visitSASTORE(SASTORE o){
  1085. stack().pop();
  1086. stack().pop();
  1087. stack().pop();
  1088. }
  1089. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1090. public void visitSIPUSH(SIPUSH o){
  1091. stack().push(Type.INT);
  1092. }
  1093. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1094. public void visitSWAP(SWAP o){
  1095. Type t = stack().pop();
  1096. Type u = stack().pop();
  1097. stack().push(t);
  1098. stack().push(u);
  1099. }
  1100. /** Symbolically executes the corresponding Java Virtual Machine instruction. */
  1101. public void visitTABLESWITCH(TABLESWITCH o){
  1102. stack().pop();
  1103. }
  1104. }