org.ow2.asmdex.structureWriter
Class CodeItem

java.lang.Object
  extended by org.ow2.asmdex.structureWriter.CodeItem

public class CodeItem
extends java.lang.Object

Class representing the code instructions and debug informations of one method. The instructions can link to debug instructions (the ones that don't concern lines/PC management). Debug line/PC advances are managed directly by this class.

Author:
Julien Névo

Field Summary
static int HEADER_SIZE
          Size in bytes of the header of the code_item structure (till insns_size included).
static int INSNS_SIZE_OFFSET
          Offset in bytes of the insns_size structure.
static int TRIES_SIZE_FIELD_OFFSET
          Offset to the tries_size field.
 
Constructor Summary
CodeItem(Method method, ConstantPool constantPool)
          Constructor of the Code Item.
 
Method Summary
 void addInstruction(Instruction instruction)
          Adds an instruction to the code item.
 void addLabel(Label label)
          Adds a label to the set of used labels.
 void addTryCatch(TryCatch tryCatch)
          Adds a Try/Catch structure to the list of Try/Catch.
 boolean areSymbolicIndexesUsedInDebugCodeItem()
          Indicates if at least one index is encoded in the debug code.
 void free()
          Frees all the structures (list of instructions, try/catch...) of this element and the debug_info_item so that they don't consume memory.
 void generateCodeItemCode()
          Generates the Instructions code, as Dalvik bytecode, in the codeItemCode buffer, as well as its header.
 ByteVector getCodeItemCode()
          Returns the code_item code (including the code_item header and the bytecode), without the try/catch fields after the insns field, but with the padding if needed.
 ByteVector getCodeItemTryCatch()
          Returns the try/catch section of the code_item, beginning by the possible padding after the insns field, or Null if no try/catch is present.
 ByteVector getDebugInfoItemCode()
          Returns the debug_info_item code, still using symbolic indexes.
 int getFirstLineNumber()
          Returns the first line number found.
 int getIncomingArgumentsSizeInWord()
          Gets the size in word of the Incoming Arguments.
 java.util.List<Label> getLabels()
          Returns the list of the Labels of this code item.
 int getOffset()
          Returns the offset of the Code Item from the beginning of the file.
 int getOutgoingArgumentsSizeInWord()
          Gets the size in word of the Outgoing Arguments.
 int getRegistersSize()
          Gets the number of registers used by this code.
 int getSize()
          Returns the size in bytes of all the instructions of this item (and by extension, the method).
 int getTriesSize()
          Returns the number of Try structure in this Code Item.
 void mapResolvedIndexes()
          Parses the bytecode and tryCatch and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones.
 void mapResolvedIndexesByteCode(ByteVector out, int offsetByteCode)
          Parses the bytecode and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones.
 ByteVector mapResolvedIndexesForDebug(ByteVector in, int offsetInputBuffer)
          Parses the debug bytecode and maps the resolved indexes (Strings, Types) from the symbolic ones.
 ByteVector mapResolvedIndexesTryCatch(ByteVector in, int offsetInInputArray, int nbTries)
          Parses the tryCatch and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones.
 void replaceInstructions(Instruction oldInsn, Instruction newInsn)
          Replaces one Instruction with a new given one.
 void setDebugInfoItemOffset(ByteVector out, int debugInfoItemOffset)
          Sets the offset of the Debug Info Item inside the already encoded Code Item.
 void setFirstLineNumber(int firstLineNumber)
          Sets the first line number of this code_item, but only if none has been found before.
 void setIncomingArgumentsSizeInWord(int incomingArgumentsSizeInWord)
          Sets the size in word of the Incoming Arguments.
 void setMethod(Method method)
          Sets the Method this Code Item is linked to.
 void setOffset(int offset)
          Sets the offset of the Code Item from the beginning of the file.
 void setOutgoingArgumentsSizeInWord(int outgoingArgumentsSizeInWord)
          Sets the size in word of the Outgoing Arguments.
 void setRegisterSize(int registerSize)
          Sets the Register Size of this code.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

TRIES_SIZE_FIELD_OFFSET

public static final int TRIES_SIZE_FIELD_OFFSET
Offset to the tries_size field.

See Also:
Constant Field Values

HEADER_SIZE

public static final int HEADER_SIZE
Size in bytes of the header of the code_item structure (till insns_size included).

See Also:
Constant Field Values

INSNS_SIZE_OFFSET

public static final int INSNS_SIZE_OFFSET
Offset in bytes of the insns_size structure.

See Also:
Constant Field Values
Constructor Detail

CodeItem

public CodeItem(Method method,
                ConstantPool constantPool)
Constructor of the Code Item.

Parameters:
method - the Method this Code Item belongs to.
Method Detail

free

public void free()
Frees all the structures (list of instructions, try/catch...) of this element and the debug_info_item so that they don't consume memory. This MUST be done after having generated the bytecode, once the method has been parsed and its end visited.


addLabel

public void addLabel(Label label)
Adds a label to the set of used labels. If Null, nothing is done.

Parameters:
label - the label to add.

addInstruction

public void addInstruction(Instruction instruction)
Adds an instruction to the code item.

Parameters:
instruction - instruction to add to the code item.

addTryCatch

public void addTryCatch(TryCatch tryCatch)
Adds a Try/Catch structure to the list of Try/Catch.

Parameters:
tryCatch - Try/Catch structure to add.

generateCodeItemCode

public void generateCodeItemCode()
Generates the Instructions code, as Dalvik bytecode, in the codeItemCode buffer, as well as its header. It uses symbolic references, so must be parsed again later to link them to the "real" elements. Also fills the debug_code_item in this instance. Note however that the debug_info_offset field in the code_item header is not set, because we don't know where the debug_info_item is encoded for now. Note that the debug_info_item is not written here, only built. The alignment is not managed here, but must be by the calling method.


replaceInstructions

public void replaceInstructions(Instruction oldInsn,
                                Instruction newInsn)
Replaces one Instruction with a new given one.

Parameters:
oldInsn - the replaced Instruction.
newInsn - the new Instruction.

mapResolvedIndexesForDebug

public ByteVector mapResolvedIndexesForDebug(ByteVector in,
                                             int offsetInputBuffer)
Parses the debug bytecode and maps the resolved indexes (Strings, Types) from the symbolic ones. The mapping between the two, done through two tables in the Constant Pool, must have been performed before.

Parameters:
in - input buffer to parse.
offsetInputBuffer - offset inside the input buffer from where to start the parsing.
Returns:
the parsed debug bytecode.

mapResolvedIndexes

public void mapResolvedIndexes()
Parses the bytecode and tryCatch and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones. The mapping between the two, done through four tables in the Constant Pool, must have been performed before. This method must be called when the method has its own bytecode i.e. when the "ConstantPool" optimization isn't performed.


mapResolvedIndexesByteCode

public void mapResolvedIndexesByteCode(ByteVector out,
                                       int offsetByteCode)
Parses the bytecode and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones. The given bytecode is modified. The mapping between the two, done through four tables in the Constant Pool, must have been performed before.

Parameters:
out - ByteVector to be read and modified.
offsetByteCode - offset in bytes where the parsing must begin.

mapResolvedIndexesTryCatch

public ByteVector mapResolvedIndexesTryCatch(ByteVector in,
                                             int offsetInInputArray,
                                             int nbTries)
Parses the tryCatch and maps the resolved indexes (Strings, Fields, Types, Methods) from the symbolic ones. The input vector is not modified. The mapping between the two, done through four tables in the Constant Pool, must have been performed before.

Parameters:
in - a ByteVector containing the try_catch bytecode to modify.
offsetInInputArray - offset in bytes where the parsing must begin.
nbTries - count of Try/Catch.
Returns:
a ByteVector containing the try_catch bytecode.

getSize

public int getSize()
Returns the size in bytes of all the instructions of this item (and by extension, the method). Does NOT take in account the header of the Code Item.

Returns:
the size in bytes of all the instructions of this item, without the header.

getTriesSize

public int getTriesSize()
Returns the number of Try structure in this Code Item.

Returns:
the number of Try structure in this Code Item.

setRegisterSize

public void setRegisterSize(int registerSize)
Sets the Register Size of this code.

Parameters:
registerSize - the Register Size of this code.

getRegistersSize

public int getRegistersSize()
Gets the number of registers used by this code.

Returns:
the number of registers used by this code.

getLabels

public java.util.List<Label> getLabels()
Returns the list of the Labels of this code item.

Returns:
the list of the Labels of this code item.

getIncomingArgumentsSizeInWord

public int getIncomingArgumentsSizeInWord()
Gets the size in word of the Incoming Arguments.

Returns:
the size in word of the Incoming Arguments.

setIncomingArgumentsSizeInWord

public void setIncomingArgumentsSizeInWord(int incomingArgumentsSizeInWord)
Sets the size in word of the Incoming Arguments.

Parameters:
incomingArgumentsSizeInWord - the size in word of the Incoming Arguments.

getOutgoingArgumentsSizeInWord

public int getOutgoingArgumentsSizeInWord()
Gets the size in word of the Outgoing Arguments.

Returns:
the size in word of the Outgoing Arguments.

setOutgoingArgumentsSizeInWord

public void setOutgoingArgumentsSizeInWord(int outgoingArgumentsSizeInWord)
Sets the size in word of the Outgoing Arguments.

Parameters:
outgoingArgumentsSizeInWord - the size in word of the Outgoing Arguments.

getOffset

public int getOffset()
Returns the offset of the Code Item from the beginning of the file. It is only known when producing the output file, after the input has been fully parsed.

Returns:
the offset of the Code Item from the beginning of the file.

setOffset

public void setOffset(int offset)
Sets the offset of the Code Item from the beginning of the file.

Parameters:
offset - the offset of the Code Item from the beginning of the file.

setMethod

public void setMethod(Method method)
Sets the Method this Code Item is linked to.

Parameters:
method - the Method this Code Item is linked to.

setDebugInfoItemOffset

public void setDebugInfoItemOffset(ByteVector out,
                                   int debugInfoItemOffset)
Sets the offset of the Debug Info Item inside the already encoded Code Item.

Parameters:
out - Vector of the Dex file. It already contains the current Code Item.
debugInfoItemOffset - the offset of the debug_info_item, encoded or soon to be.

setFirstLineNumber

public void setFirstLineNumber(int firstLineNumber)
Sets the first line number of this code_item, but only if none has been found before.

Parameters:
firstLineNumber - the first line number of this code_item.

getFirstLineNumber

public int getFirstLineNumber()
Returns the first line number found. It may be 0 if none were.

Returns:
the first line number found, or 0.

getCodeItemCode

public ByteVector getCodeItemCode()
Returns the code_item code (including the code_item header and the bytecode), without the try/catch fields after the insns field, but with the padding if needed. It uses symbolic references, so must be parsed again to link them to the "real" elements.

Returns:
the code_item code, without the try/catch fields.

getCodeItemTryCatch

public ByteVector getCodeItemTryCatch()
Returns the try/catch section of the code_item, beginning by the possible padding after the insns field, or Null if no try/catch is present. It uses symbolic references, so must be parsed again to link them to the "real" elements.

Returns:
the try/catch code, or Null.

getDebugInfoItemCode

public ByteVector getDebugInfoItemCode()
Returns the debug_info_item code, still using symbolic indexes. It is available only after this method bytecode has been generated.

Returns:
the debug_info_item code still using symbolic indexes.

areSymbolicIndexesUsedInDebugCodeItem

public boolean areSymbolicIndexesUsedInDebugCodeItem()
Indicates if at least one index is encoded in the debug code. We use it to optimize the mapping with the resolved indexes : it doesn't need do be done if no index was found.

Returns:
true if at least one index is encoded in the debug code.