下面列出了怎么用org.objectweb.asm.tree.IntInsnNode的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Given an integer, returns an InsnNode that will properly represent the int.
*
* @param i
* @return
*/
public static AbstractInsnNode toInt(int i) {
switch (i) {
case -1:
return new InsnNode(Opcodes.ICONST_M1);
case 0:
return new InsnNode(Opcodes.ICONST_0);
case 1:
return new InsnNode(Opcodes.ICONST_1);
case 2:
return new InsnNode(Opcodes.ICONST_2);
case 3:
return new InsnNode(Opcodes.ICONST_3);
case 4:
return new InsnNode(Opcodes.ICONST_4);
case 5:
return new InsnNode(Opcodes.ICONST_5);
}
if (i > -129 && i < 128) {
return new IntInsnNode(Opcodes.BIPUSH, i);
}
return new LdcInsnNode(i);
}
/**
* Given an integer, returns an InsnNode that will properly represent the
* int.
*
* @param i
* @return
*/
public static AbstractInsnNode toInt(int i) {
switch (i) {
case -1:
return new InsnNode(Opcodes.ICONST_M1);
case 0:
return new InsnNode(Opcodes.ICONST_0);
case 1:
return new InsnNode(Opcodes.ICONST_1);
case 2:
return new InsnNode(Opcodes.ICONST_2);
case 3:
return new InsnNode(Opcodes.ICONST_3);
case 4:
return new InsnNode(Opcodes.ICONST_4);
case 5:
return new InsnNode(Opcodes.ICONST_5);
}
if (i > -129 && i < 128) {
return new IntInsnNode(Opcodes.BIPUSH, i);
}
return new LdcInsnNode(i);
}
private static AbstractValue valueFromArrayInsn(IntInsnNode iinsn) {
switch (iinsn.operand) {
case T_BOOLEAN:
return new UnknownValue(iinsn, Type.getType("[Z"));
case T_CHAR:
return new UnknownValue(iinsn, Type.getType("[C"));
case T_BYTE:
return new UnknownValue(iinsn, Type.getType("[B"));
case T_SHORT:
return new UnknownValue(iinsn, Type.getType("[S"));
case T_INT:
return new UnknownValue(iinsn, Type.getType("[I"));
case T_FLOAT:
return new UnknownValue(iinsn, Type.getType("[F"));
case T_DOUBLE:
return new UnknownValue(iinsn, Type.getType("[D"));
case T_LONG:
return new UnknownValue(iinsn, Type.getType("[J"));
default:
throw new IllegalArgumentException("Invalid array type");
}
}
/**
* Given an integer, returns an InsnNode that will properly represent the int.
*
* @param i
* @return
*/
public static AbstractInsnNode toInt(int i) {
switch (i) {
case -1:
return new InsnNode(Opcodes.ICONST_M1);
case 0:
return new InsnNode(Opcodes.ICONST_0);
case 1:
return new InsnNode(Opcodes.ICONST_1);
case 2:
return new InsnNode(Opcodes.ICONST_2);
case 3:
return new InsnNode(Opcodes.ICONST_3);
case 4:
return new InsnNode(Opcodes.ICONST_4);
case 5:
return new InsnNode(Opcodes.ICONST_5);
}
if (i > -129 && i < 128) {
return new IntInsnNode(Opcodes.BIPUSH, i);
}
return new LdcInsnNode(i);
}
public static AbstractInsnNode loadInt(int i) {
switch (i) {
case -1: return new InsnNode(ICONST_M1);
case 0: return new InsnNode(ICONST_0);
case 1: return new InsnNode(ICONST_1);
case 2: return new InsnNode(ICONST_2);
case 3: return new InsnNode(ICONST_3);
case 4: return new InsnNode(ICONST_4);
case 5: return new InsnNode(ICONST_5);
default: {
if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) return new IntInsnNode(BIPUSH, i);
else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) return new IntInsnNode(SIPUSH, i);
else return new LdcInsnNode(i);
}
}
}
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
if (node1.getOpcode() != node2.getOpcode()) {
return false;
}
switch (node2.getType()) {
case VAR_INSN:
return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2);
case TYPE_INSN:
return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2);
case FIELD_INSN:
return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2);
case METHOD_INSN:
return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2);
case LDC_INSN:
return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2);
case IINC_INSN:
return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2);
case INT_INSN:
return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2);
default:
return true;
}
}
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
if (node1.getOpcode() != node2.getOpcode()) {
return false;
}
switch (node2.getType()) {
case VAR_INSN:
return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2);
case TYPE_INSN:
return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2);
case FIELD_INSN:
return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2);
case METHOD_INSN:
return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2);
case LDC_INSN:
return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2);
case IINC_INSN:
return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2);
case INT_INSN:
return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2);
default:
return true;
}
}
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
if (node1.getOpcode() != node2.getOpcode()) {
return false;
}
switch (node2.getType()) {
case VAR_INSN:
return varInsnEqual((VarInsnNode) node1, (VarInsnNode) node2);
case TYPE_INSN:
return typeInsnEqual((TypeInsnNode) node1, (TypeInsnNode) node2);
case FIELD_INSN:
return fieldInsnEqual((FieldInsnNode) node1, (FieldInsnNode) node2);
case METHOD_INSN:
return methodInsnEqual((MethodInsnNode) node1, (MethodInsnNode) node2);
case LDC_INSN:
return ldcInsnEqual((LdcInsnNode) node1, (LdcInsnNode) node2);
case IINC_INSN:
return iincInsnEqual((IincInsnNode) node1, (IincInsnNode) node2);
case INT_INSN:
return intInsnEqual((IntInsnNode) node1, (IntInsnNode) node2);
default:
return true;
}
}
public static AbstractInsnNode getPushInstruction(int value) {
if (value == -1) {
return new InsnNode(Opcodes.ICONST_M1);
} else if (value == 0) {
return new InsnNode(Opcodes.ICONST_0);
} else if (value == 1) {
return new InsnNode(Opcodes.ICONST_1);
} else if (value == 2) {
return new InsnNode(Opcodes.ICONST_2);
} else if (value == 3) {
return new InsnNode(Opcodes.ICONST_3);
} else if (value == 4) {
return new InsnNode(Opcodes.ICONST_4);
} else if (value == 5) {
return new InsnNode(Opcodes.ICONST_5);
} else if ((value >= -128) && (value <= 127)) {
return new IntInsnNode(Opcodes.BIPUSH, value);
} else if ((value >= -32768) && (value <= 32767)) {
return new IntInsnNode(Opcodes.SIPUSH, value);
} else {
return new LdcInsnNode(value);
}
}
/**
* Get the integer value of a InsnNode.
*
* @param ain
* @return
*/
public static int getIntValue(AbstractInsnNode ain) {
int opcode = ain.getOpcode();
if (opcode >= Opcodes.ICONST_M1 && opcode <= Opcodes.ICONST_5) {
return getIntValue(opcode);
} else {
return ((IntInsnNode) ain).operand;
}
}
@Override
protected void process(MethodContext context, IntInsnNode node) {
props.put("operand", String.valueOf(node.operand));
if (node.getOpcode() == Opcodes.NEWARRAY) {
instructionName += "_" + node.operand;
}
}
@Override
public IntInsnNode deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = (JsonObject) json;
int opcode, operand;
opcode = jsonObject.get("opcode").getAsInt();
operand = jsonObject.get("operand").getAsInt();
return new IntInsnNode(opcode, operand);
}
@Override
public JsonElement serialize(IntInsnNode src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.add("opcode", context.serialize(src.getOpcode(), Integer.class));
jsonObject.add("operand", context.serialize(src.operand, Integer.class));
return jsonObject;
}
/**
* Translate a single {@link AbstractInsnNode} to an {@link InstructionFilter}.
* @param ain Instruction to convert.
* @return A filter an an equivilent to the inputted instruction.
*/
public static InstructionFilter translate(AbstractInsnNode ain) {
if (ain instanceof LdcInsnNode) {
return new LdcInstructionFilter(((LdcInsnNode) ain).cst);
} else if (ain instanceof TypeInsnNode) {
return new TypeInstructionFilter(ain.getOpcode(), ((TypeInsnNode) ain).desc);
} else if (ain instanceof FieldInsnNode) {
return new FieldInstructionFilter(ain.getOpcode(), ((FieldInsnNode) ain).owner, ((FieldInsnNode) ain).name, ((FieldInsnNode) ain).desc);
} else if (ain instanceof MethodInsnNode) {
return new MethodInstructionFilter(ain.getOpcode(), ((MethodInsnNode) ain).owner, ((MethodInsnNode) ain).name, ((MethodInsnNode) ain).desc);
} else if (ain instanceof VarInsnNode) {
return new VarInstructionFilter(ain.getOpcode(), ((VarInsnNode) ain).var);
} else if (ain instanceof InsnNode) {
return new InsnInstructionFilter(ain.getOpcode());
} else if (ain instanceof IincInsnNode) {
return new IincInstructionFilter(((IincInsnNode) ain).incr, ((IincInsnNode) ain).var);
} else if (ain instanceof JumpInsnNode) {
return new JumpInstructionFilter(ain.getOpcode());
} else if (ain instanceof LabelNode) {
return InstructionFilter.ACCEPT_ALL; // TODO: Cache labels and check. // TODO: That's a fucking stupid idea.
} else if (ain instanceof MultiANewArrayInsnNode) {
return new MultiANewArrayInstructionFilter(((MultiANewArrayInsnNode) ain).desc, ((MultiANewArrayInsnNode) ain).dims);
} else if(ain instanceof IntInsnNode) {
return new IntInstructionFilter((IntInsnNode) ain);
} else {
return InstructionFilter.ACCEPT_ALL;
}
}
@Override
public boolean accept(AbstractInsnNode t) {
if (!(t instanceof IntInsnNode))
return false;
if (!opcodeFilter.accept(t))
return false;
IntInsnNode fin = (IntInsnNode) t;
if (!numberFilter.accept(fin.operand))
return false;
return true;
}
/**
* Get the integer value of a InsnNode.
*
* @param ain
* @return
*/
public static int getIntValue(AbstractInsnNode ain) {
int opcode = ain.getOpcode();
if (opcode >= Opcodes.ICONST_M1 && opcode <= Opcodes.ICONST_5) {
return getIntValue(opcode);
} else {
return ((IntInsnNode) ain).operand;
}
}
public static AbstractInsnNode generateIntPush(int i) {
if (i <= 5 && i >= -1) {
return new InsnNode(i + 3); //iconst_i
}
if (i >= -128 && i <= 127) {
return new IntInsnNode(BIPUSH, i);
}
if (i >= -32768 && i <= 32767) {
return new IntInsnNode(SIPUSH, i);
}
return new LdcInsnNode(i);
}
public static int getIntValue(AbstractInsnNode node) {
if (node.getOpcode() >= ICONST_M1 && node.getOpcode() <= ICONST_5) {
return node.getOpcode() - 3;
}
if (node.getOpcode() == SIPUSH || node.getOpcode() == BIPUSH) {
return ((IntInsnNode) node).operand;
}
if(node instanceof LdcInsnNode) {
LdcInsnNode ldc = (LdcInsnNode) node;
return Integer.parseInt(ldc.cst.toString());
}
return 0;
}
public static AbstractInsnNode getNumberInsn(int number) {
if (number >= -1 && number <= 5)
return new InsnNode(number + 3);
else if (number >= -128 && number <= 127)
return new IntInsnNode(Opcodes.BIPUSH, number);
else if (number >= -32768 && number <= 32767)
return new IntInsnNode(Opcodes.SIPUSH, number);
else
return new LdcInsnNode(number);
}
public static int getIntegerFromInsn(AbstractInsnNode insn) {
int opcode = insn.getOpcode();
if (opcode >= Opcodes.ICONST_M1 && opcode <= Opcodes.ICONST_5) {
return opcode - 3;
} else if (insn instanceof IntInsnNode
&& insn.getOpcode() != Opcodes.NEWARRAY) {
return ((IntInsnNode) insn).operand;
} else if (insn instanceof LdcInsnNode
&& ((LdcInsnNode) insn).cst instanceof Integer) {
return (Integer) ((LdcInsnNode) insn).cst;
}
throw new RadonException("Unexpected instruction");
}
@Test
public void testGetIntegerFromInsn() {
Assert.assertEquals(Opcodes.ACONST_NULL,
ASMUtils.getIntegerFromInsn(new InsnNode(Opcodes.ICONST_1)));
Assert.assertEquals(Opcodes.ACONST_NULL,
ASMUtils.getIntegerFromInsn(new IntInsnNode(Opcodes.ICONST_1, 1)));
Assert.assertEquals(Opcodes.ACONST_NULL,
ASMUtils.getIntegerFromInsn(new LdcInsnNode(Opcodes.ACONST_NULL)));
thrown.expect(RadonException.class);
ASMUtils.getIntegerFromInsn(new InsnNode(Opcodes.NOP));
}
@Override
protected void add(@NonNull AbstractInsnNode from, @NonNull AbstractInsnNode to) {
if (from.getType() == AbstractInsnNode.JUMP_INSN &&
from.getPrevious() != null &&
from.getPrevious().getType() == AbstractInsnNode.INT_INSN) {
IntInsnNode intNode = (IntInsnNode) from.getPrevious();
if (intNode.getPrevious() != null && isSdkVersionLookup(intNode.getPrevious())) {
JumpInsnNode jumpNode = (JumpInsnNode) from;
int api = intNode.operand;
boolean isJumpEdge = to == jumpNode.label;
boolean includeEdge;
switch (from.getOpcode()) {
case Opcodes.IF_ICMPNE:
includeEdge = api < mRequiredApi || isJumpEdge;
break;
case Opcodes.IF_ICMPLE:
includeEdge = api < mRequiredApi - 1 || isJumpEdge;
break;
case Opcodes.IF_ICMPLT:
includeEdge = api < mRequiredApi || isJumpEdge;
break;
case Opcodes.IF_ICMPGE:
includeEdge = api < mRequiredApi || !isJumpEdge;
break;
case Opcodes.IF_ICMPGT:
includeEdge = api < mRequiredApi - 1 || !isJumpEdge;
break;
default:
// unexpected comparison for int API level
includeEdge = true;
}
if (!includeEdge) {
return;
}
}
}
super.add(from, to);
}
/**
* Get the integer value of a InsnNode.
*
* @param ain
* @return
*/
public static int getIntValue(AbstractInsnNode ain) {
int opcode = ain.getOpcode();
if (opcode >= Opcodes.ICONST_M1 && opcode <= Opcodes.ICONST_5) {
return getIntValue(opcode);
} else {
return ((IntInsnNode) ain).operand;
}
}
@Override
public AbstractInsnNode tryMatch(InstructionMatcher matcher, AbstractInsnNode now) {
if (now.getOpcode() == Opcodes.NEWARRAY && now instanceof IntInsnNode) {
if (this.sorts.contains(((IntInsnNode) now).operand)) {
return now.getNext();
}
}
return null;
}
public static void intInsnNode(ListIterator<AbstractInsnNode> iterator, int i) {
if (i >=0 && i < 6) {
// int ICONST_0 = 3; // -
// int ICONST_1 = 4; // -
// int ICONST_2 = 5; // -
// int ICONST_3 = 6; // -
// int ICONST_4 = 7; // -
// int ICONST_5 = 8; // -
iterator.add(new InsnNode(Opcodes.ICONST_0 + i));
} else {
iterator.add(new IntInsnNode(Opcodes.BIPUSH, i));
}
}
public void extractFrom(ImagineASM asm, InsnList list) {
//Pair<String, String> fieldChunkProvider = asm.field("net/minecraft/world/World", "chunkProvider");
list.clear();
list.add(new IntInsnNode(ALOAD, 1));
list.add(new FieldInsnNode(GETFIELD, "ahb", "v", "Lapu;"));
list.add(new InsnNode(ARETURN));
}
public static void intInsnNode(ListIterator<AbstractInsnNode> iterator, int i) {
if (i >=0 && i < 6) {
// int ICONST_0 = 3; // -
// int ICONST_1 = 4; // -
// int ICONST_2 = 5; // -
// int ICONST_3 = 6; // -
// int ICONST_4 = 7; // -
// int ICONST_5 = 8; // -
iterator.add(new InsnNode(Opcodes.ICONST_0 + i));
} else {
iterator.add(new IntInsnNode(Opcodes.BIPUSH, i));
}
}
/**
* Deciding factors for Anonymous object creation 1) The current method is init e.g. new MyClass() 2) The current method is valueOf and its
* previous node is LDC, IntInsn, or Insn e.g new Double(23.3), 123, false
*/
public static boolean isAnonymousInitialization(MethodInsnNode min) {
AbstractInsnNode previousNode = min.getPrevious();
if ("<init>".equals(min.name)){
return true;
}
if ("valueOf".equals(min.name) && (previousNode instanceof LdcInsnNode) || (previousNode instanceof IntInsnNode)
|| (previousNode instanceof InsnNode)){
return true;
}
return false;
}
/**
* Respects {@link #INT_WILDCARD} and {@link #WILDCARD} instruction properties.
* Always returns true if {@code a} and {@code b} are label, line number, or frame instructions.
*
* @return Whether or not the given instructions are equivalent.
*/
public boolean areInsnsEqual(AbstractInsnNode a, AbstractInsnNode b)
{
if (a == b)
return true;
if (a == null || b == null)
return false;
if (a.equals(b))
return true;
if (a.getOpcode() != b.getOpcode())
return false;
switch (a.getType())
{
case AbstractInsnNode.VAR_INSN:
return areVarInsnsEqual((VarInsnNode) a, (VarInsnNode) b);
case AbstractInsnNode.TYPE_INSN:
return areTypeInsnsEqual((TypeInsnNode) a, (TypeInsnNode) b);
case AbstractInsnNode.FIELD_INSN:
return areFieldInsnsEqual((FieldInsnNode) a, (FieldInsnNode) b);
case AbstractInsnNode.METHOD_INSN:
return areMethodInsnsEqual((MethodInsnNode) a, (MethodInsnNode) b);
case AbstractInsnNode.LDC_INSN:
return areLdcInsnsEqual((LdcInsnNode) a, (LdcInsnNode) b);
case AbstractInsnNode.IINC_INSN:
return areIincInsnsEqual((IincInsnNode) a, (IincInsnNode) b);
case AbstractInsnNode.INT_INSN:
return areIntInsnsEqual((IntInsnNode) a, (IntInsnNode) b);
default:
return true;
}
}
void push(InsnList insnList, final int value) {
if (value >= -1 && value <= 5) {
insnList.add(new InsnNode(Opcodes.ICONST_0 + value));
} else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
insnList.add(new IntInsnNode(Opcodes.BIPUSH, value));
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
insnList.add(new IntInsnNode(Opcodes.SIPUSH, value));
} else {
insnList.add(new LdcInsnNode(value));
}
}