📄 generatoradapter.java
字号:
if ( value == null ) {
this.mv.visitInsn( Opcodes.ACONST_NULL );
} else {
this.mv.visitLdcInsn( value );
}
}
/**
* Generates the instruction to push the given value on the stack.
*
* @param value the value to be pushed on the stack.
*/
public void push(final Type value) {
if ( value == null ) {
this.mv.visitInsn( Opcodes.ACONST_NULL );
} else {
this.mv.visitLdcInsn( value );
}
}
// ------------------------------------------------------------------------
// Instructions to load and store method arguments
// ------------------------------------------------------------------------
/**
* Returns the index of the given method argument in the frame's local
* variables array.
*
* @param arg the index of a method argument.
* @return the index of the given method argument in the frame's local
* variables array.
*/
private int getArgIndex(final int arg) {
int index = ((this.access & Opcodes.ACC_STATIC) == 0 ? 1 : 0);
for ( int i = 0; i < arg; i++ ) {
index += this.argumentTypes[i].getSize();
}
return index;
}
/**
* Generates the instruction to push a local variable on the stack.
*
* @param type the type of the local variable to be loaded.
* @param index an index in the frame's local variables array.
*/
private void loadInsn(final Type type,
final int index) {
this.mv.visitVarInsn( type.getOpcode( Opcodes.ILOAD ),
index );
}
/**
* Generates the instruction to store the top stack value in a local
* variable.
*
* @param type the type of the local variable to be stored.
* @param index an index in the frame's local variables array.
*/
private void storeInsn(final Type type,
final int index) {
this.mv.visitVarInsn( type.getOpcode( Opcodes.ISTORE ),
index );
}
/**
* Generates the instruction to load 'this' on the stack.
*/
public void loadThis() {
if ( (this.access & Opcodes.ACC_STATIC) != 0 ) {
throw new IllegalStateException( "no 'this' pointer within static method" );
}
this.mv.visitVarInsn( Opcodes.ALOAD,
0 );
}
/**
* Generates the instruction to load the given method argument on the stack.
*
* @param arg the index of a method argument.
*/
public void loadArg(final int arg) {
loadInsn( this.argumentTypes[arg],
getArgIndex( arg ) );
}
/**
* Generates the instructions to load the given method arguments on the
* stack.
*
* @param arg the index of the first method argument to be loaded.
* @param count the number of method arguments to be loaded.
*/
public void loadArgs(final int arg,
final int count) {
int index = getArgIndex( arg );
for ( int i = 0; i < count; ++i ) {
final Type t = this.argumentTypes[arg + i];
loadInsn( t,
index );
index += t.getSize();
}
}
/**
* Generates the instructions to load all the method arguments on the stack.
*/
public void loadArgs() {
loadArgs( 0,
this.argumentTypes.length );
}
/**
* Generates the instructions to load all the method arguments on the stack,
* as a single object array.
*/
public void loadArgArray() {
push( this.argumentTypes.length );
newArray( GeneratorAdapter.OBJECT_TYPE );
for ( int i = 0; i < this.argumentTypes.length; i++ ) {
dup();
push( i );
loadArg( i );
box( this.argumentTypes[i] );
arrayStore( GeneratorAdapter.OBJECT_TYPE );
}
}
/**
* Generates the instruction to store the top stack value in the given
* method argument.
*
* @param arg the index of a method argument.
*/
public void storeArg(final int arg) {
storeInsn( this.argumentTypes[arg],
getArgIndex( arg ) );
}
// ------------------------------------------------------------------------
// Instructions to load and store local variables
// ------------------------------------------------------------------------
/**
* Creates a new local variable of the given type.
*
* @param type the type of the local variable to be created.
* @return the identifier of the newly created local variable.
*/
public int newLocal(final Type type) {
final int local = super.newLocal( type.getSize() );
setLocalType( local,
type );
return local;
}
/**
* Returns the type of the given local variable.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
* @return the type of the given local variable.
*/
public Type getLocalType(final int local) {
return (Type) this.localTypes.get( local - this.firstLocal );
}
/**
* Sets the current type of the given local variable.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
* @param type the type of the value being stored in the local variable
*/
private void setLocalType(final int local,
final Type type) {
final int index = local - this.firstLocal;
while ( this.localTypes.size() < index + 1 ) {
this.localTypes.add( null );
}
this.localTypes.set( index,
type );
}
/**
* Generates the instruction to load the given local variable on the stack.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
*/
public void loadLocal(final int local) {
loadInsn( getLocalType( local ),
local );
}
/**
* Generates the instruction to load the given local variable on the stack.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
* @param type the type of this local variable.
*/
public void loadLocal(final int local,
final Type type) {
setLocalType( local,
type );
loadInsn( type,
local );
}
/**
* Generates the instruction to store the top stack value in the given local
* variable.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
*/
public void storeLocal(final int local) {
storeInsn( getLocalType( local ),
local );
}
/**
* Generates the instruction to store the top stack value in the given local
* variable.
*
* @param local a local variable identifier, as returned by {@link #newLocal
* newLocal}.
* @param type the type of this local variable.
*/
public void storeLocal(final int local,
final Type type) {
setLocalType( local,
type );
storeInsn( type,
local );
}
/**
* Generates the instruction to load an element from an array.
*
* @param type the type of the array element to be loaded.
*/
public void arrayLoad(final Type type) {
this.mv.visitInsn( type.getOpcode( Opcodes.IALOAD ) );
}
/**
* Generates the instruction to store an element in an array.
*
* @param type the type of the array element to be stored.
*/
public void arrayStore(final Type type) {
this.mv.visitInsn( type.getOpcode( Opcodes.IASTORE ) );
}
// ------------------------------------------------------------------------
// Instructions to manage the stack
// ------------------------------------------------------------------------
/**
* Generates a POP instruction.
*/
public void pop() {
this.mv.visitInsn( Opcodes.POP );
}
/**
* Generates a POP2 instruction.
*/
public void pop2() {
this.mv.visitInsn( Opcodes.POP2 );
}
/**
* Generates a DUP instruction.
*/
public void dup() {
this.mv.visitInsn( Opcodes.DUP );
}
/**
* Generates a DUP2 instruction.
*/
public void dup2() {
this.mv.visitInsn( Opcodes.DUP2 );
}
/**
* Generates a DUP_X1 instruction.
*/
public void dupX1() {
this.mv.visitInsn( Opcodes.DUP_X1 );
}
/**
* Generates a DUP_X2 instruction.
*/
public void dupX2() {
this.mv.visitInsn( Opcodes.DUP_X2 );
}
/**
* Generates a DUP2_X1 instruction.
*/
public void dup2X1() {
this.mv.visitInsn( Opcodes.DUP2_X1 );
}
/**
* Generates a DUP2_X2 instruction.
*/
public void dup2X2() {
this.mv.visitInsn( Opcodes.DUP2_X2 );
}
/**
* Generates a SWAP instruction.
*/
public void swap() {
this.mv.visitInsn( Opcodes.SWAP );
}
/**
* Generates the instructions to swap the top two stack values.
*
* @param prev type of the top - 1 stack value.
* @param type type of the top stack value.
*/
public void swap(final Type prev,
final Type type) {
if ( type.getSize() == 1 ) {
if ( prev.getSize() == 1 ) {
swap(); // same as dupX1(), pop();
} else {
dupX2();
pop();
}
} else {
if ( prev.getSize() == 1 ) {
dup2X1();
pop2();
} else {
dup2X2();
pop2();
}
}
}
// ------------------------------------------------------------------------
// Instructions to do mathematical and logical operations
// ------------------------------------------------------------------------
/**
* Generates the instruction to do the specified mathematical or logical
* operation.
*
* @param op a mathematical or logical operation. Must be one of ADD, SUB,
* MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
* @param type the type of the operand(s) for this operation.
*/
public void math(final int op,
final Type type) {
this.mv.visitInsn( type.getOpcode( op ) );
}
/**
* Generates the instructions to compute the bitwise negation of the top
* stack value.
*/
public void not() {
this.mv.visitInsn( Opcodes.ICONST_1 );
this.mv.visitInsn( Opcodes.IXOR );
}
/**
* Generates the instruction to increment the given local variable.
*
* @param local the local variable to be incremented.
* @param amount the amount by which the local variable must be incremented.
*/
public void iinc(final int local,
final int amount) {
this.mv.visitIincInsn( local,
amount );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -