Top Description Fields Constructors Methods
org.droidparts.dexmaker

public final Class Code

extends Object
Class Inheritance
Imports
org.droidparts.dexmaker.dx.rop.code.*, org.droidparts.dexmaker.dx.rop.cst.CstInteger, org.droidparts.dexmaker.dx.rop.type.StdTypeList, java.util.ArrayList, .Collections, .Iterator, .List

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

Field Summary

Modifier and TypeField and Description
private StdTypeList
private final List<Label>
private final List<TypeId<?>>
private Label
currentLabel

The label currently receiving instructions.

private final List<Label>
labels

All allocated labels.

private final List<Local<?>>
private boolean
localsInitialized

true once we've fixed the positions of the parameter registers

private final MethodId<?, ?>
private final List<Local<?>>
parameters

The parameters on this method.

private SourcePosition
private final Local<?>

Constructor Summary

AccessConstructor and Description
pack-priv
Code(DexMaker.MethodDeclaration methodDeclaration)

Method Summary

Modifier and TypeMethod and Description
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.

private void
private void
addInstruction(Insn insn, Label
the branches to follow; interpretation depends on the instruction's branchingness.
branch
)

private void
adopt(Label target)

Assigns target to this code.

public void
aget(Local<?> target, Local<?> array, Local<Integer> index)

Assigns the element at index in array to target.

public void
aput(Local<?> array, Local<Integer> index, Local<?> source)

Assigns source to the element at index in array.

public <T> void
arrayLength(Local<Integer> target, Local<T> array)

Sets target to the length of the array in array.

public void
cast(Local<?> target, Local<?> source)

Performs either a numeric cast or a type cast.

private void
cleanUpLabels()

Removes empty labels and assigns IDs to non-empty labels.

private <T> Local<T>
coerce(Local<?> local, TypeId<T> expectedType)

public <T> void
compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b)

Compare ints or references.

public <T extends Number> void
compareFloatingPoint(Local<Integer> target, Local<T> a, Local<T> b, int nanValue)

Compare floats or doubles.

public void
compareLongs(Local<Integer> target, Local<Long> a, Local<Long> b)

Compare longs.

private static RegisterSpecList
concatenate(Local<?> first, Local<?>[] rest)

private Rop
getCastRop(Type sourceType, Type targetType)

public <T> Local<T>
getParameter(int index, TypeId<T> type)

Returns the local for the parameter at index index and of type type.

public <T> Local<T>
getThis(TypeId<T> type)

Returns the local for this of type type.

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.

pack-priv void
initializeLocals()

Assigns registers to locals.

public void
instanceOfType(Local<?> target, Local<?> source, TypeId<?> type)

Tests if the value in source is assignable to type.

private <D, R> void
invoke(Rop rop, MethodId<D, R> method, Local<? super R> target, Local<? extends D> object, Local<?>... args)

public <D, R> void
invokeDirect(MethodId<D, R>
either a private method or the superclass's constructor in a constructor's call to super().
method
,
Local<? super R>
the local to receive the method's return value, or null if the return type is void or if its value not needed.
target
,
Local<? extends D> instance, Local<?>... args)

Calls method of instance using args and assigns the result to target.

public <D, R> void
invokeInterface(MethodId<D, R>
a method declared on an interface.
method
,
Local<? super R>
the local to receive the method's return value, or null if the return type is void or if its value not needed.
target
,
Local<? extends D> instance, Local<?>... args)

Calls the interface method method of instance using args and assigns the result to target.

public <R> void
invokeStatic(MethodId<?, R> method, Local<? super R>
the local to receive the method's return value, or null if the return type is void or if its value not needed.
target
,
Local<?>... args)

Calls the static method method using args and assigns the result to target.

