Java Code Examples for org.objectweb.asm.commons.Method#getDescriptor()

The following examples show how to use org.objectweb.asm.commons.Method#getDescriptor() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: IncrementalChangeVisitor.java    From Aceso with Apache License 2.0 5 votes vote down vote up
public void addSupportMethod() {
        int access = Opcodes.ACC_PUBLIC;
        Method m = new Method("isSupport", "(I)Z");
        MethodVisitor mv = super.visitMethod(access,
                m.getName(),
                m.getDescriptor(),
                null, null);

        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 1);
//        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I", false);

        int[] hashArray = new int[fixMtds.size()];
        Label[] labelArray = new Label[fixMtds.size()];
        Label l0 = new Label();
        Label l1 = new Label();
        for (int i = 0; i < fixMtds.size(); i++) {
            hashArray[i] = AcesoProguardMap.instance().getClassData(visitedClassName).getMtdIndex(fixMtds.get(i));
            labelArray[i] = l0;
        }

        mv.visitLookupSwitchInsn(l1, hashArray, labelArray);
        mv.visitLabel(l0);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitLabel(l1);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.IRETURN);
        mv.visitMaxs(1, 2);
        mv.visitEnd();

        mv.visitMaxs(0, 0);
        mv.visitEnd();

    }
 
Example 2
Source File: IncrementalSupportVisitor.java    From AnoleFix with MIT License 4 votes vote down vote up
/***
 * Inserts a trampoline to this class so that the updated methods can make calls to super
 * class methods.
 * <p/>
 * Pseudo code for this trampoline:
 * <code>
 * Object access$super($classType instance, String name, object[] args) {
 * switch(name) {
 * case "firstMethod.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;":
 * return super~instance.firstMethod((String)arg[0], arg[1]);
 * case "secondMethod.(Ljava/lang/String;I)V":
 * return super~instance.firstMethod((String)arg[0], arg[1]);
 * <p>
 * default:
 * StringBuilder $local1 = new StringBuilder();
 * $local1.append("Method not found ");
 * $local1.append(name);
 * $local1.append(" in " $classType $super implementation");
 * throw new $package/InstantReloadException($local1.toString());
 * }
 * </code>
 */
private void createAccessSuper() {
    int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC
            | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_VARARGS;
    Method m = new Method("access$super", "(L" + visitedClassName
            + ";Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;");
    MethodVisitor visitor = super.visitMethod(access,
            m.getName(),
            m.getDescriptor(),
            null, null);

    final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);

    // Gather all methods from itself and its superclasses to generate a giant access$super
    // implementation.
    // This will work fine as long as we don't support adding methods to a class.
    final Map<String, MethodReference> uniqueMethods =
            new HashMap<String, MethodReference>();
    if (parentNodes.isEmpty()) {
        // if we cannot determine the parents for this class, let's blindly add all the
        // method of the current class as a gateway to a possible parent version.
        addAllNewMethods(uniqueMethods, classNode);
    } else {
        // otherwise, use the parent list.
        for (ClassNode parentNode : parentNodes) {
            addAllNewMethods(uniqueMethods, parentNode);
        }
    }

    new StringSwitch() {
        @Override
        void visitString() {
            mv.visitVarInsn(Opcodes.ALOAD, 1);
        }

        @Override
        void visitCase(String methodName) {
            MethodReference methodRef = uniqueMethods.get(methodName);

            mv.visitVarInsn(Opcodes.ALOAD, 0);

            Type[] args = Type.getArgumentTypes(methodRef.method.desc);
            int argc = 0;
            for (Type t : args) {
                mv.visitVarInsn(Opcodes.ALOAD, 2);
                mv.push(argc);
                mv.visitInsn(Opcodes.AALOAD);
                ByteCodeUtils.unbox(mv, t);
                argc++;
            }

            if (TRACING_ENABLED) {
                trace(mv, "super selected ", methodRef.owner.name,
                        methodRef.method.name, methodRef.method.desc);
            }
            // Call super on the other object, yup this works cos we are on the right place to
            // call from.
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
                    methodRef.owner.name,
                    methodRef.method.name,
                    methodRef.method.desc, false);

            Type ret = Type.getReturnType(methodRef.method.desc);
            if (ret.getSort() == Type.VOID) {
                mv.visitInsn(Opcodes.ACONST_NULL);
            } else {
                mv.box(ret);
            }
            mv.visitInsn(Opcodes.ARETURN);
        }

        @Override
        void visitDefault() {
            writeMissingMessageWithHash(mv, visitedClassName);
        }
    }.visit(mv, uniqueMethods.keySet());

    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
 
