Example usage for org.objectweb.asm.tree ClassNode ClassNode

List of usage examples for org.objectweb.asm.tree ClassNode ClassNode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree ClassNode ClassNode.

Prototype

public ClassNode(final int api) 

Source Link

Document

Constructs a new ClassNode .

Usage

From source file:de.tuberlin.uebb.jbop.access.OptimizerUtils.java

License:Open Source License

/**
 * Read class.//from ww  w. j av  a  2s  .  c om
 * 
 * @param input
 *          the input
 * @return the class node
 * @throws JBOPClassException
 *           the jBOP class exception
 */
public static ClassNode readClass(final Object input) throws JBOPClassException {
    final ClassReader classReader = new ClassReader(ClassAccessor.toBytes(input));
    final ClassNode classNode = new ClassNode(Opcodes.ASM5);
    classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
    return classNode;
}

From source file:de.tuberlin.uebb.jbop.optimizer.ClassNodeBuilder.java

License:Open Source License

private ClassNodeBuilder(final String className, final String superClass, final String constructorDesc,
        final String superConstructorDesc, final boolean isInterface) {
    this.isInterface = isInterface;
    classNode = new ClassNode(Opcodes.ASM5);
    classNode.access = ACC_PUBLIC;//from w  ww  .  ja va  2s  .c om
    classNode.name = className.replace(".", "/");
    if (superClass != null) {
        classNode.superName = superClass.replace(".", "/");
    }
    classNode.version = Opcodes.V1_7;
    if (!isInterface) {
        addConstructor(constructorDesc, superConstructorDesc);
    } else {
        classNode.access |= ACC_INTERFACE;
        classNode.access |= ACC_ABSTRACT;
    }
    lastElement = null;
}

From source file:de.tuberlin.uebb.jbop.optimizer.utils.NodeHelper.java

License:Open Source License

/**
 * To classbuilder./*  w  w w  . ja va 2s .c  om*/
 * Prints Javacode to generate the given method with {@link de.tuberlin.uebb.jbop.optimizer.ClassNodeBuilder}.
 * 
 * @param methodName
 *          the method name
 * @param ofClass
 *          the of class
 * @throws IOException
 *           Signals that an I/O exception has occurred.
 */
