下面列出了org.objectweb.asm.tree.IincInsnNode#org.objectweb.asm.tree.InsnNode 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Generates instruction to exit all monitors in the {@link LockState} object sitting in the lockstate variable.
* @param markerType debug marker type
* @param lockVars variables for lock/synchpoint functionality
* @return instructions to exit all monitors in the {@link LockState} object
* @throws NullPointerException if any argument is {@code null}
* @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions)
*/
public static InsnList exitStoredMonitors(MarkerType markerType, LockVariables lockVars) {
Validate.notNull(markerType);
Validate.notNull(lockVars);
Variable lockStateVar = lockVars.getLockStateVar();
Variable counterVar = lockVars.getCounterVar();
Variable arrayLenVar = lockVars.getArrayLenVar();
Validate.isTrue(lockStateVar != null);
Validate.isTrue(counterVar != null);
Validate.isTrue(arrayLenVar != null);
return forEach(counterVar, arrayLenVar,
merge(
debugMarker(markerType, "Loading monitors to exit"),
call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar))
),
merge(
debugMarker(markerType, "Exitting monitor"),
new InsnNode(Opcodes.MONITOREXIT)
)
);
}
/**
* 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 void addFeatureGetSet() {
for (boolean isGet : GET_SET) {
MethodNode mn = new MethodNode(ASM5, ACC_PUBLIC, // Get for non-array value
fi.getGetterSetterName(isGet),
isGet ? ("()" + rangeJavaDescriptor)
: "(" + rangeJavaDescriptor + ")V",
null, null);
InsnList il = mn.instructions;
il.add(new VarInsnNode(ALOAD, 0));
if (isGet) {
il.add(new FieldInsnNode(GETFIELD, typeJavaClassName, featureFieldName, rangeJavaDescriptor));
il.add(new InsnNode(getReturnInst(fi)));
} else {
il.add(new VarInsnNode(getLoadInst(fi), 1)); // load ref, or primitive value
il.add(new FieldInsnNode(PUTFIELD, typeJavaClassName, featureFieldName, rangeJavaDescriptor));
il.add(new InsnNode(RETURN));
}
final boolean is2slotValue = ((TypeImpl) fi.getRange()).isLongOrDouble();
mn.maxStack = isGet ? 1 : is2slotValue ? 3 : 2;
mn.maxLocals = isGet ? 1 : is2slotValue ? 3 : 2;
cn.methods.add(mn);
}
}
public static void returnNode(ListIterator<AbstractInsnNode> iterator, String paramType) {
//(Ljava/lang/String;IDCBSJZF)V
if ("I".equals(paramType)
|| "C".equals(paramType)
|| "B".equals(paramType)
|| "S".equals(paramType)
|| "Z".equals(paramType)
) {
iterator.add(new InsnNode(Opcodes.IRETURN));
} else if ("J".equals(paramType)) {
iterator.add(new InsnNode(Opcodes.LRETURN));
} else if ("F".equals(paramType)) {
iterator.add(new InsnNode(Opcodes.FRETURN));
} else if ("D".equals(paramType)) {
iterator.add(new InsnNode(Opcodes.DRETURN));
} else if ("V".equals(paramType)) {
iterator.add(new InsnNode(Opcodes.RETURN));
} else {
iterator.add(new InsnNode(Opcodes.ARETURN));
}
}
/**
* Injects a constant modifier at an implied-zero
*
* @param target target method
* @param jumpNode jump instruction (must be IFLT, IFGE, IFGT or IFLE)
*/
private void injectExpandedConstantModifier(Target target, JumpInsnNode jumpNode) {
int opcode = jumpNode.getOpcode();
if (opcode < Opcodes.IFLT || opcode > Opcodes.IFLE) {
throw new InvalidInjectionException(this.info, String.format("%s annotation selected an invalid opcode %s in %s in %s",
this.annotationType, Bytecode.getOpcodeName(opcode), target, this));
}
Extension extraStack = target.extendStack();
final InsnList insns = new InsnList();
insns.add(new InsnNode(Opcodes.ICONST_0));
AbstractInsnNode invoke = this.invokeConstantHandler(Type.getType("I"), target, extraStack, insns, insns);
insns.add(new JumpInsnNode(opcode + ModifyConstantInjector.OPCODE_OFFSET, jumpNode.label));
extraStack.add(1).apply();
target.replaceNode(jumpNode, invoke, insns);
}
/**
* Generates instruction to enter all monitors in the {@link LockState} object sitting in the lockstate variable.
* @param markerType debug marker type
* @param lockVars variables for lock/synchpoint functionality
* @return instructions to enter all monitors in the {@link LockState} object
* @throws NullPointerException if any argument is {@code null}
* @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions)
*/
public static InsnList enterStoredMonitors(MarkerType markerType, LockVariables lockVars) {
Validate.notNull(markerType);
Validate.notNull(lockVars);
Variable lockStateVar = lockVars.getLockStateVar();
Variable counterVar = lockVars.getCounterVar();
Variable arrayLenVar = lockVars.getArrayLenVar();
Validate.isTrue(lockStateVar != null);
Validate.isTrue(counterVar != null);
Validate.isTrue(arrayLenVar != null);
return forEach(counterVar, arrayLenVar,
merge(
debugMarker(markerType, "Loading monitors to enter"),
call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar))
),
merge(
debugMarker(markerType, "Entering monitor"),
new InsnNode(Opcodes.MONITORENTER)
)
);
}
@Inject(description = "Add hook before everything")
public void inject(MethodNode method) {
AbstractInsnNode node = method.instructions.getFirst();
Objects.requireNonNull(node, "Failed to find node.");
LabelNode label = new LabelNode();
InsnList list = new InsnList();
list.add(new VarInsnNode(ALOAD, 1)); // enum
list.add(new VarInsnNode(ALOAD, 2)); // blockpos
list.add(ASMHelper.call(INVOKESTATIC, TypesHook.Methods.ForgeHaxHooks_onWorldCheckLightFor));
list.add(new JumpInsnNode(IFEQ, label));
list.add(new InsnNode(ICONST_0));
list.add(new InsnNode(IRETURN));
list.add(label);
method.instructions.insertBefore(node, list);
}
@Inject(description = "Add hook to override returned value of isRowingBoat")
public void inject(MethodNode main) {
AbstractInsnNode preNode = main.instructions.getFirst();
Objects.requireNonNull(preNode, "Find pattern failed for pre node");
LabelNode jump = new LabelNode();
InsnList insnPre = new InsnList();
// insnPre.add(ASMHelper.call(GETSTATIC,
// TypesHook.Fields.ForgeHaxHooks_isNotRowingBoatActivated));
// insnPre.add(new JumpInsnNode(IFEQ, jump));
insnPre.add(new InsnNode(ICONST_0));
insnPre.add(new InsnNode(IRETURN)); // return false
// insnPre.add(jump);
main.instructions.insert(insnPre);
}
private int addMethodParametersVariable(InsnList il) {
il.add(TreeInstructions.getPushInstruction(this.methodArguments.length));
il.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));
int methodParametersIndex = getFistAvailablePosition();
il.add(new VarInsnNode(Opcodes.ASTORE, methodParametersIndex));
this.mn.maxLocals++;
for (int i = 0; i < this.methodArguments.length; i++) {
il.add(new VarInsnNode(Opcodes.ALOAD, methodParametersIndex));
il.add(TreeInstructions.getPushInstruction(i));
il.add(TreeInstructions.getLoadInst(methodArguments[i],
getArgumentPosition(i)));
MethodInsnNode mNode = TreeInstructions
.getWrapperContructionInst(methodArguments[i]);
if (mNode != null) {
il.add(mNode);
}
il.add(new InsnNode(Opcodes.AASTORE));
}
return methodParametersIndex;
}
private void addArrayFeatureGetSet() {
for (boolean isGet : GET_SET) {
MethodNode mn = new MethodNode(ASM5, ACC_PUBLIC,
fi.getGetterSetterName(isGet),
isGet ? "(I)" + rangeArrayElementJavaDescriptor
: "(I" + rangeArrayElementJavaDescriptor + ")V",
null, null);
InsnList il = mn.instructions;
il.add(new VarInsnNode(ALOAD, 0));
il.add(new FieldInsnNode(GETFIELD, typeJavaClassName, featureFieldName, rangeJavaDescriptor));
il.add(new VarInsnNode(ILOAD, 1));
if (isGet) {
il.add(new InsnNode(getArrayLoadInst(fi)));
il.add(new InsnNode(getReturnInst(fi)));
} else {
il.add(new VarInsnNode(getArrayLoadInst(fi), 2)); // load the value to be set into the array slot
il.add(new InsnNode(getArrayStoreInst(fi)));
il.add(new InsnNode(RETURN));
}
final boolean is2slotValue = ((TypeImpl) fi.getRange()).isLongOrDouble();
mn.maxStack = isGet ? 2 : (is2slotValue ? 4 : 3);
mn.maxLocals = isGet ? 2 : (is2slotValue ? 4 : 3);
cn.methods.add(mn);
}
}
@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
boolean found = false;
// RETURN opcode varies based on return type, thus we calculate what opcode we're actually looking for by inspecting the target method
int returnOpcode = Type.getReturnType(desc).getOpcode(Opcodes.IRETURN);
int ordinal = 0;
ListIterator<AbstractInsnNode> iter = insns.iterator();
while (iter.hasNext()) {
AbstractInsnNode insn = iter.next();
if (insn instanceof InsnNode && insn.getOpcode() == returnOpcode) {
if (this.ordinal == -1 || this.ordinal == ordinal) {
nodes.add(insn);
found = true;
}
ordinal++;
}
}
return found;
}
private InsnList getInstList(String owner, String name, String descriptor) {
InsnList insnList = new InsnList();
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, owner, name, descriptor, false));
LabelNode jumpNode = new LabelNode();
insnList.add(new JumpInsnNode(Opcodes.IFEQ, jumpNode));
insnList.add(new InsnNode(Opcodes.RETURN));
insnList.add(jumpNode);
return insnList;
}
@Override
public MethodNode generate() {
MethodNode method = this.createMethod(this.targetType.getSize(), this.targetType.getSize());
if (!this.targetIsStatic) {
method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
}
int opcode = this.targetIsStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD;
method.instructions.add(new FieldInsnNode(opcode, this.info.getClassNode().name, this.targetField.name, this.targetField.desc));
method.instructions.add(new InsnNode(this.targetType.getOpcode(Opcodes.IRETURN)));
return method;
}
private static void createProxy(MethodNode methodNode, ClassInfo targetClass, Method method) {
methodNode.access |= Opcodes.ACC_SYNTHETIC;
methodNode.instructions.clear();
Type[] args = Type.getArgumentTypes(methodNode.desc);
Type returnType = Type.getReturnType(methodNode.desc);
Bytecode.loadArgs(args, methodNode.instructions, 0);
methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, targetClass.getName(), method.getName(), methodNode.desc, false));
methodNode.instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN)));
methodNode.maxStack = Bytecode.getFirstNonArgLocalIndex(args, false);
methodNode.maxLocals = 0;
}
@Override
public EvaluationFunctor<Number> compare(Type lt, Type rt, ComparisonExpr.ValueComparisonType type) {
String name = lt.getClassName() + type.name() + rt.getClassName() + "RETint";
if(cache.containsKey(name)) {
return _get(name);
}
String desc = "(" + lt.getDescriptor() + rt.getDescriptor() + ")I";
MethodNode m = makeBase(name, desc);
{
Type opType = TypeUtils.resolveBinOpType(lt, rt);
InsnList insns = new InsnList();
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(lt), 0));
cast(insns, lt, opType);
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(rt), lt.getSize()));
cast(insns, rt, opType);
int op;
if (opType == Type.DOUBLE_TYPE) {
op = type == ComparisonExpr.ValueComparisonType.GT ? Opcodes.DCMPG : Opcodes.DCMPL;
} else if (opType == Type.FLOAT_TYPE) {
op = type == ComparisonExpr.ValueComparisonType.GT ? Opcodes.FCMPG : Opcodes.FCMPL;
} else if (opType == Type.LONG_TYPE) {
op = Opcodes.LCMP;
} else {
throw new IllegalArgumentException();
}
insns.add(new InsnNode(op));
insns.add(new InsnNode(Opcodes.IRETURN));
m.node.instructions = insns;
}
return buildBridge(m);
}
void box(final InsnList instructions, Type type) {
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return;
}
if (type == Type.VOID_TYPE) {
// push null
instructions.add(new InsnNode(Opcodes.ACONST_NULL));
} else {
Type boxed = getBoxedType(type);
// new instance.
newInstance(instructions, boxed);
if (type.getSize() == 2) {
// Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
// dupX2
dupX2(instructions);
// dupX2
dupX2(instructions);
// pop
pop(instructions);
} else {
// p -> po -> opo -> oop -> o
// dupX1
dupX1(instructions);
// swap
swap(instructions);
}
invokeConstructor(instructions, boxed, new Method("<init>", Type.VOID_TYPE, new Type[]{type}));
}
}
/**
* 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;
}
}
protected void writePushUses(Collection<ArgumentStmtToken> parameters){
if (parameters.isEmpty()){
add(new InsnNode(ACONST_NULL));
expr.stackPush(Memory.Type.REFERENCE);
return;
}
expr.writePushSmallInt(parameters.size());
add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Memory.class)));
expr.stackPop();
expr.stackPush(Memory.Type.REFERENCE);
int i = 0;
for(ArgumentStmtToken param : parameters){
expr.writePushDup();
expr.writePushSmallInt(i);
LocalVariable local = method.getLocalVariable(param.getName().getName());
if (local == null)
expr.writePushNull();
else
expr.writeVarLoad(local);
if (!param.isReference())
expr.writePopBoxing(true);
add(new InsnNode(AASTORE));
expr.stackPop();
expr.stackPop();
expr.stackPop();
i++;
}
}
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));
}
}
/**
* 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 {
return InstructionFilter.ACCEPT_ALL;
}
}
private InsnList generateCheck() {
LabelNode notDebugLabel = new LabelNode();
InsnList insnList = new InsnList();
insnList.add(createIsDebugList());
insnList.add(new JumpInsnNode(IFEQ, notDebugLabel));
if (RandomUtils.getRandomBoolean()) {
if (getMessage() != null) {
insnList.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
insnList.add(new LdcInsnNode(getMessage()));
insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false));
}
if (RandomUtils.getRandomBoolean()) {
insnList.add(new LdcInsnNode(RandomUtils.getRandomInt()));
insnList.add(new MethodInsnNode(INVOKESTATIC, "java/lang/System", "exit", "(I)V", false));
} else {
insnList.add(new MethodInsnNode(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false));
insnList.add(new LdcInsnNode(RandomUtils.getRandomInt()));
insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "java/lang/Runtime", "halt", "(I)V", false));
}
} else {
String message = getMessage();
if (message == null)
message = randomString();
insnList.add(new TypeInsnNode(NEW, "java/lang/RuntimeException"));
insnList.add(new InsnNode(DUP));
insnList.add(new LdcInsnNode(message));
insnList.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false));
insnList.add(new InsnNode(ATHROW));
}
insnList.add(notDebugLabel);
return insnList;
}
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 AbstractInsnNode getNumberInsn(float number) {
if (number >= 0 && number <= 2) {
return new InsnNode((int) (number + 11));
} else {
return new LdcInsnNode(number);
}
}
@Test
public void testGetDoubleFromInsn() {
Assert.assertEquals((double) Opcodes.NOP,
ASMUtils.getDoubleFromInsn(new InsnNode(Opcodes.DCONST_0)), 0);
Assert.assertEquals((double) Opcodes.ACONST_NULL,
ASMUtils.getDoubleFromInsn(new LdcInsnNode(1.0)), 0);
thrown.expect(RadonException.class);
ASMUtils.getDoubleFromInsn(new InsnNode(Opcodes.NOP));
}
private void createAndFireEvent(
MethodNode method, AbstractInsnNode location, int variableIndex, int nameIndex) {
final InsnList list = new InsnList();
// arguments
InsnList eventObjectArgs = new InsnList();
eventObjectArgs.add(new VarInsnNode(ALOAD, nameIndex));
eventObjectArgs.add(new LdcInsnNode(-1)); // TODO: get original value
list.add(
ASMHelper.newInstance(
Type.getInternalName(RenderTabNameEvent.class),
"(Ljava/lang/String;I)V",
eventObjectArgs));
list.add(new InsnNode(DUP)); // for firing event
list.add(new InsnNode(DUP)); // for getName
list.add(new VarInsnNode(ASTORE, variableIndex));
list.add(ASMHelper.call(INVOKESTATIC, TypesHook.Methods.ForgeHaxHooks_fireEvent_v));
list.add(
new MethodInsnNode(
INVOKEVIRTUAL,
Type.getInternalName(RenderTabNameEvent.class),
"getName",
"()Ljava/lang/String;"));
list.add(new VarInsnNode(ASTORE, nameIndex));
method.instructions.insert(location, list);
}
public static InsnList newInstance(String name, String desc, @Nullable InsnList args) {
InsnList list = new InsnList();
list.add(new TypeInsnNode(NEW, name));
list.add(new InsnNode(DUP));
if (args != null) {
list.add(args);
}
list.add(new MethodInsnNode(INVOKESPECIAL, name, "<init>", desc, false));
return list;
}
/**
* Adds two integers together and puts the result on to the stack.
* @param lhs instructions to generate the first operand -- must leave an int on the stack
* @param rhs instructions to generate the second operand -- must leave an int on the stack
* @return instructions to add the two numbers together -- will leave an int on the stack
* @throws NullPointerException if any argument is {@code null}
*/
public static InsnList addIntegers(InsnList lhs, InsnList rhs) {
Validate.notNull(lhs);
Validate.notNull(rhs);
InsnList ret = new InsnList();
ret.add(lhs);
ret.add(rhs);
ret.add(new InsnNode(Opcodes.IADD));
return ret;
}
void push(InsnList insnList, final String value) {
if (value == null) {
insnList.add(new InsnNode(Opcodes.ACONST_NULL));
} else {
insnList.add(new LdcInsnNode(value));
}
}
private void convertReturnInsn(InsnNode insn) {
int op = insn.getOpcode();
boolean dword = op == LRETURN || op == DRETURN;
StackFrame frame = getFrame(insn);
if (!units.containsKey(insn)) {
Operand val = dword ? popImmediateDual() : popImmediate();
ReturnStmt ret = Jimple.v().newReturnStmt(val.stackOrValue());
val.addBox(ret.getOpBox());
frame.in(val);
frame.boxes(ret.getOpBox());
setUnit(insn, ret);
} else {
frame.mergeIn(dword ? popDual() : pop());
}
}
public CodeBlock fmul()
{
instructionList.add(new InsnNode(FMUL));
return this;
}