Methods Summary |
---|
public void | annotate(com.android.dex.util.ExceptionWithContext ex)Annotates (adds context to) the given exception with information
about this instance.
int limit = stackPtr - 1;
for (int i = 0; i <= limit; i++) {
String idx = (i == limit) ? "top0" : Hex.u2(limit - i);
ex.addContext("stack[" + idx + "]: " +
stackElementString(stack[i]));
}
|
public void | change(int n, com.android.dx.rop.type.TypeBearer type)Changes an element already on a stack. This method is useful in limited
contexts, particularly when merging two instances. As such, it places
the following restriction on its behavior: You may only replace
values with other values of the same category.
throwIfImmutable();
try {
type = type.getFrameType();
} catch (NullPointerException ex) {
// Elucidate the exception.
throw new NullPointerException("type == null");
}
int idx = stackPtr - n - 1;
TypeBearer orig = stack[idx];
if ((orig == null) ||
(orig.getType().getCategory() != type.getType().getCategory())) {
throwSimException("incompatible substitution: " +
stackElementString(orig) + " -> " +
stackElementString(type));
}
stack[idx] = type;
|
public void | clear()Clears the stack. (That is, this method pops everything off.)
throwIfImmutable();
for (int i = 0; i < stackPtr; i++) {
stack[i] = null;
local[i] = false;
}
stackPtr = 0;
|
public com.android.dx.cf.code.ExecutionStack | copy()Makes and returns a mutable copy of this instance.
ExecutionStack result = new ExecutionStack(stack.length);
System.arraycopy(stack, 0, result.stack, 0, stack.length);
System.arraycopy(local, 0, result.local, 0, local.length);
result.stackPtr = stackPtr;
return result;
|
public int | getMaxStack()Gets the maximum stack size for this instance.
return stack.length;
|
public void | makeInitialized(com.android.dx.rop.type.Type type)Replaces all the occurrences of the given uninitialized type in
this stack with its initialized equivalent.
if (stackPtr == 0) {
// We have to check for this before checking for immutability.
return;
}
throwIfImmutable();
Type initializedType = type.getInitializedType();
for (int i = 0; i < stackPtr; i++) {
if (stack[i] == type) {
stack[i] = initializedType;
}
}
|
public com.android.dx.cf.code.ExecutionStack | merge(com.android.dx.cf.code.ExecutionStack other)Merges this stack with another stack. A new instance is returned if
this merge results in a change. If no change results, this instance is
returned. See {@link Merger#mergeStack(ExecutionStack,ExecutionStack)
Merger.mergeStack()}
try {
return Merger.mergeStack(this, other);
} catch (SimException ex) {
ex.addContext("underlay stack:");
this.annotate(ex);
ex.addContext("overlay stack:");
other.annotate(ex);
throw ex;
}
|
public com.android.dx.rop.type.TypeBearer | peek(int n)Peeks at the {@code n}th element down from the top of the stack.
{@code n == 0} means to peek at the top of the stack. Note that
this will return {@code null} if the indicated element is the
deeper half of a category-2 value.
if (n < 0) {
throw new IllegalArgumentException("n < 0");
}
if (n >= stackPtr) {
return throwSimException("underflow");
}
return stack[stackPtr - n - 1];
|
public boolean | peekLocal(int n)Peeks at the {@code n}th element down from the top of the
stack, returning whether or not it has local info.
if (n < 0) {
throw new IllegalArgumentException("n < 0");
}
if (n >= stackPtr) {
throw new SimException("stack: underflow");
}
return local[stackPtr - n - 1];
|
public com.android.dx.rop.type.Type | peekType(int n)Peeks at the {@code n}th element down from the top of the
stack, returning the type per se, as opposed to the
type-bearer. This method is just a convenient shorthand
for {@code peek(n).getType()}.
return peek(n).getType();
|
public com.android.dx.rop.type.TypeBearer | pop()Pops the top element off of the stack.
throwIfImmutable();
TypeBearer result = peek(0);
stack[stackPtr - 1] = null;
local[stackPtr - 1] = false;
stackPtr -= result.getType().getCategory();
return result;
|
public void | push(com.android.dx.rop.type.TypeBearer type)Pushes a value of the given type onto the stack.
throwIfImmutable();
int category;
try {
type = type.getFrameType();
category = type.getType().getCategory();
} catch (NullPointerException ex) {
// Elucidate the exception.
throw new NullPointerException("type == null");
}
if ((stackPtr + category) > stack.length) {
throwSimException("overflow");
return;
}
if (category == 2) {
stack[stackPtr] = null;
stackPtr++;
}
stack[stackPtr] = type;
stackPtr++;
|
public void | setLocal()Flags the next value pushed onto the stack as having local info.
throwIfImmutable();
local[stackPtr] = true;
|
public int | size()Gets the current stack size.
return stackPtr;
|
private static java.lang.String | stackElementString(com.android.dx.rop.type.TypeBearer type)Gets the string form for a stack element. This is the same as
{@code toString()} except that {@code null} is converted
to {@code ""}.
if (type == null) {
return "<invalid>";
}
return type.toString();
|
private static com.android.dx.rop.type.TypeBearer | throwSimException(java.lang.String msg)Throws a properly-formatted exception.
throw new SimException("stack: " + msg);
|