• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.HashSet;
33 import java.util.List;
34 import java.util.Set;
35 
36 import org.objectweb.asm.Opcodes;
37 import org.objectweb.asm.Type;
38 import org.objectweb.asm.tree.AbstractInsnNode;
39 import org.objectweb.asm.tree.FieldInsnNode;
40 import org.objectweb.asm.tree.LdcInsnNode;
41 import org.objectweb.asm.tree.MethodInsnNode;
42 
43 /**
44  * An {@link Interpreter} for {@link DataflowValue} values.
45  *
46  * @author Eric Bruneton
47  */
48 public class DataflowInterpreter implements Opcodes, Interpreter {
49 
newValue(final Type type)50     public Value newValue(final Type type) {
51         return new DataflowValue(type == null ? 1 : type.getSize());
52     }
53 
newOperation(final AbstractInsnNode insn)54     public Value newOperation(final AbstractInsnNode insn) {
55         int size;
56         switch (insn.getOpcode()) {
57             case LCONST_0:
58             case LCONST_1:
59             case DCONST_0:
60             case DCONST_1:
61                 size = 2;
62                 break;
63             case LDC:
64                 Object cst = ((LdcInsnNode) insn).cst;
65                 size = cst instanceof Long || cst instanceof Double ? 2 : 1;
66                 break;
67             case GETSTATIC:
68                 size = Type.getType(((FieldInsnNode) insn).desc).getSize();
69                 break;
70             default:
71                 size = 1;
72         }
73         return new DataflowValue(size, insn);
74     }
75 
copyOperation(final AbstractInsnNode insn, final Value value)76     public Value copyOperation(final AbstractInsnNode insn, final Value value) {
77         return new DataflowValue(value.getSize(), insn);
78     }
79 
unaryOperation(final AbstractInsnNode insn, final Value value)80     public Value unaryOperation(final AbstractInsnNode insn, final Value value)
81     {
82         int size;
83         switch (insn.getOpcode()) {
84             case LNEG:
85             case DNEG:
86             case I2L:
87             case I2D:
88             case L2D:
89             case F2L:
90             case F2D:
91             case D2L:
92                 size = 2;
93                 break;
94             case GETFIELD:
95                 size = Type.getType(((FieldInsnNode) insn).desc).getSize();
96                 break;
97             default:
98                 size = 1;
99         }
100         return new DataflowValue(size, insn);
101     }
102 
binaryOperation( final AbstractInsnNode insn, final Value value1, final Value value2)103     public Value binaryOperation(
104         final AbstractInsnNode insn,
105         final Value value1,
106         final Value value2)
107     {
108         int size;
109         switch (insn.getOpcode()) {
110             case LALOAD:
111             case DALOAD:
112             case LADD:
113             case DADD:
114             case LSUB:
115             case DSUB:
116             case LMUL:
117             case DMUL:
118             case LDIV:
119             case DDIV:
120             case LREM:
121             case DREM:
122             case LSHL:
123             case LSHR:
124             case LUSHR:
125             case LAND:
126             case LOR:
127             case LXOR:
128                 size = 2;
129                 break;
130             default:
131                 size = 1;
132         }
133         return new DataflowValue(size, insn);
134     }
135 
ternaryOperation( final AbstractInsnNode insn, final Value value1, final Value value2, final Value value3)136     public Value ternaryOperation(
137         final AbstractInsnNode insn,
138         final Value value1,
139         final Value value2,
140         final Value value3)
141     {
142         return new DataflowValue(1, insn);
143     }
144 
naryOperation(final AbstractInsnNode insn, final List values)145     public Value naryOperation(final AbstractInsnNode insn, final List values) {
146         int size;
147         if (insn.getOpcode() == MULTIANEWARRAY) {
148             size = 1;
149         } else {
150             size = Type.getReturnType(((MethodInsnNode) insn).desc).getSize();
151         }
152         return new DataflowValue(size, insn);
153     }
154 
merge(final Value v, final Value w)155     public Value merge(final Value v, final Value w) {
156         DataflowValue dv = (DataflowValue) v;
157         DataflowValue dw = (DataflowValue) w;
158         if (dv.insns instanceof SmallSet && dw.insns instanceof SmallSet) {
159             Set s = ((SmallSet) dv.insns).union((SmallSet) dw.insns);
160             if (s == dv.insns && dv.size == dw.size) {
161                 return v;
162             } else {
163                 return new DataflowValue(Math.min(dv.size, dw.size), s);
164             }
165         }
166         if (dv.size != dw.size || !dv.insns.containsAll(dw.insns)) {
167             Set s = new HashSet();
168             s.addAll(dv.insns);
169             s.addAll(dw.insns);
170             return new DataflowValue(Math.min(dv.size, dw.size), s);
171         }
172         return v;
173     }
174 }
175