FileDocCategorySizeDatePackage
Rop.javaAPI DocAndroid 1.5 API13049Wed May 06 22:41:02 BST 2009com.android.dx.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 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 BRANCH_* value
private final int
opcode
the opcode; one of the constants in {@link RegOps}
private final com.android.dx.rop.type.Type
result
non-null; result type of this operation; {@link Type#VOID} for no-result operations
private final com.android.dx.rop.type.TypeList
sources
non-null; types of all the sources of this operation
private final com.android.dx.rop.type.TypeList
exceptions
non-null; list of possible types thrown by this operation
private final int
branchingness
the branchingness of this op; one of the BRANCH_* constants in this class
private final boolean
isCallLike
whether this is a function/method call op or similar
private final String
nickname
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.

param
opcode the opcode; one of the constants in {@link RegOps}
param
result non-null; result type of this operation; {@link Type#VOID} for no-result operations
param
sources non-null; types of all the sources of this operation
param
exceptions non-null; list of possible types thrown by this operation
param
branchingness the branchingness of this op; one of the BRANCH_* constants
param
isCallLike whether the op is a function/method call or similar
param
nickname 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.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}).

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

        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}).

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

        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 branchingness is always 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 non-null; result type of this operation; {@link Type#VOID} for no-result operations
param
sources non-null; types of all the sources of this operation
param
nickname null-ok; optional nickname (used for debugging)

        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 branchingness is always 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 non-null; result type of this operation; {@link Type#VOID} for no-result operations
param
sources non-null; types of all the sources of this operation
param
exceptions non-null; list of possible types thrown by this operation
param
nickname null-ok; optional nickname (used for debugging)

        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 branchingness is always BRANCH_THROW.

param
opcode the opcode; one of the constants in {@link RegOps}
param
sources non-null; types of all the sources of this operation
param
exceptions 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 getExceptions().size() != 0.

return
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.dx.rop.type.TypeListgetExceptions()
Gets the list of exception types that might be thrown.

return
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
non-null; the nickname

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

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

return
the opcode

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

return
null-ok; the result spec

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

return
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
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();