View Javadoc

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