KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jarg > DataflowAnalizer


1 /* ====================================================================
2  * Copyright (c) 2002, Hidetoshi Ohuchi <hchacha@users.sourceforge.net>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the hchacha nor the names of its contributors
17  * may be used to endorse or promote products derived from this
18  * software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  * ====================================================================
33  */

34 package jarg;
35
36 import java.util.*;
37 import org.apache.bcel.classfile.*;
38 import org.apache.bcel.generic.*;
39 import org.apache.bcel.Constants;
40
41 /**
42  * The class for analizing data-flow.
43  *
44  * @version $Id: DataflowAnalizer.java,v 1.4 2002/04/30 12:27:09 hchacha Exp $
45  * @author Hidetoshi Ohuchi &lt;hchacha@users.sourceforge.net&gt;
46  */

47 class DataflowAnalizer {
48    private static final boolean DEBUG_TYPE = true;
49    private static final boolean DEBUG_INST = true;
50
51    private Jarg app;
52
53    DataflowAnalizer(Jarg app) {
54       this.app = app;
55    }
56
57    HashMap analize(MethodGen mg) {
58       int count = 0;
59       InstructionList il = mg.getInstructionList();
60       HashMap dataMap = new HashMap(); // HashMap<InstructionHandle, InstructionDataset>
61

62       InstructionDataset dataset0 = new InstructionDataset(null);
63       {
64          int j=0;
65          if (!mg.isStatic()) {
66             dataset0.toLoc(j++, Type.OBJECT);
67          }
68          Type[] ts = mg.getArgumentTypes();
69          for (int i=0; i<ts.length; i++) {
70             Type t = ts[i];
71             if (t == Type.LONG) {
72                dataset0.toLoc(j++, LONGUpper.instance);
73             } else if (t == Type.DOUBLE) {
74                dataset0.toLoc(j++, DOUBLEUpper.instance);
75             }
76             dataset0.toLoc(j++, t);
77          }
78       }
79       analizeDataflow(dataset0, il.getStart(), dataMap, new PassCounter(), mg.getConstantPool());
80
81       return dataMap;
82    }
83
84    private void analizeDataflow(InstructionDataset dataset0, InstructionHandle first, HashMap dataMap, PassCounter pass, ConstantPoolGen cpg) {
85       InstructionDataset dataset1;
86       for (; first != null; first=first.getNext(), dataset0 = dataset1) {
87          if (dataMap.containsKey(first)) {
88             InstructionDataset datasetX = (InstructionDataset)dataMap.get(first);
89             datasetX.merge(dataset0);
90             dataset0 = datasetX;
91          } else {
92             dataMap.put(first, dataset0);
93          }
94          dataset1 = new InstructionDataset(first);
95          dataset1.merge(dataset0); // merge
96

97          Instruction ins1 = first.getInstruction();
98          if (ins1 instanceof BranchInstruction) {
99             if (analizeBranchInstruction(first, ins1, dataset1, dataMap, pass, cpg)) {
100                break;
101             }
102          } else if (ins1 instanceof ATHROW) {
103             Type t1 = dataset1.popOpStack();
104             if (DEBUG_TYPE) {
105                checkTypeReferenceType(t1);
106             }
107             break;
108          } else if (ins1 instanceof RET) {
109             int vn = ((RET)ins1).getIndex(); // ADDRESS
110
Type t1 = dataset1.fromLoc(vn);
111             if (DEBUG_TYPE) {
112                checkTypeReturnaddressType(t1);
113             }
114             break;
115          } else if (ins1 instanceof ReturnInstruction) {
116             if (!(ins1 instanceof RETURN)) {
117                Type t1 = dataset1.popOpStack();
118                if (ins1 instanceof LRETURN || ins1 instanceof DRETURN) {
119                   Type t2 = dataset1.popOpStack();
120                }
121             }
122             break;
123
124          } else if (ins1 instanceof LocalVariableInstruction) {
125             analizeLocalVariableInstruction(ins1, dataset1);
126          } else if (ins1 instanceof ConversionInstruction) {
127             analizeConversionInstruction(ins1, dataset1);
128          } else if (ins1 instanceof CPInstruction) {
129             analizeCPInstruction(ins1, dataset1, cpg);
130
131          } else if (ins1 instanceof ACONST_NULL) {
132 // dataset1.pushOpStack(Type.NULL);
133
dataset1.pushOpStack(CONSTNull.instance);
134          } else if (ins1 instanceof ICONST || ins1 instanceof BIPUSH || ins1 instanceof SIPUSH) {
135 // dataset1.pushOpStack(Type.INT);
136
dataset1.pushOpStack(new ConstantIntType((Integer JavaDoc)((ConstantPushInstruction)ins1).getValue()));
137          } else if (ins1 instanceof FCONST) {
138             dataset1.pushOpStack(Type.FLOAT);
139          } else if (ins1 instanceof LCONST) {
140             dataset1.pushOpStack(LONGUpper.instance);
141             dataset1.pushOpStack(Type.LONG);
142          } else if (ins1 instanceof DCONST) {
143             dataset1.pushOpStack(DOUBLEUpper.instance);
144             dataset1.pushOpStack(Type.DOUBLE);
145
146          } else if (ins1 instanceof DCMPG) {
147             Type t4 = dataset1.popOpStack();
148             Type t3 = dataset1.popOpStack();
149             Type t2 = dataset1.popOpStack();
150             Type t1 = dataset1.popOpStack();
151             dataset1.pushOpStack(Type.INT);
152             if (DEBUG_TYPE) {
153                checkTypeDOUBLEUpper(t1);
154                checkTypeDOUBLE(t2);
155                checkTypeDOUBLEUpper(t3);
156                checkTypeDOUBLE(t4);
157             }
158          } else if (ins1 instanceof DCMPL) {
159             Type t4 = dataset1.popOpStack();
160             Type t3 = dataset1.popOpStack();
161             Type t2 = dataset1.popOpStack();
162             Type t1 = dataset1.popOpStack();
163             dataset1.pushOpStack(Type.INT);
164             if (DEBUG_TYPE) {
165                checkTypeDOUBLEUpper(t1);
166                checkTypeDOUBLE(t2);
167                checkTypeDOUBLEUpper(t3);
168                checkTypeDOUBLE(t4);
169             }
170          } else if (ins1 instanceof FCMPG) {
171             Type t1 = dataset1.popOpStack();
172             Type t2 = dataset1.popOpStack();
173             dataset1.pushOpStack(Type.INT);
174             if (DEBUG_TYPE) {
175                checkTypeFLOAT(t1);
176                checkTypeFLOAT(t2);
177             }
178          } else if (ins1 instanceof FCMPL) {
179             Type t1 = dataset1.popOpStack();
180             Type t2 = dataset1.popOpStack();
181             dataset1.pushOpStack(Type.INT);
182             if (DEBUG_TYPE) {
183                checkTypeFLOAT(t1);
184                checkTypeFLOAT(t2);
185             }
186          } else if (ins1 instanceof LCMP) {
187             Type t4 = dataset1.popOpStack();
188             Type t3 = dataset1.popOpStack();
189             Type t2 = dataset1.popOpStack();
190             Type t1 = dataset1.popOpStack();
191             dataset1.pushOpStack(Type.INT);
192             if (DEBUG_TYPE) {
193                checkTypeLONGUpper(t1);
194                checkTypeLONG(t2);
195                checkTypeLONGUpper(t3);
196                checkTypeLONG(t4);
197             }
198
199          } else if (ins1 instanceof NEWARRAY) {
200             Type t1 = dataset1.popOpStack();
201             dataset1.pushOpStack(Type.OBJECT);
202             if (DEBUG_TYPE) {
203                checkTypeINT(t1);
204             }
205          } else if (ins1 instanceof ArrayInstruction) {
206             analizeArrayInstruction(ins1, dataset1);
207          } else if (ins1 instanceof ARRAYLENGTH) {
208             Type t1 = dataset1.popOpStack();
209             dataset1.pushOpStack(Type.INT);
210             if (DEBUG_TYPE) {
211                checkTypeReferenceType(t1);
212             }
213
214          } else if (ins1 instanceof ArithmeticInstruction) {
215             analizeArithmeticInstruction(ins1, dataset1);
216          } else if (ins1 instanceof StackInstruction) {
217             analizeStackInstruction(ins1, dataset1);
218
219          } else if (ins1 instanceof MONITORENTER) {
220             Type t1 = dataset1.popOpStack();
221             if (DEBUG_TYPE) {
222                checkTypeReferenceType(t1);
223             }
224          } else if (ins1 instanceof MONITOREXIT) {
225             Type t1 = dataset1.popOpStack();
226             if (DEBUG_TYPE) {
227                checkTypeReferenceType(t1);
228             }
229
230          } else if (ins1 instanceof NOP) {
231          } else if (ins1 instanceof BREAKPOINT) {
232          } else if (ins1 instanceof IMPDEP1) {
233          } else if (ins1 instanceof IMPDEP2) {
234          } else {
235             if (DEBUG_INST) {
236                notReached();
237             }
238          }
239       }
240    }
241
242    private boolean analizeBranchInstruction(InstructionHandle first, Instruction ins1, InstructionDataset dataset1, HashMap dataMap, PassCounter pass, ConstantPoolGen cpg) {
243       if (ins1 instanceof IfInstruction) {
244          if (ins1 instanceof IF_ACMPEQ
245           || ins1 instanceof IF_ACMPNE
246          ) {
247             Type t1 = dataset1.popOpStack();
248             Type t2 = dataset1.popOpStack();
249             if (DEBUG_TYPE) {
250                checkTypeReferenceType(t1);
251                checkTypeReferenceType(t2);
252             }
253 // } else if (
254
// ins1 instanceof IF_ICMPGT
255
// ) {
256
// Type t1 = dataset1.popOpStack();
257
// Type t2 = dataset1.popOpStack();
258
// if (DEBUG_TYPE) {
259
// checkTypeINT(t1);
260
// checkTypeINT(t2);
261
// }
262
} else if (
263              ins1 instanceof IF_ICMPEQ
264           || ins1 instanceof IF_ICMPNE
265           || ins1 instanceof IF_ICMPGE
266           || ins1 instanceof IF_ICMPGT
267           || ins1 instanceof IF_ICMPLE
268           || ins1 instanceof IF_ICMPLT
269          ) {
270             Type t1 = dataset1.popOpStack();
271             Type t2 = dataset1.popOpStack();
272             if (DEBUG_TYPE) {
273                checkTypeINT(t1);
274                checkTypeINT(t2);
275             }
276          } else if (
277              ins1 instanceof IFEQ
278           || ins1 instanceof IFNE
279           || ins1 instanceof IFGE
280           || ins1 instanceof IFGT
281           || ins1 instanceof IFLE
282           || ins1 instanceof IFLT
283          ) {
284             Type t1 = dataset1.popOpStack();
285             if (DEBUG_TYPE) {
286                checkTypeINT(t1);
287             }
288          } else if (
289              ins1 instanceof IFNULL
290           || ins1 instanceof IFNONNULL
291          ) {
292             Type t1 = dataset1.popOpStack();
293             if (DEBUG_TYPE) {
294                checkTypeReferenceType(t1);
295             }
296          }
297       } else if (ins1 instanceof Select) {
298          Type t1 = dataset1.popOpStack();
299          if (DEBUG_TYPE) {
300             checkTypeINT(t1);
301          }
302          InstructionHandle[] targets = ((Select)ins1).getTargets();
303       } else if (ins1 instanceof JsrInstruction) {
304       } else if (ins1 instanceof GotoInstruction) {
305       } else {
306          if (DEBUG_INST) {
307             notReached();
308          }
309       }
310
311       InstructionDataset dataset2 = dataset1.duplicate();
312       if (ins1 instanceof JsrInstruction) {
313          dataset2.pushOpStack(new ReturnaddressType(first.getNext()));
314       }
315
316       InstructionHandle target = ((BranchInstruction)ins1).getTarget();
317       if (!pass.isCompleat(target)) {
318          pass.put(target);
319          analizeDataflow(dataset2, target, dataMap, pass, cpg);
320       }
321
322       if (ins1 instanceof GotoInstruction) {
323          return true;
324       } else if (ins1 instanceof Select) {
325          InstructionHandle[] targets = ((Select)ins1).getTargets();
326          for (int i=0; i<targets.length; i++) {
327             InstructionHandle targetn = targets[i];
328             if (!pass.isCompleat(targetn)) {
329                pass.put(targetn);
330                analizeDataflow(dataset1.duplicate(), targetn, dataMap, pass, cpg);
331             }
332          }
333       }
334       return false;
335    }
336
337    private void analizeLocalVariableInstruction(Instruction ins1, InstructionDataset dataset1) {
338       int vn = ((LocalVariableInstruction)ins1).getIndex();
339       if (ins1 instanceof LoadInstruction) {
340          if (ins1 instanceof ALOAD) {
341             Type t1 = dataset1.fromLoc(vn);
342             if (t1 == Type.UNKNOWN) {
343                t1 = Type.OBJECT;
344             }
345             dataset1.pushOpStack(t1);
346             if (DEBUG_TYPE) {
347                checkTypeReferenceType(t1);
348             }
349          } else if (ins1 instanceof ILOAD) {
350             Type t1 = dataset1.fromLoc(vn);
351             if (t1 == Type.UNKNOWN) {
352                t1 = Type.INT;
353             }
354             dataset1.pushOpStack(t1);
355             if (DEBUG_TYPE) {
356                checkTypeINT(t1);
357             }
358          } else if (ins1 instanceof FLOAD) {
359             Type t1 = dataset1.fromLoc(vn);
360             if (t1 == Type.UNKNOWN) {
361                t1 = Type.FLOAT;
362             }
363             dataset1.pushOpStack(t1);
364             if (DEBUG_TYPE) {
365                checkTypeFLOAT(t1);
366             }
367          } else if (ins1 instanceof LLOAD) {
368             Type t1 = dataset1.fromLoc(vn);
369             Type t2 = dataset1.fromLoc(vn+1);
370             if (t1 == Type.UNKNOWN) {
371                t1 = LONGUpper.instance;
372                t2 = Type.LONG;
373             }
374             dataset1.pushOpStack(t1);
375             dataset1.pushOpStack(t2);
376             if (DEBUG_TYPE) {
377                checkTypeLONGUpper(t1);
378                checkTypeLONG(t2);
379             }
380          } else if (ins1 instanceof DLOAD) {
381             Type t1 = dataset1.fromLoc(vn);
382             Type t2 = dataset1.fromLoc(vn+1);
383             if (t1 == Type.UNKNOWN) {
384                t1 = DOUBLEUpper.instance;
385                t2 = Type.DOUBLE;
386             }
387             dataset1.pushOpStack(t1);
388             dataset1.pushOpStack(t2);
389             if (DEBUG_TYPE) {
390                checkTypeDOUBLEUpper(t1);
391                checkTypeDOUBLE(t2);
392             }
393          } else {
394             if (DEBUG_INST) {
395                notReached();
396             }
397          }
398       } else if (ins1 instanceof StoreInstruction) {
399          if (ins1 instanceof ASTORE) {
400             Type t1 = dataset1.popOpStack();
401             dataset1.toLoc(vn, t1);
402             if (DEBUG_TYPE) {
403                checkTypeReferenceTypeOrReturnaddressType(t1);
404             }
405          } else if (ins1 instanceof ISTORE) {
406             Type t1 = dataset1.popOpStack();
407             dataset1.toLoc(vn, t1);
408             if (DEBUG_TYPE) {
409                checkTypeINT(t1);
410             }
411          } else if (ins1 instanceof FSTORE) {
412             Type t1 = dataset1.popOpStack();
413             dataset1.toLoc(vn, t1);
414             if (DEBUG_TYPE) {
415                checkTypeFLOAT(t1);
416             }
417          } else if (ins1 instanceof LSTORE) {
418             Type t2 = dataset1.popOpStack();
419             Type t1 = dataset1.popOpStack();
420             dataset1.toLoc(vn, t1);
421             dataset1.toLoc(vn+1, t2);
422             if (DEBUG_TYPE) {
423                checkTypeLONGUpper(t1);
424                checkTypeLONG(t2);
425             }
426          } else if (ins1 instanceof DSTORE) {
427             Type t2 = dataset1.popOpStack();
428             Type t1 = dataset1.popOpStack();
429             dataset1.toLoc(vn, t1);
430             dataset1.toLoc(vn+1, t2);
431             if (DEBUG_TYPE) {
432                checkTypeDOUBLEUpper(t1);
433                checkTypeDOUBLE(t2);
434             }
435          } else {
436             if (DEBUG_INST) {
437                notReached();
438             }
439          }
440       } else if (ins1 instanceof IINC) {
441          Type t1 = dataset1.fromLoc(vn);
442          if (t1 == Type.UNKNOWN || t1 instanceof ConstantIntType) {
443             t1 = Type.INT;
444          }
445          dataset1.toLoc(vn, t1);
446          if (DEBUG_TYPE) {
447             checkTypeINT(t1);
448          }
449       } else {
450          if (DEBUG_INST) {
451             notReached();
452          }
453       }
454    }
455
456    private void analizeConversionInstruction(Instruction ins1, InstructionDataset dataset1) {
457       if (ins1 instanceof D2F) {
458          Type t2 = dataset1.popOpStack();
459          Type t1 = dataset1.popOpStack();
460          dataset1.pushOpStack(Type.FLOAT);
461          if (DEBUG_TYPE) {
462             checkTypeDOUBLEUpper(t1);
463             checkTypeDOUBLE(t2);
464          }
465       } else if (ins1 instanceof D2I) {
466          Type t2 = dataset1.popOpStack();
467          Type t1 = dataset1.popOpStack();
468          dataset1.pushOpStack(Type.INT);
469          if (DEBUG_TYPE) {
470             checkTypeDOUBLEUpper(t1);
471             checkTypeDOUBLE(t2);
472          }
473       } else if (ins1 instanceof D2L) {
474          Type t2 = dataset1.popOpStack();
475          Type t1 = dataset1.popOpStack();
476          dataset1.pushOpStack(LONGUpper.instance);
477          dataset1.pushOpStack(Type.LONG);
478          if (DEBUG_TYPE) {
479             checkTypeDOUBLEUpper(t1);
480             checkTypeDOUBLE(t2);
481          }
482
483       } else if (ins1 instanceof F2D) {
484          Type t1 = dataset1.popOpStack();
485          dataset1.pushOpStack(DOUBLEUpper.instance);
486          dataset1.pushOpStack(Type.DOUBLE);
487          if (DEBUG_TYPE) {
488             checkTypeFLOAT(t1);
489          }
490       } else if (ins1 instanceof F2I) {
491          Type t1 = dataset1.popOpStack();
492          dataset1.pushOpStack(Type.INT);
493          if (DEBUG_TYPE) {
494             checkTypeFLOAT(t1);
495          }
496       } else if (ins1 instanceof F2L) {
497          Type t1 = dataset1.popOpStack();
498          dataset1.pushOpStack(LONGUpper.instance);
499          dataset1.pushOpStack(Type.LONG);
500          if (DEBUG_TYPE) {
501             checkTypeFLOAT(t1);
502          }
503
504       } else if (ins1 instanceof I2B) {
505          Type t1 = dataset1.popOpStack();
506          dataset1.pushOpStack(Type.INT);
507          if (DEBUG_TYPE) {
508             checkTypeINT(t1);
509          }
510       } else if (ins1 instanceof I2C) {
511          Type t1 = dataset1.popOpStack();
512          dataset1.pushOpStack(Type.INT);
513          if (DEBUG_TYPE) {
514             checkTypeINT(t1);
515          }
516       } else if (ins1 instanceof I2D) {
517          Type t1 = dataset1.popOpStack();
518          dataset1.pushOpStack(DOUBLEUpper.instance);
519          dataset1.pushOpStack(Type.DOUBLE);
520          if (DEBUG_TYPE) {
521             checkTypeINT(t1);
522          }
523       } else if (ins1 instanceof I2F) {
524          Type t1 = dataset1.popOpStack();
525          dataset1.pushOpStack(Type.FLOAT);
526          if (DEBUG_TYPE) {
527             checkTypeINT(t1);
528          }
529       } else if (ins1 instanceof I2L) {
530          Type t1 = dataset1.popOpStack();
531          dataset1.pushOpStack(LONGUpper.instance);
532          dataset1.pushOpStack(Type.LONG);
533          if (DEBUG_TYPE) {
534             checkTypeINT(t1);
535          }
536       } else if (ins1 instanceof I2S) {
537          Type t1 = dataset1.popOpStack();
538          dataset1.pushOpStack(Type.INT);
539          if (DEBUG_TYPE) {
540             checkTypeINT(t1);
541          }
542
543       } else if (ins1 instanceof L2D) {
544          Type t2 = dataset1.popOpStack();
545          Type t1 = dataset1.popOpStack();
546          dataset1.pushOpStack(DOUBLEUpper.instance);
547          dataset1.pushOpStack(Type.DOUBLE);
548          if (DEBUG_TYPE) {
549             checkTypeLONGUpper(t1);
550             checkTypeLONG(t2);
551          }
552       } else if (ins1 instanceof L2F) {
553          Type t2 = dataset1.popOpStack();
554          Type t1 = dataset1.popOpStack();
555          dataset1.pushOpStack(Type.FLOAT);
556          if (DEBUG_TYPE) {
557             checkTypeLONGUpper(t1);
558             checkTypeLONG(t2);
559          }
560       } else if (ins1 instanceof L2I) {
561          Type t2 = dataset1.popOpStack();
562          Type t1 = dataset1.popOpStack();
563          dataset1.pushOpStack(Type.INT);
564          if (DEBUG_TYPE) {
565             checkTypeLONGUpper(t1);
566             checkTypeLONG(t2);
567          }
568       } else {
569          if (DEBUG_INST) {
570             notReached();
571          }
572       }
573    }
574
575    private void analizeCPInstruction(Instruction ins1, InstructionDataset dataset1, ConstantPoolGen cpg) {
576       if (ins1 instanceof ANEWARRAY) {
577          Type t1 = dataset1.popOpStack();
578          dataset1.pushOpStack(Type.OBJECT);
579          if (DEBUG_TYPE) {
580             checkTypeINT(t1);
581          }
582       } else if (ins1 instanceof CHECKCAST) {
583          Type t1 = dataset1.popOpStack();
584          dataset1.pushOpStack(t1);
585          if (DEBUG_TYPE) {
586             checkTypeReferenceType(t1);
587          }
588       } else if (ins1 instanceof FieldInstruction) {
589          if (ins1 instanceof GETFIELD) {
590             Type t1 = dataset1.popOpStack();
591             if (DEBUG_TYPE) {
592                checkTypeReferenceType(t1);
593             }
594             Type tt = ((GETFIELD)ins1).getType(cpg);
595             if (!(tt instanceof ReferenceType)) {
596                if (tt == Type.LONG) {
597                   dataset1.pushOpStack(LONGUpper.instance);
598                } else if (tt == Type.DOUBLE) {
599                   dataset1.pushOpStack(DOUBLEUpper.instance);
600                }
601             }
602             dataset1.pushOpStack(tt);
603          } else if (ins1 instanceof GETSTATIC) {
604             Type tt = ((GETSTATIC)ins1).getType(cpg);
605             if (!(tt instanceof ReferenceType)) {
606                if (tt == Type.LONG) {
607                   dataset1.pushOpStack(LONGUpper.instance);
608                } else if (tt == Type.DOUBLE) {
609                   dataset1.pushOpStack(DOUBLEUpper.instance);
610                }
611             }
612             dataset1.pushOpStack(tt);
613          } else if (ins1 instanceof PUTFIELD) {
614             Type tt = ((PUTFIELD)ins1).getType(cpg);
615             if (tt == Type.LONG || tt == Type.DOUBLE) {
616                Type t3 = dataset1.popOpStack();
617             }
618             Type t2 = dataset1.popOpStack();
619             Type t1 = dataset1.popOpStack();
620             if (DEBUG_TYPE) {
621                checkTypeReferenceType(t1);
622             }
623          } else if (ins1 instanceof PUTSTATIC) {
624             Type tt = ((PUTSTATIC)ins1).getType(cpg);
625             if (tt == Type.LONG || tt == Type.DOUBLE) {
626                Type t2 = dataset1.popOpStack();
627             }
628             Type t1 = dataset1.popOpStack();
629          }
630       } else if (ins1 instanceof InvokeInstruction) {
631          Type[] args = ((InvokeInstruction)ins1).getArgumentTypes(cpg);
632          for (int i=args.length-1; i>=0; i--) {
633             Type t2 = null;
634             if (args[i] == Type.LONG || args[i] == Type.DOUBLE) {
635                t2 = dataset1.popOpStack();
636             }
637             Type t1 = dataset1.popOpStack();
638             if (DEBUG_TYPE) {
639                if (args[i] instanceof ReferenceType) {
640                   checkTypeReferenceType(t1);
641                } else if (args[i] == Type.INT || args[i] == Type.BYTE || args[i] == Type.SHORT || args[i] == Type.CHAR || args[i] == Type.BOOLEAN) {
642                   checkTypeINT(t1);
643                } else if (args[i] == Type.FLOAT) {
644                   checkTypeFLOAT(t1);
645                } else if (args[i] == Type.LONG) {
646                   checkTypeLONGUpper(t1);
647                   checkTypeLONG(t2);
648                } else if (args[i] == Type.DOUBLE) {
649                   checkTypeDOUBLEUpper(t1);
650                   checkTypeDOUBLE(t2);
651                } else {
652                   if (DEBUG_INST) {
653                      notReached();
654                   }
655                }
656             }
657          }
658          if (ins1 instanceof INVOKEINTERFACE) {
659             Type t1 = dataset1.popOpStack();
660             if (DEBUG_TYPE) {
661                checkTypeReferenceType(t1);
662             }
663          } else if (ins1 instanceof INVOKESPECIAL) {
664             Type t1 = dataset1.popOpStack();
665             if (DEBUG_TYPE) {
666                checkTypeReferenceType(t1);
667             }
668          } else if (ins1 instanceof INVOKESTATIC) {
669          } else if (ins1 instanceof INVOKEVIRTUAL) {
670             Type t1 = dataset1.popOpStack();
671             if (DEBUG_TYPE) {
672                checkTypeReferenceType(t1);
673             }
674          } else {
675             if (DEBUG_INST) {
676                notReached();
677             }
678          }
679          Type r = ((InvokeInstruction)ins1).getReturnType(cpg);
680          if (r == Type.LONG) {
681             dataset1.pushOpStack(LONGUpper.instance);
682          } else if (r == Type.DOUBLE) {
683             dataset1.pushOpStack(DOUBLEUpper.instance);
684          }
685          if (r != Type.VOID) {
686             dataset1.pushOpStack(r);
687          }
688       } else if (ins1 instanceof INSTANCEOF) {
689          Type t1 = dataset1.popOpStack();
690          dataset1.pushOpStack(Type.INT);
691          if (DEBUG_TYPE) {
692             checkTypeReferenceType(t1);
693          }
694       } else if (ins1 instanceof LDC) {
695          Type t = ((LDC)ins1).getType(cpg);
696          if (!(t instanceof ReferenceType)) {
697             if (t == Type.INT) {
698                t = new ConstantIntLType((LDC)ins1);
699             } else if (t == Type.LONG) {
700                dataset1.pushOpStack(LONGUpper.instance);
701             } else if (t == Type.DOUBLE) {
702                dataset1.pushOpStack(DOUBLEUpper.instance);
703             }
704          }
705          dataset1.pushOpStack(t);
706       } else if (ins1 instanceof LDC2_W) {
707          Type t = ((LDC2_W)ins1).getType(cpg);
708          if (!(t instanceof ReferenceType)) {
709             if (t == Type.LONG) {
710                dataset1.pushOpStack(LONGUpper.instance);
711             } else if (t == Type.DOUBLE) {
712                dataset1.pushOpStack(DOUBLEUpper.instance);
713             }
714          }
715          dataset1.pushOpStack(t);
716       } else if (ins1 instanceof MULTIANEWARRAY) {
717          short dims = ((MULTIANEWARRAY)ins1).getDimensions();
718          for (int i=0; i<dims; i++) {
719             Type t = dataset1.popOpStack();
720             if (DEBUG_TYPE) {
721                checkTypeINT(t);
722             }
723          }
724          dataset1.pushOpStack(Type.OBJECT);
725       } else if (ins1 instanceof NEW) {
726          dataset1.pushOpStack(Type.OBJECT);
727       } else {
728          if (DEBUG_INST) {
729             notReached();
730          }
731       }
732    }
733
734    private void analizeArrayInstruction(Instruction ins1, InstructionDataset dataset1) {
735       if (ins1 instanceof AASTORE
736        || ins1 instanceof BASTORE
737        || ins1 instanceof CASTORE
738        || ins1 instanceof SASTORE
739        || ins1 instanceof IASTORE
740        || ins1 instanceof FASTORE
741       ) {
742          Type t3 = dataset1.popOpStack();
743          Type t2 = dataset1.popOpStack();
744          Type t1 = dataset1.popOpStack();
745          if (DEBUG_TYPE) {
746             checkTypeReferenceType(t1);
747             checkTypeINT(t2);
748             if (ins1 instanceof AASTORE) {
749                checkTypeReferenceType(t3);
750             } else if (
751                ins1 instanceof BASTORE
752             || ins1 instanceof CASTORE
753             || ins1 instanceof SASTORE
754             || ins1 instanceof IASTORE
755             ) {
756                checkTypeINT(t3);
757             } else if (ins1 instanceof FASTORE) {
758                checkTypeFLOAT(t3);
759             }
760          }
761
762       } else if (
763           ins1 instanceof LASTORE
764        || ins1 instanceof DASTORE
765       ) {
766          Type t4 = dataset1.popOpStack();
767          Type t3 = dataset1.popOpStack();
768          Type t2 = dataset1.popOpStack();
769          Type t1 = dataset1.popOpStack();
770          if (DEBUG_TYPE) {
771             checkTypeReferenceType(t1);
772             checkTypeINT(t2);
773             if (ins1 instanceof LASTORE) {
774                checkTypeLONGUpper(t3);
775                checkTypeLONG(t4);
776             } else {
777                checkTypeDOUBLEUpper(t3);
778                checkTypeDOUBLE(t4);
779             }
780          }
781
782       } else if (ins1 instanceof AALOAD) {
783          Type t2 = dataset1.popOpStack();
784          Type t1 = dataset1.popOpStack();
785          dataset1.pushOpStack(Type.OBJECT);
786          if (DEBUG_TYPE) {
787             checkTypeReferenceType(t1);
788             checkTypeINT(t2);
789          }
790
791       } else if (
792           ins1 instanceof BALOAD
793        || ins1 instanceof CALOAD
794        || ins1 instanceof SALOAD
795        || ins1 instanceof IALOAD
796       ) {
797          Type t2 = dataset1.popOpStack();
798          Type t1 = dataset1.popOpStack();
799          dataset1.pushOpStack(Type.INT);
800          if (DEBUG_TYPE) {
801             checkTypeReferenceType(t1);
802             checkTypeINT(t2);
803          }
804
805       } else if (ins1 instanceof FALOAD) {
806          Type t2 = dataset1.popOpStack();
807          Type t1 = dataset1.popOpStack();
808          dataset1.pushOpStack(Type.FLOAT);
809          if (DEBUG_TYPE) {
810             checkTypeReferenceType(t1);
811             checkTypeINT(t2);
812          }
813
814       } else if (ins1 instanceof LALOAD) {
815          Type t2 = dataset1.popOpStack();
816          Type t1 = dataset1.popOpStack();
817          dataset1.pushOpStack(LONGUpper.instance);
818          dataset1.pushOpStack(Type.LONG);
819          if (DEBUG_TYPE) {
820             checkTypeReferenceType(t1);
821             checkTypeINT(t2);
822          }
823
824       } else if (ins1 instanceof DALOAD) {
825          Type t2 = dataset1.popOpStack();
826          Type t1 = dataset1.popOpStack();
827          dataset1.pushOpStack(DOUBLEUpper.instance);
828          dataset1.pushOpStack(Type.DOUBLE);
829          if (DEBUG_TYPE) {
830             checkTypeReferenceType(t1);
831             checkTypeINT(t2);
832          }
833       } else {
834          if (DEBUG_INST) {
835             notReached();
836          }
837       }
838    }
839
840    private void analizeArithmeticInstruction(Instruction ins1, InstructionDataset dataset1) {
841       if (ins1 instanceof DADD
842        || ins1 instanceof DDIV
843        || ins1 instanceof DMUL
844        || ins1 instanceof DREM
845        || ins1 instanceof DSUB
846       ) {
847          Type t4 = dataset1.popOpStack();
848          Type t3 = dataset1.popOpStack();
849          Type t2 = dataset1.popOpStack();
850          Type t1 = dataset1.popOpStack();
851          dataset1.pushOpStack(DOUBLEUpper.instance);
852          dataset1.pushOpStack(Type.DOUBLE);
853          if (DEBUG_TYPE) {
854             checkTypeDOUBLEUpper(t1);
855             checkTypeDOUBLE(t2);
856             checkTypeDOUBLEUpper(t3);
857             checkTypeDOUBLE(t4);
858          }
859
860       } else if (ins1 instanceof DNEG) {
861          Type t2 = dataset1.popOpStack();
862          Type t1 = dataset1.popOpStack();
863          dataset1.pushOpStack(DOUBLEUpper.instance);
864          dataset1.pushOpStack(Type.DOUBLE);
865          if (DEBUG_TYPE) {
866             checkTypeDOUBLEUpper(t1);
867             checkTypeDOUBLE(t2);
868          }
869
870       } else if (
871           ins1 instanceof FADD
872        || ins1 instanceof FDIV
873        || ins1 instanceof FMUL
874        || ins1 instanceof FREM
875        || ins1 instanceof FSUB
876       ) {
877          Type t1 = dataset1.popOpStack();
878          Type t2 = dataset1.popOpStack();
879          dataset1.pushOpStack(Type.FLOAT);
880          if (DEBUG_TYPE) {
881             checkTypeFLOAT(t1);
882             checkTypeFLOAT(t2);
883          }
884
885       } else if (ins1 instanceof FNEG) {
886          Type t1 = dataset1.popOpStack();
887          dataset1.pushOpStack(Type.FLOAT);
888          if (DEBUG_TYPE) {
889             checkTypeFLOAT(t1);
890          }
891
892       } else if (
893           ins1 instanceof IADD
894        || ins1 instanceof IDIV
895        || ins1 instanceof IMUL
896        || ins1 instanceof IREM
897        || ins1 instanceof ISUB
898       ) {
899          Type t1 = dataset1.popOpStack();
900          Type t2 = dataset1.popOpStack();
901          dataset1.pushOpStack(Type.INT);
902          if (DEBUG_TYPE) {
903             checkTypeINT(t1);
904             checkTypeINT(t2);
905          }
906
907       } else if (ins1 instanceof INEG) {
908          Type t1 = dataset1.popOpStack();
909          dataset1.pushOpStack(Type.INT);
910          if (DEBUG_TYPE) {
911             checkTypeINT(t1);
912          }
913
914       } else if (
915           ins1 instanceof LADD
916        || ins1 instanceof LDIV
917        || ins1 instanceof LMUL
918        || ins1 instanceof LREM
919        || ins1 instanceof LSUB
920       ) {
921          Type t4 = dataset1.popOpStack();
922          Type t3 = dataset1.popOpStack();
923          Type t2 = dataset1.popOpStack();
924          Type t1 = dataset1.popOpStack();
925          dataset1.pushOpStack(LONGUpper.instance);
926          dataset1.pushOpStack(Type.LONG);
927          if (DEBUG_TYPE) {
928             checkTypeLONGUpper(t1);
929             checkTypeLONG(t2);
930             checkTypeLONGUpper(t3);
931             checkTypeLONG(t4);
932          }
933
934       } else if (ins1 instanceof LNEG) {
935          Type t2 = dataset1.popOpStack();
936          Type t1 = dataset1.popOpStack();
937          dataset1.pushOpStack(LONGUpper.instance);
938          dataset1.pushOpStack(Type.LONG);
939          if (DEBUG_TYPE) {
940             checkTypeLONGUpper(t1);
941             checkTypeLONG(t2);
942          }
943
944       } else if (
945           ins1 instanceof IAND
946        || ins1 instanceof IOR
947        || ins1 instanceof ISHL
948        || ins1 instanceof ISHR
949        || ins1 instanceof IUSHR
950        || ins1 instanceof IXOR
951       ) {
952          Type t1 = dataset1.popOpStack();
953          Type t2 = dataset1.popOpStack();
954          dataset1.pushOpStack(Type.INT);
955          if (DEBUG_TYPE) {
956             checkTypeINT(t1);
957             checkTypeINT(t2);
958          }
959
960       } else if (
961           ins1 instanceof LAND
962        || ins1 instanceof LOR
963        || ins1 instanceof LXOR
964       ) {
965          Type t4 = dataset1.popOpStack();
966          Type t3 = dataset1.popOpStack();
967          Type t2 = dataset1.popOpStack();
968          Type t1 = dataset1.popOpStack();
969          dataset1.pushOpStack(LONGUpper.instance);
970          dataset1.pushOpStack(Type.LONG);
971          if (DEBUG_TYPE) {
972             checkTypeLONGUpper(t1);
973             checkTypeLONG(t2);
974             checkTypeLONGUpper(t3);
975             checkTypeLONG(t4);
976          }
977       } else if (
978           ins1 instanceof LSHL
979        || ins1 instanceof LSHR
980        || ins1 instanceof LUSHR
981       ) {
982          Type t3 = dataset1.popOpStack();
983          Type t2 = dataset1.popOpStack();
984          Type t1 = dataset1.popOpStack();
985          dataset1.pushOpStack(LONGUpper.instance);
986          dataset1.pushOpStack(Type.LONG);
987          if (DEBUG_TYPE) {
988             checkTypeLONGUpper(t1);
989             checkTypeLONG(t2);
990             checkTypeINT(t3);
991          }
992       } else {
993          if (DEBUG_INST) {
994             notReached();
995          }
996       }
997    }
998
999    private void analizeStackInstruction(Instruction ins1, InstructionDataset dataset1) {
1000      if (ins1 instanceof DUP) {
1001         Type t1 = dataset1.popOpStack();
1002         dataset1.pushOpStack(t1);
1003         dataset1.pushOpStack(t1);
1004      } else if (ins1 instanceof DUP_X1) {
1005         Type t1 = dataset1.popOpStack();
1006         Type t2 = dataset1.popOpStack();
1007         dataset1.pushOpStack(t1);
1008         dataset1.pushOpStack(t2);
1009         dataset1.pushOpStack(t1);
1010      } else if (ins1 instanceof DUP_X2) {
1011         Type t1 = dataset1.popOpStack();
1012         Type t2 = dataset1.popOpStack();
1013         Type t3 = dataset1.popOpStack();
1014         dataset1.pushOpStack(t1);
1015         dataset1.pushOpStack(t3);
1016         dataset1.pushOpStack(t2);
1017         dataset1.pushOpStack(t1);
1018      } else if (ins1 instanceof DUP2) {
1019         Type t1 = dataset1.popOpStack();
1020         Type t2 = dataset1.popOpStack();
1021         dataset1.pushOpStack(t2);
1022         dataset1.pushOpStack(t1);
1023         dataset1.pushOpStack(t2);
1024         dataset1.pushOpStack(t1);
1025      } else if (ins1 instanceof DUP2_X1) {
1026         Type t1 = dataset1.popOpStack();
1027         Type t2 = dataset1.popOpStack();
1028         Type t3 = dataset1.popOpStack();
1029         dataset1.pushOpStack(t2);
1030         dataset1.pushOpStack(t1);
1031         dataset1.pushOpStack(t3);
1032         dataset1.pushOpStack(t2);
1033         dataset1.pushOpStack(t1);
1034      } else if (ins1 instanceof DUP2_X2) {
1035         Type t1 = dataset1.popOpStack();
1036         Type t2 = dataset1.popOpStack();
1037         Type t3 = dataset1.popOpStack();
1038         Type t4 = dataset1.popOpStack();
1039         dataset1.pushOpStack(t2);
1040         dataset1.pushOpStack(t1);
1041         dataset1.pushOpStack(t4);
1042         dataset1.pushOpStack(t3);
1043         dataset1.pushOpStack(t2);
1044         dataset1.pushOpStack(t1);
1045      } else if (ins1 instanceof POP) {
1046         Type t1 = dataset1.popOpStack();
1047      } else if (ins1 instanceof POP2) {
1048         Type t1 = dataset1.popOpStack();
1049         Type t2 = dataset1.popOpStack();
1050      } else if (ins1 instanceof SWAP) {
1051         Type t1 = dataset1.popOpStack();
1052         Type t2 = dataset1.popOpStack();
1053         dataset1.pushOpStack(t1);
1054         dataset1.pushOpStack(t2);
1055      } else {
1056         if (DEBUG_INST) {
1057            notReached();
1058         }
1059      }
1060   }
1061
1062   ////
1063
private static void notReached() {
1064      int x = 0;
1065      throw new java.lang.RuntimeException JavaDoc("NOT REACHED!!");
1066   }
1067
1068   ////
1069
private static void checkTypeReturnaddressType(Type t) {
1070      if (!(t instanceof ReturnaddressType)) {
1071         notReached();
1072      }
1073   }
1074
1075   private static void checkTypeReferenceTypeOrReturnaddressType(Type t) {
1076      if (!(t instanceof ReferenceType) && !(t instanceof ReturnaddressType)) {
1077         notReached();
1078      }
1079   }
1080
1081   private static void checkTypeReferenceType(Type t) {
1082      if (!(t instanceof ReferenceType)) {
1083         notReached();
1084      }
1085   }
1086
1087   private static void checkTypeINT(Type t) {
1088      if (t != Type.INT && t != Type.BOOLEAN && t != Type.BYTE && t != Type.CHAR && t != Type.SHORT && !(t instanceof ConstantIntType)) {
1089         notReached();
1090      }
1091   }
1092
1093   private static void checkTypeFLOAT(Type t) {
1094      if (t != Type.FLOAT) {
1095         notReached();
1096      }
1097   }
1098
1099   private static void checkTypeLONGUpper(Type t) {
1100      if (t != LONGUpper.instance) {
1101         notReached();
1102      }
1103   }
1104   private static void checkTypeLONG(Type t) {
1105      if (t != Type.LONG) {
1106         notReached();
1107      }
1108   }
1109
1110   private static void checkTypeDOUBLEUpper(Type t) {
1111      if (t != DOUBLEUpper.instance) {
1112         notReached();
1113      }
1114   }
1115   private static void checkTypeDOUBLE(Type t) {
1116      if (t != Type.DOUBLE) {
1117         notReached();
1118      }
1119   }
1120
1121   ////
1122
private static class PassCounter {
1123      private static Integer JavaDoc int1 = new Integer JavaDoc(1);
1124      private static Integer JavaDoc int2 = new Integer JavaDoc(2);
1125
1126      private HashMap map = new HashMap();
1127      PassCounter() {
1128      }
1129
1130      void put(InstructionHandle target) {
1131         Integer JavaDoc cnt = (Integer JavaDoc)map.get(target);
1132         if (cnt == null) {
1133            cnt = int1;
1134         } else {
1135            cnt = int2;
1136         }
1137         map.put(target, cnt);
1138      }
1139
1140      boolean isCompleat(InstructionHandle target) {
1141         Integer JavaDoc cnt = (Integer JavaDoc)map.get(target);
1142         if (cnt == int2) {
1143            return true;
1144         }
1145         return false;
1146      }
1147   }
1148
1149   ////
1150
static class InstructionDataset implements Cloneable JavaDoc {
1151      private InstructionHandle ih;
1152      private int opStackTopIndex = -1;
1153      private ArrayList opStack = new ArrayList(); // ArrayList<Type>
1154
private ArrayList locSlot = new ArrayList(); // ArrayList<Type>
1155

1156      InstructionDataset(InstructionHandle ih) {
1157         this.ih = ih;
1158      }
1159
1160      InstructionDataset duplicate() {
1161         return (InstructionDataset)this.clone();
1162      }
1163
1164      public Object JavaDoc clone() {
1165         try {
1166            InstructionDataset r = (InstructionDataset)super.clone();
1167            r.opStack = (ArrayList)r.opStack.clone();
1168            r.locSlot = (ArrayList)r.locSlot.clone();
1169            return r;
1170         } catch (CloneNotSupportedException JavaDoc ex) {
1171            // this shouldn't happen, since we are Cloneable
1172
throw new InternalError JavaDoc(ex.getMessage());
1173         }
1174      }
1175
1176      ////
1177
Type getLocalType(int vn) {
1178         return fromLoc(vn);
1179      }
1180
1181      ////
1182
void merge(InstructionDataset pre) {
1183         // stack
1184
int preTop = pre.opStackTopIndex;
1185         if (preTop >= 0) {
1186            if (preTop >= opStack.size()) {
1187               int sz = opStack.size();
1188               for (int i=0; i<=preTop+1-sz; i++) {
1189                  opStack.add(null);
1190               }
1191            }
1192            for (int i=0; i<=preTop; i++) {
1193               Type t0 = (Type)pre.opStack.get(i);
1194               Type t1 = (Type)this.opStack.get(i);
1195
1196               if (t0 == t1) {
1197                  // do nothing
1198
} else if (t1 == null || t1 == Type.UNKNOWN) {
1199                  this.opStack.set(i, t0);
1200
1201               } else if (t0 instanceof ReferenceType && t1 instanceof ReferenceType) {
1202                  this.opStack.set(i, t0);
1203               } else if (t0 instanceof ReturnaddressType && t1 instanceof ReturnaddressType) {
1204                  this.opStack.set(i, t0);
1205
1206               } else if (
1207                   (t0 == Type.INT || t0 == Type.BOOLEAN || t0 == Type.BYTE || t0 == Type.SHORT || t0 == Type.CHAR)
1208                && (t1 == Type.INT || t1 == Type.BOOLEAN || t1 == Type.BYTE || t1 == Type.SHORT || t1 == Type.CHAR)
1209               ) {
1210                  this.opStack.set(i, t0);
1211
1212               } else if (t0 instanceof DirectConstant && t1 instanceof DirectConstant) {
1213                  this.opStack.set(i, t0);
1214               } else if (t0 instanceof DirectConstant && !(t1 instanceof DirectConstant)) {
1215                  // do nothing
1216
} else if (!(t0 instanceof DirectConstant) && t1 instanceof DirectConstant) {
1217                  this.opStack.set(i, t0);
1218
1219               } else if (t1 == LONGUpper.instance) {
1220                  this.opStack.set(i, t0);
1221               } else if (t1 == DOUBLEUpper.instance) {
1222                  this.opStack.set(i, t0);
1223
1224               } else {
1225                  this.opStack.set(i, t0);
1226               }
1227            }
1228            if (this.opStackTopIndex < preTop) {
1229               this.opStackTopIndex = preTop;
1230            }
1231         }
1232
1233         // local
1234
int preSz = pre.locSlot.size();
1235         locSlotRangeCheck(preSz-1);
1236         for (int i=0; i<preSz; i++) {
1237            Type t0 = (Type)pre.locSlot.get(i);
1238            Type t1 = (Type)this.locSlot.get(i);
1239
1240            if (t0 == t1) {
1241               // do nothing
1242
} else if (t0 == Type.UNKNOWN) {
1243               // do nothing
1244
} else if (t1 == Type.UNKNOWN) {
1245               this.locSlot.set(i, t0);
1246
1247            } else if (t0 instanceof ReferenceType && t1 instanceof ReferenceType) {
1248               this.locSlot.set(i, t0);
1249            } else if (t0 instanceof ReturnaddressType && t1 instanceof ReturnaddressType) {
1250               this.locSlot.set(i, t0);
1251
1252            } else if (
1253                (t0 == Type.INT || t0 == Type.BOOLEAN || t0 == Type.BYTE || t0 == Type.SHORT || t0 == Type.CHAR)
1254             && (t1 == Type.INT || t1 == Type.BOOLEAN || t1 == Type.BYTE || t1 == Type.SHORT || t1 == Type.CHAR)
1255            ) {
1256               this.locSlot.set(i, t0);
1257
1258            } else if (t0 instanceof DirectConstant && t1 instanceof DirectConstant) {
1259               this.locSlot.set(i, t0);
1260            } else if (t0 instanceof DirectConstant && !(t1 instanceof DirectConstant)) {
1261               // do nothing
1262
} else if (!(t0 instanceof DirectConstant) && t1 instanceof DirectConstant) {
1263               this.locSlot.set(i, t0);
1264
1265            } else if (t1 == LONGUpper.instance) {
1266               this.locSlot.set(i, t0);
1267               this.locSlot.set(i+1, Type.UNKNOWN);
1268            } else if (t1 == DOUBLEUpper.instance) {
1269               this.locSlot.set(i, t0);
1270               this.locSlot.set(i+1, Type.UNKNOWN);
1271
1272            } else {
1273               this.locSlot.set(i, Type.UNKNOWN);
1274            }
1275         }
1276      }
1277
1278      ////
1279
private void pushOpStack(Type t) {
1280         opStackTopIndex ++;
1281         if (opStackTopIndex >= opStack.size()) {
1282            opStack.add(null);
1283         }
1284         opStack.set(opStackTopIndex, t);
1285         if (DEBUG_TYPE) {
1286            if (t == Type.LONG) {
1287               Type t1 = (Type)opStack.get(opStackTopIndex-1);
1288               checkTypeLONGUpper(t1);
1289            } else if (t == Type.DOUBLE) {
1290               Type t1 = (Type)opStack.get(opStackTopIndex-1);
1291               checkTypeDOUBLEUpper(t1);
1292            }
1293         }
1294      }
1295
1296      private Type popOpStack() {
1297         if (opStackTopIndex < 0) {
1298            int x = 0;
1299         }
1300         Type r = (Type)opStack.get(opStackTopIndex);
1301         opStack.set(opStackTopIndex, null);
1302         opStackTopIndex --;
1303         return r;
1304      }
1305
1306      private void locSlotRangeCheck(int vn) {
1307         int sz = locSlot.size();
1308         for (int i=0; i<vn+1-sz; i++) {
1309            locSlot.add(Type.UNKNOWN);
1310         }
1311      }
1312
1313      private void toLoc(int vn, Type t) {
1314         locSlotRangeCheck(vn);
1315         locSlot.set(vn, t);
1316      }
1317
1318      private Type fromLoc(int vn) {
1319         locSlotRangeCheck(vn);
1320         return (Type)locSlot.get(vn);
1321      }
1322   }
1323}
1324
1325////
1326
class LONGUpper extends Type {
1327   static LONGUpper instance = new LONGUpper();
1328   private LONGUpper() {
1329      super((byte)0, "long upper");
1330   }
1331}
1332
1333class DOUBLEUpper extends Type {
1334   static DOUBLEUpper instance = new DOUBLEUpper();
1335   private DOUBLEUpper() {
1336      super((byte)0, "double upper");
1337   }
1338}
1339
1340////
1341
interface DirectConstant {
1342}
1343
1344class CONSTNull extends ReferenceType implements DirectConstant {
1345   static CONSTNull instance = new CONSTNull();
1346   private CONSTNull() {
1347      super(Constants.T_OBJECT, "<constant null object>");
1348   }
1349
1350   Instruction createInstruction() {
1351      return new ACONST_NULL();
1352   }
1353}
1354
1355class ConstantType extends Type implements DirectConstant {
1356  ConstantType(byte type) {
1357    super(type, Constants.SHORT_TYPE_NAMES[type]);
1358    if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) {
1359      throw new ClassGenException("Invalid type: " + type);
1360    }
1361  }
1362}
1363
1364class ConstantIntType extends ConstantType {
1365   private LDC inst;
1366   private int val;
1367
1368   ConstantIntType(int val) {
1369      super(Constants.T_INT);
1370      this.val = val;
1371   }
1372
1373   ConstantIntType(Integer JavaDoc value) {
1374      this(value.intValue());
1375   }
1376
1377   int getValue() {
1378      return val;
1379   }
1380
1381   Instruction createInstruction() {
1382      if (val >= -1 && val <= 5) {
1383         return new ICONST(val);
1384      } else if (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) {
1385         return new BIPUSH((byte)val);
1386      } else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) {
1387         return new SIPUSH((short)val);
1388      }
1389      return null;
1390   }
1391}
1392
1393class ConstantIntLType extends ConstantIntType {
1394   private LDC inst;
1395
1396   ConstantIntLType(LDC inst) {
1397      super(0);
1398      this.inst = inst;
1399   }
1400
1401   int getValue() {
1402      return 0;
1403   }
1404
1405   Instruction createInstruction() {
1406      return inst;
1407   }
1408}
1409
Popular Tags