Example usage for org.objectweb.asm Opcodes INVOKESPECIAL

List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes INVOKESPECIAL.

Prototype

int INVOKESPECIAL

To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.

Click Source Link

Usage

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacement.java

License:Open Source License

public void insertConstructorCall(MethodCallReplacementMethodAdapter mv, MethodCallReplacement replacement,
        boolean isSelf) {
    Label origCallLabel = new Label();
    Label afterOrigCallLabel = new Label();

    if (!isSelf) {
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, MockFramework.class.getCanonicalName().replace('.', '/'),
                "isEnabled", "()Z", false);
        Label annotationStartTag = new AnnotatedLabel(true, true);
        annotationStartTag.info = Boolean.TRUE;
        mv.visitLabel(annotationStartTag);
        mv.visitJumpInsn(Opcodes.IFEQ, origCallLabel);
        Label annotationEndTag = new AnnotatedLabel(true, false);
        annotationEndTag.info = Boolean.FALSE;
        mv.visitLabel(annotationEndTag);

        Type[] args = Type.getArgumentTypes(desc);
        Map<Integer, Integer> to = new HashMap<Integer, Integer>();
        for (int i = args.length - 1; i >= 0; i--) {
            int loc = mv.newLocal(args[i]);
            mv.storeLocal(loc);//from ww  w. j  a  v  a 2 s.c o m
            to.put(i, loc);
        }

        mv.pop2();//uninitialized reference (which is duplicated)
        mv.newInstance(Type.getType(replacement.replacementClassName));
        mv.dup();

        for (int i = 0; i < args.length; i++) {
            mv.loadLocal(to.get(i));
        }
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, replacementClassName, replacementMethodName, replacementDesc,
            false);
    if (!isSelf) {
        mv.visitJumpInsn(Opcodes.GOTO, afterOrigCallLabel);
        mv.visitLabel(origCallLabel);
        mv.getNextVisitor().visitMethodInsn(Opcodes.INVOKESPECIAL, className, methodName, desc, false);
        mv.visitLabel(afterOrigCallLabel);
    }
}

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacementCache.java

License:Open Source License

private void handleStaticReplacementMethods(Class<? extends EvoSuiteMock> mockClass) {

    for (Method m : mockClass.getMethods()) {

        StaticReplacementMethod srm = m.getAnnotation(StaticReplacementMethod.class);
        if (srm == null) {
            continue;
        }/*from ww  w . j a  va  2 s  .  co m*/

        if (!Modifier.isStatic(m.getModifiers())) {
            throw new RuntimeException("EvoSuite Bug: improper annotations in class " + mockClass.getName());
        }

        String target;
        if (OverrideMock.class.isAssignableFrom(mockClass)) {
            target = mockClass.getSuperclass().getCanonicalName();
        } else {
            throw new RuntimeException(
                    "EvoSuite Bug: StaticReplacementMethod can only be used in OverrideMock");
        }

        String desc = Type.getMethodDescriptor(m);
        addSpecialReplacementCall(
                new MethodCallReplacement(target.replace('.', '/'), m.getName(), desc, Opcodes.INVOKESPECIAL,
                        mockClass.getCanonicalName().replace('.', '/'), m.getName(), desc, false, false));

    }
}

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacementCache.java

License:Open Source License

/**
 * Replace all the constructors of {@code target} with a constructor (with
 * same input parameters) of mock subclass {@code mockClass}.
 *
 * @param mockClass// ww w  .  j av a 2s .c  o m
 * @param target
 * @throws IllegalArgumentException
 */
private void replaceAllConstructors(Class<?> mockClass, Class<?> target) throws IllegalArgumentException {

    if (!target.isAssignableFrom(mockClass)) {
        throw new IllegalArgumentException("Constructor replacement can be done only for subclasses. Class "
                + mockClass + " is not an instance of " + target);
    }

    for (Constructor<?> constructor : ReflectionUtils.getDeclaredConstructors(mockClass)) {
        String desc = Type.getConstructorDescriptor(constructor);
        addSpecialReplacementCall(new MethodCallReplacement(target.getCanonicalName().replace('.', '/'),
                "<init>", desc, Opcodes.INVOKESPECIAL, mockClass.getCanonicalName().replace('.', '/'), "<init>",
                desc, false, false));
    }
}

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacementCache.java

