FileDocCategorySizeDatePackage
Rop.javaAPI DocAndroid 5.1 API13200Thu Mar 12 22:18:30 GMT 2015com.android.dexgen.rop.code

Rop

public final class Rop extends Object
Class that describes all the immutable parts of register-based operations.

Fields Summary
public static final int
BRANCH_MIN
minimum {@code BRANCH_*} value
public static final int
BRANCH_NONE
indicates a non-branching op
public static final int
BRANCH_RETURN
indicates a function/method return
public static final int
BRANCH_GOTO
indicates an unconditional goto
public static final int
BRANCH_IF
indicates a two-way branch
public static final int
BRANCH_SWITCH
indicates a switch-style branch
public static final int
BRANCH_THROW
indicates a throw-style branch (both always-throws and may-throw)
public static final int
BRANCH_MAX
maximum {@code BRANCH_*} value
private final int
opcode
the opcode; one of the constants in {@link RegOps}
private final com.android.dexgen.rop.type.Type
result
{@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
private final com.android.dexgen.rop.type.TypeList
sources
{@code non-null;} types of all the sources of this operation
private final com.android.dexgen.rop.type.TypeList
exceptions
{@code non-null;} list of possible types thrown by this operation
private final int
branchingness
the branchingness of this op; one of the {@code BRANCH_*} constants in this class
private final boolean
isCallLike
whether 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.dexgen.rop.type.Type result, com.android.dexgen.rop.type.TypeList sources, com.android.dexgen.rop.type.TypeList exceptions, int branchingness, boolean isCallLike, String nickname)
Constructs an instance. This method is private. Use one of the public constructors.

param
opcode the opcode; one of the constants in {@link RegOps}
param
result {@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
param
sources {@code non-null;} types of all the sources of this operation
param
exceptions {@code non-null;} list of possible types thrown by this operation
param
branchingness the branchingness of this op; one of the {@code BRANCH_*} constants
param
isCallLike whether the op is a function/method call or similar
param
nickname {@code null-ok;} optional nickname (used for debugging)


                                                                                                        
          
                    
                 
        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.dexgen.rop.type.Type result, com.android.dexgen.rop.type.TypeList sources, com.android.dexgen.rop.type.TypeList exceptions, int branchingness, String nickname)
Constructs an instance. The constructed instance is never a call-like op (see {@link #isCallLike}).

param
opcode the opcode; one of the constants in {@link RegOps}
param
result {@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
param
sources {@code non-null;} types of all the sources of this operation
param
exceptions {@code non-null;} list of possible types thrown by this operation
param
branchingness the branchingness of this op; one of the {@code BRANCH_*} constants
param
nickname {@code null-ok;} optional nickname (used for debugging)

        this(opcode, result, sources, exceptions, branchingness, false,
             nickname);
    
public Rop(int opcode, com.android.dexgen.rop.type.Type result, com.android.dexgen.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}).

param
opcode the opcode; one of the constants in {@link RegOps}
param
result {@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
param
sources {@code non-null;} types of all the sources of this operation
param
branchingness the branchingness of this op; one of the {@code BRANCH_*} constants
param
nickname {@code null-ok;} optional nickname (used for debugging)

        this(opcode, result, sources, StdTypeList.EMPTY, branchingness, false,
             nickname);
    
public Rop(int opcode, com.android.dexgen.rop.type.Type result, com.android.dexgen.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}).

param
opcode the opcode; one of the constants in {@link RegOps}
param
result {@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
param
sources {@code non-null;} types of all the sources of this operation
param
nickname {@code null-ok;} optional nickname (used for debugging)

        this(opcode, result, sources, StdTypeList.EMPTY, Rop.BRANCH_NONE,
             false, nickname);
    
public Rop(int opcode, com.android.dexgen.rop.type.Type result, com.android.dexgen.rop.type.TypeList sources, com.android.dexgen.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}).

param
opcode the opcode; one of the constants in {@link RegOps}
param
result {@code non-null;} result type of this operation; {@link Type#VOID} for no-result operations
param
sources {@code non-null;} types of all the sources of this operation
param
exceptions {@code non-null;} list of possible types thrown by this operation
param
nickname {@code null-ok;} optional nickname (used for debugging)

        this(opcode, result, sources, exceptions, Rop.BRANCH_THROW, false,
             nickname);
    
public Rop(int opcode, com.android.dexgen.rop.type.TypeList sources, com.android.dexgen.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}.

param
opcode the opcode; one of the constants in {@link RegOps}
param
sources {@code non-null;} types of all the sources of this operation
param
exceptions {@code non-null;} list of possible types thrown by this operation

        this(opcode, Type.VOID, sources, exceptions, Rop.BRANCH_THROW, true,
             null);
    
Methods Summary
public final booleancanThrow()
Gets whether this operation can possibly throw an exception. This is just a convenient wrapper for {@code getExceptions().size() != 0}.

return
{@code true} iff this operation can possibly throw

        return (exceptions.size() != 0);
    
public booleanequals(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 intgetBranchingness()
Gets the branchingness of this instance.

return
the branchingness

        return branchingness;
    
public com.android.dexgen.rop.type.TypeListgetExceptions()
Gets the list of exception types that might be thrown.

return
{@code non-null;} the list of exception types

        return exceptions;
    
public java.lang.StringgetNickname()
Gets the nickname. If this instance has no nickname, this returns the result of calling {@link #toString}.

return
{@code non-null;} the nickname

        if (nickname != null) {
            return nickname;
        }

        return toString();
    
public intgetOpcode()
Gets the opcode.

return
the opcode

        return opcode;
    
public com.android.dexgen.rop.type.TypegetResult()
Gets the result type. A return value of {@link Type#VOID} means this operation returns nothing.

return
{@code null-ok;} the result spec

        return result;
    
public com.android.dexgen.rop.type.TypeListgetSources()
Gets the source types.

return
{@code non-null;} the source types

        return sources;
    
public inthashCode()
{@inheritDoc}

        int h = (opcode * 31) + branchingness;
        h = (h * 31) + result.hashCode();
        h = (h * 31) + sources.hashCode();
        h = (h * 31) + exceptions.hashCode();

        return h;
    
public booleanisCallLike()
Gets whether this opcode is a function/method call or similar.

return
{@code true} iff this opcode is call-like

        return isCallLike;
    
public booleanisCommutative()
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.

return
true if rop is commutative

        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.StringtoString()
{@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();