RopperMachine.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.FillArrayDataInsn;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Insn;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.PlainCstInsn;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.PlainInsn;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegOps;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpec;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpecList;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Rop;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.Rops;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.SourcePosition;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.SwitchInsn;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.ThrowingCstInsn;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.ThrowingInsn;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.TranslationAdvice;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstFieldRef;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstNat;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstUtf8;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList;
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Machine implementation for use by {@link Ropper}.
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*package*/ final class RopperMachine extends ValueAwareMachine {
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; array reflection class */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final CstType ARRAY_REFLECT_TYPE =
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        new CstType(Type.internClassName("java/lang/reflect/Array"));
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * non-null; method constant for use in converting
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <code>multianewarray</code> instructions
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final CstMethodRef MULTIANEWARRAY_METHOD =
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        new CstMethodRef(ARRAY_REFLECT_TYPE,
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         new CstNat(new CstUtf8("newInstance"),
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    new CstUtf8("(Ljava/lang/Class;[I)" +
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                                "Ljava/lang/Object;")));
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; {@link Ropper} controlling this instance */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final Ropper ropper;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; method being converted */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ConcreteMethod method;
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; translation advice */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final TranslationAdvice advice;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** max locals of the method */
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int maxLocals;
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; instructions for the rop basic block in-progress */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<Insn> insns;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** non-null; catches for the block currently being processed */
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeList catches;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** whether the catches have been used in an instruction */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean catchesUsed;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** whether the block contains a <code>return</code> */
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean returns;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** primary successor index */
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int primarySuccessorIndex;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** &gt;= 0; number of extra basic blocks required */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int extraBlockCount;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** true if last processed block ends with a jsr or jsr_W*/
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean hasJsr;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** true if an exception can be thrown by the last block processed */
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean blockCanThrow;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If non-null, the ReturnAddress that was used by the terminating ret
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instruction. If null, there was no ret instruction encountered.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ReturnAddress returnAddress;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * null-ok; the appropriate <code>return</code> op or <code>null</code>
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * if it is not yet known
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Rop returnOp;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * null-ok; the source position for the return block or <code>null</code>
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * if it is not yet known
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private SourcePosition returnPosition;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ropper non-null; ropper controlling this instance
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param method non-null; method being converted
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param advice non-null; translation advice to use
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RopperMachine(Ropper ropper, ConcreteMethod method,
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            TranslationAdvice advice) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(method.getEffectiveDescriptor());
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ropper == null) {
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("ropper == null");
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (advice == null) {
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("advice == null");
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.ropper = ropper;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.method = method;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.advice = advice;
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.maxLocals = method.getMaxLocals();
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.insns = new ArrayList<Insn>(25);
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catches = null;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catchesUsed = false;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returns = false;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.primarySuccessorIndex = -1;
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.extraBlockCount = 0;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.blockCanThrow = false;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returnOp = null;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.returnPosition = null;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the instructions array. It is shared and gets modified by
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subsequent calls to this instance.
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the instructions array
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ArrayList<Insn> getInsns() {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return insns;
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the return opcode encountered, if any.
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return null-ok; the return opcode
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Rop getReturnOp() {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnOp;
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the return position, if known.
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return null-ok; the return position
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public SourcePosition getReturnPosition() {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnPosition;
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets ready to start working on a new block. This will clear the
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link #insns} list, set {@link #catches}, reset whether it has
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * been used, reset whether the block contains a
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <code>return</code>, and reset {@link #primarySuccessorIndex}.
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void startBlock(TypeList catches) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.catches = catches;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insns.clear();
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchesUsed = false;
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        returns = false;
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        primarySuccessorIndex = 0;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        extraBlockCount = 0;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        blockCanThrow = false;
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hasJsr = false;
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        returnAddress = null;
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets whether {@link #catches} was used. This indicates that the
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * last instruction in the block is one of the ones that can throw.
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return whether <code>catches</code> has been used
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean wereCatchesUsed() {
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return catchesUsed;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets whether the block just processed ended with a
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <code>return</code>.
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return whether the block returns
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean returns() {
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returns;
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the primary successor index. This is the index into the
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successors list where the primary may be found or
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <code>-1</code> if there are successors but no primary
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successor. This may return something other than
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <code>-1</code> in the case of an instruction with no
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * successors at all (primary or otherwise).
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return &gt;= -1; the primary successor index
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getPrimarySuccessorIndex() {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return primarySuccessorIndex;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets how many extra blocks will be needed to represent the
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * block currently being translated. Each extra block should consist
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of one instruction from the end of the original block.
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return &gt;= 0; the number of extra blocks needed
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getExtraBlockCount() {
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return extraBlockCount;
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if at least one of the insn processed since the last
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call to startBlock() can throw.
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean canThrow() {
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return blockCanThrow;
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if a JSR has ben encountered since the last call to
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * startBlock()
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean hasJsr() {
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return hasJsr;
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if a RET has ben encountered since the last call to
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * startBlock()
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean hasRet() {
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnAddress != null;
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return null-ok; return address of a ret instruction if encountered
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * since last call to startBlock(). null if no ret instruction encountered.
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ReturnAddress getReturnAddress() {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return returnAddress;
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void run(Frame frame, int offset, int opcode) {
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * This is the stack pointer after the opcode's arguments have been
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * popped.
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackPointer = maxLocals + frame.getStack().size();
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The sources have to be retrieved before super.run() gets called.
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList sources = getSources(opcode, stackPointer);
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sourceCount = sources.size();
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super.run(frame, offset, opcode);
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SourcePosition pos = method.makeSourcePosistion(offset);
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpec localTarget = getLocalTarget();
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int destCount = resultCount();
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpec dest;
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (destCount == 0) {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (opcode) {
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.POP:
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.POP2: {
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // These simply don't appear in the rop form.
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return;
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (localTarget != null) {
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = localTarget;
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (destCount == 1) {
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = RegisterSpec.make(stackPointer, result(0));
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * This clause only ever applies to the stack manipulation
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * ops that have results (that is, dup* and swap but not
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * pop*).
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * What we do is first move all the source registers into
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * the "temporary stack" area defined for the method, and
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * then move stuff back down onto the main "stack" in the
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * arrangement specified by the stack op pattern.
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Note: This code ends up emitting a lot of what will
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * turn out to be superfluous moves (e.g., moving back and
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * forth to the same local when doing a dup); however,
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * that makes this code a bit easier (and goodness knows
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it doesn't need any extra complexity), and all the SSA
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * stuff is going to want to deal with this sort of
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * superfluous assignment anyway, so it should be a wash
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * in the end.
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int scratchAt = ropper.getFirstTempStackReg();
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount];
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < sourceCount; i++) {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec src = sources.get(i);
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = src.getTypeBearer();
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec scratch = src.withReg(scratchAt);
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insns.add(new PlainInsn(Rops.opMove(type), pos, scratch, src));
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                scratchRegs[i] = scratch;
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                scratchAt += src.getCategory();
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int which = (pattern & 0x0f) - 1;
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec scratch = scratchRegs[which];
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = scratch.getTypeBearer();
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insns.add(new PlainInsn(Rops.opMove(type), pos,
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        scratch.withReg(stackPointer),
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                        scratch));
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                stackPointer += type.getType().getCategory();
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TypeBearer destType = (dest != null) ? dest : Type.VOID;
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Constant cst = getAuxCst();
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int ropOpcode;
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Rop rop;
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Insn insn;
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (opcode == ByteOps.MULTIANEWARRAY) {
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            blockCanThrow = true;
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add the extra instructions for handling multianewarray.
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount = 6;
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add an array constructor for the int[] containing all the
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * dimensions.
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec dimsReg =
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY);
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount);
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingCstInsn(rop, pos, sources, catches,
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    CstType.INT_ARRAY);
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add a move-result for the new-filled-array
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResult(Type.INT_ARRAY);
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY);
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add a const-class instruction for the specified array
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * class.
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Remove as many dimensions from the originally specified
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * class as are given in the explicit list of dimensions,
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * so as to pass the right component class to the standard
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Java library array constructor.
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Type componentType = ((CstType) cst).getClassType();
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < sourceCount; i++) {
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                componentType = componentType.getComponentType();
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec classReg =
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getReg(), Type.CLASS);
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (componentType.isPrimitive()) {
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The component type is primitive (e.g., int as opposed
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * to Integer), so we have to fetch the corresponding
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * TYPE class.
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstFieldRef typeField =
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    CstFieldRef.forPrimitiveType(componentType);
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos,
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           RegisterSpecList.EMPTY,
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           catches, typeField);
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The component type is an object type, so just make a
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * normal class reference.
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos,
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           RegisterSpecList.EMPTY, catches,
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                           new CstType(componentType));
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add a move-result-pseudo for the get-static or const
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResultPseudo(classReg.getType());
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY);
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Add a call to the "multianewarray method," that is,
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Array.newInstance(class, dims). Note: The result type
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * of newInstance() is Object, which is why the last
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * instruction in this sequence is a cast to the right
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * type for the original instruction.
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec objectReg =
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec.make(dest.getReg(), Type.OBJECT);
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingCstInsn(
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()),
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pos, RegisterSpecList.make(classReg, dimsReg),
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    catches, MULTIANEWARRAY_METHOD);
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Add a move-result
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype()
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .getReturnType());
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY);
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * And finally, set up for the remainder of this method to
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * add an appropriate cast.
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            opcode = ByteOps.CHECKCAST;
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = RegisterSpecList.make(objectReg);
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (opcode == ByteOps.JSR) {
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // JSR has no Rop instruction
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hasJsr = true;
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (opcode == ByteOps.RET) {
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                returnAddress = (ReturnAddress)arg(0);
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch (ClassCastException ex) {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new RuntimeException(
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "Argument to RET was not a ReturnAddress", ex);
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // RET has no Rop instruction.
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ropOpcode = jopToRopOpcode(opcode, cst);
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        rop = Rops.ropFor(ropOpcode, destType, sources, cst);
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Insn moveResult = null;
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dest != null && rop.isCallLike()) {
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // We're going to want to have a move-result in the next basic block
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            moveResult = new PlainInsn(
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opMoveResult(((CstMethodRef) cst).getPrototype()
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .getReturnType()), pos, dest, RegisterSpecList.EMPTY);
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (dest != null && rop.canThrow()) {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // We're going to want to have a move-result-pseudo
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // in the next basic block
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            moveResult = new PlainInsn(
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Rops.opMoveResultPseudo(dest.getTypeBearer()),
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    pos, dest, RegisterSpecList.EMPTY);
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dest = null;
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ropOpcode == RegOps.NEW_ARRAY) {
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * In the original bytecode, this was either a primitive
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * array constructor "newarray" or an object array
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * constructor "anewarray". In the former case, there is
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * no explicit constant, and in the latter, the constant
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * is for the element type and not the array type. The rop
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * instruction form for both of these is supposed to be
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * the resulting array type, so we initialize / alter
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * "cst" here, accordingly. Conveniently enough, the rop
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * opcode already gets constructed with the proper array
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * type.
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cst = CstType.intern(rop.getResult());
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if ((cst == null) && (sourceCount == 2)) {
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            TypeBearer lastType = sources.get(1).getTypeBearer();
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (lastType.isConstant()
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    && advice.hasConstantOperation(rop,
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.get(0), sources.get(1))) {
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The target architecture has an instruction that can
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * build in the constant found in the second argument,
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * so pull it out of the sources and just use it as a
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * constant here.
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cst = (Constant) lastType;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sources = sources.withoutLast();
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rop = Rops.ropFor(ropOpcode, destType, sources, cst);
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SwitchList cases = getAuxCases();
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayList<Constant> initValues = getInitValues();
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean canThrow = rop.canThrow();
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        blockCanThrow |= canThrow;
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cases != null) {
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cases.size() == 0) {
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // It's a default-only switch statement. It can happen!
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new PlainInsn(Rops.GOTO, pos, null,
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     RegisterSpecList.EMPTY);
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = 0;
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                IntList values = cases.getValues();
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new SwitchInsn(rop, pos, dest, sources, values);
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = values.size();
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (ropOpcode == RegOps.RETURN) {
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Returns get turned into the combination of a move (if
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * non-void and if the return doesn't already mention
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * register 0) and a goto (to the return block).
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (sources.size() != 0) {
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec source = sources.get(0);
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                TypeBearer type = source.getTypeBearer();
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (source.getReg() != 0) {
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    insns.add(new PlainInsn(Rops.opMove(type), pos,
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            RegisterSpec.make(0, type),
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            source));
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY);
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            primarySuccessorIndex = 0;
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            updateReturnOp(rop, pos);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returns = true;
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (cst != null) {
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (canThrow) {
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn =
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    new ThrowingCstInsn(rop, pos, sources, catches, cst);
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                catchesUsed = true;
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = catches.size();
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insn = new PlainCstInsn(rop, pos, dest, sources, cst);
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (canThrow) {
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new ThrowingInsn(rop, pos, sources, catches);
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catchesUsed = true;
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (opcode == ByteOps.ATHROW) {
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The op athrow is the only one where it's possible
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * to have non-empty successors and yet not have a
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * primary successor.
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = -1;
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                primarySuccessorIndex = catches.size();
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new PlainInsn(rop, pos, dest, sources);
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        insns.add(insn);
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (moveResult != null) {
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(moveResult);
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * If initValues is non-null, it means that the parser has seen a group
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * of compatible constant initialization bytecodes that are applied to
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the current newarray. The action we take here is to convert these
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * initialization bytecodes into a single fill-array-data ROP which lays
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * out all the constant values in a table.
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (initValues != null) {
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            extraBlockCount++;
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn = new FillArrayDataInsn(Rops.FILL_ARRAY_DATA, pos,
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpecList.make(moveResult.getResult()), initValues,
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    cst);
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insns.add(insn);
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Helper for {@link #run}, which gets the list of sources for the.
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instruction.
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param opcode the opcode being translated
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param stackPointer &gt;= 0; the stack pointer after the instruction's
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * arguments have been popped
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the sources
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private RegisterSpecList getSources(int opcode, int stackPointer) {
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = argCount();
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (count == 0) {
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // We get an easy out if there aren't any sources.
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return RegisterSpecList.EMPTY;
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int localIndex = getLocalIndex();
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpecList sources;
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (localIndex >= 0) {
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // The instruction is operating on a local variable.
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = new RegisterSpecList(1);
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources.set(0, RegisterSpec.make(localIndex, arg(0)));
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources = new RegisterSpecList(count);
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int regAt = stackPointer;
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < count; i++) {
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec spec = RegisterSpec.make(regAt, arg(i));
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sources.set(i, spec);
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                regAt += spec.getCategory();
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (opcode) {
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.IASTORE: {
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * The Java argument order for array stores is
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * (array, index, value), but the rop argument
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * order is (value, array, index). The following
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * code gets the right arguments in the right
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * places.
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (count != 3) {
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new RuntimeException("shouldn't happen");
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec array = sources.get(0);
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec index = sources.get(1);
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec value = sources.get(2);
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(0, value);
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(1, array);
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(2, index);
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ByteOps.PUTFIELD: {
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * Similar to above: The Java argument order for
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * putfield is (object, value), but the rop
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * argument order is (value, object).
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (count != 2) {
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new RuntimeException("shouldn't happen");
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec obj = sources.get(0);
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec value = sources.get(1);
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(0, value);
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sources.set(1, obj);
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources.setImmutable();
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sources;
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets or updates the information about the return block.
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param op non-null; the opcode to use
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param pos non-null; the position to use
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void updateReturnOp(Rop op, SourcePosition pos) {
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (op == null) {
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("op == null");
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pos == null) {
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("pos == null");
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (returnOp == null) {
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returnOp = op;
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            returnPosition = pos;
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (returnOp != op) {
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new SimException("return op mismatch: " + op + ", " +
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                       returnOp);
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (pos.getLine() > returnPosition.getLine()) {
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Pick the largest line number to be the "canonical" return.
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                returnPosition = pos;
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the register opcode for the given Java opcode.
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param jop &gt;= 0; the Java opcode
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param cst null-ok; the constant argument, if any
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return &gt;= 0; the corresponding register opcode
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int jopToRopOpcode(int jop, Constant cst) {
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (jop) {
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.POP:
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.POP2:
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP:
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP_X1:
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP_X2:
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2:
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2_X1:
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DUP2_X2:
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.SWAP:
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.JSR:
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.RET:
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MULTIANEWARRAY: {
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // These need to be taken care of specially.
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NOP: {
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NOP;
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LDC:
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LDC2_W: {
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CONST;
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ILOAD:
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISTORE: {
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MOVE;
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IALOAD: {
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.AGET;
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IASTORE: {
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.APUT;
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IADD:
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IINC: {
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.ADD;
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISUB: {
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SUB;
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IMUL: {
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MUL;
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IDIV: {
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.DIV;
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IREM: {
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.REM;
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INEG: {
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEG;
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISHL: {
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SHL;
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ISHR: {
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SHR;
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IUSHR: {
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.USHR;
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IAND: {
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.AND;
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IOR: {
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.OR;
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IXOR: {
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.XOR;
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2L:
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2F:
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2D:
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2I:
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2F:
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.L2D:
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2I:
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2L:
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.F2D:
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2I:
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2L:
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.D2F: {
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CONV;
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2B: {
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_BYTE;
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2C: {
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_CHAR;
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.I2S: {
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.TO_SHORT;
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LCMP:
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.FCMPL:
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DCMPL: {
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CMPL;
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.FCMPG:
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.DCMPG: {
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CMPG;
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFEQ:
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPEQ:
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ACMPEQ:
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNULL: {
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_EQ;
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNE:
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPNE:
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ACMPNE:
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFNONNULL: {
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_NE;
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFLT:
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPLT: {
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_LT;
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFGE:
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPGE: {
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_GE;
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFGT:
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPGT: {
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_GT;
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IFLE:
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IF_ICMPLE: {
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.IF_LE;
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GOTO: {
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GOTO;
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.LOOKUPSWITCH: {
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.SWITCH;
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.IRETURN:
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.RETURN: {
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.RETURN;
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GETSTATIC: {
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GET_STATIC;
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.PUTSTATIC: {
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.PUT_STATIC;
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.GETFIELD: {
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.GET_FIELD;
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.PUTFIELD: {
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.PUT_FIELD;
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKEVIRTUAL: {
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_VIRTUAL;
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKESPECIAL: {
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Determine whether the opcode should be
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * INVOKE_DIRECT or INVOKE_SUPER. See vmspec-2 section 6
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * on "invokespecial" as well as section 4.8.2 (7th
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * bullet point) for the gory details.
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstMethodRef ref = (CstMethodRef) cst;
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ref.isInstanceInit() ||
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    (ref.getDefiningClass() == method.getDefiningClass()) ||
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    !method.getAccSuper()) {
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return RegOps.INVOKE_DIRECT;
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_SUPER;
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKESTATIC: {
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_STATIC;
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INVOKEINTERFACE: {
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INVOKE_INTERFACE;
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NEW: {
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEW_INSTANCE;
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.NEWARRAY:
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ANEWARRAY: {
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.NEW_ARRAY;
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ARRAYLENGTH: {
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.ARRAY_LENGTH;
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.ATHROW: {
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.THROW;
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.CHECKCAST: {
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.CHECK_CAST;
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.INSTANCEOF: {
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.INSTANCE_OF;
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MONITORENTER: {
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MONITOR_ENTER;
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case ByteOps.MONITOREXIT: {
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return RegOps.MONITOR_EXIT;
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new RuntimeException("shouldn't happen");
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
937