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.type.Type; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ExceptionWithContext; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.MutabilityControl; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Representation of a Java method execution stack. 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p><b>Note:</b> For the most part, the documentation for this class 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ignores the distinction between {@link Type} and {@link 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TypeBearer}.</p> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class ExecutionStack extends MutabilityControl { 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** non-null; array of stack contents */ 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final TypeBearer[] stack; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * >= 0; stack pointer (points one past the end) / current stack 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * size 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int stackPtr; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param maxStack >= 0; the maximum size of the stack for this 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instance 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ExecutionStack(int maxStack) { 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(maxStack != 0); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack = new TypeBearer[maxStack]; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPtr = 0; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes and returns a mutable copy of this instance. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return non-null; the copy 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ExecutionStack copy() { 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExecutionStack result = new ExecutionStack(stack.length); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.arraycopy(stack, 0, result.stack, 0, stack.length); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.stackPtr = stackPtr; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Annotates (adds context to) the given exception with information 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * about this instance. 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ex non-null; the exception to annotate 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void annotate(ExceptionWithContext ex) { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int limit = stackPtr - 1; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i <= limit; i++) { 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String idx = (i == limit) ? "top0" : Hex.u2(limit - i); 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ex.addContext("stack[" + idx + "]: " + 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackElementString(stack[i])); 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replaces all the occurrences of the given uninitialized type in 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this stack with its initialized equivalent. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type non-null; type to replace 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void makeInitialized(Type type) { 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (stackPtr == 0) { 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We have to check for this before checking for immutability. 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Type initializedType = type.getInitializedType(); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < stackPtr; i++) { 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (stack[i] == type) { 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[i] = initializedType; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the maximum stack size for this instance. 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return >= 0; the max stack size 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int getMaxStack() { 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return stack.length; 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the current stack size. 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return >= 0, < getMaxStack(); the current stack size 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int size() { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return stackPtr; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clears the stack. (That is, this method pops everything off.) 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void clear() { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < stackPtr; i++) { 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[i] = null; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPtr = 0; 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pushes a value of the given type onto the stack. 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type non-null; type of the value 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SimException thrown if there is insufficient room on the 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stack for the value 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void push(TypeBearer type) { 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = type.getFrameType(); 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project category = type.getType().getCategory(); 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (NullPointerException ex) { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Elucidate the exception. 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("type == null"); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((stackPtr + category) > stack.length) { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSimException("overflow"); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (category == 2) { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[stackPtr] = null; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPtr++; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[stackPtr] = type; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPtr++; 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Peeks at the <code>n</code>th element down from the top of the stack. 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>n == 0</code> means to peek at the top of the stack. Note that 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this will return <code>null</code> if the indicated element is the 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * deeper half of a category-2 value. 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param n >= 0; which element to peek at 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return null-ok; the type of value stored at that element 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SimException thrown if <code>n >= size()</code> 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeBearer peek(int n) { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n < 0) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException("n < 0"); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (n >= stackPtr) { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return throwSimException("underflow"); 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return stack[stackPtr - n - 1]; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Peeks at the <code>n</code>th element down from the top of the 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stack, returning the type per se, as opposed to the 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <i>type-bearer</i>. This method is just a convenient shorthand 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for <code>peek(n).getType()</code>. 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see #peek 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Type peekType(int n) { 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return peek(n).getType(); 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pops the top element off of the stack. 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return non-null; the type formerly on the top of the stack 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SimException thrown if the stack is empty 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public TypeBearer pop() { 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer result = peek(0); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[stackPtr - 1] = null; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackPtr -= result.getType().getCategory(); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changes an element already on a stack. This method is useful in limited 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contexts, particularly when merging two instances. As such, it places 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the following restriction on its behavior: You may only replace 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * values with other values of the same category. 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param n >= 0; which element to change, where <code>0</code> is 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the top element of the stack 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type non-null; type of the new value 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SimException thrown if <code>n >= size()</code> or 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the action is otherwise prohibited 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void change(int n, TypeBearer type) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwIfImmutable(); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = type.getFrameType(); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (NullPointerException ex) { 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Elucidate the exception. 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException("type == null"); 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idx = stackPtr - n - 1; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TypeBearer orig = stack[idx]; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((orig == null) || 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (orig.getType().getCategory() != type.getType().getCategory())) { 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throwSimException("incompatible substitution: " + 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackElementString(orig) + " -> " + 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackElementString(type)); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stack[idx] = type; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merges this stack with another stack. A new instance is returned if 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this merge results in a change. If no change results, this instance is 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returned. See {@link Merger#mergeStack(ExecutionStack,ExecutionStack) 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Merger.mergeStack()} 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param other non-null; a stack to merge with 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return non-null; the result of the merge 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public ExecutionStack merge(ExecutionStack other) { 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Merger.mergeStack(this, other); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (SimException ex) { 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ex.addContext("underlay stack:"); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.annotate(ex); 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ex.addContext("overlay stack:"); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project other.annotate(ex); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw ex; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the string form for a stack element. This is the same as 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>toString()</code> except that <code>null</code> is converted 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to <code>"<invalid>"</code>. 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param type null-ok; the stack element 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return non-null; the string form 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static String stackElementString(TypeBearer type) { 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (type == null) { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return "<invalid>"; 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return type.toString(); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Throws a properly-formatted exception. 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param msg non-null; useful message 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return never (keeps compiler happy) 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static TypeBearer throwSimException(String msg) { 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new SimException("stack: " + msg); 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 306