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.LocalItem; 20fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.RegisterSpec; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Prototype; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base implementation of {@link Machine}. 30de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p><b>Note:</b> For the most part, the documentation for this class 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ignores the distinction between {@link Type} and {@link 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TypeBearer}.</p> 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class BaseMachine implements Machine { 3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* {@code non-null;} the prototype for the associated method */ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Prototype prototype; 38de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} primary arguments */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private TypeBearer[] args; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= 0;} number of primary arguments */ 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int argCount; 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} type of the operation, if salient */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Type auxType; 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** auxiliary {@code int} argument */ 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int auxInt; 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} auxiliary constant argument */ 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Constant auxCst; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** auxiliary branch target argument */ 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int auxTarget; 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} auxiliary switch cases argument */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private SwitchList auxCases; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} auxiliary initial value list for newarray */ 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private ArrayList<Constant> auxInitValues; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code >= -1;} last local accessed */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int localIndex; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao /** specifies if local has info in the local variable table */ 67c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao private boolean localInfo; 68c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} local target spec, if salient and calculated */ 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private RegisterSpec localTarget; 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} results */ 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private TypeBearer[] results; 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code >= -1;} count of the results, or {@code -1} if no results 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have been set 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int resultCount; 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 83de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 843d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * @param prototype {@code non-null;} the prototype for the 853d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * associated method 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public BaseMachine(Prototype prototype) { 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (prototype == null) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("prototype == null"); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.prototype = prototype; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = new TypeBearer[10]; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project results = new TypeBearer[6]; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearArgs(); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Prototype getPrototype() { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return prototype; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void clearArgs() { 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argCount = 0; 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxType = null; 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxInt = 0; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxCst = null; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxTarget = 0; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxCases = null; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxInitValues = null; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localIndex = -1; 113c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao localInfo = false; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localTarget = null; 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultCount = -1; 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void popArgs(Frame frame, int count) { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExecutionStack stack = frame.getStack(); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearArgs(); 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count > args.length) { 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Grow args, and add a little extra room to grow even more. 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args = new TypeBearer[count + 10]; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = count - 1; i >= 0; i--) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args[i] = stack.pop(); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argCount = count; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void popArgs(Frame frame, Prototype prototype) { 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StdTypeList types = prototype.getParameterTypes(); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int size = types.size(); 140de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Use the above method to do the actual popping... 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project popArgs(frame, size); 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // ...and then verify the popped types. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < size; i++) { 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("at stack depth " + (size - 1 - i) + 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ", expected type " + types.getType(i).toHuman() + 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[i].getType().toHuman()); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void popArgs(Frame frame, Type type) { 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Use the above method to do the actual popping... 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project popArgs(frame, 1); 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // ...and then verify the popped type. 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type, args[0])) { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("expected type " + type.toHuman() + 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[0].getType().toHuman()); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void popArgs(Frame frame, Type type1, Type type2) { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Use the above method to do the actual popping... 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project popArgs(frame, 2); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // ...and then verify the popped types. 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type1, args[0])) { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("expected type " + type1.toHuman() + 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[0].getType().toHuman()); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type2, args[1])) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("expected type " + type2.toHuman() + 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[1].getType().toHuman()); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void popArgs(Frame frame, Type type1, Type type2, 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type type3) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Use the above method to do the actual popping... 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project popArgs(frame, 3); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // ...and then verify the popped types. 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type1, args[0])) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("expected type " + type1.toHuman() + 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[0].getType().toHuman()); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type2, args[1])) { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("expected type " + type2.toHuman() + 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[1].getType().toHuman()); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(type3, args[2])) { 203c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao throw new SimException("expected type " + type3.toHuman() + 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " but found " + args[2].getType().toHuman()); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void localArg(Frame frame, int idx) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project clearArgs(); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project args[0] = frame.getLocals().get(idx); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argCount = 1; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localIndex = idx; 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 217c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao public final void localInfo(boolean local) { 218c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao localInfo = local; 219c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao } 220c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao 221c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao /** {@inheritDoc} */ 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxType(Type type) { 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxType = type; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxIntArg(int value) { 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxInt = value; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxCstArg(Constant cst) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cst == null) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("cst == null"); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxCst = cst; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxTargetArg(int target) { 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxTarget = target; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxSwitchArg(SwitchList cases) { 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (cases == null) { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("cases == null"); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxCases = cases; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void auxInitValues(ArrayList<Constant> initValues) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project auxInitValues = initValues; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void localTarget(int idx, Type type, LocalItem local) { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localTarget = RegisterSpec.makeLocalOptional(idx, type, local); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the number of primary arguments. 266de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 26799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the number of primary arguments 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int argCount() { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return argCount; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the width of the arguments (where a category-2 value counts as 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * two). 276de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 27799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the argument width 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int argWidth() { 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = 0; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < argCount; i++) { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result += args[i].getType().getCategory(); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 29099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code n}th primary argument. 291de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 29299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0, < argCount();} which argument 29399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the indicated argument 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final TypeBearer arg(int n) { 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n >= argCount) { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n >= argCount"); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return args[n]; 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ArrayIndexOutOfBoundsException ex) { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n < 0"); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the type auxiliary argument. 310de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 31199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the salient type 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final Type getAuxType() { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxType; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 31899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code int} auxiliary argument. 319de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the argument value 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getAuxInt() { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxInt; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the constant auxiliary argument. 328de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 32999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the argument value 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final Constant getAuxCst() { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxCst; 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the branch target auxiliary argument. 337de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the argument value 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getAuxTarget() { 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxTarget; 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the switch cases auxiliary argument. 346de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 34799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the argument value 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final SwitchList getAuxCases() { 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxCases; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the init values auxiliary argument. 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 35699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the argument value 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final ArrayList<Constant> getInitValues() { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return auxInitValues; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the last local index accessed. 363de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 36499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= -1;} the salient local index or {@code -1} if none 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * was set since the last time {@link #clearArgs} was called 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getLocalIndex() { 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return localIndex; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 372c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao * Gets whether the loaded local has info in the local variable table. 373c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao * 374c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao * @return {@code true} if local arg has info in the local variable table 375c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao */ 376c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao protected final boolean getLocalInfo() { 377c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao return localInfo; 378c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao } 379c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao 380c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao /** 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the target local register spec of the current operation, if any. 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The local target spec is the combination of the values indicated 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by a previous call to {@link #localTarget} with the type of what 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should be the sole result set by a call to {@link #setResult} (or 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the combination {@link #clearResult} then {@link #addResult}. 386de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 3873d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * @param isMove {@code true} if the operation being performed on the 3883d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * local is a move. This will cause constant values to be propagated 3893d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * to the returned local 39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} the salient register spec or {@code null} if no 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * local target was set since the last time {@link #clearArgs} was 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * called 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3943d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein protected final RegisterSpec getLocalTarget(boolean isMove) { 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localTarget == null) { 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultCount != 1) { 400de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro throw new SimException("local target with " + 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((resultCount == 0) ? "no" : "multiple") + " results"); 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer result = results[0]; 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type resultType = result.getType(); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type localType = localTarget.getType(); 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultType == localType) { 4093d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein /* 4103d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * If this is to be a move operation and the result is a 4113d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * known value, make the returned localTarget embody that 4123d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein * value. 4133d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein */ 4143d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein if (isMove) { 4153d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein return localTarget.withType(result); 4163d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein } else { 4173d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein return localTarget; 4183d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein } 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! Merger.isPossiblyAssignableFrom(localType, resultType)) { 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The result and local types are inconsistent. Complain! 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwLocalMismatch(resultType, localType); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localType == Type.OBJECT) { 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The result type is more specific than the local type, 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so use that instead. 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localTarget = localTarget.withType(result); 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return localTarget; 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clears the results. 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void clearResult() { 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultCount = 0; 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the results list to be the given single value. 447de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p><b>Note:</b> If there is more than one result value, the 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * others may be added by using {@link #addResult}.</p> 450de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 45199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result value 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void setResult(TypeBearer result) { 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("result == null"); 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project results[0] = result; 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultCount = 1; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adds an additional element to the list of results. 464de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #setResult 466de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 46799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param result {@code non-null;} result value 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void addResult(TypeBearer result) { 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("result == null"); 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project results[resultCount] = result; 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultCount++; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the count of results. This throws an exception if results were 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * never set. (Explicitly clearing the results counts as setting them.) 481de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 48299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the count 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int resultCount() { 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultCount < 0) { 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("results never set"); 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resultCount; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the width of the results (where a category-2 value counts as 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * two). 495de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 49699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the result width 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int resultWidth() { 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = 0; 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < resultCount; i++) { 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width += results[i].getType().getCategory(); 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return width; 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 50999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the {@code n}th result value. 510de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 51199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param n {@code >= 0, < resultCount();} which result 51299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the indicated result value 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final TypeBearer result(int n) { 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n >= resultCount) { 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n >= resultCount"); 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return results[n]; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (ArrayIndexOutOfBoundsException ex) { 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Translate the exception. 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n < 0"); 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stores the results of the latest operation into the given frame. If 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * there is a local target (see {@link #localTarget}), then the sole 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result is stored to that target; otherwise any results are pushed 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * onto the stack. 532de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 53399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param frame {@code non-null;} frame to operate on 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void storeResults(Frame frame) { 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultCount < 0) { 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("results never set"); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultCount == 0) { 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Nothing to do. 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localTarget != null) { 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note: getLocalTarget() doesn't necessarily return 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * localTarget directly. 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5503d0823c03df73acc786940489dcdd5b8e0d7cefeDan Bornstein frame.getLocals().set(getLocalTarget(false)); 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExecutionStack stack = frame.getStack(); 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < resultCount; i++) { 554c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao if (localInfo) { 555c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao stack.setLocal(); 556c31f795aef67a0d6af9abe4610db5ecae8d30c19jeffhao } 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack.push(results[i]); 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws an exception that indicates a mismatch in local variable 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * types. 565de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 56699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param found {@code non-null;} the encountered type 56799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code non-null;} the local variable's claimed type 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public static void throwLocalMismatch(TypeBearer found, 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer local) { 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("local variable type mismatch: " + 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "attempt to set or access a value of type " + 573de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro found.toHuman() + 574de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro " using a local variable of type " + 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project local.toHuman() + 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ". This is symptomatic of .class transformation tools " + 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "that ignore local variable information."); 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 580