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