com.google.dexmaker
Class Code

java.lang.Object
  extended by com.google.dexmaker.Code

public final class Code
extends Object

Builds a sequence of instructions.

Locals

All data manipulation takes place in local variables. Each parameter gets its own local by default; access these using getParameter(). Non-static methods and constructors also have a this parameter; it's available as getThis(). Allocate a new local variable using newLocal(), and assign a default value to it with loadConstant(). Copy a value from one local to another with move().

Every local variable has a fixed type. This is either a primitive type (of any size) or a reference type. This class emits instructions appropriate to the types they operate on. Not all operations are local on all types; attempting to emit such an operation will fail with an unchecked exception.

Math and Bit Operations

Transform a single value into another related value using op(UnaryOp, Local, Local). Transform two values into a third value using op(BinaryOp, Local, Local, Local). In either overload the first Local parameter is where the result will be sent; the other Local parameters are the inputs.

Comparisons

There are three different comparison operations each with different constraints: There's no single operation to compare longs and jump, or to compare ints and store the result in a local. Accomplish these goals by chaining multiple operations together.

Branches, Labels and Returns

Basic control flow is expressed using jumps and labels. Each label must be marked exactly once and may be jumped to any number of times. Create a label using its constructor: new Label(), and mark it using mark(Label). All jumps to a label will execute instructions starting from that label. You can jump to a label that hasn't yet been marked (jumping forward) or to a label that has already been marked (jumping backward). Jump unconditionally with jump(Label) or conditionally based on a comparison using compare().

Most methods should contain either a return instruction. Void methods should use returnVoid(); non-void methods should use returnValue() with a local whose return type matches the method's return type. Constructors are considered void methods and should call returnVoid(). Methods may make multiple returns. Methods containing no return statements must either loop infinitely or throw unconditionally; it is not legal to end a sequence of instructions without a jump, return or throw.

Throwing and Catching

This API uses labels to handle thrown exceptions, errors and throwables. Call addCatchClause() to register the target label and throwable class. All statements that follow will jump to that catch clause if they throw a Throwable assignable to that type. Use removeCatchClause() to unregister the throwable class.

Throw an throwable by first assigning it to a local and then calling throwValue(). Control flow will jump to the nearest label assigned to a type assignable to the thrown type. In this context, "nearest" means the label requiring the fewest stack frames to be popped.

Calling methods

A method's caller must know its return type, name, parameters, and invoke kind. Lookup a method on a type using TypeId.getMethod(). This is more onerous than Java language invokes, which can infer the target method using the target object and parameters. There are four invoke kinds: All invoke methods take a local for the return value. For void methods this local is unused and may be null.

Field Access

Read static fields using sget(); write them using sput(). For instance values you'll need to specify the declaring instance; use getThis() in an instance method to use this. Read instance values using iget() and write them with iput().

Array Access

Allocate an array using newArray(). Read an array's length with arrayLength() and its elements with aget(). Write an array's elements with aput().

Types

Use cast() to perform either a numeric cast or a type cast. Interrogate the type of a value in a local using instanceOfType().

Synchronization

Acquire a monitor using monitorEnter(); release it with monitorExit(). It is the caller's responsibility to guarantee that enter and exit calls are balanced, even in the presence of exceptions thrown. Warning: Even if a method has the synchronized flag, dex requires instructions to acquire and release monitors manually. A method declared with SYNCHRONIZED but without manual calls to monitorEnter() and monitorExit() will not be synchronized when executed.


Method Summary
 void addCatchClause(TypeId<? extends Throwable> toCatch, Label catchClause)
          Registers catchClause as a branch target for all instructions in this frame that throw a class assignable to toCatch.
 void aget(Local<?> target, Local<?> array, Local<Integer> index)
          Assigns target to the element of array at index index.
 void aput(Local<?> array, Local<Integer> index, Local<?> source)
          Sets the element at index in array the value in source.
<T> void
arrayLength(Local<Integer> target, Local<T> array)
          Sets target to the length of the array in array.
 void cast(Local<?> target, Local<?> source)
          Performs either a numeric cast or a type cast.
<T> void
compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b)
          Compare ints or references.
<T extends Number>
void
compareFloatingPoint(Local<Integer> target, Local<T> a, Local<T> b, int nanValue)
          Compare floats or doubles.
 void compareLongs(Local<Integer> target, Local<Long> a, Local<Long> b)
          Compare longs.
<T> Local<T>
getParameter(int index, TypeId<T> type)
          Returns the local for the parameter at index index and of type type.
<T> Local<T>
getThis(TypeId<T> type)
          Returns the local for this of type type.
<D,V> void
iget(FieldId<D,V> fieldId, Local<V> target, Local<D> instance)
          Copies the value in instance field fieldId of instance to target.
 void instanceOfType(Local<?> target, Local<?> source, TypeId<?> type)
          Tests if the value in source is assignable to type.