Example 3
Source File: IncrementalSupportVisitor.java    From AnoleFix with MIT License 4 votes vote down vote up
/***
 * Inserts a trampoline to this class so that the updated methods can make calls to
 * constructors.
 * <p>
 * <p/>
 * Pseudo code for this trampoline:
 * <code>
 * ClassName(Object[] args, Marker unused) {
 * String name = (String) args[0];
 * if (name.equals(
 * "java/lang/ClassName.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) {
 * this((String)arg[1], arg[2]);
 * return
 * }
 * if (name.equals("SuperClassName.(Ljava/lang/String;I)V")) {
 * super((String)arg[1], (int)arg[2]);
 * return;
 * }
 * ...
 * StringBuilder $local1 = new StringBuilder();
 * $local1.append("Method not found ");
 * $local1.append(name);
 * $local1.append(" in " $classType $super implementation");
 * throw new $package/InstantReloadException($local1.toString());
 * }
 * </code>
 */
private void createDispatchingThis() {
    // Gather all methods from itself and its superclasses to generate a giant constructor
    // implementation.
    // This will work fine as long as we don't support adding constructors to classes.
    final Map<String, MethodNode> uniqueMethods = new HashMap<String, MethodNode>();

    addAllNewConstructors(uniqueMethods, classNode, true /*keepPrivateConstructors*/);
    for (ClassNode parentNode : parentNodes) {
        addAllNewConstructors(uniqueMethods, parentNode, false /*keepPrivateConstructors*/);
    }

    int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;

    Method m = new Method(AsmUtils.CONSTRUCTOR,
            ConstructorArgsRedirection.DISPATCHING_THIS_SIGNATURE);
    MethodVisitor visitor = super.visitMethod(0, m.getName(), m.getDescriptor(), null, null);
    final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);

    mv.visitCode();
    // Mark this code as redirection code
    Label label = new Label();
    mv.visitLineNumber(0, label);

    // Get and store the constructor canonical name.
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.push(0);
    mv.visitInsn(Opcodes.AALOAD);
    mv.unbox(Type.getType("Ljava/lang/String;"));
    final int constructorCanonicalName = mv.newLocal(Type.getType("Ljava/lang/String;"));
    mv.storeLocal(constructorCanonicalName);

    new StringSwitch() {

        @Override
        void visitString() {
            mv.loadLocal(constructorCanonicalName);
        }

        @Override
        void visitCase(String canonicalName) {
            MethodNode methodNode = uniqueMethods.get(canonicalName);
            String owner = canonicalName.split("\\.")[0];

            // Parse method arguments and
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            Type[] args = Type.getArgumentTypes(methodNode.desc);
            int argc = 0;
            for (Type t : args) {
                mv.visitVarInsn(Opcodes.ALOAD, 1);
                mv.push(argc + 1);
                mv.visitInsn(Opcodes.AALOAD);
                ByteCodeUtils.unbox(mv, t);
                argc++;
            }

            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, AsmUtils.CONSTRUCTOR,
                    methodNode.desc, false);

            mv.visitInsn(Opcodes.RETURN);
        }

        @Override
        void visitDefault() {
            writeMissingMessageWithHash(mv, visitedClassName);
        }
    }.visit(mv, uniqueMethods.keySet());

    mv.visitMaxs(1, 3);
    mv.visitEnd();
}
 
