Fields Summary |
---|
private final com.android.dx.rop.type.Prototype | prototype |
private com.android.dx.rop.type.TypeBearer[] | args{@code non-null;} primary arguments |
private int | argCount{@code >= 0;} number of primary arguments |
private com.android.dx.rop.type.Type | auxType{@code null-ok;} type of the operation, if salient |
private int | auxIntauxiliary {@code int} argument |
private com.android.dx.rop.cst.Constant | auxCst{@code null-ok;} auxiliary constant argument |
private int | auxTargetauxiliary branch target argument |
private SwitchList | auxCases{@code null-ok;} auxiliary switch cases argument |
private ArrayList | auxInitValues{@code null-ok;} auxiliary initial value list for newarray |
private int | localIndex{@code >= -1;} last local accessed |
private boolean | localInfospecifies if local has info in the local variable table |
private com.android.dx.rop.code.RegisterSpec | localTarget{@code null-ok;} local target spec, if salient and calculated |
private com.android.dx.rop.type.TypeBearer[] | results{@code non-null;} results |
private int | resultCount{@code >= -1;} count of the results, or {@code -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 {@code 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;
localInfo = false;
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 {@code 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 boolean | getLocalInfo()Gets whether the loaded local has info in the local variable table.
return localInfo;
|
protected final com.android.dx.rop.code.RegisterSpec | getLocalTarget(boolean isMove)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) {
/*
* If this is to be a move operation and the result is a
* known value, make the returned localTarget embody that
* value.
*/
if (isMove) {
return localTarget.withType(result);
} else {
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 | localInfo(boolean local){@inheritDoc}
localInfo = local;
|
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 " + type3.toHuman() +
" but found " + args[2].getType().toHuman());
}
|
protected final com.android.dx.rop.type.TypeBearer | result(int n)Gets the {@code 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(false));
} else {
ExecutionStack stack = frame.getStack();
for (int i = 0; i < resultCount; i++) {
if (localInfo) {
stack.setLocal();
}
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.");
|