Search in sources :

Example 21 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project android_frameworks_base by AOSPA.

the class AsmGenerator method transform.

/**
     * Transforms a class.
     * <p/>
     * There are 3 kind of transformations:
     *
     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
     * left intact. Modified classes must be overridable (non-private, non-final).
     * Native methods must be made non-final, non-private.
     *
     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
     * If a class has native methods, it must also be made non-private, non-final.
     *
     * Note that unfortunately static methods cannot be changed to non-static (since static and
     * non-static are invoked differently.)
     */
byte[] transform(ClassReader cr, boolean stubNativesOnly) {
    boolean hasNativeMethods = hasNativeMethods(cr);
    // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
    String className = cr.getClassName();
    String newName = transformName(className);
    // transformName returns its input argument if there's no need to rename the class
    if (!newName.equals(className)) {
        mRenameCount++;
        // This class is being renamed, so remove it from the list of classes not renamed.
        mClassesNotRenamed.remove(className);
    }
    mLog.debug("Transform %s%s%s%s", className, newName.equals(className) ? "" : " (renamed to " + newName + ")", hasNativeMethods ? " -- has natives" : "", stubNativesOnly ? " -- stub natives only" : "");
    // Rewrite the new class from scratch, without reusing the constant pool from the
    // original class reader.
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;
    // FIXME Generify
    if ("android/content/res/Resources".equals(className)) {
        cv = new FieldInjectorAdapter(cv);
    }
    if (mReplaceMethodCallsClasses.contains(className)) {
        cv = new ReplaceMethodCallsAdapter(cv, className);
    }
    cv = new RefactorClassAdapter(cv, mRefactorClasses);
    if (!newName.equals(className)) {
        cv = new RenameClassAdapter(cv, className, newName);
    }
    String binaryNewName = newName.replace('/', '.');
    if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
        cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
    }
    cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), newName, cv, stubNativesOnly);
    Set<String> delegateMethods = mDelegateMethods.get(className);
    if (delegateMethods != null && !delegateMethods.isEmpty()) {
        // known to have no native methods, just skip this step.
        if (hasNativeMethods || !(delegateMethods.size() == 1 && delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
            cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
        }
    }
    Set<String> promoteFields = mPromotedFields.get(className);
    if (promoteFields != null && !promoteFields.isEmpty()) {
        cv = new PromoteFieldClassAdapter(cv, promoteFields);
    }
    cr.accept(cv, 0);
    return cw.toByteArray();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter)

Example 22 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project android_frameworks_base by ResurrectionRemix.

the class AsmGenerator method transform.

/**
     * Transforms a class.
     * <p/>
     * There are 3 kind of transformations:
     *
     * 1- For "mock" dependencies classes, we want to remove all code from methods and replace
     * by a stub. Native methods must be implemented with this stub too. Abstract methods are
     * left intact. Modified classes must be overridable (non-private, non-final).
     * Native methods must be made non-final, non-private.
     *
     * 2- For "keep" classes, we want to rewrite all native methods as indicated above.
     * If a class has native methods, it must also be made non-private, non-final.
     *
     * Note that unfortunately static methods cannot be changed to non-static (since static and
     * non-static are invoked differently.)
     */
byte[] transform(ClassReader cr, boolean stubNativesOnly) {
    boolean hasNativeMethods = hasNativeMethods(cr);
    // Get the class name, as an internal name (e.g. com/android/SomeClass$InnerClass)
    String className = cr.getClassName();
    String newName = transformName(className);
    // transformName returns its input argument if there's no need to rename the class
    if (!newName.equals(className)) {
        mRenameCount++;
        // This class is being renamed, so remove it from the list of classes not renamed.
        mClassesNotRenamed.remove(className);
    }
    mLog.debug("Transform %s%s%s%s", className, newName.equals(className) ? "" : " (renamed to " + newName + ")", hasNativeMethods ? " -- has natives" : "", stubNativesOnly ? " -- stub natives only" : "");
    // Rewrite the new class from scratch, without reusing the constant pool from the
    // original class reader.
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;
    // FIXME Generify
    if ("android/content/res/Resources".equals(className)) {
        cv = new FieldInjectorAdapter(cv);
    }
    if (mReplaceMethodCallsClasses.contains(className)) {
        cv = new ReplaceMethodCallsAdapter(cv, className);
    }
    cv = new RefactorClassAdapter(cv, mRefactorClasses);
    if (!newName.equals(className)) {
        cv = new RenameClassAdapter(cv, className, newName);
    }
    String binaryNewName = newName.replace('/', '.');
    if (mInjectedMethodsMap.keySet().contains(binaryNewName)) {
        cv = new InjectMethodsAdapter(cv, mInjectedMethodsMap.get(binaryNewName));
    }
    cv = new TransformClassAdapter(mLog, mStubMethods, mDeleteReturns.get(className), newName, cv, stubNativesOnly);
    Set<String> delegateMethods = mDelegateMethods.get(className);
    if (delegateMethods != null && !delegateMethods.isEmpty()) {
        // known to have no native methods, just skip this step.
        if (hasNativeMethods || !(delegateMethods.size() == 1 && delegateMethods.contains(DelegateClassAdapter.ALL_NATIVES))) {
            cv = new DelegateClassAdapter(mLog, cv, className, delegateMethods);
        }
    }
    Set<String> promoteFields = mPromotedFields.get(className);
    if (promoteFields != null && !promoteFields.isEmpty()) {
        cv = new PromoteFieldClassAdapter(cv, promoteFields);
    }
    cr.accept(cv, 0);
    return cw.toByteArray();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter)

