Roppublic final class Rop extends Object Class that describes all the immutable parts of register-based operations. |
Fields Summary |
---|
public static final int | BRANCH_MINminimum {@code BRANCH_*} value | public static final int | BRANCH_NONEindicates a non-branching op | public static final int | BRANCH_RETURNindicates a function/method return | public static final int | BRANCH_GOTOindicates an unconditional goto | public static final int | BRANCH_IFindicates a two-way branch | public static final int | BRANCH_SWITCHindicates a switch-style branch | public static final int | BRANCH_THROWindicates a throw-style branch (both always-throws and may-throw) | public static final int | BRANCH_MAXmaximum {@code BRANCH_*} value | private final int | opcodethe opcode; one of the constants in {@link RegOps} | private final com.android.dx.rop.type.Type | result{@code non-null;} result type of this operation; {@link Type#VOID} for
no-result operations | private final com.android.dx.rop.type.TypeList | sources{@code non-null;} types of all the sources of this operation | private final com.android.dx.rop.type.TypeList | exceptions{@code non-null;} list of possible types thrown by this operation | private final int | branchingnessthe branchingness of this op; one of the {@code BRANCH_*}
constants in this class | private final boolean | isCallLikewhether this is a function/method call op or similar | private final String | nickname{@code null-ok;} nickname, if specified (used for debugging) |
Constructors Summary |
---|
public Rop(int opcode, com.android.dx.rop.type.Type result, com.android.dx.rop.type.TypeList sources, com.android.dx.rop.type.TypeList exceptions, int branchingness, boolean isCallLike, String nickname)Constructs an instance. This method is private. Use one of the
public constructors.
if (result == null) {
throw new NullPointerException("result == null");
}
if (sources == null) {
throw new NullPointerException("sources == null");
}
if (exceptions == null) {
throw new NullPointerException("exceptions == null");
}
if ((branchingness < BRANCH_MIN) || (branchingness > BRANCH_MAX)) {
throw new IllegalArgumentException("bogus branchingness");
}
if ((exceptions.size() != 0) && (branchingness != BRANCH_THROW)) {
throw new IllegalArgumentException("exceptions / branchingness " +
"mismatch");
}
this.opcode = opcode;
this.result = result;
this.sources = sources;
this.exceptions = exceptions;
this.branchingness = branchingness;
this.isCallLike = isCallLike;
this.nickname = nickname;
| public Rop(int opcode, com.android.dx.rop.type.Type result, com.android.dx.rop.type.TypeList sources, com.android.dx.rop.type.TypeList exceptions, int branchingness, String nickname)Constructs an instance. The constructed instance is never a
call-like op (see {@link #isCallLike}).
this(opcode, result, sources, exceptions, branchingness, false,
nickname);
| public Rop(int opcode, com.android.dx.rop.type.Type result, com.android.dx.rop.type.TypeList sources, int branchingness, String nickname)Constructs a no-exception instance. The constructed instance is never a
call-like op (see {@link #isCallLike}).
this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false,
nickname);
| public Rop(int opcode, com.android.dx.rop.type.Type result, com.android.dx.rop.type.TypeList sources, String nickname)Constructs a non-branching no-exception instance. The
{@code branchingness} is always {@code BRANCH_NONE},
and it is never a call-like op (see {@link #isCallLike}).
this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE,
false, nickname);
| public Rop(int opcode, com.android.dx.rop.type.Type result, com.android.dx.rop.type.TypeList sources, com.android.dx.rop.type.TypeList exceptions, String nickname)Constructs a non-empty exceptions instance. Its
{@code branchingness} is always {@code BRANCH_THROW},
but it is never a call-like op (see {@link #isCallLike}).
this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false,
nickname);
| public Rop(int opcode, com.android.dx.rop.type.TypeList sources, com.android.dx.rop.type.TypeList exceptions)Constructs a non-nicknamed instance with non-empty exceptions, which
is always a call-like op (see {@link #isCallLike}). Its
{@code branchingness} is always {@code BRANCH_THROW}.
this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true,
null);
|
Methods Summary |
---|
public final boolean | canThrow()Gets whether this operation can possibly throw an exception. This
is just a convenient wrapper for
{@code getExceptions().size() != 0}.
return (exceptions.size() != 0);
| public boolean | equals(java.lang.Object other){@inheritDoc}
if (this == other) {
// Easy out.
return true;
}
if (!(other instanceof Rop)) {
return false;
}
Rop rop = (Rop) other;
return (opcode == rop.opcode) &&
(branchingness == rop.branchingness) &&
(result == rop.result) &&
sources.equals(rop.sources) &&
exceptions.equals(rop.exceptions);
| public int | getBranchingness()Gets the branchingness of this instance.
return branchingness;
| public com.android.dx.rop.type.TypeList | getExceptions()Gets the list of exception types that might be thrown.
return exceptions;
| public java.lang.String | getNickname()Gets the nickname. If this instance has no nickname, this returns
the result of calling {@link #toString}.
if (nickname != null) {
return nickname;
}
return toString();
| public int | getOpcode()Gets the opcode.
return opcode;
| public com.android.dx.rop.type.Type | getResult()Gets the result type. A return value of {@link Type#VOID}
means this operation returns nothing.
return result;
| public com.android.dx.rop.type.TypeList | getSources()Gets the source types.
return sources;
| public int | hashCode(){@inheritDoc}
int h = (opcode * 31) + branchingness;
h = (h * 31) + result.hashCode();
h = (h * 31) + sources.hashCode();
h = (h * 31) + exceptions.hashCode();
return h;
| public boolean | isCallLike()Gets whether this opcode is a function/method call or similar.
return isCallLike;
| public boolean | isCommutative()Gets whether this opcode is commutative (the order of its sources are
unimportant) or not. All commutative Rops have exactly two sources and
have no branchiness.
switch (opcode) {
case RegOps.AND:
case RegOps.OR:
case RegOps.XOR:
case RegOps.ADD:
case RegOps.MUL:
return true;
default:
return false;
}
| public java.lang.String | toString(){@inheritDoc}
StringBuffer sb = new StringBuffer(40);
sb.append("Rop{");
sb.append(RegOps.opName(opcode));
if (result != Type.VOID) {
sb.append(" ");
sb.append(result);
} else {
sb.append(" .");
}
sb.append(" <-");
int sz = sources.size();
if (sz == 0) {
sb.append(" .");
} else {
for (int i = 0; i < sz; i++) {
sb.append(' ");
sb.append(sources.getType(i));
}
}
if (isCallLike) {
sb.append(" call");
}
sz = exceptions.size();
if (sz != 0) {
sb.append(" throws");
for (int i = 0; i < sz; i++) {
sb.append(' ");
Type one = exceptions.getType(i);
if (one == Type.THROWABLE) {
sb.append("<any>");
} else {
sb.append(exceptions.getType(i));
}
}
} else {
switch (branchingness) {
case BRANCH_NONE: sb.append(" flows"); break;
case BRANCH_RETURN: sb.append(" returns"); break;
case BRANCH_GOTO: sb.append(" gotos"); break;
case BRANCH_IF: sb.append(" ifs"); break;
case BRANCH_SWITCH: sb.append(" switches"); break;
default: sb.append(" " + Hex.u1(branchingness)); break;
}
}
sb.append('}");
return sb.toString();
|
|