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; 354596322b12a72cdeea8deba1242d9b74da5ba12ajeffhaoimport com.android.dx.rop.cst.CstInteger; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstNat; 38333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList; 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 { 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code 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 /** 5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} method constant for use in converting 56de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * {@code multianewarray} 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, 60333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson new CstNat(new CstString("newInstance"), 61333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson new CstString("(Ljava/lang/Class;[I)" + 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Ljava/lang/Object;"))); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} {@link Ropper} controlling this instance */ 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Ropper ropper; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} method being converted */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ConcreteMethod method; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code 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 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code 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 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code 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 8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** whether the block contains a {@code return} */ 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 9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 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 /** 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the appropriate {@code return} op or {@code null} 109de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 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 /** 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code null-ok;} the source position for the return block or {@code null} 115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 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. 121de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ropper {@code non-null;} ropper controlling this instance 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param method {@code non-null;} method being converted 12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param advice {@code 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()); 129de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 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. 156de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 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. 165de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 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. 174de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 17599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code 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 18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code return}, 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. 203de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return whether {@code catches} 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 21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code return}. 213de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 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 22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code -1} if there are successors but no primary 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * successor. This may return something other than 22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code -1} in the case of an instruction with no 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * successors at all (primary or otherwise). 227de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= -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. 238de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 23999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 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 /** 262d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * @return {@code true} if a {@code ret} has ben encountered since 263d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * the last call to {@code 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 /** 270d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * @return {@code null-ok;} return address of a {@code ret} 271d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * instruction if encountered since last call to startBlock(). 272d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * {@code null} if no ret instruction encountered. 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ReturnAddress getReturnAddress() { 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return returnAddress; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void run(Frame frame, int offset, int opcode) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is the stack pointer after the opcode's arguments have been 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * popped. 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int stackPointer = maxLocals + frame.getStack().size(); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The sources have to be retrieved before super.run() gets called. 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList sources = getSources(opcode, stackPointer); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sourceCount = sources.size(); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super.run(frame, offset, opcode); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SourcePosition pos = method.makeSourcePosistion(offset); 2943d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein RegisterSpec localTarget = getLocalTarget(opcode == ByteOps.ISTORE); 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int destCount = resultCount(); 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec dest; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (destCount == 0) { 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest = null; 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opcode) { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.POP: 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.POP2: { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // These simply don't appear in the rop form. 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (localTarget != null) { 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest = localTarget; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (destCount == 1) { 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest = RegisterSpec.make(stackPointer, result(0)); 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This clause only ever applies to the stack manipulation 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ops that have results (that is, dup* and swap but not 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pop*). 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * What we do is first move all the source registers into 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the "temporary stack" area defined for the method, and 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then move stuff back down onto the main "stack" in the 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * arrangement specified by the stack op pattern. 321de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note: This code ends up emitting a lot of what will 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * turn out to be superfluous moves (e.g., moving back and 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * forth to the same local when doing a dup); however, 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that makes this code a bit easier (and goodness knows 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it doesn't need any extra complexity), and all the SSA 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stuff is going to want to deal with this sort of 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superfluous assignment anyway, so it should be a wash 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the end. 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int scratchAt = ropper.getFirstTempStackReg(); 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec[] scratchRegs = new RegisterSpec[sourceCount]; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sourceCount; i++) { 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec src = sources.get(i); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer type = src.getTypeBearer(); 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec scratch = src.withReg(scratchAt); 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(new PlainInsn(Rops.opMove(type), pos, scratch, src)); 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project scratchRegs[i] = scratch; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project scratchAt += src.getCategory(); 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) { 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int which = (pattern & 0x0f) - 1; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec scratch = scratchRegs[which]; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer type = scratch.getTypeBearer(); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(new PlainInsn(Rops.opMove(type), pos, 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project scratch.withReg(stackPointer), 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project scratch)); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPointer += type.getType().getCategory(); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 353de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer destType = (dest != null) ? dest : Type.VOID; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Constant cst = getAuxCst(); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ropOpcode; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rop rop; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Insn insn; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opcode == ByteOps.MULTIANEWARRAY) { 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project blockCanThrow = true; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add the extra instructions for handling multianewarray. 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extraBlockCount = 6; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add an array constructor for the int[] containing all the 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dimensions. 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 372de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro RegisterSpec dimsReg = 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new ThrowingCstInsn(rop, pos, sources, catches, 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstType.INT_ARRAY); 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add a move-result for the new-filled-array 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rop = Rops.opMoveResult(Type.INT_ARRAY); 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY); 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add a const-class instruction for the specified array 386de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * class. 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Remove as many dimensions from the originally specified 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * class as are given in the explicit list of dimensions, 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so as to pass the right component class to the standard 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Java library array constructor. 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type componentType = ((CstType) cst).getClassType(); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sourceCount; i++) { 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project componentType = componentType.getComponentType(); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec classReg = 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec.make(dest.getReg(), Type.CLASS); 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (componentType.isPrimitive()) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The component type is primitive (e.g., int as opposed 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to Integer), so we have to fetch the corresponding 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TYPE class. 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstFieldRef typeField = 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstFieldRef.forPrimitiveType(componentType); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos, 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList.EMPTY, 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches, typeField); 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The component type is an object type, so just make a 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * normal class reference. 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList.EMPTY, catches, 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new CstType(componentType)); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Add a move-result-pseudo for the get-static or const 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rop = Rops.opMoveResultPseudo(classReg.getType()); 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY); 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add a call to the "multianewarray method," that is, 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Array.newInstance(class, dims). Note: The result type 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of newInstance() is Object, which is why the last 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction in this sequence is a cast to the right 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type for the original instruction. 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec objectReg = 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec.make(dest.getReg(), Type.OBJECT); 441de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new ThrowingCstInsn( 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()), 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pos, RegisterSpecList.make(classReg, dimsReg), 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catches, MULTIANEWARRAY_METHOD); 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 448d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein // Add a move-result. 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype() 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getReturnType()); 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY); 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * And finally, set up for the remainder of this method to 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * add an appropriate cast. 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project opcode = ByteOps.CHECKCAST; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = RegisterSpecList.make(objectReg); 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 rop = Rops.ropFor(ropOpcode, destType, sources, cst); 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Insn moveResult = null; 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dest != null && rop.isCallLike()) { 481d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein /* 482d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * We're going to want to have a move-result in the next 483d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * basic block. 484d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein */ 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extraBlockCount++; 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project moveResult = new PlainInsn( 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rops.opMoveResult(((CstMethodRef) cst).getPrototype() 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getReturnType()), pos, dest, RegisterSpecList.EMPTY); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest = null; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (dest != null && rop.canThrow()) { 493d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein /* 494d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * We're going to want to have a move-result-pseudo in the 495d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * next basic block. 496d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein */ 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extraBlockCount++; 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project moveResult = new PlainInsn( 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rops.opMoveResultPseudo(dest.getTypeBearer()), 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pos, dest, RegisterSpecList.EMPTY); 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dest = null; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ropOpcode == RegOps.NEW_ARRAY) { 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In the original bytecode, this was either a primitive 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * array constructor "newarray" or an object array 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * constructor "anewarray". In the former case, there is 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * no explicit constant, and in the latter, the constant 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is for the element type and not the array type. The rop 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction form for both of these is supposed to be 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the resulting array type, so we initialize / alter 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "cst" here, accordingly. Conveniently enough, the rop 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * opcode already gets constructed with the proper array 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type. 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cst = CstType.intern(rop.getResult()); 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ((cst == null) && (sourceCount == 2)) { 5204596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao TypeBearer firstType = sources.get(0).getTypeBearer(); 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer lastType = sources.get(1).getTypeBearer(); 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5234596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao if ((lastType.isConstant() || firstType.isConstant()) && 5244596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao advice.hasConstantOperation(rop, sources.get(0), 5254596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao sources.get(1))) { 5264596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao 5274596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao if (lastType.isConstant()) { 5284596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao /* 5294596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * The target architecture has an instruction that can 5304596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * build in the constant found in the second argument, 5314596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * so pull it out of the sources and just use it as a 5324596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * constant here. 5334596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao */ 5344596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao cst = (Constant) lastType; 5354596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao sources = sources.withoutLast(); 5364596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao 5374596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao // For subtraction, change to addition and invert constant 5384596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao if (rop.getOpcode() == RegOps.SUB) { 5394596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao ropOpcode = RegOps.ADD; 5404596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao CstInteger cstInt = (CstInteger) lastType; 5414596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao cst = CstInteger.make(-cstInt.getValue()); 5424596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao } 5434596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao } else { 5444596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao /* 5454596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * The target architecture has an instruction that can 5464596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * build in the constant found in the first argument, 5474596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * so pull it out of the sources and just use it as a 5484596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao * constant here. 5494596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao */ 5504596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao cst = (Constant) firstType; 5514596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao sources = sources.withoutFirst(); 5524596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao } 5534596322b12a72cdeea8deba1242d9b74da5ba12ajeffhao 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rop = Rops.ropFor(ropOpcode, destType, sources, cst); 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SwitchList cases = getAuxCases(); 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<Constant> initValues = getInitValues(); 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean canThrow = rop.canThrow(); 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project blockCanThrow |= canThrow; 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cases != null) { 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cases.size() == 0) { 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // It's a default-only switch statement. It can happen! 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(Rops.GOTO, pos, null, 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList.EMPTY); 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = 0; 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IntList values = cases.getValues(); 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new SwitchInsn(rop, pos, dest, sources, values); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = values.size(); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (ropOpcode == RegOps.RETURN) { 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns get turned into the combination of a move (if 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * non-void and if the return doesn't already mention 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * register 0) and a goto (to the return block). 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sources.size() != 0) { 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec source = sources.get(0); 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer type = source.getTypeBearer(); 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (source.getReg() != 0) { 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(new PlainInsn(Rops.opMove(type), pos, 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec.make(0, type), 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project source)); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY); 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = 0; 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project updateReturnOp(rop, pos); 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returns = true; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (cst != null) { 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (canThrow) { 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project new ThrowingCstInsn(rop, pos, sources, catches, cst); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchesUsed = true; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = catches.size(); 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainCstInsn(rop, pos, dest, sources, cst); 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (canThrow) { 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new ThrowingInsn(rop, pos, sources, catches); 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchesUsed = true; 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opcode == ByteOps.ATHROW) { 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The op athrow is the only one where it's possible 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to have non-empty successors and yet not have a 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * primary successor. 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = -1; 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project primarySuccessorIndex = catches.size(); 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new PlainInsn(rop, pos, dest, sources); 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (moveResult != null) { 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(moveResult); 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 627d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * If initValues is non-null, it means that the parser has 628d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * seen a group of compatible constant initialization 629d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * bytecodes that are applied to the current newarray. The 630d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * action we take here is to convert these initialization 631d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * bytecodes into a single fill-array-data ROP which lays out 632d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * all the constant values in a table. 633de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro */ 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (initValues != null) { 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project extraBlockCount++; 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn = new FillArrayDataInsn(Rops.FILL_ARRAY_DATA, pos, 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList.make(moveResult.getResult()), initValues, 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cst); 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insns.add(insn); 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Helper for {@link #run}, which gets the list of sources for the. 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. 646de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param opcode the opcode being translated 648d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * @param stackPointer {@code >= 0;} the stack pointer after the 649d24414a5d1780ce25179f3467b228f9a53863fb4Dan Bornstein * instruction's arguments have been popped 65099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the sources 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private RegisterSpecList getSources(int opcode, int stackPointer) { 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = argCount(); 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == 0) { 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We get an easy out if there aren't any sources. 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegisterSpecList.EMPTY; 658de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro } 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int localIndex = getLocalIndex(); 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList sources; 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localIndex >= 0) { 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The instruction is operating on a local variable. 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = new RegisterSpecList(1); 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(0, RegisterSpec.make(localIndex, arg(0))); 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = new RegisterSpecList(count); 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int regAt = stackPointer; 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < count; i++) { 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec spec = RegisterSpec.make(regAt, arg(i)); 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(i, spec); 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regAt += spec.getCategory(); 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opcode) { 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IASTORE: { 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The Java argument order for array stores is 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (array, index, value), but the rop argument 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * order is (value, array, index). The following 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * code gets the right arguments in the right 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * places. 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count != 3) { 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen"); 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec array = sources.get(0); 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec index = sources.get(1); 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec value = sources.get(2); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(0, value); 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(1, array); 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(2, index); 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.PUTFIELD: { 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Similar to above: The Java argument order for 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * putfield is (object, value), but the rop 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument order is (value, object). 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count != 2) { 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen"); 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec obj = sources.get(0); 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec value = sources.get(1); 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(0, value); 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(1, obj); 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.setImmutable(); 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets or updates the information about the return block. 720de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 72199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param op {@code non-null;} the opcode to use 72299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param pos {@code non-null;} the position to use 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void updateReturnOp(Rop op, SourcePosition pos) { 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (op == null) { 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("op == null"); 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pos == null) { 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("pos == null"); 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (returnOp == null) { 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnOp = op; 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnPosition = pos; 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (returnOp != op) { 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("return op mismatch: " + op + ", " + 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnOp); 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pos.getLine() > returnPosition.getLine()) { 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Pick the largest line number to be the "canonical" return. 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project returnPosition = pos; 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the register opcode for the given Java opcode. 751de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 75299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param jop {@code >= 0;} the Java opcode 75399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param cst {@code null-ok;} the constant argument, if any 75499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the corresponding register opcode 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int jopToRopOpcode(int jop, Constant cst) { 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (jop) { 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.POP: 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.POP2: 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP: 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP_X1: 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP_X2: 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP2: 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP2_X1: 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DUP2_X2: 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.SWAP: 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.JSR: 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.RET: 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.MULTIANEWARRAY: { 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // These need to be taken care of specially. 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.NOP: { 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.NOP; 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.LDC: 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.LDC2_W: { 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.CONST; 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 780de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro case ByteOps.ILOAD: 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ISTORE: { 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.MOVE; 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IALOAD: { 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.AGET; 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IASTORE: { 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.APUT; 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IADD: 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IINC: { 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.ADD; 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ISUB: { 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.SUB; 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IMUL: { 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.MUL; 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IDIV: { 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.DIV; 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IREM: { 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.REM; 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INEG: { 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.NEG; 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ISHL: { 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.SHL; 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ISHR: { 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.SHR; 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IUSHR: { 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.USHR; 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IAND: { 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.AND; 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IOR: { 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.OR; 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IXOR: { 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.XOR; 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2L: 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2F: 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2D: 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.L2I: 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.L2F: 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.L2D: 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.F2I: 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.F2L: 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.F2D: 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.D2I: 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.D2L: 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.D2F: { 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.CONV; 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2B: { 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.TO_BYTE; 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2C: { 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.TO_CHAR; 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.I2S: { 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.TO_SHORT; 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.LCMP: 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.FCMPL: 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DCMPL: { 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.CMPL; 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.FCMPG: 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.DCMPG: { 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.CMPG; 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFEQ: 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPEQ: 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ACMPEQ: 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFNULL: { 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_EQ; 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFNE: 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPNE: 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ACMPNE: 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFNONNULL: { 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_NE; 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFLT: 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPLT: { 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_LT; 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFGE: 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPGE: { 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_GE; 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFGT: 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPGT: { 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_GT; 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IFLE: 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IF_ICMPLE: { 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.IF_LE; 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.GOTO: { 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.GOTO; 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.LOOKUPSWITCH: { 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.SWITCH; 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.IRETURN: 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.RETURN: { 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.RETURN; 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.GETSTATIC: { 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.GET_STATIC; 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.PUTSTATIC: { 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.PUT_STATIC; 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.GETFIELD: { 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.GET_FIELD; 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.PUTFIELD: { 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.PUT_FIELD; 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INVOKEVIRTUAL: { 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INVOKE_VIRTUAL; 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INVOKESPECIAL: { 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether the opcode should be 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * INVOKE_DIRECT or INVOKE_SUPER. See vmspec-2 section 6 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on "invokespecial" as well as section 4.8.2 (7th 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bullet point) for the gory details. 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstMethodRef ref = (CstMethodRef) cst; 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ref.isInstanceInit() || 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (ref.getDefiningClass() == method.getDefiningClass()) || 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !method.getAccSuper()) { 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INVOKE_DIRECT; 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INVOKE_SUPER; 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INVOKESTATIC: { 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INVOKE_STATIC; 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INVOKEINTERFACE: { 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INVOKE_INTERFACE; 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.NEW: { 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.NEW_INSTANCE; 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.NEWARRAY: 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ANEWARRAY: { 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.NEW_ARRAY; 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ARRAYLENGTH: { 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.ARRAY_LENGTH; 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.ATHROW: { 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.THROW; 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.CHECKCAST: { 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.CHECK_CAST; 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.INSTANCEOF: { 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.INSTANCE_OF; 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.MONITORENTER: { 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.MONITOR_ENTER; 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case ByteOps.MONITOREXIT: { 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegOps.MONITOR_EXIT; 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException("shouldn't happen"); 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 963