You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ExecutionVisitor.java 36KB

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