Example 4
Source File: TestThreadExecutionGenerator.java    From lin-check with GNU Lesser General Public License v3.0 4 votes vote down vote up
private static void generateRun(ClassVisitor cv, Type testType, int iThread, List<Actor> actors, List<Object> objArgs, boolean waitsEnabled) {
    int access = ACC_PUBLIC;
    Method m = new Method("call", RESULT_ARRAY_TYPE, NO_ARGS);
    GeneratorAdapter mv = new GeneratorAdapter(access, m,
        // Try-catch blocks sorting is required
        new TryCatchBlockSorter(cv.visitMethod(access, m.getName(), m.getDescriptor(), null, null),
            access, m.getName(), m.getDescriptor(), null, null)
    );
    mv.visitCode();
    // Create Result[] array and store it to a local variable
    int resLocal = createResultArray(mv, actors.size());
    // Call runner's onStart(iThread) method
    mv.loadThis();
    mv.getField(TEST_THREAD_EXECUTION_TYPE, "runner", RUNNER_TYPE);
    mv.push(iThread);
    mv.invokeVirtual(RUNNER_TYPE, RUNNER_ON_START_METHOD);
    // Number of current operation (starts with 0)
    int iLocal = mv.newLocal(Type.INT_TYPE);
    mv.push(0);
    mv.storeLocal(iLocal);
    // Invoke actors
    for (int i = 0; i < actors.size(); i++) {
        Actor actor = actors.get(i);
        // Add busy-wait before operation execution (for non-first operations only)
        if (waitsEnabled && i > 0) {
            mv.loadThis();
            mv.getField(TEST_THREAD_EXECUTION_TYPE, "waits", INT_ARRAY_TYPE);
            mv.push(i - 1);
            mv.arrayLoad(Type.INT_TYPE);
            mv.invokeStatic(UTILS_TYPE, UTILS_CONSUME_CPU);
        }
        // Start of try-catch block for exceptions which this actor should handle
        Label start, end = null, handler = null, handlerEnd = null;
        if (actor.handlesExceptions()) {
            start = mv.newLabel();
            end = mv.newLabel();
            handler = mv.newLabel();
            handlerEnd = mv.newLabel();
            for (Class<? extends Throwable> ec : actor.handledExceptions)
                mv.visitTryCatchBlock(start, end, handler, Type.getType(ec).getInternalName());
            mv.visitLabel(start);
        }
        // Load result array and index to store the current result
        mv.loadLocal(resLocal);
        mv.push(i);
        // Load test instance
        mv.loadThis();
        mv.getField(TEST_THREAD_EXECUTION_TYPE, "testInstance", OBJECT_TYPE);
        mv.checkCast(testType);
        // Load arguments for operation
        for (int j = 0; j < actor.arguments.length; j++) {
            pushArgumentOnStack(mv, objArgs, actor.arguments[j], actor.method.getParameterTypes()[j]);
        }
        // Invoke operation
        Method actorMethod = Method.getMethod(actor.method);
        mv.invokeVirtual(testType, actorMethod);
        // Create result
        mv.box(actorMethod.getReturnType()); // box if needed
        if (actor.method.getReturnType() == void.class) {
            mv.pop();
            mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_VOID_RESULT);
        } else {
            mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_VALUE_RESULT);
        }
        // Store result to array
        mv.arrayStore(RESULT_TYPE);
        // End of try-catch block
        if (actor.handlesExceptions()) {
            mv.visitLabel(end);
            mv.goTo(handlerEnd);
            mv.visitLabel(handler);
            storeExceptionResultFromThrowable(mv, resLocal, iLocal);
            mv.visitLabel(handlerEnd);
        }
        // Increment number of current operation
        mv.iinc(iLocal, 1);
    }
    // Call runner's onFinish(iThread) method
    mv.loadThis();
    mv.getField(TEST_THREAD_EXECUTION_TYPE, "runner", RUNNER_TYPE);
    mv.push(iThread);
    mv.invokeVirtual(RUNNER_TYPE, RUNNER_ON_FINISH_METHOD);
    // Return results
    mv.loadThis();
    mv.loadLocal(resLocal);
    mv.returnValue();
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}