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