KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > 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 org.objectweb.asm.tree.analysis;
31
32 import java.util.List JavaDoc;
33
34 import org.objectweb.asm.Opcodes;
35 import org.objectweb.asm.Type;
36 import org.objectweb.asm.tree.AbstractInsnNode;
37 import org.objectweb.asm.tree.FieldInsnNode;
38 import org.objectweb.asm.tree.IntInsnNode;
39 import org.objectweb.asm.tree.LdcInsnNode;
40 import org.objectweb.asm.tree.MethodInsnNode;
41 import org.objectweb.asm.tree.MultiANewArrayInsnNode;
42 import org.objectweb.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                     case T_CHAR:
186                     case T_BYTE:
187                     case T_SHORT:
188                     case T_INT:
189                         return newValue(Type.getType("[I"));
190                     case T_FLOAT:
191                         return newValue(Type.getType("[F"));
192                     case T_DOUBLE:
193                         return newValue(Type.getType("[D"));
194                     case T_LONG:
195                         return newValue(Type.getType("[J"));
196                     default:
197                         throw new AnalyzerException("Invalid array type");
198                 }
199             case ANEWARRAY:
200                 String JavaDoc desc = ((TypeInsnNode) insn).desc;
201                 if (desc.charAt(0) == '[') {
202                     return newValue(Type.getType("[" + desc));
203                 } else {
204                     return newValue(Type.getType("[L" + desc + ";"));
205                 }
206             case ARRAYLENGTH:
207                 return BasicValue.INT_VALUE;
208             case ATHROW:
209                 return null;
210             case CHECKCAST:
211                 desc = ((TypeInsnNode) insn).desc;
212                 if (desc.charAt(0) == '[') {
213                     return newValue(Type.getType(desc));
214                 } else {
215                     return newValue(Type.getType("L" + desc + ";"));
216                 }
217             case INSTANCEOF:
218                 return BasicValue.INT_VALUE;
219             case MONITORENTER:
220             case MONITOREXIT:
221             case IFNULL:
222             case IFNONNULL:
223                 return null;
224             default:
225                 throw new RuntimeException JavaDoc("Internal error.");
226         }
227     }
228
229     public Value binaryOperation(
230         final AbstractInsnNode insn,
231         final Value value1,
232         final Value value2) throws AnalyzerException
233     {
234         switch (insn.getOpcode()) {
235             case IALOAD:
236             case BALOAD:
237             case CALOAD:
238             case SALOAD:
239             case IADD:
240             case ISUB:
241             case IMUL:
242             case IDIV:
243             case IREM:
244             case ISHL:
245             case ISHR:
246             case IUSHR:
247             case IAND:
248             case IOR:
249             case IXOR:
250                 return BasicValue.INT_VALUE;
251             case FALOAD:
252             case FADD:
253             case FSUB:
254             case FMUL:
255             case FDIV:
256             case FREM:
257                 return BasicValue.FLOAT_VALUE;
258             case LALOAD:
259             case LADD:
260             case LSUB:
261             case LMUL:
262             case LDIV:
263             case LREM:
264             case LSHL:
265             case LSHR:
266             case LUSHR:
267             case LAND:
268             case LOR:
269             case LXOR:
270                 return BasicValue.LONG_VALUE;
271             case DALOAD:
272             case DADD:
273             case DSUB:
274             case DMUL:
275             case DDIV:
276             case DREM:
277                 return BasicValue.DOUBLE_VALUE;
278             case AALOAD:
279                 Type t = ((BasicValue) value1).getType();
280                 if (t != null && t.getSort() == Type.ARRAY) {
281                     return newValue(t.getElementType());
282                 } else {
283                     return BasicValue.REFERENCE_VALUE;
284                 }
285             case LCMP:
286             case FCMPL:
287             case FCMPG:
288             case DCMPL:
289             case DCMPG:
290                 return BasicValue.INT_VALUE;
291             case IF_ICMPEQ:
292             case IF_ICMPNE:
293             case IF_ICMPLT:
294             case IF_ICMPGE:
295             case IF_ICMPGT:
296             case IF_ICMPLE:
297             case IF_ACMPEQ:
298             case IF_ACMPNE:
299             case PUTFIELD:
300                 return null;
301             default:
302                 throw new RuntimeException JavaDoc("Internal error.");
303         }
304     }
305
306     public Value ternaryOperation(
307         final AbstractInsnNode insn,
308         final Value value1,
309         final Value value2,
310         final Value value3) throws AnalyzerException
311     {
312         return null;
313     }
314
315     public Value naryOperation(final AbstractInsnNode insn, final List JavaDoc values)
316             throws AnalyzerException
317     {
318         if (insn.getOpcode() == MULTIANEWARRAY) {
319             return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
320         } else {
321             return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
322         }
323     }
324
325     public Value merge(final Value v, final Value w) {
326         if (!v.equals(w)) {
327             return BasicValue.UNINITIALIZED_VALUE;
328         }
329         return v;
330     }
331 }
332
Popular Tags