public static void toClassbuilder(final String methodName, final Class<?> ofClass) throws IOException {
    final ClassNode classVisitor = new ClassNode(ASM5);
    new ClassReader(ofClass.getName()).accept(classVisitor, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
    for (final MethodNode method : classVisitor.methods) {
        if (methodName.equals(method.name)) {
            NodeHelper.printMethod(method, true);
        }
    }
}

From source file:edu.mit.streamjit.util.bytecode.KlassUnresolver.java

License:Open Source License

private KlassUnresolver(Klass k) {
    this.klass = k;
    this.classNode = new ClassNode(Opcodes.ASM4);
}

From source file:jvstm.atomic.ProcessParNestAnnotations.java

License:Open Source License

protected static void processClassFile(File classFile) {
    alreadyProcessed = new ArrayList<String>();
    callablesCreated = new HashMap<String, String>();
    InputStream is = null;//from   w  w w .  j  a v a 2  s .  co  m

    try {
        // get an input stream to read the bytecode of the class
        is = new FileInputStream(classFile);
        ClassNode cn = new ClassNode(ASM4);
        ClassReader cr = new ClassReader(is);
        cr.accept(cn, 0);

        List<MethodNode> parNestedMethods = new ArrayList<MethodNode>();
        MethodNode combinerMethod = null;
        MethodNode execMethod = null;

        List<MethodNode> staticMethodsToAdd = new ArrayList<MethodNode>();

        boolean parallelSpawn = extendsParallelSpawn(cn);
        boolean unsafeSpawn = extendsUnsafeSpawn(cn);
        if (parallelSpawn || unsafeSpawn) {
            Iterator<MethodNode> methodIter = cn.methods.iterator();
            while (methodIter.hasNext()) {
                MethodNode mn = methodIter.next();
                if (mn.name.equals("exec") && execMethod == null) {
                    execMethod = mn;
                    continue;
                }
                if (mn.invisibleAnnotations == null) {
                    continue;
                }
                for (AnnotationNode an : mn.invisibleAnnotations) {
                    if (an.desc.equals(PAR_NEST.getDescriptor())) {
                        // Ensure the method can be called from outside
                        mn.access = (mn.access & ~ACC_PRIVATE) | ACC_PUBLIC;
                        parNestedMethods.add(mn);
                        String uniqueMethodName = createUniqueMethodName(mn.name);
                        String callableClass;
                        if (parallelSpawn) {
                            callableClass = cn.name + "$nested$work$unit$" + uniqueMethodName;
                        } else {
                            callableClass = cn.name + "$unsafe$work$unit$" + uniqueMethodName;
                        }
                        callablesCreated.put(mn.name, callableClass);
                        boolean readOnlyCallable = (an.values == null) ? false : (Boolean) an.values.get(1);
                        generateCallable(classFile, cn.name, callableClass, mn, readOnlyCallable, unsafeSpawn);
                        staticMethodsToAdd.add(generateStaticCallableCreation(cn, cn.name, callableClass, mn));
                        break;
                    } else if (an.desc.equals(COMBINER.getDescriptor())) {
                        if (combinerMethod != null) {
                            throw new RuntimeException("Class: " + cn.name + " contains two @Combiner methods: "
                                    + combinerMethod.name + " and " + mn.name);
                        }
                        combinerMethod = mn;
                    }
                }
            }

            // TODO Verify the @Combiner method
            // The return should be of the same type of the parameterization
            // of the ParallelSpawn

            for (MethodNode methodToAdd : staticMethodsToAdd) {
                cn.methods.add(methodToAdd);
            }

            if (alreadyProcessed.size() == 0) {
                throw new RuntimeException(
                        "Class: " + cn.name + " must have at least one method annotated with @ParNested");
            }
            if (combinerMethod == null) {
                throw new RuntimeException(
                        "Class: " + cn.name + " must have one method annotated with @Combiner");
            }

            List<Integer> localVariablesIdx = new ArrayList<Integer>();
            int numberLocalVariables = 0;
            int listIndex = execMethod.maxLocals;
            execMethod.maxLocals++;

            InsnList preamble = new InsnList();
            preamble.add(new TypeInsnNode(NEW, ARRAY_LIST.getInternalName()));
            preamble.add(new InsnNode(DUP));
            preamble.add(new MethodInsnNode(INVOKESPECIAL, ARRAY_LIST.getInternalName(), "<init>", "()V"));
            preamble.add(new VarInsnNode(ASTORE, listIndex));

            Iterator<AbstractInsnNode> execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode instr = execInstIter.next();
                // Look out for calls to methods
                if (instr.getOpcode() == INVOKEVIRTUAL || instr.getOpcode() == INVOKESPECIAL) {
                    MethodInsnNode methodInstr = (MethodInsnNode) instr;
                    // Is method being called annotated with @ParNested
                    for (MethodNode parNestedMethod : parNestedMethods) {
                        if (parNestedMethod.name.equals(methodInstr.name)) {
                            numberLocalVariables++;
                        }
                    }
                }
            }

            for (int i = 0; i < numberLocalVariables; i++) {
                localVariablesIdx.add(i, execMethod.maxLocals);
                execMethod.maxLocals++;
            }

            int callablesManipulated = 0;
            execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode instr = execInstIter.next();
                // Look out for calls to methods
                if (instr.getOpcode() != INVOKEVIRTUAL && instr.getOpcode() != INVOKESPECIAL) {
                    continue;
                }

                MethodInsnNode methodInstr = (MethodInsnNode) instr;
                // Is method being called annotated with @ParNested
                boolean isParNestedMethod = false;
                for (MethodNode parNestedMethod : parNestedMethods) {
                    if (parNestedMethod.name.equals(methodInstr.name)) {
                        isParNestedMethod = true;
                        break;
                    }
                }
                if (!isParNestedMethod) {
                    continue;
                }

                // Let's change this call
                // If it was a call to: @ParNested public int add(int i1,
                // int i2)
                // add(foo, bar) -> add$static$callable$creator(this, foo,
                // bar)
                // the 'this' will be already in the right place in the
                // stack
                // because the method being called now is static whereas
                // previously
                // it was not
                methodInstr.setOpcode(INVOKESTATIC);
                methodInstr.name = methodInstr.name + "$static$callable$creator";
                for (MethodNode staticCreated : staticMethodsToAdd) {
                    if (staticCreated.name.equals(methodInstr.name)) {
                        methodInstr.desc = staticCreated.desc;
                        break;
                    }
                }

                InsnList midterm = new InsnList();

                // Store the callable instantiated in local variable
                midterm.add(new VarInsnNode(ASTORE, localVariablesIdx.get(callablesManipulated)));
                // Load the list
                midterm.add(new VarInsnNode(ALOAD, listIndex));
                // Load the callable
                midterm.add(new VarInsnNode(ALOAD, localVariablesIdx.get(callablesManipulated)));
                // Add it to the list
                midterm.add(new MethodInsnNode(INVOKEVIRTUAL, ARRAY_LIST.getInternalName(), "add",
                        "(Ljava/lang/Object;)Z"));
                // Pop the boolean that results from the add(Object)
                // May reuse a POP if the previous call had a return
                if (methodInstr.getNext().getOpcode() != POP) {
                    midterm.add(new InsnNode(POP));
                }

                // Add this set of instructions after the call to the
                // constrution of the callable
                execMethod.instructions.insert(methodInstr, midterm);
                callablesManipulated++;

            }

            // Insert the preamble in the start
            execMethod.instructions.insert(preamble);

            InsnList finish = new InsnList();
            // Push 'this' for the call to the combiner method
            finish.add(new VarInsnNode(ALOAD, 0));
            // Call the static method current() of jvstm.Transaction
            finish.add(new MethodInsnNode(INVOKESTATIC, TRANSACTION.getInternalName(), "current",
                    "()Ljvstm/Transaction;"));
            // Load the callables list
            finish.add(new VarInsnNode(ALOAD, listIndex));
            // Call the manage parnested method
            finish.add(new MethodInsnNode(INVOKEVIRTUAL, TRANSACTION.getInternalName(),
                    "manageNestedParallelTxs", "(Ljava/util/List;)Ljava/util/List;"));
            // Call the combiner method
            finish.add(new MethodInsnNode(INVOKEVIRTUAL, cn.name, combinerMethod.name, combinerMethod.desc));
            // Return what the combiner returns
            finish.add(new InsnNode(ARETURN));

            // Remove the "return null" that's supposed to be at the end of
            // the exec method
            execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode curNode = execInstIter.next();
                if (!execInstIter.hasNext()) {
                    // Insert the finish in the end
                    execMethod.instructions.insert(curNode.getPrevious().getPrevious(), finish);
                    execMethod.instructions.remove(curNode.getPrevious());
                    execMethod.instructions.remove(curNode);
                    break;
                }
            }

        }

        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cn.accept(cw);
        writeClassFile(classFile, cw.toByteArray());
    } catch (IOException e) {
        throw new Error("Error processing class file", e);
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
}

