ValueAwareMachine.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dx.cf.code;
18
19import com.android.dx.rop.cst.CstType;
20import com.android.dx.rop.type.Prototype;
21import com.android.dx.rop.type.Type;
22import com.android.dx.rop.type.TypeBearer;
23import com.android.dx.util.Hex;
24
25/**
26 * {@link Machine} which keeps track of known values but does not do
27 * smart/realistic reference type calculations.
28 */
29public class ValueAwareMachine extends BaseMachine {
30    /**
31     * Constructs an instance.
32     *
33     * @param prototype non-null; the prototype for the associated method
34     */
35    public ValueAwareMachine(Prototype prototype) {
36        super(prototype);
37    }
38
39    /** {@inheritDoc} */
40    public void run(Frame frame, int offset, int opcode) {
41        switch (opcode) {
42            case ByteOps.NOP:
43            case ByteOps.IASTORE:
44            case ByteOps.POP:
45            case ByteOps.POP2:
46            case ByteOps.IFEQ:
47            case ByteOps.IFNE:
48            case ByteOps.IFLT:
49            case ByteOps.IFGE:
50            case ByteOps.IFGT:
51            case ByteOps.IFLE:
52            case ByteOps.IF_ICMPEQ:
53            case ByteOps.IF_ICMPNE:
54            case ByteOps.IF_ICMPLT:
55            case ByteOps.IF_ICMPGE:
56            case ByteOps.IF_ICMPGT:
57            case ByteOps.IF_ICMPLE:
58            case ByteOps.IF_ACMPEQ:
59            case ByteOps.IF_ACMPNE:
60            case ByteOps.GOTO:
61            case ByteOps.RET:
62            case ByteOps.LOOKUPSWITCH:
63            case ByteOps.IRETURN:
64            case ByteOps.RETURN:
65            case ByteOps.PUTSTATIC:
66            case ByteOps.PUTFIELD:
67            case ByteOps.ATHROW:
68            case ByteOps.MONITORENTER:
69            case ByteOps.MONITOREXIT:
70            case ByteOps.IFNULL:
71            case ByteOps.IFNONNULL: {
72                // Nothing to do for these ops in this class.
73                clearResult();
74                break;
75            }
76            case ByteOps.LDC:
77            case ByteOps.LDC2_W: {
78                setResult((TypeBearer) getAuxCst());
79                break;
80            }
81            case ByteOps.ILOAD:
82            case ByteOps.ISTORE: {
83                setResult(arg(0));
84                break;
85            }
86            case ByteOps.IALOAD:
87            case ByteOps.IADD:
88            case ByteOps.ISUB:
89            case ByteOps.IMUL:
90            case ByteOps.IDIV:
91            case ByteOps.IREM:
92            case ByteOps.INEG:
93            case ByteOps.ISHL:
94            case ByteOps.ISHR:
95            case ByteOps.IUSHR:
96            case ByteOps.IAND:
97            case ByteOps.IOR:
98            case ByteOps.IXOR:
99            case ByteOps.IINC:
100            case ByteOps.I2L:
101            case ByteOps.I2F:
102            case ByteOps.I2D:
103            case ByteOps.L2I:
104            case ByteOps.L2F:
105            case ByteOps.L2D:
106            case ByteOps.F2I:
107            case ByteOps.F2L:
108            case ByteOps.F2D:
109            case ByteOps.D2I:
110            case ByteOps.D2L:
111            case ByteOps.D2F:
112            case ByteOps.I2B:
113            case ByteOps.I2C:
114            case ByteOps.I2S:
115            case ByteOps.LCMP:
116            case ByteOps.FCMPL:
117            case ByteOps.FCMPG:
118            case ByteOps.DCMPL:
119            case ByteOps.DCMPG:
120            case ByteOps.ARRAYLENGTH: {
121                setResult(getAuxType());
122                break;
123            }
124            case ByteOps.DUP:
125            case ByteOps.DUP_X1:
126            case ByteOps.DUP_X2:
127            case ByteOps.DUP2:
128            case ByteOps.DUP2_X1:
129            case ByteOps.DUP2_X2:
130            case ByteOps.SWAP: {
131                clearResult();
132                for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {
133                    int which = (pattern & 0x0f) - 1;
134                    addResult(arg(which));
135                }
136                break;
137            }
138
139            case ByteOps.JSR: {
140                setResult(new ReturnAddress(getAuxTarget()));
141                break;
142            }
143            case ByteOps.GETSTATIC:
144            case ByteOps.GETFIELD:
145            case ByteOps.INVOKEVIRTUAL:
146            case ByteOps.INVOKESTATIC:
147            case ByteOps.INVOKEINTERFACE: {
148                Type type = ((TypeBearer) getAuxCst()).getType();
149                if (type == Type.VOID) {
150                    clearResult();
151                } else {
152                    setResult(type);
153                }
154                break;
155            }
156            case ByteOps.INVOKESPECIAL: {
157                Type thisType = arg(0).getType();
158                if (thisType.isUninitialized()) {
159                    frame.makeInitialized(thisType);
160                }
161                Type type = ((TypeBearer) getAuxCst()).getType();
162                if (type == Type.VOID) {
163                    clearResult();
164                } else {
165                    setResult(type);
166                }
167                break;
168            }
169            case ByteOps.NEW: {
170                Type type = ((CstType) getAuxCst()).getClassType();
171                setResult(type.asUninitialized(offset));
172                break;
173            }
174            case ByteOps.NEWARRAY:
175            case ByteOps.CHECKCAST:
176            case ByteOps.MULTIANEWARRAY: {
177                Type type = ((CstType) getAuxCst()).getClassType();
178                setResult(type);
179                break;
180            }
181            case ByteOps.ANEWARRAY: {
182                Type type = ((CstType) getAuxCst()).getClassType();
183                setResult(type.getArrayType());
184                break;
185            }
186            case ByteOps.INSTANCEOF: {
187                setResult(Type.INT);
188                break;
189            }
190            default: {
191                throw new RuntimeException("shouldn't happen: " +
192                                           Hex.u1(opcode));
193            }
194        }
195
196        storeResults(frame);
197    }
198}
199