<D,R> void
invokeDirect(MethodId<D,R> method, Local<? super R> target, Local<? extends D> instance, Local<?>... args)
          Calls method of instance using args and assigns the result to target.
<D,R> void
invokeInterface(MethodId<D,R> method, Local<? super R> target, Local<? extends D> instance, Local<?>... args)
          Calls the interface method method of instance using args and assigns the result to target.
<R> void
invokeStatic(MethodId<?,R> method, Local<? super R> target, Local<?>... args)
          Calls the static method method using args and assigns the result to target.
<D,R> void
invokeSuper(MethodId<D,R> method, Local<? super R> target, Local<? extends D> instance, Local<?>... args)
          Calls the closest superclass's virtual method method of instance using args and assigns the result to target.
<D,R> void
invokeVirtual(MethodId<D,R> method, Local<? super R> target, Local<? extends D> instance, Local<?>... args)
          Calls the non-private instance method method of instance using args and assigns the result to target.
<D,V> void
iput(FieldId<D,V> fieldId, Local<D> instance, Local<V> source)
          Copies the value in source to the instance field fieldId of instance.
 void jump(Label target)
          Transfers flow control to the instructions at target.
<T> void
loadConstant(Local<T> target, T value)
          Copies the constant value value to target.
 void mark(Label label)
          Start defining instructions for the named label.
 void monitorEnter(Local<?> monitor)
          Awaits the lock on monitor, and acquires it.
 void monitorExit(Local<?> monitor)
          Releases the held lock on monitor.
<T> void
move(Local<T> target, Local<T> source)
          Copies the value in source to target.
<T> void
newArray(Local<T> target, Local<Integer> length)
          Assigns target to a newly allocated array of length length.
<T> void
newInstance(Local<T> target, MethodId<T,Void> constructor, Local<?>... args)
          Calls the constructor constructor using args and assigns the new instance to target.
<T> Local<T>
newLocal(TypeId<T> type)
          Allocates a new local variable of type type.
<T> void
op(BinaryOp op, Local<T> target, Local<T> a, Local<T> b)
          Executes op and sets target to the result.
<T> void
op(UnaryOp op, Local<T> target, Local<T> source)
          Executes op and sets target to the result.
 Label removeCatchClause(TypeId<? extends Throwable> toCatch)
          Deregisters the catch clause label for toCatch and returns it.
 void returnValue(Local<?> result)
          Returns the value in result to the calling method.
 void returnVoid()
          Returns from a void method.
<V> void
sget(FieldId<?,V> fieldId, Local<V> target)
          Copies the value in target to the static field fieldId.
<V> void
sput(FieldId<?,V> fieldId, Local<V> source)
          Copies the value in source to the static field fieldId.
 void throwValue(Local<? extends Throwable> toThrow)
          Throws the throwable in toThrow.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

newLocal

public <T> Local<T> newLocal(TypeId<T> type)
Allocates a new local variable of type type. It is an error to allocate a local after instructions have been emitted.


getParameter

public <T> Local<T> getParameter(int index,
                                 TypeId<T> type)
Returns the local for the parameter at index index and of type type.


getThis

public <T> Local<T> getThis(TypeId<T> type)
Returns the local for this of type type. It is an error to call getThis() if this is a static method.


mark

public void mark(Label label)
Start defining instructions for the named label.


jump

public void jump(Label target)
Transfers flow control to the instructions at target. It is an error to jump to a label not marked on this Code.


addCatchClause

public void addCatchClause(TypeId<? extends Throwable> toCatch,
                           Label catchClause)
Registers catchClause as a branch target for all instructions in this frame that throw a class assignable to toCatch. This includes methods invoked from this frame. Deregister the clause using removeCatchClause(). It is an error to register a catch clause without also marking it in the same Code instance.


removeCatchClause

public Label removeCatchClause(TypeId<? extends Throwable> toCatch)
Deregisters the catch clause label for toCatch and returns it.


throwValue

public void throwValue(Local<? extends Throwable> toThrow)
Throws the throwable in toThrow.


loadConstant

public <T> void loadConstant(Local<T> target,
                             T value)
Copies the constant value value to target. The constant must be a primitive, String, Class, TypeId, or null.


move

public <T> void move(Local<T> target,
                     Local<T> source)
Copies the value in source to target.


op

public <T> void op(UnaryOp op,
                   Local<T> target,
                   Local<T> source)
Executes op and sets target to the result.


op

public <T> void op(BinaryOp op,
                   Local<T> target,
                   Local<T> a,
                   Local<T> b)
Executes op and sets target to the result.


compare

public <T> void compare(Comparison comparison,
                        Label trueLabel,
                        Local<T> a,
                        Local<T> b)
Compare ints or references. If the comparison is true, execution jumps to trueLabel. If it is false, execution continues to the next instruction.


compareFloatingPoint

public <T extends Number> void compareFloatingPoint(Local<Integer> target,
                                                    Local<T> a,
                                                    Local<T> b,
                                                    int nanValue)