From source file:net.dv8tion.ClassTransformer.java

License:Apache License

/**
 * Helper method to modify the getAllUsernames method in ServerConfigurationManager.
 * Takes into account obfuscated method names based on boolean.
 * //  w ww .j av a2s .c  o m
 * Replaces the call "return astring" at the end of ServerConfigurationManager's
 * getAllUsernames method with "return NameLoader.loadNames(astring)"
 * Because of how The JVM and ByteCode work with arrays, we do not need to
 * remove any instructions, only inject code. The array "astring" in the
 * call "return astring" will be provided as the param for the loadNames method.
 * 
 * @param className
 *            The class name, proceeded by the package it is in, if it is in one.
 * @param classData
 *            The byte code of the class.
 * @param obfuscated
 *            Is the code obfuscated?
 * @return
 *         Returns the modified byte code of the class.
 */
public byte[] patchClassWithASM(String className, byte[] classData, boolean obfuscated) {
    String methodName = obfuscated ? "d" : "getAllUsernames";

    ClassNode classNode = new ClassNode(Opcodes.ASM4);
    ClassReader classReader = new ClassReader(classData);
    classReader.accept(classNode, ClassReader.EXPAND_FRAMES);

    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        MethodNode m = methods.next();
        int arrayReturn_index = -1;

        if ((m.name.equals(methodName) && m.desc.equals("()[Ljava/lang/String;"))) {
            AbstractInsnNode currentNode = null;
            Iterator<AbstractInsnNode> iter = m.instructions.iterator();

            int index = -1;

            while (iter.hasNext()) {
                index++;
                currentNode = iter.next();

                if (currentNode.getOpcode() == Opcodes.ARETURN) {
                    arrayReturn_index = index;
                }
            }

            //Calls NameLoader.loadNames(String[]) 
            m.instructions.insertBefore(m.instructions.get(arrayReturn_index),
                    new MethodInsnNode(Opcodes.INVOKESTATIC, "net/dv8tion/NameLoader", "loadNames",
                            "([Ljava/lang/String;)[Ljava/lang/String;"));

            System.out.println("[IRC NameBridge] Patching Complete!");
            break;
        }
    }
    //ASM specific for cleaning up and returning the final bytes for JVM processing.
    //Use 0 here instead of like ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS because
    //We need to have ASM recalculate things.  
    ClassWriter writer = new ClassWriter(0);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.fabricmc.weave.merge.ClassMerger.java

License:Apache License

