Fields Summary |
---|
private final com.android.dx.rop.type.Prototype | prototype |
private com.android.dx.rop.type.TypeBearer[] | argsnon-null; primary arguments |
private int | argCount>= 0; number of primary arguments |
private com.android.dx.rop.type.Type | auxTypenull-ok; type of the operation, if salient |
private int | auxIntauxiliary int argument |
private com.android.dx.rop.cst.Constant | auxCstnull-ok; auxiliary constant argument |
private int | auxTargetauxiliary branch target argument |
private SwitchList | auxCasesnull-ok; auxiliary switch cases argument |
private ArrayList | auxInitValuesnull-ok; auxiliary initial value list for newarray |
private int | localIndex>= -1; last local accessed |
private com.android.dx.rop.code.RegisterSpec | localTargetnull-ok; local target spec, if salient and calculated |
private com.android.dx.rop.type.TypeBearer[] | resultsnon-null; results |
private int | resultCount>= -1; count of the results, or -1 if no results
have been set |
Methods Summary |
---|
protected final void | addResult(com.android.dx.rop.type.TypeBearer result)Adds an additional element to the list of results.
if (result == null) {
throw new NullPointerException("result == null");
}
results[resultCount] = result;
resultCount++;
|
protected final com.android.dx.rop.type.TypeBearer | arg(int n)Gets the n th primary argument.
if (n >= argCount) {
throw new IllegalArgumentException("n >= argCount");
}
try {
return args[n];
} catch (ArrayIndexOutOfBoundsException ex) {
// Translate the exception.
throw new IllegalArgumentException("n < 0");
}
|
protected final int | argCount()Gets the number of primary arguments.
return argCount;
|
protected final int | argWidth()Gets the width of the arguments (where a category-2 value counts as
two).
int result = 0;
for (int i = 0; i < argCount; i++) {
result += args[i].getType().getCategory();
}
return result;
|
public final void | auxCstArg(com.android.dx.rop.cst.Constant cst){@inheritDoc}
if (cst == null) {
throw new NullPointerException("cst == null");
}
auxCst = cst;
|
public final void | auxInitValues(java.util.ArrayList initValues){@inheritDoc}
auxInitValues = initValues;
|
public final void | auxIntArg(int value){@inheritDoc}
auxInt = value;
|
public final void | auxSwitchArg(SwitchList cases){@inheritDoc}
if (cases == null) {
throw new NullPointerException("cases == null");
}
auxCases = cases;
|
public final void | auxTargetArg(int target){@inheritDoc}
auxTarget = target;
|
public final void | auxType(com.android.dx.rop.type.Type type){@inheritDoc}
auxType = type;
|
public final void | clearArgs(){@inheritDoc}
argCount = 0;
auxType = null;
auxInt = 0;
auxCst = null;
auxTarget = 0;
auxCases = null;
auxInitValues = null;
localIndex = -1;
localTarget = null;
resultCount = -1;
|
protected final void | clearResult()Clears the results.
resultCount = 0;
|
protected final SwitchList | getAuxCases()Gets the switch cases auxiliary argument.
return auxCases;
|
protected final com.android.dx.rop.cst.Constant | getAuxCst()Gets the constant auxiliary argument.
return auxCst;
|
protected final int | getAuxInt()Gets the int auxiliary argument.
return auxInt;
|
protected final int | getAuxTarget()Gets the branch target auxiliary argument.
return auxTarget;
|
protected final com.android.dx.rop.type.Type | getAuxType()Gets the type auxiliary argument.
return auxType;
|
protected final java.util.ArrayList | getInitValues()Gets the init values auxiliary argument.
return auxInitValues;
|
protected final int | getLocalIndex()Gets the last local index accessed.
return localIndex;
|
protected final com.android.dx.rop.code.RegisterSpec | getLocalTarget()Gets the target local register spec of the current operation, if any.
The local target spec is the combination of the values indicated
by a previous call to {@link #localTarget} with the type of what
should be the sole result set by a call to {@link #setResult} (or
the combination {@link #clearResult} then {@link #addResult}.
if (localTarget == null) {
return null;
}
if (resultCount != 1) {
throw new SimException("local target with " +
((resultCount == 0) ? "no" : "multiple") + " results");
}
TypeBearer result = results[0];
Type resultType = result.getType();
Type localType = localTarget.getType();
if (resultType == localType) {
return localTarget;
}
if (! Merger.isPossiblyAssignableFrom(localType, resultType)) {
// The result and local types are inconsistent. Complain!
throwLocalMismatch(resultType, localType);
return null;
}
if (localType == Type.OBJECT) {
/*
* The result type is more specific than the local type,
* so use that instead.
*/
localTarget = localTarget.withType(result);
}
return localTarget;
|
public com.android.dx.rop.type.Prototype | getPrototype(){@inheritDoc}
return prototype;
|
public final void | localArg(Frame frame, int idx){@inheritDoc}
clearArgs();
args[0] = frame.getLocals().get(idx);
argCount = 1;
localIndex = idx;
|
public final void | localTarget(int idx, com.android.dx.rop.type.Type type, com.android.dx.rop.code.LocalItem local){@inheritDoc}
localTarget = RegisterSpec.makeLocalOptional(idx, type, local);
|
public final void | popArgs(Frame frame, int count){@inheritDoc}
ExecutionStack stack = frame.getStack();
clearArgs();
if (count > args.length) {
// Grow args, and add a little extra room to grow even more.
args = new TypeBearer[count + 10];
}
for (int i = count - 1; i >= 0; i--) {
args[i] = stack.pop();
}
argCount = count;
|
public void | popArgs(Frame frame, com.android.dx.rop.type.Prototype prototype){@inheritDoc}
StdTypeList types = prototype.getParameterTypes();
int size = types.size();
// Use the above method to do the actual popping...
popArgs(frame, size);
// ...and then verify the popped types.
for (int i = 0; i < size; i++) {
if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) {
throw new SimException("at stack depth " + (size - 1 - i) +
", expected type " + types.getType(i).toHuman() +
" but found " + args[i].getType().toHuman());
}
}
|
public final void | popArgs(Frame frame, com.android.dx.rop.type.Type type)
// Use the above method to do the actual popping...
popArgs(frame, 1);
// ...and then verify the popped type.
if (! Merger.isPossiblyAssignableFrom(type, args[0])) {
throw new SimException("expected type " + type.toHuman() +
" but found " + args[0].getType().toHuman());
}
|
public final void | popArgs(Frame frame, com.android.dx.rop.type.Type type1, com.android.dx.rop.type.Type type2){@inheritDoc}
// Use the above method to do the actual popping...
popArgs(frame, 2);
// ...and then verify the popped types.
if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
throw new SimException("expected type " + type1.toHuman() +
" but found " + args[0].getType().toHuman());
}
if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
throw new SimException("expected type " + type2.toHuman() +
" but found " + args[1].getType().toHuman());
}
|
public final void | popArgs(Frame frame, com.android.dx.rop.type.Type type1, com.android.dx.rop.type.Type type2, com.android.dx.rop.type.Type type3){@inheritDoc}
// Use the above method to do the actual popping...
popArgs(frame, 3);
// ...and then verify the popped types.
if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
throw new SimException("expected type " + type1.toHuman() +
" but found " + args[0].getType().toHuman());
}
if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
throw new SimException("expected type " + type2.toHuman() +
" but found " + args[1].getType().toHuman());
}
if (! Merger.isPossiblyAssignableFrom(type3, args[2])) {
throw new SimException("expected type " + type2.toHuman() +
" but found " + args[2].getType().toHuman());
}
|
protected final com.android.dx.rop.type.TypeBearer | result(int n)Gets the n th result value.
if (n >= resultCount) {
throw new IllegalArgumentException("n >= resultCount");
}
try {
return results[n];
} catch (ArrayIndexOutOfBoundsException ex) {
// Translate the exception.
throw new IllegalArgumentException("n < 0");
}
|
protected final int | resultCount()Gets the count of results. This throws an exception if results were
never set. (Explicitly clearing the results counts as setting them.)
if (resultCount < 0) {
throw new SimException("results never set");
}
return resultCount;
|
protected final int | resultWidth()Gets the width of the results (where a category-2 value counts as
two).
int width = 0;
for (int i = 0; i < resultCount; i++) {
width += results[i].getType().getCategory();
}
return width;
|
protected final void | setResult(com.android.dx.rop.type.TypeBearer result)Sets the results list to be the given single value.
Note: If there is more than one result value, the
others may be added by using {@link #addResult}.
if (result == null) {
throw new NullPointerException("result == null");
}
results[0] = result;
resultCount = 1;
|
protected final void | storeResults(Frame frame)Stores the results of the latest operation into the given frame. If
there is a local target (see {@link #localTarget}), then the sole
result is stored to that target; otherwise any results are pushed
onto the stack.
if (resultCount < 0) {
throw new SimException("results never set");
}
if (resultCount == 0) {
// Nothing to do.
return;
}
if (localTarget != null) {
/*
* Note: getLocalTarget() doesn't necessarily return
* localTarget directly.
*/
frame.getLocals().set(getLocalTarget());
} else {
ExecutionStack stack = frame.getStack();
for (int i = 0; i < resultCount; i++) {
stack.push(results[i]);
}
}
|
public static void | throwLocalMismatch(com.android.dx.rop.type.TypeBearer found, com.android.dx.rop.type.TypeBearer local)Throws an exception that indicates a mismatch in local variable
types.
throw new SimException("local variable type mismatch: " +
"attempt to set or access a value of type " +
found.toHuman() +
" using a local variable of type " +
local.toHuman() +
". This is symptomatic of .class transformation tools " +
"that ignore local variable information.");
|