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