下面列出了org.objectweb.asm.Opcodes# DUP_X2 ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void genericSswap(String desc) {
//caters for double, int on stack - to swap
if(desc.equals("J") || desc.equals("D")){//long and double take up two slots insteead of 1
super.visitInsn(Opcodes.DUP_X2);
super.visitInsn(Opcodes.POP);
}
else{//1 slot each
super.visitInsn(Opcodes.SWAP);
}
}
public static int getDupXOpcode(Type dType, Type bType) {
if (dType.getSize() == 1 && bType.getSize() == 1) {
return Opcodes.DUP_X1;
} else if (dType.getSize() == 1 && bType.getSize() == 2) {
return Opcodes.DUP_X2;
} else if (dType.getSize() == 2 && bType.getSize() == 1) {
return Opcodes.DUP2_X1;
} else if (dType.getSize() == 2 && bType.getSize() == 2) {
return Opcodes.DUP2_X2;
} else {
throw new IllegalArgumentException(dType.toString() + " " + bType.toString());
}
}
/**
* NOTE: All calls to instruction visitation routines are made against super, directly, since we do frame offset accounting within our overrides
* and that offset only applies to incoming bytecodes, not outgoing ones.
*
* @param opcode The opcode.
* @param descriptor The type descriptor of the field to which the opcode is applied.
*/
private void checkInjectLazyLoad(int opcode, String descriptor) {
// If this is a PUTFIELD or GETFIELD, we want to call "lazyLoad()":
// -PUTIFELD: DUP2, POP, INVOKEVIRTUAL
// -GETIFELD: DUP, INVOKEVIRTUAL
if ((Opcodes.PUTFIELD == opcode) && ((null == this.tracker) || !this.tracker.isThisTargetOfPut(this.frameOffset))) {
// We need to see how big this type is since double and long need a far more complex dance.
if ((1 == descriptor.length()) && ((DescriptorParser.LONG == descriptor.charAt(0)) || (DescriptorParser.DOUBLE == descriptor.charAt(0)))) {
// Here, the stack looks like: ... OBJECT, VAR1, VAR2 (top)
// Where we need: ... OBJECT, VAR1, VAR2, OBJECT (top)
// This is multiple stages:
// DUP2_X1: ... VAR1, VAR2, OBJECT, VAR1, VAR2 (top)
super.visitInsn(Opcodes.DUP2_X1);
// POP2: ... VAR1, VAR2, OBJECT (top)
super.visitInsn(Opcodes.POP2);
// DUP: ... VAR1, VAR2, OBJECT, OBJECT (top)
super.visitInsn(Opcodes.DUP);
// INOKE: ... VAR1, VAR2, OBJECT (top)
super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
// DUP_X2: ... OBJECT, VAR1, VAR2, OBJECT (top)
super.visitInsn(Opcodes.DUP_X2);
// POP: ... OBJECT, VAR1, VAR2 (top)
super.visitInsn(Opcodes.POP);
} else {
// Here, the stack looks like: ... OBJECT, VAR, (top)
// Where we need: ... OBJECT, VAR, OBJECT (top)
// Stages:
// DUP2: ... OBJECT, VAR, OBJECT, VAR (top)
super.visitInsn(Opcodes.DUP2);
// POP: ... OBJECT, VAR, OBJECT (top)
super.visitInsn(Opcodes.POP);
// INOKE: ... OBJECT, VAR (top)
super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
}
} else if ((Opcodes.GETFIELD == opcode) && ((null == this.tracker) || !this.tracker.isThisTargetOfGet(this.frameOffset))) {
// Here, the stack looks like: ... OBJECT, (top)
// Where we need: ... OBJECT, OBJECT (top)
super.visitInsn(Opcodes.DUP);
super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, SHADOW_OBJECT_NAME, LAZY_LOAD_NAME, LAZY_LOAD_DESCRIPTOR, false);
}
}