public final class CodeBuilder extends java.lang.Object implements Opcodes
Create a new CodeBuilder and pass it the CfMethod that is being constructed. CodeBuilder can then be used to declare local variables, define if/else blocks, emit bytecode, etc.
When done generating code, call close() to flush the newly generated bytecode to a new AttrCode attribute of the CfMethod that the builder was given originally.
VOP_START, xDCONST, xIPUSH, xLCONST, xLOAD, xRETURN, xSTORE
AALOAD, AASTORE, ACC_ABSTRACT, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_TRANSIENT, ACC_VOLATILE, ACCESS_NAMES, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ANEWARRAY_QUICK, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, ATTR_CODE, ATTR_CONSTANT_VALUE, ATTR_DEPRECATED, ATTR_EXCEPTIONS, ATTR_LINE_NUMBER_TABLE, ATTR_LOCAL_VARIABLE_TABLE, ATTR_SOURCE_FILE, ATTR_SYNTHETIC, BALOAD, BASTORE, BIPUSH, BREAKPOINT, CALOAD, CASTORE, CHECKCAST, CHECKCAST_QUICK, CONSTANT_Class, CONSTANT_Double, CONSTANT_Fieldref, CONSTANT_Float, CONSTANT_Integer, CONSTANT_InterfaceMethodref, CONSTANT_Long, CONSTANT_Methodref, CONSTANT_NameAndType, CONSTANT_NAMES, CONSTANT_String, CONSTANT_Utf8, CONSTRUCTOR_NAME, CONSUME_STACK, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, GETFIELD, GETFIELD_QUICK, GETFIELD_QUICK_W, GETFIELD2_QUICK, GETSTATIC, GETSTATIC_QUICK, GETSTATIC2_QUICK, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILLEGAL_OPCODE, ILLEGAL_TYPE, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMPDEP1, IMPDEP2, IMUL, INEG, INSTANCEOF, INSTANCEOF_QUICK, INT2BYTE, INT2CHAR, INT2SHORT, INTERFACES_IMPLEMENTED_BY_ARRAYS, INVOKEINTERFACE, INVOKEINTERFACE_QUICK, INVOKENONVIRTUAL, INVOKENONVIRTUAL_QUICK, INVOKESPECIAL, INVOKESTATIC, INVOKESTATIC_QUICK, INVOKESUPER_QUICK, INVOKEVIRTUAL, INVOKEVIRTUAL_QUICK, INVOKEVIRTUAL_QUICK_W, INVOKEVIRTUALOBJECT_QUICK, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, IUSHR, IXOR, JSR, JSR_W, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_QUICK, LDC_W, LDC_W_QUICK, LDC2_W, LDC2_W_QUICK, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MAJOR, MAJOR_1_1, MAJOR_1_2, MAJOR_1_3, MAX_ACC_FLAG, MAX_BYTE, MAX_CODE_SIZE, MAX_CP_ENTRIES, MAX_SHORT, MINOR, MINOR_1_1, MINOR_1_2, MINOR_1_3, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, MULTIANEWARRAY_QUICK, NEW, NEW_QUICK, NEWARRAY, NO_OF_OPERANDS, NOP, OPCODE_NAMES, POP, POP2, PRODUCE_STACK, PUSH, PUTFIELD, PUTFIELD_QUICK, PUTFIELD_QUICK_W, PUTFIELD2_QUICK, PUTSTATIC, PUTSTATIC_QUICK, PUTSTATIC2_QUICK, RESERVED, RET, RETURN, SALOAD, SASTORE, SHORT_TYPE_NAMES, SIPUSH, STATIC_INITIALIZER_NAME, SWAP, SWITCH, T_ADDRESS, T_ARRAY, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_OBJECT, T_REFERENCE, T_SHORT, T_UNKNOWN, T_VOID, TABLESWITCH, TYPE_NAMES, TYPE_OF_OPERANDS, UNDEFINED, UNPREDICTABLE, WIDE
Constructor and Description |
---|
CodeBuilder(CfMethod cfMethod)
Create a new builder attached to the given method.
|
Modifier and Type | Method and Description |
---|---|
void |
add(short opcode)
Append an opcode that takes no arguments.
|
void |
add(short opcode,
CfField field)
Add a field opcode, such as PUTFIELD, GETFIELD, PUTSTATIC, GETSTATIC.
|
void |
add(short opcode,
CfMethod method)
Add a method opcode such as INVOKEVIRTUAL.
|
void |
add(short opcode,
java.lang.Class clas)
Add an opcode that takes a CONSTANT_Class_info index.
|
void |
add(short opcode,
CpClass clas)
Add an opcode that takes a CONSTANT_Class_info index.
|
void |
add(short opcode,
CpRef ref)
Add a field or method opcode.
|
void |
add(short opcode,
double d) |
void |
add(short opcode,
int i)
Add an instruction that takes a single byte, short, or int parameter.
|
void |
add(short opcode,
Label f)
Add a branch instruction, to branch to the given Label.
|
void |
add(short opcode,
LocalVariable var)
Add a LOAD/STORE instruction referencing the given local variable.
|
void |
add(short opcode,
LocalVariable var,
int n)
Generate an IINC, which takes both a local and an amount.
|
void |
add(short opcode,
long l)
Add an xLCONST instruction, with a long parameter.
|
void |
add(short opcode,
java.lang.String s1)
Process an opcode with a single String argument -- obviously no opcodes
actually take a String as an argument, so the argument must first be
converted into a constant String index, a constant methodref index, or a
constant class index.
|
void |
add(short opcode,
java.lang.String type,
int count)
Add a MULTIANEWARRAY instruction, the only instruction
with this particular format.
|
void |
add(short opcode,
java.lang.String s1,
java.lang.String s2)
Process an opcode that can concievably take two String
arguments ...
|
void |
add(short opcode,
java.lang.String className,
java.lang.String methodName,
java.lang.Class returnType,
java.lang.Class[] paramTypes)
A convenient form for a methodref based opcode, especially when dealing
with Java Method reflection.
|
void |
add(short opcode,
java.lang.String className,
java.lang.String methodName,
java.lang.String sig)
Add an opcode that takes a CpRef (MethodRef) as an argument.
|
java.lang.String |
addImport(java.lang.String fqClassName)
Convenience method to add import to ConstantPool SigConverter.
|
LocalVariable |
addLocal(CpClass type) |
LocalVariable |
addLocal(CpClass type,
java.lang.String name) |
LocalVariable |
addLocal(java.lang.String sig) |
LocalVariable |
addLocal(java.lang.String sig,
java.lang.String name)
Declare a local variable within the current code block (within the
method if there is no active code block).
|
void |
blockCatch(LocalVariable catchAndStore)
Start a catch block, for catching the exception with
the same type as the given local variable and storing
it automatically in that variable (adds an ASTORE automatically).
|
void |
blockCatch(java.lang.String exceptionType)
Start a catch block to catch the given type.
|
void |
blockElse()
Start an else block.
|
void |
blockEnd()
End the current block, be it a generic block, and if/else block,
or a try/catch/finally block.
|
void |
blockFinally()
Start the finally clause.
|
void |
blockIf(short opcode)
Start an If block, executing the THEN block if the given opcode fails
to branch.
|
void |
blockIfEQ()
Start an If block, executing the THEN block if the stack operand is
equal to zero.
|
void |
blockIfEQ(int type)
Start an If block, executing the THEN block if the top two
primitive operands are equal in value (of the given type).
|
void |
blockIfFalse()
Start an If block, executing the THEN block if the stack operand
is equal to zero (aka "false").
|
void |
blockIfNE()
Start an If block, executing the THEN block if the stack operand is
not equal to zero.
|
void |
blockIfNotNull()
Start an If block, executing the THEN block if the stack operand
is not null.
|
void |
blockIfNull()
Start an If block, executing the THEN block if the stack operand
is null.
|
void |
blockIfObjectsEQ()
Start an If block, executing the THEN block block if the two top stack
operands are equivalent object references (IF_ACMPEQ).
|
void |
blockIfObjectsNE()
Start an If block, executing the THEN block block if the two top stack
operands are different object references (IF_ACMPNE).
|
void |
blockIfTrue()
Start an If block, executing the THEN block if the stack operand
is not equal to zero (aka "true").
|
void |
blockStart()
Start a generic (ie, "scope") block.
|
void |
blockTry()
Begin a try/catch/finally block.
|
Label |
createLabel()
Create a new Label to be used in branch/goto instructions.
|
Label |
defineLabel()
Create and define a new Label to be used in branch/goto
instructions.
|
void |
defineLocals(LocalVariable undeclaredLocals,
int endPc)
Define the given linked-list of local variables as ending on the
given PC.
|
void |
flush()
Update the attached CfMethod's AttrCode based on the current contents of
the bytecode, local variables, exceptions, etc.
|
ByteArray |
getByteArray()
Returns the ByteArray that bytecode is written to.
|
LocalVariable |
getLocal(int slot)
Return the LocalVariable currently occupying the requested local variable
index.
|
int |
getMaxLocals() |
int |
getMaxStack() |
CfMethod |
getMethod() |
void |
init(CfMethod cfMethod)
Reinitialize this builder with the given method builder.
|
void |
setLineNumber(int line)
Attach the given line number to the current program counter offset.
|
void |
setMethod(CfMethod method)
Set the method to be built.
|
public CodeBuilder(CfMethod cfMethod)
public void setMethod(CfMethod method)
public void init(CfMethod cfMethod)
public ByteArray getByteArray()
public LocalVariable getLocal(int slot)
Remember that doubles and longs occupy 2 consecutive indexes.
This can be used to access the method arguments as LocalVariables.
NOTE - at present the CodeBuilder does not re-use locals, so a declared local is scoped to the entire method code body.
Note that newly added LocalVariables are not added to the CfMethod until the CodeBuilder is closed. This method does, however, search both the method and any pending declarations, so it will return a newly declared local.
slot
- The local slot number. For a static method the first arg
is zero, for a non-static method the first is 1 (as zero is 'this').java.util.NoSuchElementException
- If no local can be found with
the requested index.public LocalVariable addLocal(java.lang.String sig, java.lang.String name)
The local will not appear in the method's list of locals until the
code block is ended. However, it can be found by calling getLocal(int)
, which searches pending declarations as well as the
method's existing local variable table.
sig
- A type signature, in VM format.name
- An optional name for the local. If no name is given it
will assign it the name "local_X", where X is the slot number assigned.public LocalVariable addLocal(java.lang.String sig)
public LocalVariable addLocal(CpClass type)
public LocalVariable addLocal(CpClass type, java.lang.String name)
public void setLineNumber(int line)
This will generate a LineNumber in the line number table of the attached CfMethod. It does not check for duplicates.
public CfMethod getMethod()
public int getMaxLocals()
public int getMaxStack()
public Label createLabel()
public Label defineLabel()
public void flush()
public void defineLocals(LocalVariable undeclaredLocals, int endPc)
undeclaredLocals
- Linked list of LocalVariableendPc
- The ending program counter, generally the current PC.public java.lang.String addImport(java.lang.String fqClassName)
ConstantPool#addImport}
public void add(short opcode)
The opcode is tested to ensure it really takes no arguments.
public void add(short opcode, long l)
To push a long zero or one on the stack just use:
code.add (LCONST_0); or code.add (LCONST_1);This method provides support for:
code.add (xLCONST, (long) someValue);It automatically generates LCONST_0 or LCONST_1 if the argument is a zero or one.
opcode
- l
- public void add(short opcode, double d)
public void add(short opcode, int i)
Supports Virtual Opcode "xPUSH
public void add(short opcode, java.lang.Class clas)
public void add(short opcode, CpClass clas)
These would be instructions like CHECKCAST, NEW, INSTANCEOF, etc.
public void add(short opcode, java.lang.String s1)
Allowed opcodes: ANEWARRAY, CHECKCAST, INSTANCEOF, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, LDC, LDC2_W, LDC_W, NEW.
opcode
- ANEWARRAY, CHECKCAST, INSTANCEOF,
INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL,
LDC, LDC2_W, LDC_W, NEW.s1
- will be converted into a CpClass, a CpRef, or a CpString
based on the given opcode and what it requires.public void add(short opcode, java.lang.String type, int count)
public void add(short opcode, java.lang.String s1, java.lang.String s2)
opcode
- The opcode for GETFIELD, PUTFIELD, GETSTATIC, or PUTSTATIC.s1
- The Java Language signature for the field, such as
"int[][]".s2
- The name of the class, followed by the name of the
field.public void add(short opcode, Label f)
This Label may not have been resolved yet, that's okay, the code will be backpatched automatically when needed.
public void add(short opcode, java.lang.String className, java.lang.String methodName, java.lang.Class returnType, java.lang.Class[] paramTypes)
opcode
- className
- Either VM or short format class name.methodName
- returnType
- paramTypes
- public void add(short opcode, java.lang.String className, java.lang.String methodName, java.lang.String sig)
opcode
- className
- methodName
- sig
- public void add(short opcode, CfField field)
The argument is a CfField.
public void add(short opcode, CfMethod method)
The argument is a CfMethod.
public void add(short opcode, CpRef ref)
public void add(short opcode, LocalVariable var)
This also supports the virtual xLOAD and xSTORE opcodes, which automatically determine which opcode to use based on the type of the local.
For example, an 'int' local will generate an ILOAD instruction.
This method will also select the best form of the instruction, shortening ILOAD, 2 to ILOAD_2.
public void add(short opcode, LocalVariable var, int n)
opcode
- must be IINC.var
- variable to increment.n
- amount to increment local var.public void blockEnd()
public void blockStart()
public void blockIf(short opcode)
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfEQ()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfNE()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfEQ(int type)
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
type
- On of the JVM.T_XXX constants, to generate the proper
comparison bytecodes.public void blockIfObjectsEQ()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfObjectsNE()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfNull()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfNotNull()
This generates the inverse instruction, which branches around the THEN block (ie, to the ELSE block if there is one, or to the end of the THEN block if not).
If there is an ELSE block, the THEN block will end with a GOTO to jump around it (automatically).
public void blockIfFalse()
Synonymous with blockIfEQ()
.
public void blockIfTrue()
Synonymous with blockIfNE()
.
public void blockElse()
public void blockTry()
public void blockCatch(LocalVariable catchAndStore)
The caught exception will be stored in the given local.
public void blockCatch(java.lang.String exceptionType)
The caught exception will be on the stack.
exceptionType
- An exception type in JVM format, such
as "java/lang/IllegalArgumentException".public void blockFinally()
Copyright ? 2000-2003 Clarity Systems Group, LLC. All Rights Reserved.