下面列出了org.objectweb.asm.Opcodes# BIPUSH 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void visitIntInsn(final int opcode, final int operand) {
checkVisitCodeCalled();
checkVisitMaxsNotCalled();
checkOpcodeMethod(opcode, Method.VISIT_INT_INSN);
switch (opcode) {
case Opcodes.BIPUSH:
checkSignedByte(operand, "Invalid operand");
break;
case Opcodes.SIPUSH:
checkSignedShort(operand, "Invalid operand");
break;
case Opcodes.NEWARRAY:
if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
throw new IllegalArgumentException(
"Invalid operand (must be an array type code T_...): " + operand);
}
break;
default:
throw new AssertionError();
}
super.visitIntInsn(opcode, operand);
++insnCount;
}
private static boolean containsSimpleSdkCheck(@NonNull MethodNode method) {
// Look for a compiled version of "if (Build.VERSION.SDK_INT op N) {"
InsnList nodes = method.instructions;
for (int i = 0, n = nodes.size(); i < n; i++) {
AbstractInsnNode instruction = nodes.get(i);
if (isSdkVersionLookup(instruction)) {
AbstractInsnNode bipush = getNextInstruction(instruction);
if (bipush != null && bipush.getOpcode() == Opcodes.BIPUSH) {
AbstractInsnNode ifNode = getNextInstruction(bipush);
if (ifNode != null && ifNode.getType() == AbstractInsnNode.JUMP_INSN) {
return true;
}
}
}
}
return false;
}
/**
* If the supplied instruction is a constant, returns the constant value
* from the instruction
*
* @param insn constant instruction to process
* @return the constant value or <tt>null</tt> if the value cannot be parsed
* (<tt>null</tt> constant is returned as <tt>Type.VOID_TYPE</tt>)
*/
public static Object getConstant(AbstractInsnNode insn) {
if (insn == null) {
return null;
} else if (insn instanceof LdcInsnNode) {
return ((LdcInsnNode)insn).cst;
} else if (insn instanceof IntInsnNode) {
int value = ((IntInsnNode)insn).operand;
if (insn.getOpcode() == Opcodes.BIPUSH || insn.getOpcode() == Opcodes.SIPUSH) {
return Integer.valueOf(value);
}
throw new IllegalArgumentException("IntInsnNode with invalid opcode " + insn.getOpcode() + " in getConstant");
} else if (insn instanceof TypeInsnNode) {
if (insn.getOpcode() < Opcodes.CHECKCAST) {
return null; // Don't treat NEW and ANEWARRAY as constants
}
return Type.getObjectType(((TypeInsnNode)insn).desc);
}
int index = Ints.indexOf(Bytecode.CONSTANTS_ALL, insn.getOpcode());
return index < 0 ? null : Bytecode.CONSTANTS_VALUES[index];
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
checkStartCode();
checkEndCode();
checkOpcode(opcode, 1);
switch (opcode) {
case Opcodes.BIPUSH:
checkSignedByte(operand, "Invalid operand");
break;
case Opcodes.SIPUSH:
checkSignedShort(operand, "Invalid operand");
break;
// case Constants.NEWARRAY:
default:
if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
throw new IllegalArgumentException("Invalid operand (must be an array type code T_...): " + operand);
}
}
super.visitIntInsn(opcode, operand);
++insnCount;
}
/**
* 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 LoadIntStep() {
super((a) ->
{
if(!(a instanceof LdcInsnNode))
return true;
return ((LdcInsnNode)a).cst instanceof Integer;
},Opcodes.ICONST_M1,
Opcodes.ICONST_0,
Opcodes.ICONST_1,
Opcodes.ICONST_2,
Opcodes.ICONST_3,
Opcodes.ICONST_4,
Opcodes.ICONST_5,
Opcodes.LDC,
Opcodes.BIPUSH,
Opcodes.SIPUSH
);
}
public static boolean isInteger(AbstractInsnNode ain)
{
if (ain == null) return false;
if((ain.getOpcode() >= Opcodes.ICONST_M1
&& ain.getOpcode() <= Opcodes.ICONST_5)
|| ain.getOpcode() == Opcodes.SIPUSH
|| ain.getOpcode() == Opcodes.BIPUSH)
return true;
if(ain instanceof LdcInsnNode)
{
LdcInsnNode ldc = (LdcInsnNode)ain;
if(ldc.cst instanceof Integer)
return true;
}
return false;
}
public static int getIntValue(AbstractInsnNode node)
{
if(node.getOpcode() >= Opcodes.ICONST_M1
&& node.getOpcode() <= Opcodes.ICONST_5)
return node.getOpcode() - 3;
if(node.getOpcode() == Opcodes.SIPUSH
|| node.getOpcode() == Opcodes.BIPUSH)
return ((IntInsnNode)node).operand;
if(node instanceof LdcInsnNode)
{
LdcInsnNode ldc = (LdcInsnNode)node;
if(ldc.cst instanceof Integer)
return (int)ldc.cst;
}
return 0;
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
checkVisitCodeCalled();
checkVisitMaxsNotCalled();
checkOpcodeMethod(opcode, Method.VISIT_INT_INSN);
switch (opcode) {
case Opcodes.BIPUSH:
checkSignedByte(operand, "Invalid operand");
break;
case Opcodes.SIPUSH:
checkSignedShort(operand, "Invalid operand");
break;
case Opcodes.NEWARRAY:
if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
throw new IllegalArgumentException(
"Invalid operand (must be an array type code T_...): " + operand);
}
break;
default:
throw new AssertionError();
}
super.visitIntInsn(opcode, operand);
++insnCount;
}
@Override
public void visitInsn(int opcode)
{
if(methodData.hasHookAt(HookPosition.METHOD_END) && opcode >= 172
&& opcode <= 177)
{
HookData hookData = methodData.getHook(HookPosition.METHOD_END);
super.visitLdcInsn(className + "." + methodName + "|end");
if(hookData.collectsParams())
{
super.visitIntInsn(Opcodes.BIPUSH, paramCount);
super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
for(byte i = 0; i < paramCount; i++)
{
super.visitInsn(Opcodes.DUP);
super.visitIntInsn(Opcodes.BIPUSH, i);
super.visitVarInsn(Opcodes.ALOAD, i);
super.visitInsn(Opcodes.AASTORE);
}
}
// TODO: Custom class path
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"tk/wurst_client/hooks/HookManager", "hook",
"(Ljava/lang/String;"
+ (hookData.collectsParams() ? "[Ljava/lang/Object;" : "")
+ ")V", false);
}
super.visitInsn(opcode);
}
public PushIntConst(int value) {
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
useLdcInsn = true;
} else {
useLdcInsn = false;
if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
this.operation = Opcodes.SIPUSH;
} else {
this.operation = Opcodes.BIPUSH;
}
}
this.value = value;
}
@Test
public void test_checkBranch() throws Exception {
List<BasicBlock> hashCodeBlocks = METHOD_BLOCKS.get("checkBranch(I)I");
int[][] expectedHashCodeBlocks = new int[][]{
{Opcodes.ICONST_5, Opcodes.ISTORE, Opcodes.ILOAD, Opcodes.BIPUSH, Opcodes.IF_ICMPLE},
{Opcodes.BIPUSH, Opcodes.ISTORE, Opcodes.GOTO},
{Opcodes.ICONST_4, Opcodes.ISTORE},
{Opcodes.ILOAD, Opcodes.IRETURN},
};
boolean didMatch = compareBlocks(expectedHashCodeBlocks, hashCodeBlocks);
Assert.assertTrue(didMatch);
}
public static boolean isIntInsn(AbstractInsnNode insn) {
if (insn == null) {
return false;
}
int opcode = insn.getOpcode();
return ((opcode >= Opcodes.ICONST_M1 && opcode <= Opcodes.ICONST_5)
|| opcode == Opcodes.BIPUSH
|| opcode == Opcodes.SIPUSH
|| (insn instanceof LdcInsnNode
&& ((LdcInsnNode) insn).cst instanceof Integer));
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
if ((opcode == Opcodes.BIPUSH) || (opcode == Opcodes.SIPUSH)) {
mutate(operand);
} else {
super.visitIntInsn(opcode, operand);
}
}
@Override
public void visitCode()
{
super.visitCode();
if(methodData.hasHookAt(HookPosition.METHOD_START))
{
HookData hookData = methodData.getHook(HookPosition.METHOD_START);
super.visitLdcInsn(className + "." + methodName + "|start");
if(hookData.collectsParams())
{
super.visitIntInsn(Opcodes.BIPUSH, paramCount);
super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
for(byte i = 0; i < paramCount; i++)
{
super.visitInsn(Opcodes.DUP);
super.visitIntInsn(Opcodes.BIPUSH, i);
super.visitVarInsn(Opcodes.ALOAD, i);
super.visitInsn(Opcodes.AASTORE);
}
}
// TODO: Custom class path
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"tk/wurst_client/hooks/HookManager", "hook",
"(Ljava/lang/String;"
+ (hookData.collectsParams() ? "[Ljava/lang/Object;" : "")
+ ")V", false);
}
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
if ((opcode == Opcodes.BIPUSH) || (opcode == Opcodes.SIPUSH)) {
mutate(operand);
} else {
super.visitIntInsn(opcode, operand);
}
}
@Override
public void visitIntInsn(final int opcode, final int operand) {
switch (opcode) {
case Opcodes.BIPUSH:
iconst(operand);
break;
case Opcodes.SIPUSH:
iconst(operand);
break;
case Opcodes.NEWARRAY:
switch (operand) {
case Opcodes.T_BOOLEAN:
newarray(Type.BOOLEAN_TYPE);
break;
case Opcodes.T_CHAR:
newarray(Type.CHAR_TYPE);
break;
case Opcodes.T_BYTE:
newarray(Type.BYTE_TYPE);
break;
case Opcodes.T_SHORT:
newarray(Type.SHORT_TYPE);
break;
case Opcodes.T_INT:
newarray(Type.INT_TYPE);
break;
case Opcodes.T_FLOAT:
newarray(Type.FLOAT_TYPE);
break;
case Opcodes.T_LONG:
newarray(Type.LONG_TYPE);
break;
case Opcodes.T_DOUBLE:
newarray(Type.DOUBLE_TYPE);
break;
default:
throw new IllegalArgumentException();
}
break;
default:
throw new IllegalArgumentException();
}
}
public InsnValue createConstant(AbstractInsnNode insn) throws AnalyzerException {
switch (insn.getOpcode()) {
case Opcodes.ACONST_NULL:
return InsnValue.NULL_REFERENCE_VALUE;
case Opcodes.ICONST_M1:
case Opcodes.ICONST_0:
case Opcodes.ICONST_1:
case Opcodes.ICONST_2:
case Opcodes.ICONST_3:
case Opcodes.ICONST_4:
case Opcodes.ICONST_5:
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
return InsnValue.intValue(insn);
case Opcodes.LCONST_0:
case Opcodes.LCONST_1:
return InsnValue.longValue(insn.getOpcode());
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
return InsnValue.floatValue(insn.getOpcode());
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
return InsnValue.doubleValue(insn.getOpcode());
case Opcodes.LDC:
Object obj = ((LdcInsnNode) insn).cst;
if (obj instanceof Type) {
return new InsnValue((Type) obj);
} else {
Type t = Type.getType(obj.getClass());
int sort = t.getSort();
// Non-included types:
// Type.ARRAY
// Type.VOID
// Type.METHOD
switch (sort) {
case Type.BOOLEAN:
return InsnValue.intValue((int) obj);
case Type.CHAR:
return InsnValue.charValue((char) obj);
case Type.BYTE:
return InsnValue.byteValue((byte) obj);
case Type.SHORT:
return InsnValue.shortValue((short) obj);
case Type.INT:
return InsnValue.intValue((int) obj);
case Type.FLOAT:
return InsnValue.floatValue((float) obj);
case Type.LONG:
return InsnValue.longValue((long) obj);
case Type.DOUBLE:
return InsnValue.doubleValue((double) obj);
case Type.OBJECT:
return new InsnValue(t, obj);
}
return new InsnValue(t);
}
case Opcodes.NEW:
return new InsnValue(Type.getType(((TypeInsnNode) insn).desc));
case Opcodes.JSR:
// TODO: IDK if this is right.
return InsnValue.REFERENCE_VALUE;
}
return null;
}
public IntInsnNode() {
super(Opcodes.BIPUSH);
}
@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");
}