下面列出了org.objectweb.asm.Opcodes# ILOAD 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private List<AbstractInsnNode> getPossibleInsns3(AbstractInsnNode ain)
{
List<AbstractInsnNode> instrs = new ArrayList<>();
while(ain != null)
{
if(ain instanceof LineNumberNode || ain instanceof FrameNode)
{
ain = ain.getNext();
continue;
}
instrs.add(ain);
if(instrs.size() >= 7)
break;
ain = ain.getNext();
}
if(instrs.size() == 7 && instrs.get(0).getOpcode() == Opcodes.ILOAD
&& instrs.get(1).getOpcode() == Opcodes.ILOAD
&& instrs.get(2).getOpcode() == Opcodes.ICONST_1
&& instrs.get(3).getOpcode() == Opcodes.ISUB
&& instrs.get(4).getOpcode() == Opcodes.IMUL
&& instrs.get(5).getOpcode() == Opcodes.ICONST_2
&& instrs.get(6).getOpcode() == Opcodes.IREM)
return instrs;
return null;
}
public static int getVarOpcode(Type type, boolean store) {
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.CHAR:
case Type.BYTE:
case Type.SHORT:
case Type.INT:
return store ? Opcodes.ISTORE : Opcodes.ILOAD;
case Type.FLOAT:
return store ? Opcodes.FSTORE : Opcodes.FLOAD;
case Type.LONG:
return store ? Opcodes.LSTORE : Opcodes.LLOAD;
case Type.DOUBLE:
return store ? Opcodes.DSTORE : Opcodes.DLOAD;
case Type.ARRAY:
case Type.OBJECT:
return store ? Opcodes.ASTORE : Opcodes.ALOAD;
default:
throw new AssertionError("Unknown type: " + type.getClassName());
}
}
@Override
public void visitBaseType(char c) {
int idx = paramIndex++;
int opcode;
switch (c) {
// two-word data
case 'J': opcode = Opcodes.LLOAD; paramIndex++; localSize++; break;
case 'D': opcode = Opcodes.DLOAD; paramIndex++; localSize++; break;
// float has a special opcode
case 'F': opcode = Opcodes.FLOAD; break;
default: opcode = Opcodes.ILOAD; break;
}
load(opcode, idx);
localSize++;
}
public static int getLoadOp(char c){
switch(c){
case 'Z': return Opcodes.ILOAD ;
case 'B': return Opcodes.ILOAD ;
case 'S': return Opcodes.ILOAD;
case 'I': return Opcodes.ILOAD ;
case 'J': return Opcodes.LLOAD ;
case 'F': return Opcodes.FLOAD ;
case 'D': return Opcodes.DLOAD ;
case 'C': return Opcodes.ILOAD ;
default:
return Opcodes.ALOAD;
}
}
@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) {
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();
}
}
private boolean isEqual(AbstractInsnNode ain)
{
if(ain.getNext() == null)
return false;
if(ain.getOpcode() == Opcodes.LDC && ain.getNext().getOpcode() == Opcodes.LDC
&& ((LdcInsnNode)ain).cst.equals(((LdcInsnNode)ain.getNext()).cst))
return true;
if(ain.getOpcode() >= Opcodes.ILOAD && ain.getOpcode() <= Opcodes.ALOAD
&& ain.getNext().getOpcode() == ain.getOpcode()
&& ((VarInsnNode)ain).var == ((VarInsnNode)ain.getNext()).var)
return true;
return false;
}
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;
}
@Test
public void test_checkTableSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkTableSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.TABLESWITCH},
{Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_0, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
int[][] expectedSwitchCounts = new int[][]{
{4},
{},
{},
{},
{},
{},
};
// Verify the shape of the blocks.
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
// Verify the switch option value.
didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
@Test
public void test_checkLookupSwitch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkLookupSwitch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.LOOKUPSWITCH},
{Opcodes.ICONST_1, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_2, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_3, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_0, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
int[][] expectedSwitchCounts = new int[][]{
{4},
{},
{},
{},
{},
{},
};
// Verify the shape of the blocks.
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
// Verify the switch option value.
didMatch = compareSwitches(expectedSwitchCounts, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
private static void removeInterpolation(ClassNode node, boolean isObfuscated)
{
// We're attempting to turn this line from EntityOtherPlayerMP.func_180426_a:
// this.otherPlayerMPPosRotationIncrements = p_180426_9_;
// into this:
// this.otherPlayerMPPosRotationIncrements = 1;
final String methodName = "func_180426_a";
final String methodDescriptor = "(DDDFFIZ)V"; // double x/y/z, float yaw/pitch, int increments, bool (unused), returns void.
System.out.println("MALMO: Found EntityOtherPlayerMP, attempting to transform it");
for (MethodNode method : node.methods)
{
if (method.name.equals(methodName) && method.desc.equals(methodDescriptor))
{
System.out.println("MALMO: Found EntityOtherPlayerMP.func_180426_a() method, attempting to transform it");
for (AbstractInsnNode instruction : method.instructions.toArray())
{
if (instruction.getOpcode() == Opcodes.ILOAD)
{
LdcInsnNode newNode = new LdcInsnNode(new Integer(1));
method.instructions.insert(instruction, newNode);
method.instructions.remove(instruction);
return;
}
}
}
}
}
private List<AbstractInsnNode> getPossibleInsns4(AbstractInsnNode ain)
{
List<AbstractInsnNode> instrs = new ArrayList<>();
while(ain != null)
{
if(ain instanceof LineNumberNode || ain instanceof FrameNode)
{
ain = ain.getNext();
continue;
}
instrs.add(ain);
if(instrs.size() >= 11)
break;
ain = ain.getNext();
}
if(instrs.size() == 11 && instrs.get(0).getOpcode() == Opcodes.ILOAD
&& instrs.get(1).getOpcode() == Opcodes.ICONST_1
&& instrs.get(2).getOpcode() == Opcodes.ISUB
&& instrs.get(3).getOpcode() == Opcodes.ISTORE)
{
int var1 = ((VarInsnNode)instrs.get(0)).var;
int var2 = ((VarInsnNode)instrs.get(3)).var;
if(instrs.get(4).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(4)).var == var1
&& instrs.get(5).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(5)).var == var2
&& instrs.get(6).getOpcode() == Opcodes.IMUL
&& instrs.get(7).getOpcode() == Opcodes.ISTORE
&& ((VarInsnNode)instrs.get(7)).var == var2
&& instrs.get(8).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(8)).var == var2
&& instrs.get(9).getOpcode() == Opcodes.ICONST_2
&& instrs.get(10).getOpcode() == Opcodes.IREM)
return instrs;
}
return null;
}
@Test
public void shouldMatchAgainstCapturedILoadVariable() {
final Slot<Integer> slot = Slot.create(Integer.class);
this.context.store(slot.write(), 3);
final VarInsnNode matchingNode = new VarInsnNode(Opcodes.ILOAD, 3);
assertTrue(anILoadOf(slot.read()).test(this.context,matchingNode));
final VarInsnNode nonMatchingNode = new VarInsnNode(Opcodes.ILOAD, 4);
assertFalse(anILoadOf(slot.read()).test(this.context,nonMatchingNode));
}
public static VarInsnNode getLoadInst(Type type, int position) {
int opCode = -1;
switch (type.getDescriptor().charAt(0)) {
case 'B':
opCode = Opcodes.ILOAD;
break;
case 'C':
opCode = Opcodes.ILOAD;
break;
case 'D':
opCode = Opcodes.DLOAD;
break;
case 'F':
opCode = Opcodes.FLOAD;
break;
case 'I':
opCode = Opcodes.ILOAD;
break;
case 'J':
opCode = Opcodes.LLOAD;
break;
case 'L':
opCode = Opcodes.ALOAD;
break;
case '[':
opCode = Opcodes.ALOAD;
break;
case 'Z':
opCode = Opcodes.ILOAD;
break;
case 'S':
opCode = Opcodes.ILOAD;
break;
default:
throw new ClassFormatError("Invalid method signature: "
+ type.getDescriptor());
}
return new VarInsnNode(opCode, position);
}
@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();
}
}
@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) {
switch (opcode) {
case Opcodes.ILOAD :
load(var, JavaType.INT);
break;
case Opcodes.LLOAD :
load(var, JavaType.LONG);
break;
case Opcodes.FLOAD :
load(var, JavaType.FLOAT);
break;
case Opcodes.DLOAD :
load(var, JavaType.DOUBLE);
break;
case Opcodes.ALOAD :
load(var, JavaType.OBJECT);
break;
case Opcodes.ISTORE :
store(var, JavaType.INT);
break;
case Opcodes.LSTORE :
store(var, JavaType.LONG);
break;
case Opcodes.FSTORE :
store(var, JavaType.FLOAT);
break;
case Opcodes.DSTORE :
store(var, JavaType.DOUBLE);
break;
case Opcodes.ASTORE :
store(var, JavaType.OBJECT);
break;
case Opcodes.RET :
recorder.add(new Runnable() {
public void run() {
block.addOp(new RetSub(lineNumber));
}
});
break;
default :
throw new UnsupportedOperationException("opcode: " + opcode);
}
}
private List<AbstractInsnNode> getPossibleInsns2(AbstractInsnNode ain)
{
List<AbstractInsnNode> instrs = new ArrayList<>();
while(ain != null)
{
if(ain instanceof LineNumberNode || ain instanceof FrameNode)
{
ain = ain.getNext();
continue;
}
instrs.add(ain);
if(instrs.size() >= 14)
break;
ain = ain.getNext();
}
if(instrs.size() == 14 && instrs.get(0).getOpcode() == Opcodes.ILOAD
&& instrs.get(1).getOpcode() == Opcodes.ICONST_1
&& instrs.get(2).getOpcode() == Opcodes.ISUB
&& instrs.get(3).getOpcode() == Opcodes.ISTORE)
{
int var1 = ((VarInsnNode)instrs.get(0)).var;
int var2 = ((VarInsnNode)instrs.get(3)).var;
if(instrs.get(4).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(4)).var == var1
&& instrs.get(5).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(5)).var == var2
&& instrs.get(6).getOpcode() == Opcodes.IMUL
&& instrs.get(7).getOpcode() == Opcodes.ISTORE
&& ((VarInsnNode)instrs.get(7)).var == var2
&& instrs.get(8).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(8)).var == var2
&& instrs.get(9).getOpcode() == Opcodes.ICONST_2
&& instrs.get(10).getOpcode() == Opcodes.IREM
&& instrs.get(11).getOpcode() == Opcodes.ISTORE
&& ((VarInsnNode)instrs.get(11)).var == var2
&& instrs.get(12).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(12)).var == var2
&& instrs.get(13).getOpcode() == Opcodes.IADD)
return instrs;
}
return null;
}
@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");
}