License:Open Source License

/**
 * Replace all the constructors of {@code target} with a static call (with
 * same input parameters) of static mock class {@code mockClass}.
 *
 * @param mockClass//w w w  .  j ava 2 s. co m
 * @param target
 * @throws IllegalArgumentException
 */
private void replaceAllConstructorsWithStaticCalls(Class<?> mockClass, Class<?> target)
        throws IllegalArgumentException {

    for (Constructor<?> constructor : target.getConstructors()) {
        String desc = Type.getConstructorDescriptor(constructor);
        String replacementDesc = desc.substring(0, desc.length() - 1) + Type.getDescriptor(target);
        addReplacementCall(new MethodCallReplacement(target.getCanonicalName().replace('.', '/'), "<init>",
                desc, Opcodes.INVOKESPECIAL, mockClass.getCanonicalName().replace('.', '/'),
                target.getSimpleName(), replacementDesc, true, true));
    }
}

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacementCache.java

License:Open Source License

/**
 * Replace all the methods of {@code target} with a method (with same input
 * parameters) of mock subclass {@code mockClass}.
 *
 * @param mockClass//w  w w .  java 2s  .co m
 * @param target
 * @throws IllegalArgumentException
 */
private void replaceAllInvokeSpecial(Class<?> mockClass, Class<?> target) throws IllegalArgumentException {

    if (!target.isAssignableFrom(mockClass)) {
        throw new IllegalArgumentException("Method replacement can be done only for subclasses. Class "
                + mockClass + " is not an instance of " + target);
    }

    logger.debug("Static Mock: " + mockClass.getCanonicalName() + " for " + target.getCanonicalName());
    for (Method method : mockClass.getMethods()) {
        String desc = Type.getMethodDescriptor(method);
        addSpecialReplacementCall(new MethodCallReplacement(target.getCanonicalName().replace('.', '/'),
                method.getName(), desc, Opcodes.INVOKESPECIAL, mockClass.getCanonicalName().replace('.', '/'),
                method.getName(), desc, false, false));
    }
}

From source file:org.evosuite.runtime.instrumentation.MethodCallReplacementMethodAdapter.java

License:Open Source License

/** {@inheritDoc} */
@Override//ww  w  .j  av a2  s.  c om
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {

    boolean isReplaced = false;
    // Static replacement methods
    // For invokespecial this can only be used if a constructor is called,
    // not for super calls because not all mock classes may be superclasses
    // of the actual object. E.g. Throwable -> Exception -> RuntimeException
    // A MockRuntimeException is not a subclass of MockException and MockThrowable
    if (MethodCallReplacementCache.getInstance().hasReplacementCall(owner, name + desc)
            && (opcode != Opcodes.INVOKESPECIAL || name.equals("<init>"))) {
        MethodCallReplacement replacement = MethodCallReplacementCache.getInstance().getReplacementCall(owner,
                name + desc);
        isReplaced = true;
        replacement.insertMethodCall(this, Opcodes.INVOKESTATIC);
        hasBeenInstrumented = true;
    }

    // for constructors
    if (!isReplaced) {
        if (MethodCallReplacementCache.getInstance().hasSpecialReplacementCall(owner, name + desc)) {
            MethodCallReplacement replacement = MethodCallReplacementCache.getInstance()
                    .getSpecialReplacementCall(owner, name + desc);
            if (replacement.isTarget(owner, name, desc) && opcode == Opcodes.INVOKESPECIAL
                    && name.equals("<init>")) {
                isReplaced = true;
                hasBeenInstrumented = true;
                boolean isSelf = false;
                if (needToWaitForSuperConstructor) {
                    String originalClassNameWithDots = owner.replace('/', '.');
                    if (originalClassNameWithDots.equals(superClassName)) {
                        isSelf = true;
                    }
                }
                if (replacement.getMethodName().equals("<init>"))
                    replacement.insertConstructorCall(this, replacement, isSelf);
                else {
                    replacement.insertMethodCall(this, Opcodes.INVOKESPECIAL);
                }
            }
        }
    }

    // non-static replacement methods
    //      if (!isReplaced) {
    //         iterator = MethodCallReplacementCache.getInstance().getVirtualReplacementCalls();
    //         while(iterator.hasNext()) {
    //            MethodCallReplacement replacement = iterator.next();
    //            if (replacement.isTarget(owner, name, desc)) {
    //               isReplaced = true;
    //               replacement.insertMethodCall(this, Opcodes.INVOKEVIRTUAL);
    //               break;
    //            }
    //         }
    //      }

    if (!isReplaced) {
        super.visitMethodInsn(opcode, owner, name, desc, itf);
    }
    if (needToWaitForSuperConstructor) {
        if (opcode == Opcodes.INVOKESPECIAL) {
            String originalClassNameWithDots = owner.replace('/', '.');
            if (originalClassNameWithDots.equals(superClassName)) {
                needToWaitForSuperConstructor = false;
            }
        }
    }
}

