Search in sources :

Example 21 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project evosuite by EvoSuite.

the class MethodNodeTransformer method transform.

/**
 * <p>transform</p>
 *
 * @param mn a {@link org.objectweb.asm.tree.MethodNode} object.
 */
public void transform(MethodNode mn) {
    setupLocals(mn);
    Set<AbstractInsnNode> originalNodes = new HashSet<AbstractInsnNode>();
    AbstractInsnNode node = mn.instructions.getFirst();
    while (node != mn.instructions.getLast()) {
        originalNodes.add(node);
        node = node.getNext();
    }
    // int currentIndex = 0;
    node = mn.instructions.getFirst();
    // while (currentIndex < mn.instructions.size()) {
    boolean finished = false;
    while (!finished) {
        // } else
        if (node instanceof MethodInsnNode) {
            node = transformMethodInsnNode(mn, (MethodInsnNode) node);
        } else if (node instanceof VarInsnNode) {
            node = transformVarInsnNode(mn, (VarInsnNode) node);
        } else if (node instanceof FieldInsnNode) {
            node = transformFieldInsnNode(mn, (FieldInsnNode) node);
        } else if (node instanceof InsnNode) {
            node = transformInsnNode(mn, (InsnNode) node);
        } else if (node instanceof TypeInsnNode) {
            node = transformTypeInsnNode(mn, (TypeInsnNode) node);
        } else if (node instanceof JumpInsnNode) {
            node = transformJumpInsnNode(mn, (JumpInsnNode) node);
        } else if (node instanceof LabelNode) {
            node = transformLabelNode(mn, (LabelNode) node);
        } else if (node instanceof IntInsnNode) {
            node = transformIntInsnNode(mn, (IntInsnNode) node);
        } else if (node instanceof MultiANewArrayInsnNode) {
            node = transformMultiANewArrayInsnNode(mn, (MultiANewArrayInsnNode) node);
        }
        if (node == mn.instructions.getLast()) {
            finished = true;
        } else {
            node = node.getNext();
        }
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) MultiANewArrayInsnNode(org.objectweb.asm.tree.MultiANewArrayInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) MultiANewArrayInsnNode(org.objectweb.asm.tree.MultiANewArrayInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) HashSet(java.util.HashSet)

Example 22 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project jacoco by jacoco.

the class CondyProbeArrayStrategyTest method should_store_instance_using_condy_and_checkcast.

@Test
public void should_store_instance_using_condy_and_checkcast() {
    final MethodNode m = new MethodNode();
    final int maxStack = strategy.storeInstance(m, false, 1);
    assertEquals(1, maxStack);
    final ConstantDynamic constantDynamic = (ConstantDynamic) ((LdcInsnNode) m.instructions.get(0)).cst;
    assertEquals("$jacocoData", constantDynamic.getName());
    assertEquals("Ljava/lang/Object;", constantDynamic.getDescriptor());
    final Handle bootstrapMethod = constantDynamic.getBootstrapMethod();
    assertEquals(Opcodes.H_INVOKESTATIC, bootstrapMethod.getTag());
    assertEquals("ClassName", bootstrapMethod.getOwner());
    assertEquals("$jacocoInit", bootstrapMethod.getName());
    assertEquals("(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z", bootstrapMethod.getDesc());
    assertTrue(bootstrapMethod.isInterface());
    final TypeInsnNode castInstruction = (TypeInsnNode) m.instructions.get(1);
    assertEquals(Opcodes.CHECKCAST, castInstruction.getOpcode());
    assertEquals("[Z", castInstruction.desc);
    final VarInsnNode storeInstruction = (VarInsnNode) m.instructions.get(2);
    assertEquals(Opcodes.ASTORE, storeInstruction.getOpcode());
    assertEquals(1, storeInstruction.var);
    assertEquals(3, m.instructions.size());
}
Also used : MethodNode(org.objectweb.asm.tree.MethodNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) ConstantDynamic(org.objectweb.asm.ConstantDynamic) Handle(org.objectweb.asm.Handle) Test(org.junit.Test)

Example 23 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project evosuite by EvoSuite.

the class Instrumenter method addCaptureCall.

private InsnList addCaptureCall(final boolean isStatic, final String internalClassName, final String methodName, final String methodDesc, final Type[] argTypes) {
    // construction of
    // Capturer.capture(final Object receiver, final String methodName, final Object[] methodParams)
    // call
    final InsnList il = new InsnList();
    il.add(new LdcInsnNode(this.captureId));
    // --- load receiver argument
    int varIndex;
    if (isStatic) {
        // static method invocation
        il.add(new LdcInsnNode(internalClassName));
        il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(CaptureUtil.class), "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"));
        varIndex = 0;
    } else {
        // non-static method call
        il.add(new VarInsnNode(Opcodes.ALOAD, 0));
        varIndex = 1;
    }
    // --- load method name argument
    il.add(new LdcInsnNode(methodName));
    // --- load method description argument
    il.add(new LdcInsnNode(methodDesc));
    // --- load methodParams arguments
    // load methodParams length
    // TODO ICONST_1 to ICONST_5 would be more efficient
    il.add(new IntInsnNode(Opcodes.BIPUSH, argTypes.length));
    // create array object
    il.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));
    for (int i = 0; i < argTypes.length; i++) {
        il.add(new InsnNode(Opcodes.DUP));
        // TODO ICONST_1 to ICONST_5 would be more efficient
        il.add(new IntInsnNode(Opcodes.BIPUSH, i));
        // check for primitives
        this.loadAndConvertToObject(il, argTypes[i], varIndex++);
        il.add(new InsnNode(Opcodes.AASTORE));
        // long/double take two registers
        if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
            varIndex++;
        }
    }
    // --- construct Capture.capture() call
    il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(org.evosuite.testcarver.capture.Capturer.class), "capture", "(ILjava/lang/Object;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V"));
    return il;
}
Also used : FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 24 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project evosuite by EvoSuite.