public byte[] merge(byte[] classClient, byte[] classServer) {
    ClassReader readerC = new ClassReader(classClient);
    ClassReader readerS = new ClassReader(classServer);
    ClassWriter writer = new ClassWriter(0);

    ClassNode nodeC = new ClassNode(Opcodes.ASM5);
    readerC.accept(nodeC, 0);//from   w  w w . ja va2  s. co  m

    ClassNode nodeS = new ClassNode(Opcodes.ASM5);
    readerS.accept(nodeS, 0);

    ClassNode nodeOut = new ClassNode(Opcodes.ASM5);
    nodeOut.version = nodeC.version;
    nodeOut.access = nodeC.access;
    nodeOut.name = nodeC.name;
    nodeOut.signature = nodeC.signature;
    nodeOut.interfaces = nodeC.interfaces;
    nodeOut.superName = nodeC.superName;
    nodeOut.sourceFile = nodeC.sourceFile;
    nodeOut.sourceDebug = nodeC.sourceDebug;
    nodeOut.outerClass = nodeC.outerClass;
    nodeOut.outerMethod = nodeC.outerMethod;
    nodeOut.outerMethodDesc = nodeC.outerMethodDesc;

    nodeOut.invisibleAnnotations = nodeC.invisibleAnnotations;
    nodeOut.invisibleTypeAnnotations = nodeC.invisibleTypeAnnotations;
    nodeOut.visibleAnnotations = nodeC.visibleAnnotations;
    nodeOut.visibleTypeAnnotations = nodeC.visibleTypeAnnotations;
    nodeOut.attrs = nodeC.attrs;

    new Merger<InnerClassNode>(nodeC.innerClasses, nodeS.innerClasses) {
        @Override
        public String getName(InnerClassNode entry) {
            return entry.name;
        }

        @Override
        public void applySide(InnerClassNode entry, String side) {
        }
    }.merge(nodeOut.innerClasses);

    new Merger<FieldNode>(nodeC.fields, nodeS.fields) {
        @Override
        public String getName(FieldNode entry) {
            return entry.name + "," + entry.desc + "," + entry.signature;
        }

        @Override
        public void applySide(FieldNode entry, String side) {
            AnnotationVisitor av = entry.visitAnnotation("Lnet/fabricmc/api/Sided;", true);
            visitSideAnnotation(av, side);
        }
    }.merge(nodeOut.fields);

    new Merger<MethodNode>(nodeC.methods, nodeS.methods) {
        @Override
        public String getName(MethodNode entry) {
            return entry.name + "," + entry.desc + "," + entry.signature;
        }

        @Override
        public void applySide(MethodNode entry, String side) {
            AnnotationVisitor av = entry.visitAnnotation("Lnet/fabricmc/api/Sided;", true);
            visitSideAnnotation(av, side);
        }
    }.merge(nodeOut.methods);

    nodeOut.accept(writer);
    return writer.toByteArray();
}

From source file:org.apache.commons.weaver.privilizer.BlueprintingVisitor.java

License:Apache License

/**
 * Create a new {@link BlueprintingVisitor}.
 * @param privilizer owner/* w w  w  . j  av  a2 s  .c om*/
 * @param nextVisitor wrapped
 * @param config annotation
 */
BlueprintingVisitor(@SuppressWarnings("PMD.UnusedFormalParameter") final Privilizer privilizer, //false positive
        final ClassVisitor nextVisitor, final Privilizing config) {
    privilizer.super(new ClassNode(Privilizer.ASM_VERSION));
    this.nextVisitor = nextVisitor;

    // load up blueprint methods:
    for (final Privilizing.CallTo callTo : config.value()) {
        final Type blueprintType = Type.getType(callTo.value());
        blueprintTypes.add(blueprintType);

        final Set<String> methodNames = new HashSet<>(Arrays.asList(callTo.methods()));

        typeInfo(blueprintType).methods.entrySet().stream()
                .filter(e -> methodNames.isEmpty() || methodNames.contains(e.getKey().getName()))
                .forEach(e -> blueprintRegistry.put(Pair.of(blueprintType, e.getKey()), e.getValue()));
    }
}

From source file:org.apache.commons.weaver.privilizer.BlueprintingVisitor.java

License:Apache License

private ClassNode read(final String className) {
    final ClassNode result = new ClassNode(Privilizer.ASM_VERSION);
    try (InputStream bytecode = privilizer().env.getClassfile(className).getInputStream()) {
        new ClassReader(bytecode).accept(result, ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES);
    } catch (final Exception e) {
        throw new IllegalStateException(e);
    }//  ww w . j av a 2 s . c o m
    return result;
}

From source file:org.apache.drill.exec.compile.AsmUtil.java

License:Apache License

/**
 * Create a ClassNode from bytecode./*  www. j a  va 2  s. c  om*/
 *
 * @param classBytes the bytecode
 * @param asmReaderFlags flags for ASM; see {@link org.objectweb.asm.ClassReader#accept(org.objectweb.asm.ClassVisitor, int)}
 * @return the ClassNode
 */
public static ClassNode classFromBytes(final byte[] classBytes, final int asmReaderFlags) {
    final ClassNode classNode = new ClassNode(CompilationConfig.ASM_API_VERSION);
    final ClassReader classReader = new ClassReader(classBytes);
    classReader.accept(classNode, asmReaderFlags);
    return classNode;
}