KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > tree > analysis > BasicInterpreter


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

30 package com.tc.asm.tree.analysis;
31
32 import java.util.List JavaDoc;
33
34 import com.tc.asm.Opcodes;
35 import com.tc.asm.Type;
36 import com.tc.asm.tree.AbstractInsnNode;
37 import com.tc.asm.tree.FieldInsnNode;
38 import com.tc.asm.tree.IntInsnNode;
39 import com.tc.asm.tree.LdcInsnNode;
40 import com.tc.asm.tree.MethodInsnNode;
41 import com.tc.asm.tree.MultiANewArrayInsnNode;
42 import com.tc.asm.tree.TypeInsnNode;
43
44 /**
45  * An {@link Interpreter} for {@link BasicValue} values.
46  *
47  * @author Eric Bruneton
48  * @author Bing Ran
49  */

50 public class BasicInterpreter implements Opcodes, Interpreter {
51
52     public Value newValue(final Type type) {
53         if (type == null) {
54             return BasicValue.UNINITIALIZED_VALUE;
55         }
56         switch (type.getSort()) {
57             case Type.VOID:
58                 return null;
59             case Type.BOOLEAN:
60             case Type.CHAR:
61             case Type.BYTE:
62             case Type.SHORT:
63             case Type.INT:
64                 return BasicValue.INT_VALUE;
65             case Type.FLOAT:
66                 return BasicValue.FLOAT_VALUE;
67             case Type.LONG:
68                 return BasicValue.LONG_VALUE;
69             case Type.DOUBLE:
70                 return BasicValue.DOUBLE_VALUE;
71             case Type.ARRAY:
72             case Type.OBJECT:
73                 return BasicValue.REFERENCE_VALUE;
74             default:
75                 throw new RuntimeException JavaDoc("Internal error.");
76         }
77     }
78
79     public Value newOperation(final AbstractInsnNode insn) {
80         switch (insn.getOpcode()) {
81             case ACONST_NULL:
82                 return newValue(Type.getType("Lnull;"));
83             case ICONST_M1:
84             case ICONST_0:
85             case ICONST_1:
86             case ICONST_2:
87             case ICONST_3:
88             case ICONST_4:
89             case ICONST_5:
90                 return BasicValue.INT_VALUE;
91             case LCONST_0:
92             case LCONST_1:
93                 return BasicValue.LONG_VALUE;
94             case FCONST_0:
95             case FCONST_1:
96             case FCONST_2:
97                 return BasicValue.FLOAT_VALUE;
98             case DCONST_0:
99             case DCONST_1:
100                 return BasicValue.DOUBLE_VALUE;
101             case BIPUSH:
102             case SIPUSH:
103                 return BasicValue.INT_VALUE;
104             case LDC:
105                 Object JavaDoc cst = ((LdcInsnNode) insn).cst;
106                 if (cst instanceof Integer JavaDoc) {
107                     return BasicValue.INT_VALUE;
108                 } else if (cst instanceof Float JavaDoc) {
109                     return BasicValue.FLOAT_VALUE;
110                 } else if (cst instanceof Long JavaDoc) {
111                     return BasicValue.LONG_VALUE;
112                 } else if (cst instanceof Double JavaDoc) {
113                     return BasicValue.DOUBLE_VALUE;
114                 } else if (cst instanceof Type) {
115                     return newValue(Type.getType("Ljava/lang/Class;"));
116                 } else {
117                     return newValue(Type.getType(cst.getClass()));
118                 }
119             case JSR:
120                 return BasicValue.RETURNADDRESS_VALUE;
121             case GETSTATIC:
122                 return newValue(Type.getType(((FieldInsnNode) insn).desc));
123             case NEW:
124                 return newValue(Type.getType("L" + ((TypeInsnNode) insn).desc
125                         + ";"));
126             default:
127                 throw new RuntimeException JavaDoc("Internal error.");
128         }
129     }
130
131     public Value copyOperation(final AbstractInsnNode insn, final Value value)
132             throws AnalyzerException
133     {
134         return value;
135     }
136
137     public Value unaryOperation(final AbstractInsnNode insn, final Value value)
138             throws AnalyzerException
139     {
140         switch (insn.getOpcode()) {
141             case INEG:
142             case IINC:
143             case L2I:
144             case F2I:
145             case D2I:
146             case I2B:
147             case I2C:
148             case I2S:
149                 return BasicValue.INT_VALUE;
150             case FNEG:
151             case I2F:
152             case L2F:
153             case D2F:
154                 return BasicValue.FLOAT_VALUE;
155             case LNEG:
156             case I2L:
157             case F2L:
158             case D2L:
159                 return BasicValue.LONG_VALUE;
160             case DNEG:
161             case I2D:
162             case L2D:
163             case F2D:
164                 return BasicValue.DOUBLE_VALUE;
165             case IFEQ:
166             case IFNE:
167             case IFLT:
168             case IFGE:
169             case IFGT:
170             case IFLE:
171             case TABLESWITCH:
172             case LOOKUPSWITCH:
173             case IRETURN:
174             case LRETURN:
175             case FRETURN:
176             case DRETURN:
177             case ARETURN:
178             case PUTSTATIC:
179                 return null;
180             case GETFIELD:
181                 return newValue(Type.getType(((FieldInsnNode) insn).desc));
182             case NEWARRAY:
183                 switch (((IntInsnNode) insn).operand) {
184                     case T_BOOLEAN:
185                         return newValue(Type.getType("[Z"));
186                     case T_CHAR:
187                         return newValue(Type.getType("[C"));
188                     case T_BYTE:
189                         return newValue(Type.getType("[B"));
190                     case T_SHORT:
191                         return newValue(Type.getType("[S"));
192                     case T_INT:
193                         return newValue(Type.getType("[I"));
194                     case T_FLOAT:
195                         return newValue(Type.getType("[F"));
196                     case T_DOUBLE:
197                         return newValue(Type.getType("[D"));
198                     case T_LONG:
199                         return newValue(Type.getType("[J"));
200                     default:
201                         throw new AnalyzerException("Invalid array type");
202                 }
203             case ANEWARRAY:
204                 String JavaDoc desc = ((TypeInsnNode) insn).desc;
205                 if (desc.charAt(0) == '[') {
206                     return newValue(Type.getType("[" + desc));
207                 } else {
208                     return newValue(Type.getType("[L" + desc + ";"));
209                 }
210             case ARRAYLENGTH:
211                 return BasicValue.INT_VALUE;
212             case ATHROW:
213                 return null;
214             case CHECKCAST:
215                 desc = ((TypeInsnNode) insn).desc;
216                 if (desc.charAt(0) == '[') {
217                     return newValue(Type.getType(desc));
218                 } else {
219                     return newValue(Type.getType("L" + desc + ";"));
220                 }
221             case INSTANCEOF:
222                 return BasicValue.INT_VALUE;
223             case MONITORENTER:
224             case MONITOREXIT:
225             case IFNULL:
226             case IFNONNULL:
227                 return null;
228             default:
229                 throw new RuntimeException JavaDoc("Internal error.");
230         }
231     }
232
233     public Value binaryOperation(
234         final AbstractInsnNode insn,
235         final Value value1,
236         final Value value2) throws AnalyzerException
237     {
238         switch (insn.getOpcode()) {
239             case IALOAD:
240             case BALOAD:
241             case CALOAD:
242             case SALOAD:
243             case IADD:
244             case ISUB:
245             case IMUL:
246             case IDIV:
247             case IREM:
248             case ISHL:
249             case ISHR:
250             case IUSHR:
251             case IAND:
252             case IOR:
253             case IXOR:
254                 return BasicValue.INT_VALUE;
255             case FALOAD:
256             case FADD:
257             case FSUB:
258             case FMUL:
259             case FDIV:
260             case FREM:
261                 return BasicValue.FLOAT_VALUE;
262             case LALOAD:
263             case LADD:
264             case LSUB:
265             case LMUL:
266             case LDIV:
267             case LREM:
268             case LSHL:
269             case LSHR:
270             case LUSHR:
271             case LAND:
272             case LOR:
273             case LXOR:
274                 return BasicValue.LONG_VALUE;
275             case DALOAD:
276             case DADD:
277             case DSUB:
278             case DMUL:
279             case DDIV:
280             case DREM:
281                 return BasicValue.DOUBLE_VALUE;
282             case AALOAD:
283                 Type t = ((BasicValue) value1).getType();
284                 if (t != null && t.getSort() == Type.ARRAY) {
285                     return newValue(t.getElementType());
286                 } else {
287                     return BasicValue.REFERENCE_VALUE;
288                 }
289             case LCMP:
290             case FCMPL:
291             case FCMPG:
292             case DCMPL:
293             case DCMPG:
294                 return BasicValue.INT_VALUE;
295             case IF_ICMPEQ:
296             case IF_ICMPNE:
297             case IF_ICMPLT:
298             case IF_ICMPGE:
299             case IF_ICMPGT:
300             case IF_ICMPLE:
301             case IF_ACMPEQ:
302             case IF_ACMPNE:
303             case PUTFIELD:
304                 return null;
305             default:
306                 throw new RuntimeException JavaDoc("Internal error.");
307         }
308     }
309
310     public Value ternaryOperation(
311         final AbstractInsnNode insn,
312         final Value value1,
313         final Value value2,
314         final Value value3) throws AnalyzerException
315     {
316         return null;
317     }
318
319     public Value naryOperation(final AbstractInsnNode insn, final List JavaDoc values)
320             throws AnalyzerException
321     {
322         if (insn.getOpcode() == MULTIANEWARRAY) {
323             return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
324         } else {
325             return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
326         }
327     }
328
329     public Value merge(final Value v, final Value w) {
330         if (!v.equals(w)) {
331             return BasicValue.UNINITIALIZED_VALUE;
332         }
333         return v;
334     }
335 }
336
Popular Tags