public <D, R> void
invokeSuper(MethodId<D, R> method, Local<? super R>
the local to receive the method's return value, or null if the return type is void or if its value not needed.
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.

public <D, R> void
invokeVirtual(MethodId<D, R>
a non-private, non-static, method declared on a class. May not be an interface method or a constructor.
method
,
Local<? super R>
the local to receive the method's return value, or null if the return type is void or if its value not needed.
target
,
Local<? extends D> instance, Local<?>... args)

Calls the non-private instance method method of instance using args and assigns the result to target.

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.

public void
jump(Label target)

Transfers flow control to the instructions at target.

public <T> void
loadConstant(Local<T> target, T value)

Copies the constant value value to target.

public void
mark(Label label)

Start defining instructions for the named label.

public void
monitorEnter(Local<?> monitor)

Awaits the lock on monitor, and acquires it.

public void
monitorExit(Local<?> monitor)

Releases the held lock on monitor.

public <T> void
move(Local<T> target, Local<T> source)

Copies the value in source to target.

private void
moveResult(Local<?> target, boolean afterNonInvokeThrowingInsn)

public <T> void
newArray(Local<T> target, Local<Integer> length)

Assigns target to a newly allocated array of length length.

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.

public <T> Local<T>
newLocal(TypeId<T> type)

Allocates a new local variable of type type.

public <T> void
op(UnaryOp op, Local<T> target, Local<T> source)

Executes op and sets target to the result.

public <T1, T2> void
op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b)

Executes op and sets target to the result.

pack-priv int
paramSize()

Returns the number of registers to hold the parameters.

public Label
removeCatchClause(TypeId<? extends Throwable> toCatch)

Deregisters the catch clause label for toCatch and returns it.

public void
returnValue(Local<?> result)

Returns the value in result to the calling method.

public void
returnVoid()

Returns from a void method.

public <V> void
sget(FieldId<?, V> fieldId, Local<V> target)

Copies the value in the static field fieldId to target.

private void
splitCurrentLabel(Label alternateSuccessor, List<Label>
an immutable list of catch labels
catchLabels
)

Closes the current label and starts a new one.

public <V> void
sput(FieldId<?, V> fieldId, Local<V> source)

Copies the value in source to the static field fieldId.

public void
throwValue(Local<? extends Throwable> toThrow)

Throws the throwable in toThrow.

pack-priv BasicBlockList
private StdTypeList
toTypeList(List<TypeId<?>> types)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

catchesback to summary
private StdTypeList catches
catchLabelsback to summary
private final List<Label> catchLabels
catchTypesback to summary
private final List<TypeId<?>> catchTypes
currentLabelback to summary
private Label currentLabel

The label currently receiving instructions. This is null if the most recent instruction was a return or goto.

labelsback to summary
private final List<Label> labels

All allocated labels. Although the order of the labels in this list shouldn't impact behavior, it is used to determine basic block indices.

localsback to summary
private final List<Local<?>> locals
localsInitializedback to summary
private boolean localsInitialized

true once we've fixed the positions of the parameter registers

methodback to summary
private final MethodId<?, ?> method
parametersback to summary
private final List<Local<?>> parameters

The parameters on this method. If this is non-static, the first parameter is 'thisLocal' and we have to offset the user's indices by one.

sourcePositionback to summary
private SourcePosition sourcePosition
thisLocalback to summary
private final Local<?> thisLocal

Constructor Detail

Codeback to summary
pack-priv Code(DexMaker.MethodDeclaration methodDeclaration)

Method Detail

addCatchClauseback to summary
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.

addInstructionback to summary
private void addInstruction(Insn insn)
addInstructionback to summary
private void addInstruction(Insn insn, Label branch)
Parameters
branch:Label

the branches to follow; interpretation depends on the instruction's branchingness.

adoptback to summary
private void adopt(Label target)

Assigns target to this code.

agetback to summary
public void aget(Local<?> target, Local<?> array, Local<Integer> index)

Assigns the element at index in array to target.

aputback to summary
public void aput(Local<?> array, Local<Integer> index, Local<?> source)

Assigns source to the element at index in array.

arrayLengthback to summary
public <T> void arrayLength(Local<Integer> target, Local<T> array)

Sets target to the length of the array in array.

castback to summary
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.
cleanUpLabelsback to summary
private void cleanUpLabels()

