@Override public void visit(UnOp node) { if (node.op() == UnOp.Op.NOT) { il.add(new VarInsnNode(ALOAD, slot(node.arg()))); il.add(ConversionMethods.booleanValueOf()); il.add(new InsnNode(ICONST_1)); il.add(new InsnNode(IXOR)); il.add(BoxedPrimitivesMethods.box(Type.BOOLEAN_TYPE, Type.getType(Boolean.class))); } else { ResumptionPoint rp = newResumptionPoint(); il.add(rp.save()); il.add(loadExecutionContext()); il.add(new VarInsnNode(ALOAD, slot(node.arg()))); il.add(DispatchMethods.dynamic(dispatchMethodName(node.op()), 1)); il.add(rp.resume()); il.add(retrieve_0()); } il.add(new VarInsnNode(ASTORE, slot(node.dest()))); }
private void staticCpuWithdraw(int cost) { switch (context.compilerSettings.cpuAccountingMode()) { case NO_CPU_ACCOUNTING: { // no-op break; } case IN_EVERY_BASIC_BLOCK: { ResumptionPoint rp = newResumptionPoint(); il.add(rp.save()); il.add(loadExecutionContext()); il.add(new InsnNode(DUP)); il.add(ASMUtils.loadInt(cost)); il.add(ExecutionContextMethods.registerTicks()); il.add(ExecutionContextMethods.checkCallYield()); il.add(rp.resume()); break; } default: throw new UnsupportedOperationException( "Unsupported CPU accounting mode: " + context.compilerSettings.cpuAccountingMode()); } }
protected InsnList resumptionHandler(LabelNode label) { InsnList il = new InsnList(); il.add(label); il.add(ASMUtils.frameSame1(UnresolvedControlThrowable.class)); il.add(createSnapshot()); // register snapshot with the control exception il.add(new MethodInsnNode( INVOKEVIRTUAL, Type.getInternalName(UnresolvedControlThrowable.class), "resolve", Type.getMethodType( Type.getType(ResolvedControlThrowable.class), Type.getType(Resumable.class), Type.getType(Object.class)).getDescriptor(), false)); // rethrow il.add(new InsnNode(ATHROW)); return il; }
@Override public void transform(ClassNode clazz, MethodNode method, InsnMatcher matcher) { method.tryCatchBlocks.clear(); method.localVariables.clear(); method.instructions.clear(); /* this.loginHandlerList.put(SteamIdAsString, loginHandler); */ method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, "com/wurmonline/server/steam/SteamHandler", "loginHandlerList", "Ljava/util/Map;")); method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1)); method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2)); method.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true)); method.instructions.add(new InsnNode(Opcodes.POP)); /* return true; */ method.instructions.add(new InsnNode(Opcodes.ICONST_1)); method.instructions.add(new InsnNode(Opcodes.IRETURN)); }
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); } } }
private void convertArrayLoadInsn(InsnNode insn) { StackFrame frame = getFrame(insn); Operand[] out = frame.out(); Operand opr; if (out == null) { Operand indx = popImmediate(); Operand base = popImmediate(); ArrayRef ar = Jimple.v().newArrayRef( base.stackOrValue(), indx.stackOrValue()); indx.addBox(ar.getIndexBox()); base.addBox(ar.getBaseBox()); opr = new Operand(insn, ar); frame.in(indx, base); frame.boxes(ar.getIndexBox(), ar.getBaseBox()); frame.out(opr); } else { opr = out[0]; frame.mergeIn(pop(), pop()); } int op = insn.getOpcode(); if (op == DALOAD || op == LALOAD) pushDual(opr); else push(opr); }
private void convertArrayStoreInsn(InsnNode insn) { int op = insn.getOpcode(); boolean dword = op == LASTORE || op == DASTORE; StackFrame frame = getFrame(insn); if (!units.containsKey(insn)) { Operand valu = dword ? popImmediateDual() : popImmediate(); Operand indx = popImmediate(); Operand base = popLocal(); ArrayRef ar = Jimple.v().newArrayRef( base.stackOrValue(), indx.stackOrValue()); indx.addBox(ar.getIndexBox()); base.addBox(ar.getBaseBox()); AssignStmt as = Jimple.v().newAssignStmt(ar, valu.stackOrValue()); valu.addBox(as.getRightOpBox()); frame.in(valu, indx, base); frame.boxes(as.getRightOpBox(), ar.getIndexBox(), ar.getBaseBox()); setUnit(insn, as); } else { frame.mergeIn(dword ? popDual() : pop(), pop(), pop()); } }
/** Test. */ @Test public void testNonEmptyFilter() throws Exception { final String className = SampleClass.class.getName(); IMethodFilter filter = new EmptyMethodFilter(); MethodNode methodNode; methodNode = new MethodNode(); methodNode.instructions = new InsnList(); methodNode.instructions.add(new InsnNode(Opcodes.NOP)); methodNode.maxLocals = 0; methodNode.maxStack = 0; assertFalse(analyze(filter, className, "empty", "()V", methodNode)); methodNode = new MethodNode(); methodNode.instructions = new InsnList(); methodNode.instructions.add(new InsnNode(Opcodes.ICONST_1)); methodNode.instructions.add(new InsnNode(Opcodes.IRETURN)); methodNode.maxLocals = 0; methodNode.maxStack = 1; assertTrue(analyze(filter, className, "returnTrue", "()Z", methodNode)); }
static AbstractInsnNode getDefaultLdcNode(Type type) { switch (type.getSort()) { case Type.INT: return getIntNode(0); case Type.BOOLEAN: return new LdcInsnNode(false); case Type.BYTE: return new LdcInsnNode((byte) 0); case Type.SHORT: return new LdcInsnNode((short) 0); case Type.LONG: return new LdcInsnNode(0L); case Type.FLOAT: return new LdcInsnNode(0F); case Type.DOUBLE: return new LdcInsnNode(0D); case Type.CHAR: return new LdcInsnNode((char) 0); default: return new InsnNode(ACONST_NULL); } }
public static void markClinitCallback(ClassNode node, Runnable... runnables) { callback_mapping.get(node.name).addAll(Arrays.asList(runnables)); for (String i : node.interfaces) if (i.equals(CALLBACK_FLAG_DESC)) return; node.interfaces.add(CALLBACK_FLAG_DESC); MethodNode clinit = null; for (MethodNode method : node.methods) if (method.name.equals("<clinit>")) { clinit = method; break; } boolean flag = clinit == null; if (flag) node.methods.add(clinit = new MethodNode(0, "<clinit>", "()V", null, null)); InsnList list = new InsnList(); list.add(new LdcInsnNode(node.name)); list.add(new MethodInsnNode(INVOKESTATIC, "index/alchemy/core/asm/transformer/AlchemyTransformerManager", "callback", "(Ljava/lang/String;)V", false)); if (flag) list.add(new InsnNode(RETURN)); clinit.instructions.insert(list); }
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { ClassReader reader = new ClassReader(basicClass); ClassNode node = new ClassNode(ASM5); reader.accept(node, 0); node.methods.removeIf(m -> !m.name.equals("<init>")); node.methods.stream() .map(m -> m.instructions) .peek(InsnList::clear) .peek(l -> l.add(new VarInsnNode(ALOAD, 0))) .peek(l -> l.add(new MethodInsnNode(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false))) .forEach(l -> l.add(new InsnNode(RETURN))); node.interfaces.clear(); node.superName = "java/lang/Object"; node.innerClasses.clear(); ClassWriter writer = ASMHelper.newClassWriter(0); node.accept(writer); return writer.toByteArray(); }
private void patchMenu(ClassNode node) { Logger.Info("Patching menu (" + node.name + ".class)"); Iterator<MethodNode> methodNodeList = node.methods.iterator(); while (methodNodeList.hasNext()) { MethodNode methodNode = methodNodeList.next(); // Menu swap hook if (methodNode.name.equals("e") && methodNode.desc.equals("(II)V")) { AbstractInsnNode first = methodNode.instructions.getFirst(); LabelNode label = new LabelNode(); methodNode.instructions.insertBefore(first, new VarInsnNode(Opcodes.ALOAD, 0)); methodNode.instructions.insertBefore(first, new MethodInsnNode(Opcodes.INVOKESTATIC, "Game/Menu", "switchList", "(Ljava/lang/Object;)Z")); methodNode.instructions.insertBefore(first, new JumpInsnNode(Opcodes.IFGT, label)); methodNode.instructions.insertBefore(first, new InsnNode(Opcodes.RETURN)); methodNode.instructions.insertBefore(first, label); } } }
/** * TODO: Complete JavaDoc * * @param methodNode * @param owner The class of the variable to be hooked * @param var The variable to be hooked * @param desc * @param newClass The class the hooked variable will be stored in * @param newVar The variable name the hooked variable will be stored in * @param newDesc * @param canRead Specifies if the hooked variable should be readable * @param canWrite Specifies if the hooked variable should be writable */ private void hookClassVariable(MethodNode methodNode, String owner, String var, String desc, String newClass, String newVar, String newDesc, boolean canRead, boolean canWrite) { Iterator<AbstractInsnNode> insnNodeList = methodNode.instructions.iterator(); while (insnNodeList.hasNext()) { AbstractInsnNode insnNode = insnNodeList.next(); int opcode = insnNode.getOpcode(); if (opcode == Opcodes.GETFIELD || opcode == Opcodes.PUTFIELD) { FieldInsnNode field = (FieldInsnNode)insnNode; if (field.owner.equals(owner) && field.name.equals(var) && field.desc.equals(desc)) { if (opcode == Opcodes.GETFIELD && canWrite) { methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.GETSTATIC, newClass, newVar, newDesc)); methodNode.instructions.insert(insnNode, new InsnNode(Opcodes.POP)); } else if (opcode == Opcodes.PUTFIELD && canRead) { methodNode.instructions.insertBefore(insnNode, new InsnNode(Opcodes.DUP_X1)); methodNode.instructions.insert(insnNode, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, newVar, newDesc)); } } } } }
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)); } }
private void addObfuscatedLong(ListIterator<AbstractInsnNode> iterator, long l) { boolean negative = l < 0; iterator.add( new LdcInsnNode ( negative?-l:l ) ); int val = ((rand.nextInt(10) + 1) * 2) + (negative?1:0); for(int i = 0; i < val; i++) iterator.add( new InsnNode ( LNEG ) ); }
private AbstractInsnNode primitiveNull(Type type) { char desc = type.getDescriptor().charAt(0); switch (desc) { case 'C': case 'Z': case 'B': case 'S': case 'I': return new InsnNode(Opcodes.ICONST_0); case 'J': return new InsnNode(Opcodes.LCONST_0); case 'F': return new InsnNode(Opcodes.FCONST_0); case 'D': return new InsnNode(Opcodes.DCONST_0); default: return null; } }
@Override public InsnList build(MethodContext context) { Type[] argumentTypes = context.getArgumentTypes(); InsnList insnList = new InsnList(); insnList.add(new LdcInsnNode(argumentTypes.length)); insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(java.lang.reflect.Type.class))); for (int i = 0; i < argumentTypes.length; i++) { insnList.add(new InsnNode(DUP)); insnList.add(new LdcInsnNode(i)); insnList.add(new PushBoxedType(argumentTypes[i]).build(context)); insnList.add(new InsnNode(AASTORE)); } return insnList; }
@Override public InsnList build(MethodContext context) { Type[] argumentTypes = context.getArgumentTypes(); int[] arguments = context.getArguments(); InsnList insnList = new InsnList(); insnList.add(new LdcInsnNode(arguments.length)); insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(Object.class))); for (int i = 0; i < arguments.length; i++) { insnList.add(new InsnNode(DUP)); insnList.add(new LdcInsnNode(i)); int index = arguments[i]; Type type = argumentTypes[i]; insnList.add(new VarInsnNode(type.getOpcode(ILOAD), index)); insnList.add(new BoxPrimitives(type).build(context)); insnList.add(new InsnNode(AASTORE)); } return insnList; }
@Override public InsnList build(MethodContext context) { Type[] argumentTypes = Type.getArgumentTypes(call.desc); InsnList insnList = new InsnList(); insnList.add(new LdcInsnNode(argumentTypes.length)); insnList.add(new TypeInsnNode(Opcodes.ANEWARRAY, Type.getInternalName(java.lang.reflect.Type.class))); for (int i = 0; i < argumentTypes.length; i++) { insnList.add(new InsnNode(DUP)); insnList.add(new LdcInsnNode(i)); insnList.add(new PushBoxedType(argumentTypes[i]).build(context)); insnList.add(new InsnNode(AASTORE)); } return insnList; }
private void patchShouldBob(MethodNode mn) { //Loop through the instructions of the method Iterator<AbstractInsnNode> it = mn.instructions.iterator(); boolean didInject = false; while(it.hasNext()) { AbstractInsnNode currentNode = it.next(); /* In the RenderItem class, line 803: * * We just need to change "iconst_1" to "iconst_0". */ if(currentNode.getOpcode() == Opcodes.ICONST_1 && currentNode.getNext().getOpcode() == Opcodes.IRETURN) { FMLLog.log("NoItemRotation", Level.INFO, "Found target instruction \"iconst_1\" followed by \"ireturn\""); //Replace with "iconst_0" mn.instructions.set(currentNode, new InsnNode(Opcodes.ICONST_0)); didInject = true; break; } } if(didInject) FMLLog.log("NoItemRotation", Level.INFO, "Successfully injected into %s%s", mn.name, mn.desc); else FMLLog.log("NoItemRotation", Level.ERROR, "Failed injection into %s%s", mn.name, mn.desc); }
private byte[] transformObjectFactoryClient(byte[] before) { ClassNode classNode = new ClassNode(); ClassReader reader = new ClassReader(before); reader.accept(classNode, 0); for (MethodNode m : classNode.methods) { if (m.name.equals("preBeginGame")) { m.instructions.clear(); m.instructions.add(new TypeInsnNode(NEW, "alexiil/mods/load/LiteLoaderProgress")); m.instructions.add(new MethodInsnNode(INVOKESPECIAL, "alexiil/mods/load/LiteLoaderProgress", "<init>", "()V", false)); m.instructions.add(new InsnNode(RETURN)); } } ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classNode.accept(cw); return cw.toByteArray(); }
/** * Generates instructions to pop the result of the method off the stack. This will only generate instructions if the method being * invoked generates a return value. * @param invokeInsnNode instruction for the method that was invoked (can either be of type {@link MethodInsnNode} or * {@link InvokeDynamicInsnNode} -- this is used to determine how many items to pop off the stack * @return instructions for a pop (only if the method being invoked generates a return value) * @throws IllegalArgumentException if {@code invokeInsnNode} isn't of type {@link MethodInsnNode} or {@link InvokeDynamicInsnNode} * @throws NullPointerException if any argument is {@code null} */ private static InsnList popMethodResult(AbstractInsnNode invokeInsnNode) { Validate.notNull(invokeInsnNode); Type returnType = getReturnTypeOfInvocation(invokeInsnNode); InsnList ret = new InsnList(); switch (returnType.getSort()) { case Type.LONG: case Type.DOUBLE: ret.add(new InsnNode(Opcodes.POP2)); break; case Type.VOID: break; case Type.METHOD: throw new IllegalStateException(); // this should never happen default: ret.add(new InsnNode(Opcodes.POP)); break; } return ret; }
/*** * * @param inst * @param dsi */ private void fieldValueIsNull(FieldNode fn, InsnList inst) { if ("Ljava/lang/Integer;".equals(fn.desc)) { inst.add(new InsnNode(ICONST_0)); inst.add(AsmHelper.newMethodInsnNode(INVOKESTATIC, "java/lang/Integer", "valueOf", "(J)Ljava/lang/Integer;", false)); } else if ("Ljava/lang/Long;".equals(fn.desc)) { inst.add(new InsnNode(LCONST_0)); inst.add(AsmHelper.newMethodInsnNode(INVOKESTATIC, "java/lang/Lang", "valueOf", "(J)Ljava/lang/Long;", false)); } else if ("Ljava/lang/Double;".equals(fn.desc)) { inst.add(new InsnNode(DCONST_0)); inst.add(AsmHelper.newMethodInsnNode(INVOKESTATIC, "java/lang/Double", "valueOf", "(J)Ljava/lang/Double;", false)); } else if("Ljava/lang/Short;".equals(fn.desc)) { inst.add(new InsnNode(DCONST_0)); inst.add(AsmHelper.newMethodInsnNode(INVOKESTATIC, "java/lang/Short", "valueOf", "(J)Ljava/lang/Short;", false)); } }
private void implementInterface(ClassNode cn) { MethodNode toMethod = new MethodNode(ACC_PUBLIC, "toData", "(Ljava/io/DataOutput;)V", null, new String[] { "java/io/IOException" }); InsnList instToMethod = toMethod.instructions; MethodNode fromMethod = new MethodNode(ACC_PUBLIC, "fromData", "(Ljava/io/DataInput;)V", null, new String[] { "java/io/IOException", "java/lang/ClassNotFoundException" }); InsnList instFromMethod = fromMethod.instructions; for (int i = 0; i < cn.fields.size(); i++) { FieldNode fn = (FieldNode) cn.fields.get(i); fp.toMethod(cn.name, fn, instToMethod); fp.fromMethod(cn.name, fn, instFromMethod); } instToMethod.add(new InsnNode(RETURN)); cn.methods.add(toMethod); instFromMethod.add(new InsnNode(RETURN)); cn.methods.add(fromMethod); // if (DomainMojoHelper.log().isDebugEnabled()) // DomainMojoHelper.log().debug(cn.name + " add toData and fromData method."); }
private void addMapperValueMethod(ClassNode domain, ClassNode mapper) { if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperValue(IDataSource)V method..."); MethodNode mn = new MethodNode(ACC_PUBLIC, "mapperValue", "(Lgemlite/core/internal/domain/IDataSource;)L" + domain.name + ";", null, null); InsnList insn = mn.instructions; insn.add(new TypeInsnNode(NEW, domain.name)); insn.add(new InsnNode(DUP)); insn.add(AsmHelper.newMethodInsnNode(INVOKESPECIAL, domain.name, "<init>", "()V", false)); insn.add(new VarInsnNode(ASTORE, 2)); insn.add(new VarInsnNode(ALOAD, 0)); insn.add(new VarInsnNode(ALOAD, 1)); insn.add(new VarInsnNode(ALOAD, 2)); insn.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, mapper.name, "mapperValue", "(Lgemlite/core/internal/domain/IDataSource;L" + domain.name + ";)L" + domain.name + ";", false)); insn.add(new InsnNode(POP)); insn.add(new VarInsnNode(ALOAD, 2)); insn.add(new InsnNode(ARETURN)); mapper.methods.add(mn); if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperValue(IDataSource)V method done."); }
private void addValue2KeySimple(ClassNode domain, ClassNode mapper, FieldNode key) { if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add value2key(V)K method, key field:" + key.name); String s1 = key.name.substring(0, 1); String s2 = key.name.substring(1); String getMethod = "get" + s1.toUpperCase() + s2; String fullDesc = AsmHelper.toFullName(key.desc); MethodNode mn = new MethodNode(ACC_PUBLIC, "value2Key", "(L" + domain.name + ";)" + fullDesc, null, null); InsnList insn = mn.instructions; insn.add(new VarInsnNode(ALOAD, 1)); insn.add(AsmHelper.newMethodInsnNode(INVOKEVIRTUAL, domain.name, getMethod, "()" + key.desc, false)); AsmHelper.addTypeConvert(insn, key.desc); insn.add(new InsnNode(ARETURN)); mapper.methods.add(mn); if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add value2key(V)K method, key field:" + key.name + " done."); }
private void addMapperKeySimple(ClassNode mapper, FieldNode key) { if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperKey(IDataSource)K method, key field:" + key.name); String fullDesc = AsmHelper.toFullName(key.desc); MethodNode mn = new MethodNode(ACC_PUBLIC, "mapperKey", "(Lgemlite/core/internal/domain/IDataSource;)" + fullDesc, null, null); InsnList insn = mn.instructions; insn.add(new VarInsnNode(ALOAD, 1)); insn.add(new LdcInsnNode(key.name)); Item1 mti = MapperToolRegistry.getDataSItem(key.desc); insn.add(AsmHelper.newMethodInsnNode(INVOKEINTERFACE, "gemlite/core/internal/domain/IDataSource", mti.getMethod, "(Ljava/lang/String;)" + key.desc, true)); AsmHelper.addTypeConvert(insn, key.desc); insn.add(new InsnNode(ARETURN)); mapper.methods.add(mn); if (DomainMojoHelper.log().isDebugEnabled()) DomainMojoHelper.log().debug("Add mapperKey(IDataSource)K method, key field:" + key.name); }
/** * Calls a constructor with a set of arguments. After execution the stack should have an extra item pushed on it: the object that was * created by this constructor. * @param constructor constructor to call * @param args constructor argument instruction lists -- each instruction list must leave one item on the stack of the type expected * by the constructor * @return instructions to invoke a constructor * @throws NullPointerException if any argument is {@code null} or array contains {@code null} * @throws IllegalArgumentException if the length of {@code args} doesn't match the number of parameters in {@code constructor} */ public static InsnList construct(Constructor<?> constructor, InsnList ... args) { Validate.notNull(constructor); Validate.notNull(args); Validate.noNullElements(args); Validate.isTrue(constructor.getParameterCount() == args.length); InsnList ret = new InsnList(); Type clsType = Type.getType(constructor.getDeclaringClass()); Type methodType = Type.getType(constructor); ret.add(new TypeInsnNode(Opcodes.NEW, clsType.getInternalName())); ret.add(new InsnNode(Opcodes.DUP)); for (InsnList arg : args) { ret.add(arg); } ret.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, clsType.getInternalName(), "<init>", methodType.getDescriptor(), false)); return ret; }
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; }
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); } }
/** * Generates instructions for generating marker instructions. These marker instructions are meant to be is useful for debugging * instrumented code. For example, you can spot a specific portion of instrumented code by looking for specific markers in the assembly * output. * @param markerType marker type (determines what kind of instructions are generated) * @param text text to print out * @return instructions to call System.out.println with a string constant * @throws NullPointerException if any argument is {@code null} */ public static InsnList debugMarker(MarkerType markerType, String text) { Validate.notNull(markerType); Validate.notNull(text); InsnList ret = new InsnList(); switch (markerType) { case NONE: break; case CONSTANT: ret.add(new LdcInsnNode(text)); ret.add(new InsnNode(Opcodes.POP)); break; case STDOUT: ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")); ret.add(new LdcInsnNode(text)); ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false)); break; default: throw new IllegalStateException(); } return ret; }
/** * Insert a call to the isNull helper function * * @param opcode * @param position * @param list */ public void insertPushNull(int opcode, JumpInsnNode position, InsnList list) { int branchId = getBranchID(currentMethodNode, position); logger.info("Inserting instrumentation for NULL check at branch " + branchId + " in method " + currentMethodNode.name); MethodInsnNode nullCheck = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "isNull", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.getType(Object.class), Type.INT_TYPE }), false); list.insertBefore(position, new InsnNode(Opcodes.DUP)); list.insertBefore(position, new LdcInsnNode(opcode)); list.insertBefore(position, nullCheck); //list.insertBefore(position, // new LdcInsnNode(getBranchID(currentMethodNode, position))); insertBranchIdPlaceholder(currentMethodNode, position, branchId); MethodInsnNode push = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushPredicate", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE, Type.INT_TYPE }), false); list.insertBefore(position, push); }
/** * Insert a call to the reference equality check helper function * * @param opcode * @param position * @param list */ public void insertPushEquals(int opcode, JumpInsnNode position, InsnList list) { MethodInsnNode equalCheck = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "isEqual", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.getType(Object.class), Type.getType(Object.class), Type.INT_TYPE }), false); list.insertBefore(position, new InsnNode(Opcodes.DUP2)); list.insertBefore(position, new LdcInsnNode(opcode)); list.insertBefore(position, equalCheck); //list.insertBefore(position, // new LdcInsnNode(getBranchID(currentMethodNode, position))); insertBranchIdPlaceholder(currentMethodNode, position); MethodInsnNode push = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushPredicate", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE, Type.INT_TYPE }), false); list.insertBefore(position, push); }
/** * Insert a call to the distance function for unary comparison * * @param opcode * @param position * @param list */ public void insertPush(int opcode, JumpInsnNode position, InsnList list) { list.insertBefore(position, new InsnNode(Opcodes.DUP)); // TODO: We have to put a placeholder here instead of the actual branch ID // TODO: And then later add another transformation where we replace this with // actual branch IDs //list.insertBefore(position, // new LdcInsnNode(getBranchID(currentMethodNode, position))); insertBranchIdPlaceholder(currentMethodNode, position); MethodInsnNode push = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushPredicate", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE, Type.INT_TYPE }), false); list.insertBefore(position, push); }
/** * Insert a call to the distance function for binary comparison * * @param opcode * @param position * @param list */ public void insertPush2(int opcode, JumpInsnNode position, InsnList list) { list.insertBefore(position, new InsnNode(Opcodes.DUP2)); //list.insertBefore(position, new InsnNode(Opcodes.ISUB)); MethodInsnNode sub = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "intSub", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.INT_TYPE, Type.INT_TYPE }), false); list.insertBefore(position, sub); insertBranchIdPlaceholder(currentMethodNode, position); // list.insertBefore(position, // new LdcInsnNode(getBranchID(currentMethodNode, position))); MethodInsnNode push = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class), "pushPredicate", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE, Type.INT_TYPE }), false); list.insertBefore(position, push); }
@Override protected AbstractInsnNode transformInsnNode(MethodNode mn, InsnNode insnNode) { BooleanTestabilityTransformation.logger.info("Checking transformation of InsnNode "); if (insnNode.getOpcode() == Opcodes.ICONST_0 && this.booleanTestabilityTransformation.isBooleanAssignment(insnNode, mn)) { TransformationStatistics.insertedGet(); this.booleanTestabilityTransformation.insertGet(insnNode, mn.instructions); } else if (insnNode.getOpcode() == Opcodes.ICONST_1 && this.booleanTestabilityTransformation.isBooleanAssignment(insnNode, mn)) { TransformationStatistics.insertedGet(); this.booleanTestabilityTransformation.insertGet(insnNode, mn.instructions); //} else if (insnNode.getOpcode() == Opcodes.IRETURN // && isBooleanAssignment(insnNode, mn)) { // TransformationStatistics.insertedGet(); // insertGetBefore(insnNode, mn.instructions); } return insnNode; }
/** * <p> * addDefaultCaseInstrumentation * </p> * * @param v * a {@link org.evosuite.graphs.cfg.BytecodeInstruction} object. * @param instrumentation * a {@link org.objectweb.asm.tree.InsnList} object. * @param mySwitch * a {@link org.objectweb.asm.tree.AbstractInsnNode} object. * @param defaultLabel * a {@link org.objectweb.asm.tree.LabelNode} object. * @param caseLabel * a {@link org.objectweb.asm.tree.LabelNode} object. * @param endLabel * a {@link org.objectweb.asm.tree.LabelNode} object. */ protected void addDefaultCaseInstrumentation(BytecodeInstruction v, InsnList instrumentation, AbstractInsnNode mySwitch, LabelNode defaultLabel, LabelNode caseLabel, LabelNode endLabel) { int defaultCaseBranchId = BranchPool.getInstance(classLoader).getDefaultBranchForSwitch(v).getActualBranchId(); // add helper switch instrumentation.add(new InsnNode(Opcodes.DUP)); instrumentation.add(mySwitch); // add call for default case not covered instrumentation.add(caseLabel); addDefaultCaseNotCoveredCall(v, instrumentation, defaultCaseBranchId); // jump over default (break) instrumentation.add(new JumpInsnNode(Opcodes.GOTO, endLabel)); // add call for default case covered instrumentation.add(defaultLabel); addDefaultCaseCoveredCall(v, instrumentation, defaultCaseBranchId); instrumentation.add(endLabel); }
private static AbstractInsnNode getDefault(Type type) { if (type.equals(Type.BOOLEAN_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.BYTE_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.CHAR_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.DOUBLE_TYPE)) { return new LdcInsnNode(0.0); } else if (type.equals(Type.FLOAT_TYPE)) { return new LdcInsnNode(0.0F); } else if (type.equals(Type.INT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.LONG_TYPE)) { return new LdcInsnNode(0L); } else if (type.equals(Type.SHORT_TYPE)) { return new LdcInsnNode(0); } else if (type.equals(Type.VOID_TYPE)) { return new LabelNode(); } else { return new InsnNode(Opcodes.ACONST_NULL); } }
/** * <p> * getInfectionDistance * </p> * * @param original * a {@link org.objectweb.asm.tree.FieldInsnNode} object. * @param mutant * a {@link org.objectweb.asm.tree.InsnList} object. * @return a {@link org.objectweb.asm.tree.InsnList} object. */ public InsnList getInfectionDistance(FieldInsnNode original, InsnList mutant) { InsnList distance = new InsnList(); if (original.getOpcode() == Opcodes.GETFIELD) distance.add(new InsnNode(Opcodes.DUP)); //make sure to re-load this for GETFIELD distance.add(new FieldInsnNode(original.getOpcode(), original.owner, original.name, original.desc)); Type type = Type.getType(original.desc); if (type.getDescriptor().startsWith("L") || type.getDescriptor().startsWith("[")) { ReplaceVariable.addReferenceDistanceCheck(distance, type, mutant); } else { ReplaceVariable.addPrimitiveDistanceCheck(distance, type, mutant); } return distance; }