the class Instrumenter method wrapMethod.

/**
 * 	public int myMethod(int i)
 *		{
 *			try
 *			{
 *				return _sw_prototype_original_myMethod(i)
 *			}
 *			finally
 *			{
 *				Capturer.enable();
 *			}
 *		}
 *
 * @param classNode
 * @param className
 * @param methodNode
 */
@SuppressWarnings("unchecked")
private MethodNode wrapMethod(final ClassNode classNode, final String className, final MethodNode methodNode) {
    methodNode.maxStack += 4;
    // create wrapper for original method
    final MethodNode wrappingMethodNode = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()]));
    wrappingMethodNode.maxStack = methodNode.maxStack;
    // assign annotations to wrapping method
    wrappingMethodNode.visibleAnnotations = methodNode.visibleAnnotations;
    wrappingMethodNode.visibleParameterAnnotations = methodNode.visibleParameterAnnotations;
    // remove annotations from wrapped method to avoid wrong behavior controlled by annotations
    methodNode.visibleAnnotations = null;
    methodNode.visibleParameterAnnotations = null;
    // rename original method
    methodNode.access = TransformerUtil.modifyVisibility(methodNode.access, Opcodes.ACC_PRIVATE);
    final LabelNode l0 = new LabelNode();
    final LabelNode l1 = new LabelNode();
    final LabelNode l2 = new LabelNode();
    final InsnList wInstructions = wrappingMethodNode.instructions;
    if ("<init>".equals(methodNode.name)) {
        // wrap a constructor
        methodNode.name = WRAP_NAME_PREFIX + "init" + WRAP_NAME_PREFIX;
        // move call to other constructors to new method
        AbstractInsnNode ins = null;
        ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator();
        // number of invokespecial calls before actual constructor call
        int numInvokeSpecials = 0;
        while (iter.hasNext()) {
            ins = iter.next();
            iter.remove();
            wInstructions.add(ins);
            if (ins instanceof MethodInsnNode) {
                MethodInsnNode mins = (MethodInsnNode) ins;
                if (ins.getOpcode() == Opcodes.INVOKESPECIAL) {
                    if (mins.name.startsWith("<init>")) {
                        if (numInvokeSpecials == 0) {
                            break;
                        } else {
                            numInvokeSpecials--;
                        }
                    }
                }
            } else if (ins instanceof TypeInsnNode) {
                TypeInsnNode typeIns = (TypeInsnNode) ins;
                if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) {
                    numInvokeSpecials++;
                }
            }
        }
    } else {
        methodNode.name = WRAP_NAME_PREFIX + methodNode.name;
    }
    int varReturnValue = 0;
    final Type returnType = Type.getReturnType(methodNode.desc);
    if (returnType.equals(Type.VOID_TYPE)) {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, "java/lang/Throwable"));
    } else {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/Throwable"));
        if (!TransformerUtil.isStatic(methodNode.access)) {
            // load "this"
            varReturnValue++;
        }
        // consider method arguments to find right variable index
        final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
        for (int i = 0; i < argTypes.length; i++) {
            varReturnValue++;
            // long/double take two registers
            if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
                varReturnValue++;
            }
        }
        // push NULL on the stack and initialize variable for return value for it
        wInstructions.add(new InsnNode(Opcodes.ACONST_NULL));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
    }
    int var = 0;
    // --- L0
    wInstructions.add(l0);
    wInstructions.add(this.addCaptureCall(TransformerUtil.isStatic(methodNode.access), className, wrappingMethodNode.name, wrappingMethodNode.desc, Type.getArgumentTypes(methodNode.desc)));
    if (!TransformerUtil.isStatic(methodNode.access)) {
        // load "this" to call method
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        var++;
    }
    final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
    for (int i = 0; i < argTypes.length; i++) {
        this.addLoadInsn(wInstructions, argTypes[i], var++);
        // long/double take two registers
        if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
            var++;
        }
    }
    if (TransformerUtil.isStatic(methodNode.access)) {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, methodNode.name, methodNode.desc));
    } else {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, methodNode.name, methodNode.desc));
    }
    var++;
    if (returnType.equals(Type.VOID_TYPE)) {
        wInstructions.add(new JumpInsnNode(Opcodes.GOTO, l2));
        // --- L1
        wInstructions.add(l1);
        wInstructions.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
        // FIXME <--- DUPLICATE CODE
        // --- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new InsnNode(Opcodes.RETURN));
    } else {
        // construct store of the wrapped method call's result
        this.addBoxingStmt(wInstructions, returnType);
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, varReturnValue));
        this.addUnBoxingStmt(wInstructions, returnType);
        final int storeOpcode = returnType.getOpcode(Opcodes.ISTORE);
        // might be only var
        wInstructions.add(new VarInsnNode(storeOpcode, ++var));
        // --- L1
        wInstructions.add(l1);
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        // construct load of the wrapped method call's result
        int loadOpcode = returnType.getOpcode(Opcodes.ILOAD);
        wInstructions.add(new VarInsnNode(loadOpcode, var));
        // construct return of the wrapped method call's result
        this.addReturnInsn(wInstructions, returnType);
        // ---- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_FULL, 2, new Object[] { className, this.getInternalName(returnType) }, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
    }
    transformWrapperCalls(methodNode);
    return wrappingMethodNode;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) FrameNode(org.objectweb.asm.tree.FrameNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 25 with TypeInsnNode

use of org.objectweb.asm.tree.TypeInsnNode in project spring-loaded by spring-projects.

the class TypeDiffComputer method sameTypeInsn.

private static boolean sameTypeInsn(AbstractInsnNode o, AbstractInsnNode n) {
    TypeInsnNode oi = (TypeInsnNode) o;
    if (!(n instanceof TypeInsnNode)) {
        return false;
    }
    TypeInsnNode ni = (TypeInsnNode) n;
    return oi.desc.equals(ni.desc);
}
Also used : TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode)

Aggregations

TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)29 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)18 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)14 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)13 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)12 InsnNode (org.objectweb.asm.tree.InsnNode)11 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)9 IntInsnNode (org.objectweb.asm.tree.IntInsnNode)8 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)8 MethodNode (org.objectweb.asm.tree.MethodNode)8 Type (org.objectweb.asm.Type)7 InsnList (org.objectweb.asm.tree.InsnList)7 LabelNode (org.objectweb.asm.tree.LabelNode)7 ClassNode (org.objectweb.asm.tree.ClassNode)5 FieldNode (org.objectweb.asm.tree.FieldNode)4 MultiANewArrayInsnNode (org.objectweb.asm.tree.MultiANewArrayInsnNode)3 JsonObject (com.google.gson.JsonObject)2 ClassWriter (org.objectweb.asm.ClassWriter)2 FrameNode (org.objectweb.asm.tree.FrameNode)2 IincInsnNode (org.objectweb.asm.tree.IincInsnNode)2