下面列出了org.objectweb.asm.Opcodes# DLOAD 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static int getVariableLoadOpcode(Type type) {
if (type.getSort() >= Type.BOOLEAN && type.getSort() <= Type.INT) {
return Opcodes.ILOAD;
} else if (type == Type.LONG_TYPE) {
return Opcodes.LLOAD;
} else if (type == Type.FLOAT_TYPE) {
return Opcodes.FLOAD;
} else if (type == Type.DOUBLE_TYPE) {
return Opcodes.DLOAD;
} else if (type.getSort() >= Type.ARRAY && type.getSort() <= Type.OBJECT) {
return Opcodes.ALOAD;
} else {
return getVariableLoadOpcode(asSimpleType(type));
// throw new IllegalArgumentException(type.toString());
}
}
private void prepareParametersToPassToSuper(String description, MethodVisitor methodVisitor) {
int offset = 0;
methodVisitor.visitCode();
methodVisitor.visitVarInsn(Opcodes.ALOAD, offset++);
List<Integer> opCodes = getOpCodes(description);
for (int idx = 0; idx < opCodes.size(); idx++) {
final Integer opcode = opCodes.get(idx);
methodVisitor.visitVarInsn(opcode, idx + offset);
if (opcode == Opcodes.DLOAD || opcode == Opcodes.LLOAD) // Double and Long take two registers.
offset++;
}
}
@Override
public void transform(ClassNode classNode, String name) {
for (MethodNode methodNode : classNode.methods) {
if (TransformerMethod.getMouseOver.matches(methodNode)) {
// Objective:
// Find: The entity list variable.
// Insert EntityRendererHook.removeEntities(list);
Iterator<AbstractInsnNode> iterator = methodNode.instructions.iterator();
while (iterator.hasNext()) {
AbstractInsnNode abstractNode = iterator.next();
if (abstractNode instanceof VarInsnNode && abstractNode.getOpcode() == Opcodes.DLOAD) {
VarInsnNode varInsnNode = (VarInsnNode)abstractNode;
if (varInsnNode.var == 5) { // List variable is created right before variable 5 is accessed (double d3 = d2;)
methodNode.instructions.insertBefore(varInsnNode, insertRemoveEntities());
break;
}
}
}
} else if (TransformerMethod.getNightVisionBrightness.matches(methodNode)) {
// Objective:
// Find: Method head.
// Insert: ReturnValue returnValue = new ReturnValue();
// EntityPlayerSPHook.preventBlink(returnValue);
// if (returnValue.isCancelled()) {
// return 1.0F;
// }
methodNode.instructions.insertBefore(methodNode.instructions.getFirst(), insertNightVision());
}
}
}
@Override
public void visitVarInsn(int opcode, int var) {
mv.visitVarInsn(opcode, var);
switch (opcode) {
case Opcodes.ILOAD:
if (this.shouldMutate("Decremented (a--) integer local variable number " + var)) {
mv.visitIincInsn(var, -1);
}
break;
case Opcodes.FLOAD:
if (this.shouldMutate("Decremented (a--) float local variable number " + var)) {
mv.visitInsn(Opcodes.DUP);
mv.visitInsn(Opcodes.FCONST_1);
mv.visitInsn(Opcodes.FSUB);
mv.visitVarInsn(Opcodes.FSTORE, var);
}
break;
case Opcodes.LLOAD:
if (this.shouldMutate("Decremented (a--) long local variable number " + var)) {
mv.visitInsn(Opcodes.DUP2);
mv.visitInsn(Opcodes.LCONST_1);
mv.visitInsn(Opcodes.LSUB);
mv.visitVarInsn(Opcodes.LSTORE, var);
}
break;
case Opcodes.DLOAD:
if (this.shouldMutate("Decremented (a--) double local variable number " + var)) {
mv.visitInsn(Opcodes.DUP2);
mv.visitInsn(Opcodes.DCONST_1);
mv.visitInsn(Opcodes.DSUB);
mv.visitVarInsn(Opcodes.DSTORE, var);
}
break;
default:
break;
}
}
@Override
public void visitVarInsn(final int opcode, final int var) {
super.visitVarInsn(opcode, var);
boolean isLongOrDouble =
opcode == Opcodes.LLOAD
|| opcode == Opcodes.DLOAD
|| opcode == Opcodes.LSTORE
|| opcode == Opcodes.DSTORE;
maxLocals = Math.max(maxLocals, var + (isLongOrDouble ? 2 : 1));
execute(opcode, var, null);
}
@Override
public void visitVarInsn(final int opcode, final int var) {
switch (opcode) {
case Opcodes.ILOAD:
load(var, Type.INT_TYPE);
break;
case Opcodes.LLOAD:
load(var, Type.LONG_TYPE);
break;
case Opcodes.FLOAD:
load(var, Type.FLOAT_TYPE);
break;
case Opcodes.DLOAD:
load(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ALOAD:
load(var, OBJECT_TYPE);
break;
case Opcodes.ISTORE:
store(var, Type.INT_TYPE);
break;
case Opcodes.LSTORE:
store(var, Type.LONG_TYPE);
break;
case Opcodes.FSTORE:
store(var, Type.FLOAT_TYPE);
break;
case Opcodes.DSTORE:
store(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ASTORE:
store(var, OBJECT_TYPE);
break;
case Opcodes.RET:
ret(var);
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public void visitVarInsn(final int opcode, final int var) {
switch (opcode) {
case Opcodes.ILOAD:
load(var, Type.INT_TYPE);
break;
case Opcodes.LLOAD:
load(var, Type.LONG_TYPE);
break;
case Opcodes.FLOAD:
load(var, Type.FLOAT_TYPE);
break;
case Opcodes.DLOAD:
load(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ALOAD:
load(var, OBJECT_TYPE);
break;
case Opcodes.ISTORE:
store(var, Type.INT_TYPE);
break;
case Opcodes.LSTORE:
store(var, Type.LONG_TYPE);
break;
case Opcodes.FSTORE:
store(var, Type.FLOAT_TYPE);
break;
case Opcodes.DSTORE:
store(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ASTORE:
store(var, OBJECT_TYPE);
break;
case Opcodes.RET:
ret(var);
break;
default:
throw new IllegalArgumentException();
}
}
public void visitVarInsn(final int opcode, final int var) {
int size;
switch (opcode) {
case Opcodes.LLOAD:
case Opcodes.LSTORE:
case Opcodes.DLOAD:
case Opcodes.DSTORE:
size = 2;
break;
default:
size = 1;
}
mv.visitVarInsn(opcode, remap(var, size));
}
@Override
public void visitVarInsn(int opcode, int var) {
mv.visitVarInsn(opcode, var); // push the variable.
switch (opcode) {
case Opcodes.ILOAD:
if (this.shouldMutate("Negated integer local variable number " + var)) {
mv.visitInsn(Opcodes.INEG);
}
break;
case Opcodes.FLOAD:
if (this.shouldMutate("Negated float local variable number " + var)) {
mv.visitInsn(Opcodes.FNEG);
}
break;
case Opcodes.LLOAD:
if (this.shouldMutate("Negated long local variable number " + var)) {
mv.visitInsn(Opcodes.LNEG);
}
break;
case Opcodes.DLOAD:
if (this.shouldMutate("Negated double local variable number " + var)) {
mv.visitInsn(Opcodes.DNEG);
}
break;
default:
break;
}
}
@Override
public void visitVarInsn(final int opcode, final int var) {
Type varType;
switch (opcode) {
case Opcodes.LLOAD:
case Opcodes.LSTORE:
varType = Type.LONG_TYPE;
break;
case Opcodes.DLOAD:
case Opcodes.DSTORE:
varType = Type.DOUBLE_TYPE;
break;
case Opcodes.FLOAD:
case Opcodes.FSTORE:
varType = Type.FLOAT_TYPE;
break;
case Opcodes.ILOAD:
case Opcodes.ISTORE:
varType = Type.INT_TYPE;
break;
case Opcodes.ALOAD:
case Opcodes.ASTORE:
case Opcodes.RET:
varType = OBJECT_TYPE;
break;
default:
throw new IllegalArgumentException("Invalid opcode " + opcode);
}
super.visitVarInsn(opcode, remap(var, varType));
}
@Override
public void visitVarInsn(final int opcode, final int var) {
super.visitVarInsn(opcode, var);
boolean isLongOrDouble =
opcode == Opcodes.LLOAD
|| opcode == Opcodes.DLOAD
|| opcode == Opcodes.LSTORE
|| opcode == Opcodes.DSTORE;
maxLocals = Math.max(maxLocals, var + (isLongOrDouble ? 2 : 1));
execute(opcode, var, null);
}
@Override
public void visitVarInsn(final int opcode, final int var) {
switch (opcode) {
case Opcodes.ILOAD:
load(var, Type.INT_TYPE);
break;
case Opcodes.LLOAD:
load(var, Type.LONG_TYPE);
break;
case Opcodes.FLOAD:
load(var, Type.FLOAT_TYPE);
break;
case Opcodes.DLOAD:
load(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ALOAD:
load(var, OBJECT_TYPE);
break;
case Opcodes.ISTORE:
store(var, Type.INT_TYPE);
break;
case Opcodes.LSTORE:
store(var, Type.LONG_TYPE);
break;
case Opcodes.FSTORE:
store(var, Type.FLOAT_TYPE);
break;
case Opcodes.DSTORE:
store(var, Type.DOUBLE_TYPE);
break;
case Opcodes.ASTORE:
store(var, OBJECT_TYPE);
break;
case Opcodes.RET:
ret(var);
break;
default:
throw new IllegalArgumentException();
}
}
public static boolean isArg(Instruction instr) {
if (instr instanceof ArithmeticExpression) {
return true;
}
if (instr instanceof AssignableExpression) {
StringBuilder dummy = new StringBuilder();
if (((AssignableExpression)instr).assignTo(null, dummy)) {
return true;
}
}
int opcode = instr.getOpcode();
switch (opcode) {
case Opcodes.FLOAD:
case Opcodes.DLOAD:
case Opcodes.ILOAD:
case Opcodes.LLOAD:
case org.objectweb.asm.Opcodes.ICONST_0:
case org.objectweb.asm.Opcodes.ICONST_1:
case org.objectweb.asm.Opcodes.ICONST_2:
case org.objectweb.asm.Opcodes.ICONST_3:
case org.objectweb.asm.Opcodes.ICONST_4:
case org.objectweb.asm.Opcodes.ICONST_5:
case org.objectweb.asm.Opcodes.ICONST_M1:
case org.objectweb.asm.Opcodes.LCONST_0:
case org.objectweb.asm.Opcodes.LCONST_1:
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
case org.objectweb.asm.Opcodes.BIPUSH:
case org.objectweb.asm.Opcodes.SIPUSH:
case Opcodes.LDC:
return true;
}
return false;
}
private boolean willPush(AbstractInsnNode ain)
{
if(ain.getOpcode() == Opcodes.LDC && (((LdcInsnNode)ain).cst instanceof Long || ((LdcInsnNode)ain).cst instanceof Double))
return false;
return (Utils.willPushToStack(ain.getOpcode()) || ain.getOpcode() == Opcodes.NEW) && ain.getOpcode() != Opcodes.GETSTATIC
&& ain.getOpcode() != Opcodes.LLOAD && ain.getOpcode() != Opcodes.DLOAD;
}
@Override
public void visitVarInsn(int opcode, int var) {
mv.visitVarInsn(opcode, var);
switch (opcode) {
case Opcodes.ILOAD:
if (this.shouldMutate("Incremented (a++) integer local variable number " + var)) {
mv.visitIincInsn(var, 1);
}
break;
case Opcodes.FLOAD:
if (this.shouldMutate("Incremented (a++) float local variable number " + var)) {
mv.visitInsn(Opcodes.DUP);
mv.visitInsn(Opcodes.FCONST_1);
mv.visitInsn(Opcodes.FADD);
mv.visitVarInsn(Opcodes.FSTORE, var);
}
break;
case Opcodes.LLOAD:
if (this.shouldMutate("Incremented (a++) long local variable number " + var)) {
mv.visitInsn(Opcodes.DUP2);
mv.visitInsn(Opcodes.LCONST_1);
mv.visitInsn(Opcodes.LADD);
mv.visitVarInsn(Opcodes.LSTORE, var);
}
break;
case Opcodes.DLOAD:
if (this.shouldMutate("Incremented (a++) double local variable number " + var)) {
mv.visitInsn(Opcodes.DUP2);
mv.visitInsn(Opcodes.DCONST_1);
mv.visitInsn(Opcodes.DADD);
mv.visitVarInsn(Opcodes.DSTORE, var);
}
break;
default:
break;
}
}
private boolean willPush2(AbstractInsnNode ain)
{
return ain.getOpcode() == Opcodes.LCONST_0 || ain.getOpcode() == Opcodes.LCONST_1
|| ain.getOpcode() == Opcodes.DCONST_0 || ain.getOpcode() == Opcodes.DCONST_1
|| (ain.getOpcode() == Opcodes.LDC &&
(((LdcInsnNode)ain).cst instanceof Long || ((LdcInsnNode)ain).cst instanceof Double))
|| ain.getOpcode() == Opcodes.LLOAD || ain.getOpcode() == Opcodes.DLOAD;
}
private boolean willPush(AbstractInsnNode ain)
{
if(ain.getOpcode() == Opcodes.LDC && (((LdcInsnNode)ain).cst instanceof Long || ((LdcInsnNode)ain).cst instanceof Double))
return false;
return Utils.willPushToStack(ain.getOpcode()) && ain.getOpcode() != Opcodes.GETSTATIC
&& ain.getOpcode() != Opcodes.LLOAD && ain.getOpcode() != Opcodes.DLOAD;
}
@Override
public void visitVarInsn(final int opcode, final int var) {
Type varType;
switch (opcode) {
case Opcodes.LLOAD:
case Opcodes.LSTORE:
varType = Type.LONG_TYPE;
break;
case Opcodes.DLOAD:
case Opcodes.DSTORE:
varType = Type.DOUBLE_TYPE;
break;
case Opcodes.FLOAD:
case Opcodes.FSTORE:
varType = Type.FLOAT_TYPE;
break;
case Opcodes.ILOAD:
case Opcodes.ISTORE:
varType = Type.INT_TYPE;
break;
case Opcodes.ALOAD:
case Opcodes.ASTORE:
case Opcodes.RET:
varType = OBJECT_TYPE;
break;
default:
throw new IllegalArgumentException("Invalid opcode " + opcode);
}
super.visitVarInsn(opcode, remap(var, varType));
}
@Override
public void visitVarInsn(int opcode, int var) {
switch (opcode) {
case Opcodes.ILOAD:
if (this.shouldMutate("Incremented (++a) integer local variable number " + var)) {
mv.visitIincInsn(var, 1);
}
mv.visitVarInsn(opcode, var);
break;
case Opcodes.FLOAD:
if (this.shouldMutate("Incremented (++a) float local variable number " + var)) {
mv.visitVarInsn(opcode, var);
mv.visitInsn(Opcodes.FCONST_1);
mv.visitInsn(Opcodes.FADD);
mv.visitVarInsn(Opcodes.FSTORE, var);
}
mv.visitVarInsn(opcode, var);
break;
case Opcodes.LLOAD:
if (this.shouldMutate("Incremented (++a) long local variable number " + var)) {
mv.visitVarInsn(opcode, var);
mv.visitInsn(Opcodes.LCONST_1);
mv.visitInsn(Opcodes.LADD);
mv.visitVarInsn(Opcodes.LSTORE, var);
}
mv.visitVarInsn(opcode, var);
break;
case Opcodes.DLOAD:
if (this.shouldMutate("Incremented (++a) double local variable number " + var)) {
mv.visitVarInsn(opcode, var);
mv.visitInsn(Opcodes.DCONST_1);
mv.visitInsn(Opcodes.DADD);
mv.visitVarInsn(Opcodes.DSTORE, var);
}
mv.visitVarInsn(opcode, var);
break;
default:
mv.visitVarInsn(opcode, var);
break;
}
}
@Override
public void appendInstruction(StringBuilder b) {
b.append(" ");
switch(opcode) {
case Opcodes.ILOAD:
b.append("(*SP).type = CN1_TYPE_INT; /* ILOAD */ \n" +
" (*SP).data.i = ilocals_");
b.append(var);
b.append("_; \n SP++;\n");
return;
case Opcodes.LLOAD:
b.append("BC_LLOAD(");
break;
case Opcodes.FLOAD:
b.append("BC_FLOAD(");
break;
case Opcodes.DLOAD:
b.append("BC_DLOAD(");
break;
case Opcodes.ALOAD:
b.append("BC_ALOAD(");
break;
case Opcodes.ISTORE:
b.append("BC_ISTORE(");
break;
case Opcodes.LSTORE:
b.append("BC_LSTORE(");
break;
case Opcodes.FSTORE:
b.append("BC_FSTORE(");
break;
case Opcodes.DSTORE:
b.append("BC_DSTORE(");
break;
case Opcodes.ASTORE:
b.append("BC_ASTORE(");
break;
case Opcodes.RET:
b.append("/* RET TODO */");
//b.append("goto label_");
//b.append(var);
//b.append("; /* RET */\n");
return;
case Opcodes.SIPUSH:
case Opcodes.BIPUSH:
b.append("PUSH_INT(");
break;
case Opcodes.NEWARRAY:
switch(var) {
case 4: // boolean
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_BOOLEAN, sizeof(JAVA_ARRAY_BOOLEAN), 1));\n");
break;
case 5: // char
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_CHAR, sizeof(JAVA_ARRAY_CHAR), 1));\n");
break;
case 6: // float
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_FLOAT, sizeof(JAVA_ARRAY_FLOAT), 1));\n");
break;
case 7: // double
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_DOUBLE, sizeof(JAVA_ARRAY_DOUBLE), 1));\n");
break;
case 8: // byte
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_BYTE, sizeof(JAVA_ARRAY_BYTE), 1));\n");
break;
case 9: // short
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_SHORT, sizeof(JAVA_ARRAY_SHORT), 1));\n");
break;
case 10: // int
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_INT, sizeof(JAVA_ARRAY_INT), 1));\n");
break;
case 11: // long
b.append("PUSH_OBJ(allocArray(threadStateData, POP_INT(), &class_array1__JAVA_LONG, sizeof(JAVA_ARRAY_LONG), 1));\n");
break;
}
return;
default:
throw new RuntimeException("Missing opcode: " + opcode);
}
b.append(var);
b.append(");\n");
}