From source file:org.evosuite.testcarver.instrument.Instrumenter.java

License:Open Source License

@SuppressWarnings("unchecked")
private void addFieldRegistryRegisterCall(final MethodNode methodNode) {
    AbstractInsnNode ins = null;//  w  w w .  jav  a 2  s  . c o m
    ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator();

    int numInvokeSpecials = 0; // number of invokespecial calls before actual constructor call

    while (iter.hasNext()) {
        ins = iter.next();

        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++;
            }
        }
    }

    final InsnList instructions = new InsnList();

    instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(FieldRegistry.class),
            "register", "(Ljava/lang/Object;)V"));

    methodNode.instructions.insert(ins, instructions);
}

From source file:org.evosuite.testcarver.instrument.Instrumenter.java

License:Open Source License

/**
 *    public int myMethod(int i)//from ww w.  jav a 2s. co  m
   {
 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();

        int numInvokeSpecials = 0; // number of invokespecial calls before actual constructor call

        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"));

        //--- create "Object returnValue = null;"

        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)));

    // --- construct call to wrapped methode

    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);
        wInstructions.add(new VarInsnNode(storeOpcode, ++var)); // might be only 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;
}

From source file:org.fabric3.implementation.bytecode.reflection.BytecodeHelper.java

License:Open Source License

/**
 * Creates a no-args constructor./*from   w  ww.j  ava 2  s  .  com*/
 *
 * @param cw the class writer
 */
public static void writeConstructor(ClassWriter cw, Class<?> superType) {
    String descriptor = Type.getDescriptor(ServiceInvoker.class);

    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    Label label = new Label();
    mv.visitLabel(label);
    mv.visitLineNumber(6, label);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(superType), "<init>", "()V");
    mv.visitInsn(Opcodes.RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", descriptor, null, label, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:org.formulacompiler.compiler.internal.bytecode.FactoryCompiler.java

License:Open Source License

private void buildDefaultConstructor(Type _parentType) {
    final GeneratorAdapter mv = newMethod(Opcodes.ACC_PUBLIC, "<init>", ENV_CONSTRUCTOR_SIG);
    mv.visitCode();/*from  w  w w . ja  va  2 s. com*/
    mv.loadThis();
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, _parentType.getInternalName(), "<init>", "()V");
    mv.loadThis();
    mv.loadArg(0);
    mv.putField(this.classType(), ByteCodeEngineCompiler.ENV_MEMBER_NAME, ByteCodeEngineCompiler.ENV_CLASS);
    mv.visitInsn(Opcodes.RETURN);
    endMethod(mv);
}