Removes empty labels and assigns IDs to non-empty labels.

coerceback to summary
private <T> Local<T> coerce(Local<?> local, TypeId<T> expectedType)
Annotations
@SuppressWarnings:unchecked
compareback to summary
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.

compareFloatingPointback to summary
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.

compareLongsback to summary
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.

concatenateback to summary
private static RegisterSpecList concatenate(Local<?> first, Local<?>[] rest)
getCastRopback to summary
private Rop getCastRop(Type sourceType, Type targetType)
getParameterback to summary
public <T> Local<T> getParameter(int index, TypeId<T> type)

Returns the local for the parameter at index index and of type type.

getThisback to summary
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.

igetback to summary
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.

initializeLocalsback to summary
pack-priv void initializeLocals()

Assigns registers to locals. From the spec: "the N arguments to a method land in the last N registers of the method's invocation frame, in order. Wide arguments consume two registers. Instance methods are passed a this reference as their first argument." In addition to assigning registers to each of the locals, this creates instructions to move parameters into their initial registers. These instructions are inserted before the code's first real instruction.

instanceOfTypeback to summary
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.

invokeback to summary
private <D, R> void invoke(Rop rop, MethodId<D, R> method, Local<? super R> target, Local<? extends D> object, Local<?>... args)
invokeDirectback to summary
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:MethodId<D, R>

either a private method or the superclass's constructor in a constructor's call to super().

target:Local<? super R>

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

invokeInterfaceback to summary
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:MethodId<D, R>

a method declared on an interface.

target:Local<? super R>

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

invokeStaticback to summary
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:Local<? super R>

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

invokeSuperback to summary
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:Local<? super R>

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

invokeVirtualback to summary
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:MethodId<D, R>

a non-private, non-static, method declared on a class. May not be an interface method or a constructor.

target:Local<? super R>

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

iputback to summary
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.

jumpback to summary
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.

loadConstantback to summary
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.

markback to summary
public void mark(Label label)

Start defining instructions for the named label.

monitorEnterback to summary
public void monitorEnter(Local<?> monitor)

Awaits the lock on monitor, and acquires it.

monitorExitback to summary
public void monitorExit(Local<?> monitor)

Releases the held lock on monitor.

moveback to summary
public <T> void move(Local<T> target, Local<T> source)

Copies the value in source to target.

moveResultback to summary
private void moveResult(Local<?> target, boolean afterNonInvokeThrowingInsn)
newArrayback to summary
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.

newInstanceback to summary
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.

newLocalback to summary
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.

opback to summary
public <T> void op(UnaryOp op, Local<T> target, Local<T> source)

Executes op and sets target to the result.

opback to summary
public <T1, T2> void op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b)

Executes op and sets target to the result. For most binary operations, the types of a and b must be the same. Shift operations (like BinaryOp#SHIFT_LEFT) require b to be an int, even when a is a long.

paramSizeback to summary
pack-priv int paramSize()

Returns the number of registers to hold the parameters. This includes the 'this' parameter if it exists.

removeCatchClauseback to summary
public Label removeCatchClause(TypeId<? extends Throwable> toCatch)

Deregisters the catch clause label for toCatch and returns it.

returnValueback to summary
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.

returnVoidback to summary
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.

sgetback to summary
public <V> void sget(FieldId<?, V> fieldId, Local<V> target)

Copies the value in the static field fieldId to target.

splitCurrentLabelback to summary
private void splitCurrentLabel(Label alternateSuccessor, List<Label> catchLabels)

Closes the current label and starts a new one.

Parameters
catchLabels:List<Label>

an immutable list of catch labels

sputback to summary
public <V> void sput(FieldId<?, V> fieldId, Local<V> source)

Copies the value in source to the static field fieldId.

throwValueback to summary
public void throwValue(Local<? extends Throwable> toThrow)

Throws the throwable in toThrow.

toBasicBlocksback to summary
pack-priv BasicBlockList toBasicBlocks()
toTypeListback to summary
private StdTypeList toTypeList(List<TypeId<?>> types)