public class CodeAttr extends Attribute implements AttrContainer
Most of the actual methods that generate bytecode operation
are in this class (typically with names starting with emit
),
though there are also some in Method
.
Note that a CodeAttr
is an Attribute
of a Method
, and can in turn contain other
Attribute
s, such as a LineNumbersAttr
.
Modifier and Type | Field and Description |
---|---|
static int |
DONT_USE_JSR |
static int |
GENERATE_STACK_MAP_TABLE |
static boolean |
instructionLineMode
If true we get a line number entry for each instruction.
|
LocalVarsAttr |
locals |
Type[] |
stack_types |
StackMapTableAttr |
stackMap |
Modifier and Type | Method and Description |
---|---|
void |
addHandler(int start_pc,
int end_pc,
int handler_pc,
int catch_type)
Add an exception handler.
|
void |
addHandler(Label start_try,
Label end_try,
ClassType catch_type)
Add an exception handler.
|
Variable |
addLocal(Type type)
Add a new local variable (in the current scope).
|
Variable |
addLocal(Type type,
java.lang.String name)
Add a new local variable (in the current scope).
|
void |
addParamLocals()
Call addLocal for parameters (as implied by method type).
|
void |
assignConstants(ClassType cl)
Add any needed constant pool entries for this Attribute.
|
int |
beginFragment(Label after) |
int |
beginFragment(Label start,
Label after) |
static java.lang.String |
calculateSplit(java.lang.String str)
Calculate how many CONSTANT_String constants we need for a string.
|
static boolean |
castNeeded(Type top,
Type required) |
void |
disAssemble(ClassTypeWriter dst,
int start,
int limit) |
void |
emitAdd()
Deprecated.
|
void |
emitAdd(char sig) |
void |
emitAdd(PrimType type) |
void |
emitAnd() |
void |
emitAndThen()
Convenience for compiling
if P1 && P2 then S1 else S2 . |
void |
emitArrayLength() |
void |
emitArrayLoad()
Load an element from an array.
|
void |
emitArrayLoad(Type element_type)
Load an element from an array.
|
void |
emitArrayStore()
Store into an element of an array.
|
void |
emitArrayStore(Type element_type)
Store into an element of an array.
|
void |
emitBinop(int base_code,
Type type) |
void |
emitCatchEnd() |
void |
emitCatchStart(ClassType type) |
void |
emitCatchStart(Variable var) |
void |
emitCheckcast(Type type) |
void |
emitConvert(PrimType from,
PrimType to) |
void |
emitDiv() |
void |
emitDup()
Emit code to duplicate the top element of the stack.
|
void |
emitDup(int size)
Compile code to duplicate the top 1 or 2 words.
|
void |
emitDup(int size,
int offset)
Compile code to duplicate with offset.
|
void |
emitDup(Type type) |
void |
emitDupX()
Emit code to duplicate the top element of the stack
and place the copy before the previous element.
|
void |
emitElse()
Compile start of else clause.
|
void |
emitFi()
Compile end of conditional.
|
void |
emitFinallyEnd() |
void |
emitFinallyStart() |
void |
emitGetField(Field field)
Compile code to get a non-static field value.
|
void |
emitGetStatic(Field field)
Compile code to get a static field value.
|
void |
emitGoto(Label label)
Compile an unconditional branch (goto).
|
void |
emitGotoIfCompare1(Label label,
int opcode) |
void |
emitGotoIfCompare2(Label label,
int logop) |
void |
emitGotoIfEq(Label label)
Compile a conditional transfer if 2 top stack elements are equal.
|
void |
emitGotoIfEq(Label label,
boolean invert)
Deprecated.
|
void |
emitGotoIfGe(Label label) |
void |
emitGotoIfGt(Label label) |
void |
emitGotoIfIntEqZero(Label label) |
void |
emitGotoIfIntGeZero(Label label) |
void |
emitGotoIfIntGtZero(Label label) |
void |
emitGotoIfIntLeZero(Label label) |
void |
emitGotoIfIntLtZero(Label label) |
void |
emitGotoIfIntNeZero(Label label) |
void |
emitGotoIfLe(Label label) |
void |
emitGotoIfLt(Label label) |
void |
emitGotoIfNE(Label label)
Compile conditional transfer if 2 top stack elements are not equal.
|
void |
emitGotoIfNonNull(Label label) |
void |
emitGotoIfNull(Label label) |
void |
emitIfCompare1(int opcode)
Compile start of a conditional:
if (!(x opcode 0)) ....
|
void |
emitIfEq()
Compile start of a conditional:
if (x == y) ...
The values of x and y must already have been pushed. |
void |
emitIfGe()
Compile start of a conditional:
if (x >= y) ...
The values of x and y must already have been pushed. |
void |
emitIfGt()
Compile start of a conditional:
if (x > y) ...
The values of x and y must already have been pushed. |
void |
emitIfIntCompare(int opcode)
Compile start of a conditional:
if (!(x OPCODE y)) ...
The value of x and y must already have been pushed. |
void |
emitIfIntEqZero()
Compile start of conditional: if (x == 0) ....
|
void |
emitIfIntGEq() |
void |
emitIfIntGEqZero()
Compile start of conditional:
if (x >= 0) . |
void |
emitIfIntLEqZero()
Compile start of conditional:
if (x <= 0) . |
void |
emitIfIntLt() |
void |
emitIfIntNotZero()
Compile start of conditional: if (x != 0) ....
|
void |
emitIfLe()
Compile start of a conditional:
if (x <= y) ...
The values of x and y must already have been pushed. |
void |
emitIfLt()
Compile start of a conditional:
if (x < y) ...
The values of x and y must already have been pushed. |
void |
emitIfNEq()
Compile start of a conditional: if (x != y) ...
|
void |
emitIfNotNull()
Compile start of conditional:
if (x != null) ... . |
void |
emitIfNull()
Compile start of conditional:
if (x == null) ... |
Label |
emitIfRaw()
Start a new if/then/else block.
|
void |
emitIfRefCompare1(int opcode)
Compile start of a conditional:
if (!(x opcode null)) ... . |
void |
emitIfThen() |
void |
emitInc(Variable var,
short inc)
Emit an instruction to increment a variable by some amount.
|
void |
emitInstanceof(Type type) |
void |
emitInvoke(Method method) |
void |
emitInvokeInterface(Method method) |
void |
emitInvokeMethod(Method method,
int opcode) |
void |
emitInvokeSpecial(Method method) |
void |
emitInvokeStatic(Method method)
Compile a static method call.
|
void |
emitInvokeVirtual(Method method)
Compile a virtual method call.
|
void |
emitIOr() |
void |
emitJsr(Label label) |
void |
emitLoad(Variable var)
Compile code to push the contents of a local variable onto the statck.
|
void |
emitMonitorEnter() |
void |
emitMonitorExit() |
void |
emitMul() |
void |
emitNew(ClassType type)
Invoke new on a class type.
|
void |
emitNewArray(Type element_type) |
void |
emitNewArray(Type element_type,
int dims)
Compile code to allocate a new array.
|
void |
emitNot(Type type)
Compile 'not', assuming 0 or 1 is on the JVM stack.
|
void |
emitPop(int nvalues)
Compile code to pop values off the stack (and ignore them).
|
void |
emitPrimop(int opcode,
int arg_count,
Type retType) |
void |
emitPushClass(ObjectType ctype)
Push a class constant pool entry.
|
void |
emitPushConstant(CpoolEntry cnst) |
void |
emitPushConstant(int val,
Type type) |
void |
emitPushDefaultValue(Type type)
Push zero or null as appropriate for the given type.
|
void |
emitPushDouble(double x) |
void |
emitPushFloat(float x) |
void |
emitPushInt(int i) |
void |
emitPushLong(long i) |
void |
emitPushMethodHandle(Method method)
Push a MethodHandle, using an appropriate constant pool entry.
|
void |
emitPushNull() |
void |
emitPushNull(ObjectType type) |
void |
emitPushPrimArray(java.lang.Object value,
ArrayType arrayType) |
void |
emitPushPrimArray(java.lang.Object value,
int len,
int count,
ArrayType arrayType)
Emit code to push a constant primitive array.
|
void |
emitPushString(java.lang.String str)
Emit code to push the value of a constant String.
|
void |
emitPushThis() |
void |
emitPutField(Field field)
Compile code to put a non-static field value.
|
void |
emitPutStatic(Field field)
Compile code to put a static field value.
|
void |
emitRem() |
void |
emitRet(Variable var)
Emit a 'ret' instruction.
|
void |
emitReturn()
Compile a method return.
|
void |
emitShl() |
void |
emitShr() |
void |
emitStore(Variable var) |
void |
emitStoreDefaultValue(Variable var)
Initialize a variable to zero or null, as appropriate.
|
void |
emitSub()
Deprecated.
|
void |
emitSub(char sig) |
void |
emitSub(PrimType type) |
void |
emitSwap() |
void |
emitTailCall(boolean pop_args,
Label start)
Compile a tail-call to position 0 of the current procedure.
|
void |
emitTailCall(boolean pop_args,
Scope scope)
Compile a tail-call to position 0 of the current procedure.
|
void |
emitThen() |
void |
emitThrow() |
void |
emitTryCatchEnd() |
void |
emitTryEnd()
Deprecated.
|
void |
emitTryStart(boolean has_finally,
Type result_type) |
void |
emitUshr() |
void |
emitWithCleanupCatch(Variable catchVar)
Called after a
body that has a cleanup clause. |
void |
emitWithCleanupDone()
Called after generating a
cleanup handler. |
void |
emitWithCleanupStart()
Beginning of code that has a cleanup handler.
|
void |
emitXOr() |
void |
endExitableBlock()
End a block entered by a previous startExitableBlock.
|
void |
endFragment(int cookie)
End a fragment.
|
void |
enterScope(Scope scope) |
void |
fixUnsigned(Type stackType) |
void |
fixupAdd(int kind,
Label label)
Add a fixup at this location.
|
void |
fixupChain(Label here,
Label target)
This causes a later processFixup to rearrange the code.
|
Variable |
getArg(int index)
Get the index'th parameter.
|
Attribute |
getAttributes()
Get the (first) Attribute of this container.
|
byte[] |
getCode()
Get the code (instruction bytes) of this method.
|
int |
getCodeLength()
Set the current lengthof the code (instruction bytes) of this method.
|
ConstantPool |
getConstants() |
Scope |
getCurrentScope() |
TryState |
getCurrentTry() |
Label |
getLabel()
Get a new Label for the current location.
|
int |
getLength()
Return the length of the attribute in bytes.
|
int |
getMaxLocals()
Get the maximum number of local variable words in this method.
|
int |
getMaxStack()
Get the maximum number of words on the operand stack in this method.
|
Method |
getMethod() |
int |
getPC() |
int |
getSP() |
boolean |
isInTry() |
Variable |
lookup(java.lang.String name)
Search by name for a Variable
|
void |
noteVarType(int offset,
Type type) |
Scope |
popScope() |
Type |
popType() |
void |
print(ClassTypeWriter dst) |
void |
processFixups() |
Scope |
pushAutoPoppableScope()
Create a Scope that is automatically popped.
|
Scope |
pushScope() |
void |
pushType(Type type) |
void |
put1(int i)
Write an 8-bit byte to the current code-stream.
|
void |
put2(int i)
Write a 16-bit short to the current code-stream
|
void |
put4(int i)
Write a 32-bit int to the current code-stream
|
void |
putIndex2(CpoolEntry cnst) |
void |
putLineNumber(int linenumber) |
void |
putLineNumber(java.lang.String filename,
int linenumber) |
boolean |
reachableHere()
True if control could reach here.
|
void |
reserve(int bytes) |
void |
setAttributes(Attribute attributes)
Set the (list of) Attributes of this container.
|
void |
setCode(byte[] code)
Set the code (instruction bytes) of this method.
|
void |
setCodeLength(int len)
Set the length the the code (instruction bytes) of this method.
|
void |
setMaxLocals(int n)
Set the maximum number of local variable words in this method.
|
void |
setMaxStack(int n)
Set the maximum number of words on the operand stack in this method.
|
void |
setReachable(boolean val) |
void |
setTypes(Label label)
Set the current type state from a label.
|
void |
setTypes(Type[] labelLocals,
Type[] labelStack)
Set the current type state from a label.
|
void |
setUnreachable() |
ExitableBlock |
startExitableBlock(Type resultType,
boolean runFinallyBlocks)
Enter a block which can be exited.
|
SwitchState |
startSwitch()
Start a new switch statment or expression.
|
Type |
topType() |
void |
write(java.io.DataOutputStream dstr)
Write out the contents of the Attribute.
|
addToFrontOf, assignConstants, count, get, getContainer, getLengthAll, getName, getNameIndex, getNext, isSkipped, setContainer, setName, setNameIndex, setNext, setSkipped, setSkipped, writeAll
public LocalVarsAttr locals
public StackMapTableAttr stackMap
public static final int GENERATE_STACK_MAP_TABLE
public static final int DONT_USE_JSR
public Type[] stack_types
public static boolean instructionLineMode
LINE==PC
.public CodeAttr(Method meth)
public final Attribute getAttributes()
AttrContainer
getAttributes
in interface AttrContainer
public final void setAttributes(Attribute attributes)
AttrContainer
setAttributes
in interface AttrContainer
public final void fixupChain(Label here, Label target)
goto target; here:
,
but implemented by code re-arranging. Therefore there should be
at some later point a goto here; target:
.public final void fixupAdd(int kind, Label label)
kind
- one of the FIXUP_xxx codes.label
- varies - typically the target of jump.public final Method getMethod()
public final int getPC()
public final int getSP()
public final ConstantPool getConstants()
getConstants
in interface AttrContainer
getConstants
in class Attribute
public final boolean reachableHere()
public final void setReachable(boolean val)
public final void setUnreachable()
public int getMaxStack()
public int getMaxLocals()
public void setMaxStack(int n)
public void setMaxLocals(int n)
public byte[] getCode()
public void setCode(byte[] code)
code
- the code bytes (which are not copied).
Implicitly calls setCodeLength(code.length).public void setCodeLength(int len)
public int getCodeLength()
public final void reserve(int bytes)
public final void put1(int i)
i
- the byte to writepublic final void put2(int i)
i
- the value to writepublic final void put4(int i)
i
- the value to writepublic final void putIndex2(CpoolEntry cnst)
public final void putLineNumber(java.lang.String filename, int linenumber)
public final void putLineNumber(int linenumber)
public void noteVarType(int offset, Type type)
public final void setTypes(Label label)
public final void setTypes(Type[] labelLocals, Type[] labelStack)
public final void pushType(Type type)
public final Type popType()
public final Type topType()
public void emitPop(int nvalues)
nvalues
- the number of values (not words) to poppublic Label getLabel()
public void emitSwap()
public void emitDup()
public void emitDupX()
public void emitDup(int size, int offset)
size
- the size of the stack item to duplicate (1 or 2)offset
- where to insert the result (must be 0, 1, or 2)
The new words get inserted at stack[SP-size-offset]public void emitDup(int size)
size
- number of words to duplicatepublic void emitDup(Type type)
public void enterScope(Scope scope)
public Scope pushScope()
public Scope pushAutoPoppableScope()
public Scope getCurrentScope()
public Scope popScope()
public Variable getArg(int index)
public Variable lookup(java.lang.String name)
name
- name to search forpublic Variable addLocal(Type type)
type
- type of the new Variable.public Variable addLocal(Type type, java.lang.String name)
type
- type of the new Variable.name
- name of the new Variable.public void addParamLocals()
public final void emitPushConstant(int val, Type type)
public final void emitPushConstant(CpoolEntry cnst)
public final void emitPushInt(int i)
public void emitPushLong(long i)
public void emitPushFloat(float x)
public void emitPushDouble(double x)
public static final java.lang.String calculateSplit(java.lang.String str)
public final void emitPushString(java.lang.String str)
public final void emitPushClass(ObjectType ctype)
public final void emitPushMethodHandle(Method method)
public void emitPushNull()
public void emitPushNull(ObjectType type)
public void emitPushDefaultValue(Type type)
public void emitStoreDefaultValue(Variable var)
public final void emitPushThis()
public final void emitPushPrimArray(java.lang.Object value, ArrayType arrayType)
public final void emitPushPrimArray(java.lang.Object value, int len, int count, ArrayType arrayType)
value
- The array value that we want the emitted code to re-create.arrayType
- The ArrayType that matches value.public final void emitArrayLength()
public void emitArrayStore(Type element_type)
public void emitArrayStore()
public void emitArrayLoad(Type element_type)
public void emitArrayLoad()
emitArrayLoad(Type)
, but element_type is implied.
Must already have pushed the array and the index (in that order):
Stack: ..., array, index => ..., valuepublic void emitNew(ClassType type)
type
- the desired new object typepublic void emitNewArray(Type element_type, int dims)
element_type
- type of the array elementsdims
- number of dimensions - more than 1 is untestedpublic void emitNewArray(Type element_type)
public void emitBinop(int base_code, Type type)
public final void emitAdd(char sig)
public final void emitAdd(PrimType type)
@Deprecated public final void emitAdd()
public final void emitSub(char sig)
public final void emitSub(PrimType type)
@Deprecated public final void emitSub()
public final void emitMul()
public final void emitDiv()
public final void emitRem()
public final void emitAnd()
public final void emitIOr()
public final void emitXOr()
public final void emitShl()
public final void emitShr()
public final void emitUshr()
public final void emitNot(Type type)
public void emitPrimop(int opcode, int arg_count, Type retType)
public final void emitLoad(Variable var)
var
- The variable whose contents we want to push.public void emitStore(Variable var)
public void emitInc(Variable var, short inc)
public final void emitGetStatic(Field field)
... => ..., value
public final void emitGetField(Field field)
..., objectref => ..., value
public final void emitPutStatic(Field field)
..., value => ...
public final void emitPutField(Field field)
..., objectref, value => ...
public void emitInvokeMethod(Method method, int opcode)
public void emitInvoke(Method method)
public void emitInvokeVirtual(Method method)
method
- the method to invoke virtuallypublic void emitInvokeSpecial(Method method)
public void emitInvokeStatic(Method method)
method
- the static method to invokepublic void emitInvokeInterface(Method method)
public final void emitGoto(Label label)
label
- target of the branch (must be in this method).public final void emitJsr(Label label)
public ExitableBlock startExitableBlock(Type resultType, boolean runFinallyBlocks)
public void endExitableBlock()
public final void emitGotoIfCompare1(Label label, int opcode)
public final void emitGotoIfIntEqZero(Label label)
public final void emitGotoIfIntNeZero(Label label)
public final void emitGotoIfIntLtZero(Label label)
public final void emitGotoIfIntGeZero(Label label)
public final void emitGotoIfIntGtZero(Label label)
public final void emitGotoIfIntLeZero(Label label)
public final void emitGotoIfNull(Label label)
public final void emitGotoIfNonNull(Label label)
public final void emitGotoIfCompare2(Label label, int logop)
@Deprecated public final void emitGotoIfEq(Label label, boolean invert)
public final void emitGotoIfEq(Label label)
public final void emitGotoIfNE(Label label)
public final void emitGotoIfLt(Label label)
public final void emitGotoIfGe(Label label)
public final void emitGotoIfGt(Label label)
public final void emitGotoIfLe(Label label)
public final void emitIfCompare1(int opcode)
public final void emitIfIntNotZero()
public final void emitIfIntEqZero()
public final void emitIfIntLEqZero()
if (x <= 0)
.public final void emitIfIntGEqZero()
if (x >= 0)
.public final void emitIfRefCompare1(int opcode)
if (!(x opcode null)) ...
.
The value of x must already have been pushed and must be of
reference type.public final void emitIfNotNull()
if (x != null) ...
.public final void emitIfNull()
if (x == null) ...
public final void emitIfIntCompare(int opcode)
if (!(x OPCODE y)) ...
The value of x and y must already have been pushed.public final void emitIfIntLt()
public final void emitIfIntGEq()
public final void emitIfNEq()
public final void emitIfEq()
if (x == y) ...
The values of x and y must already have been pushed.public final void emitIfLt()
if (x < y) ...
The values of x and y must already have been pushed.public final void emitIfGe()
if (x >= y) ...
The values of x and y must already have been pushed.public final void emitIfGt()
if (x > y) ...
The values of x and y must already have been pushed.public final void emitIfLe()
if (x <= y) ...
The values of x and y must already have been pushed.public void emitRet(Variable var)
var
- the variable containing the return addresspublic final void emitThen()
public final void emitIfThen()
public final void emitElse()
public final void emitFi()
public void emitAndThen()
if P1 && P2 then S1 else S2
.
Compile that as:
compile P1, including an appropriate emitIfXxx emitAndThen() compile P2, including an appropriate emitIfXxx compile S1 emitElse compile S2 emitFi
public Label emitIfRaw()
public final void fixUnsigned(Type stackType)
public void emitCheckcast(Type type)
public void emitInstanceof(Type type)
public final void emitThrow()
public final void emitMonitorEnter()
public final void emitMonitorExit()
public final void emitReturn()
public void addHandler(int start_pc, int end_pc, int handler_pc, int catch_type)
#emitCatchStart
is preferred.public void addHandler(Label start_try, Label end_try, ClassType catch_type)
emitCatchStart(gnu.bytecode.Variable)
is preferred.public void emitWithCleanupStart()
try body catch (Throwable ex) { cleanup; throw ex; }
Call emitWithCleanupStart
before the body
.public void emitWithCleanupCatch(Variable catchVar)
body
that has a cleanup
clause.
Followed by the cleanup
code.public void emitWithCleanupDone()
cleanup
handler.public void emitTryStart(boolean has_finally, Type result_type)
@Deprecated public void emitTryEnd()
public void emitCatchStart(Variable var)
public void emitCatchStart(ClassType type)
public void emitCatchEnd()
public void emitFinallyStart()
public void emitFinallyEnd()
public void emitTryCatchEnd()
public final TryState getCurrentTry()
public final boolean isInTry()
public SwitchState startSwitch()
public void emitTailCall(boolean pop_args, Label start)
pop_args
- if true, copy argument registers (except this) from stack.start
- the Label to jump back to.public void emitTailCall(boolean pop_args, Scope scope)
pop_args
- if true, copy argument registers (except this) from stack.scope
- Scope whose start we jump back to.public void processFixups()
public void assignConstants(ClassType cl)
Attribute
assignConstants
in class Attribute
public final int getLength()
Attribute
public void write(java.io.DataOutputStream dstr) throws java.io.IOException
Attribute
public void print(ClassTypeWriter dst)
public void disAssemble(ClassTypeWriter dst, int start, int limit)
public int beginFragment(Label after)
public void endFragment(int cookie)
cookie
- the return value from the previous beginFragment.