Compare floats or doubles. This stores -1 in target if a < b, 0 in target if a == b and 1 in target if a > b. This stores nanValue in target if either value is NaN.


compareLongs

public void compareLongs(Local<Integer> target,
                         Local<Long> a,
                         Local<Long> b)
Compare longs. This stores -1 in target if a < b, 0 in target if a == b and 1 in target if a > b.


iget

public <D,V> void iget(FieldId<D,V> fieldId,
                       Local<V> target,
                       Local<D> instance)
Copies the value in instance field fieldId of instance to target.


iput

public <D,V> void iput(FieldId<D,V> fieldId,
                       Local<D> instance,
                       Local<V> source)
Copies the value in source to the instance field fieldId of instance.


sget

public <V> void sget(FieldId<?,V> fieldId,
                     Local<V> target)
Copies the value in target to the static field fieldId.


sput

public <V> void sput(FieldId<?,V> fieldId,
                     Local<V> source)
Copies the value in source to the static field fieldId.


newInstance

public <T> void newInstance(Local<T> target,
                            MethodId<T,Void> constructor,
                            Local<?>... args)
Calls the constructor constructor using args and assigns the new instance to target.


invokeStatic

public <R> void invokeStatic(MethodId<?,R> method,
                             Local<? super R> target,
                             Local<?>... args)
Calls the static method method using args and assigns the result to target.

Parameters:
target - the local to receive the method's return value, or null if the return type is void or if its value not needed.

invokeVirtual

public <D,R> void invokeVirtual(MethodId<D,R> method,
                                Local<? super R> target,
                                Local<? extends D> instance,
                                Local<?>... args)
Calls the non-private instance method method of instance using args and assigns the result to target.

Parameters:
method - a non-private, non-static, method declared on a class. May not be an interface method or a constructor.
target - the local to receive the method's return value, or null if the return type is void or if its value not needed.

invokeDirect

public <D,R> void invokeDirect(MethodId<D,R> method,
                               Local<? super R> target,
                               Local<? extends D> instance,
                               Local<?>... args)
Calls method of instance using args and assigns the result to target.

Parameters:
method - either a private method or the superclass's constructor in a constructor's call to super().
target - the local to receive the method's return value, or null if the return type is void or if its value not needed.

invokeSuper

public <D,R> void invokeSuper(MethodId<D,R> method,
                              Local<? super R> target,
                              Local<? extends D> instance,
                              Local<?>... args)
Calls the closest superclass's virtual method method of instance using args and assigns the result to target.

Parameters:
target - the local to receive the method's return value, or null if the return type is void or if its value not needed.

invokeInterface

public <D,R> void invokeInterface(MethodId<D,R> method,
                                  Local<? super R> target,
                                  Local<? extends D> instance,
                                  Local<?>... args)
Calls the interface method method of instance using args and assigns the result to target.

Parameters:
method - a method declared on an interface.
target - the local to receive the method's return value, or null if the return type is void or if its value not needed.

instanceOfType

public void instanceOfType(Local<?> target,
                           Local<?> source,
                           TypeId<?> type)
Tests if the value in source is assignable to type. If it is, target is assigned to 1; otherwise target is assigned to 0.


cast

public void cast(Local<?> target,
                 Local<?> source)
Performs either a numeric cast or a type cast.

Numeric Casts

Converts a primitive to a different representation. Numeric casts may be lossy. For example, converting the double 1.8d to an integer yields 1, losing the fractional part. Converting the integer 0x12345678 to a short yields 0x5678, losing the high bytes. The following numeric casts are supported:

FromTo
intbyte, char, short, long, float, double
longint, float, double
floatint, long, double
doubleint, long, float

For some primitive conversions it will be necessary to chain multiple cast operations. For example, to go from float to short one would first cast float to int and then int to short.

Numeric casts never throw ClassCastException.

Type Casts

Checks that a reference value is assignable to the target type. If it is assignable it is copied to the target local. If it is not assignable a ClassCastException is thrown.


arrayLength

public <T> void arrayLength(Local<Integer> target,
                            Local<T> array)
Sets target to the length of the array in array.


newArray

public <T> void newArray(Local<T> target,
                         Local<Integer> length)
Assigns target to a newly allocated array of length length. The array's type is the same as target's type.


aget

public void aget(Local<?> target,
                 Local<?> array,
                 Local<Integer> index)
Assigns target to the element of array at index index.


aput

public void aput(Local<?> array,
                 Local<Integer> index,
                 Local<?> source)
Sets the element at index in array the value in source.


returnVoid

public void returnVoid()
Returns from a void method. After a return it is an error to define further instructions after a return without first marking an existing unmarked label.


returnValue

public void returnValue(Local<?> result)
Returns the value in result to the calling method. After a return it is an error to define further instructions after a return without first marking an existing unmarked label.


monitorEnter

public void monitorEnter(Local<?> monitor)
Awaits the lock on monitor, and acquires it.


monitorExit

public void monitorExit(Local<?> monitor)
Releases the held lock on monitor.