Example 23 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project CodeChickenLib by Chicken-Bones.

the class ASMHelper method dump.

public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
    try {
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        if (!file.exists())
            file.createNewFile();
        PrintWriter pout = new PrintWriter(file);
        ClassVisitor cv = new TraceClassVisitor(null, textify ? new Textifier() : new ASMifier(), pout);
        if (filterImportant)
            cv = new ImportantInsnVisitor(cv);
        if (sortLocals)
            cv = new LocalVariablesSorterVisitor(cv);
        acceptor.accept(cv);
        pout.close();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : ASMifier(org.objectweb.asm.util.ASMifier) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) IOException(java.io.IOException) Textifier(org.objectweb.asm.util.Textifier) PrintWriter(java.io.PrintWriter)

Example 24 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project aries by apache.

the class ProxySubclassGenerator method generateAndLoadSubclass.

private static Class<?> generateAndLoadSubclass(Class<?> aClass, ClassLoader loader) throws UnableToProxyException {
    LOGGER.debug(Constants.LOG_ENTRY, "generateAndLoadSubclass", new Object[] { aClass, loader });
    // set the newClassName
    String newClassName = "$" + aClass.getSimpleName() + aClass.hashCode();
    String packageName = aClass.getPackage().getName();
    if (packageName.startsWith("java.") || packageName.startsWith("javax.")) {
        packageName = "org.apache.aries.blueprint.proxy." + packageName;
    }
    String fullNewClassName = (packageName + "." + newClassName).replaceAll("\\.", "/");
    LOGGER.debug("New class name: {}", newClassName);
    LOGGER.debug("Full new class name: {}", fullNewClassName);
    Class<?> clazz = null;
    try {
        ClassReader cReader = new ClassReader(loader.getResourceAsStream(aClass.getName().replaceAll("\\.", "/") + ".class"));
        ClassWriter cWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        ClassVisitor dynamicSubclassAdapter = new ProxySubclassAdapter(cWriter, fullNewClassName, loader);
        byte[] byteClassData = processClass(cReader, cWriter, dynamicSubclassAdapter);
        clazz = loadClassFromBytes(loader, getBinaryName(fullNewClassName), byteClassData, aClass.getName());
    } catch (IOException ioe) {
        LOGGER.debug(Constants.LOG_EXCEPTION, ioe);
        throw new ProxyClassBytecodeGenerationException(aClass.getName(), ioe);
    } catch (TypeNotPresentException tnpe) {
        LOGGER.debug(Constants.LOG_EXCEPTION, tnpe);
        throw new ProxyClassBytecodeGenerationException(tnpe.typeName(), tnpe.getCause());
    }
    LOGGER.debug(Constants.LOG_EXIT, "generateAndLoadSubclass", clazz);
    return clazz;
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter)

Example 25 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project aries by apache.

the class Synthesizer method main.

/**
   * This is the main method for running the Synthesizer
   * 
   * @param args - String[] of file paths to class files
   * @throws Exception 
   */
public static void main(String[] args) throws Exception {
    //add the synthetic modifier for each of the supplied args
    for (String arg : args) {
        FileInputStream classInStream = null;
        ClassWriter writer = null;
        try {
            //read in the class
            classInStream = new FileInputStream(arg);
            ClassReader reader = new ClassReader(classInStream);
            //make a ClassWriter constructed with the reader for speed
            //since we are mostly just copying
            //we just need to override the visit method so we can add
            //the synthetic modifier, otherwise we use the methods in
            //a standard writer
            writer = new ClassWriter(reader, 0);
            ClassVisitor cv = new CustomClassVisitor((ClassVisitor) writer);
            //call accept on the reader to start the visits
            //using the writer we created as the visitor
            reader.accept(cv, 0);
        } finally {
            if (classInStream != null)
                classInStream.close();
        }
        FileOutputStream classOutStream = null;
        try {
            //write out the new bytes of the class file
            classOutStream = new FileOutputStream(arg);
            if (writer != null)
                classOutStream.write(writer.toByteArray());
        } finally {
            //close the OutputStream if it is still around
            if (classOutStream != null)
                classOutStream.close();
        }
    }
}
Also used : FileOutputStream(java.io.FileOutputStream) ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor) FileInputStream(java.io.FileInputStream) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

ClassVisitor (org.objectweb.asm.ClassVisitor)70 ClassReader (org.objectweb.asm.ClassReader)47 ClassWriter (org.objectweb.asm.ClassWriter)41 MethodVisitor (org.objectweb.asm.MethodVisitor)23 InputStream (java.io.InputStream)12 IOException (java.io.IOException)10 Type (org.objectweb.asm.Type)9 Test (org.junit.Test)7 File (java.io.File)6 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)6 FieldList (net.bytebuddy.description.field.FieldList)5 MethodList (net.bytebuddy.description.method.MethodList)5 TypeDescription (net.bytebuddy.description.type.TypeDescription)5 TypePool (net.bytebuddy.pool.TypePool)5 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)5 URL (java.net.URL)4 MethodDescription (net.bytebuddy.description.method.MethodDescription)4 FileOutputStream (java.io.FileOutputStream)3 Path (java.nio.file.Path)3 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)3