Search in sources :

Example 26 with ClassWriter

use of org.objectweb.asm.ClassWriter in project presto by prestodb.

the class CompilerUtils method defineClasses.

private static Map<String, Class<?>> defineClasses(List<ClassDefinition> classDefinitions, DynamicClassLoader classLoader) {
    ClassInfoLoader classInfoLoader = ClassInfoLoader.createClassInfoLoader(classDefinitions, classLoader);
    if (DUMP_BYTE_CODE_TREE) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DumpBytecodeVisitor dumpBytecode = new DumpBytecodeVisitor(new PrintStream(out));
        for (ClassDefinition classDefinition : classDefinitions) {
            dumpBytecode.visitClass(classDefinition);
        }
        System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8));
    }
    Map<String, byte[]> bytecodes = new LinkedHashMap<>();
    for (ClassDefinition classDefinition : classDefinitions) {
        ClassWriter cw = new SmartClassWriter(classInfoLoader);
        try {
            classDefinition.visit(ADD_FAKE_LINE_NUMBER ? new AddFakeLineNumberClassVisitor(cw) : cw);
        } catch (IndexOutOfBoundsException | NegativeArraySizeException e) {
            Printer printer = new Textifier();
            StringWriter stringWriter = new StringWriter();
            TraceClassVisitor tcv = new TraceClassVisitor(null, printer, new PrintWriter(stringWriter));
            classDefinition.visit(tcv);
            throw new IllegalArgumentException("An error occurred while processing classDefinition:" + System.lineSeparator() + stringWriter.toString(), e);
        }
        try {
            byte[] bytecode = cw.toByteArray();
            if (RUN_ASM_VERIFIER) {
                ClassReader reader = new ClassReader(bytecode);
                CheckClassAdapter.verify(reader, classLoader, true, new PrintWriter(System.out));
            }
            bytecodes.put(classDefinition.getType().getJavaClassName(), bytecode);
        } catch (RuntimeException e) {
            throw new CompilationException("Error compiling class " + classDefinition.getName(), e);
        }
    }
    String dumpClassPath = DUMP_CLASS_FILES_TO.get();
    if (dumpClassPath != null) {
        for (Map.Entry<String, byte[]> entry : bytecodes.entrySet()) {
            File file = new File(dumpClassPath, ParameterizedType.typeFromJavaClassName(entry.getKey()).getClassName() + ".class");
            try {
                log.debug("ClassFile: " + file.getAbsolutePath());
                Files.createParentDirs(file);
                Files.write(entry.getValue(), file);
            } catch (IOException e) {
                log.error(e, "Failed to write generated class file to: %s" + file.getAbsolutePath());
            }
        }
    }
    if (DUMP_BYTE_CODE_RAW) {
        for (byte[] bytecode : bytecodes.values()) {
            ClassReader classReader = new ClassReader(bytecode);
            classReader.accept(new TraceClassVisitor(new PrintWriter(System.err)), ClassReader.EXPAND_FRAMES);
        }
    }
    Map<String, Class<?>> classes = classLoader.defineClasses(bytecodes);
    try {
        for (Class<?> clazz : classes.values()) {
            Reflection.initialize(clazz);
        }
    } catch (VerifyError e) {
        throw new RuntimeException(e);
    }
    return classes;
}
Also used : Textifier(org.objectweb.asm.util.Textifier) Printer(org.objectweb.asm.util.Printer) LinkedHashMap(java.util.LinkedHashMap) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) StringWriter(java.io.StringWriter) PrintWriter(java.io.PrintWriter) PrintStream(java.io.PrintStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter) ClassReader(org.objectweb.asm.ClassReader) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) File(java.io.File)

Example 27 with ClassWriter

use of org.objectweb.asm.ClassWriter in project bazel by bazelbuild.

the class RClassGenerator method write.

/** Builds the bytecode and writes out the R.class file, and R$inner.class files. */
public void write() throws IOException {
    Iterable<String> folders = PACKAGE_SPLITTER.split(packageName);
    Path packageDir = outFolder;
    for (String folder : folders) {
        packageDir = packageDir.resolve(folder);
    }
    // At least create the outFolder that was requested. However, if there are no symbols, don't
    // create the R.class and inner class files (no need to have an empty class).
    Files.createDirectories(packageDir);
    if (initializers.isEmpty()) {
        return;
    }
    Path rClassFile = packageDir.resolve(SdkConstants.FN_COMPILED_RESOURCE_CLASS);
    String packageWithSlashes = packageName.replaceAll("\\.", "/");
    String rClassName = packageWithSlashes.isEmpty() ? "R" : (packageWithSlashes + "/R");
    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classWriter.visit(JAVA_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER, rClassName, null, /* signature */
    SUPER_CLASS, null);
    classWriter.visitSource(SdkConstants.FN_RESOURCE_CLASS, null);
    writeConstructor(classWriter);
    // Build the R.class w/ the inner classes, then later build the individual R$inner.class.
    for (ResourceType resourceType : initializers.keySet()) {
        String innerClassName = rClassName + "$" + resourceType;
        classWriter.visitInnerClass(innerClassName, rClassName, resourceType.toString(), Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC);
    }
    classWriter.visitEnd();
    Files.write(rClassFile, classWriter.toByteArray());
    // Now generate the R$inner.class files.
    for (Map.Entry<ResourceType, List<FieldInitializer>> entry : initializers.entrySet()) {
        writeInnerClass(entry.getValue(), packageDir, rClassName, entry.getKey().toString());
    }
}
Also used : Path(java.nio.file.Path) ResourceType(com.android.resources.ResourceType) ArrayList(java.util.ArrayList) List(java.util.List) Map(java.util.Map) EnumMap(java.util.EnumMap) ClassWriter(org.objectweb.asm.ClassWriter)

Example 28 with ClassWriter

use of org.objectweb.asm.ClassWriter in project bazel by bazelbuild.

the class GenZipWithEntries method dump.

public static byte[] dump(String name) {
    ClassWriter cw = new ClassWriter(0);
    cw.visit(52, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, name, null, "java/lang/Object", null);
    {
        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    cw.visitEnd();
    return cw.toByteArray();
}
Also used : ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 29 with ClassWriter

use of org.objectweb.asm.ClassWriter in project platform_frameworks_base by android.

the class DelegateClassAdapterTest method testConstructorsNotSupported.

/**
     * {@link DelegateMethodAdapter} does not support overriding constructors yet,
     * so this should fail with an {@link UnsupportedOperationException}.
     *
     * Although not tested here, the message of the exception should contain the
     * constructor signature.
     */
@Test(expected = UnsupportedOperationException.class)
public void testConstructorsNotSupported() throws IOException {
    ClassWriter cw = new ClassWriter(0);
    String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
    HashSet<String> delegateMethods = new HashSet<>();
    delegateMethods.add("<init>");
    DelegateClassAdapter cv = new DelegateClassAdapter(mLog, cw, internalClassName, delegateMethods);
    ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
    cr.accept(cv, 0);
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 30 with ClassWriter

use of org.objectweb.asm.ClassWriter in project platform_frameworks_base by android.

the class DelegateClassAdapterTest method testDelegateInner.

@Test
public void testDelegateInner() throws Throwable {
    // We'll delegate the "get" method of both the inner and outer class.
    HashSet<String> delegateMethods = new HashSet<>();
    delegateMethods.add("get");
    delegateMethods.add("privateMethod");
    // Generate the delegate for the outer class.
    ClassWriter cwOuter = new ClassWriter(0);
    String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvOuter = new DelegateClassAdapter(mLog, cwOuter, outerClassName, delegateMethods);
    ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
    cr.accept(cvOuter, 0);
    // Generate the delegate for the inner class.
    ClassWriter cwInner = new ClassWriter(0);
    String innerClassName = INNER_CLASS_NAME.replace('.', '/');
    DelegateClassAdapter cvInner = new DelegateClassAdapter(mLog, cwInner, innerClassName, delegateMethods);
    cr = new ClassReader(INNER_CLASS_NAME);
    cr.accept(cvInner, 0);
    // Load the generated classes in a different class loader and try them
    ClassLoader2 cl2 = null;
    try {
        cl2 = new ClassLoader2() {

            @Override
            public void testModifiedInstance() throws Exception {
                // Check the outer class
                Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
                Object o2 = outerClazz2.newInstance();
                assertNotNull(o2);
                // The original Outer.get returns 1+10+20,
                // but the delegate makes it return 4+10+20
                assertEquals(4 + 10 + 20, callGet(o2, 10, 20));
                assertEquals(1 + 10 + 20, callGet_Original(o2, 10, 20));
                // The original Outer has a private method,
                // so by default we can't access it.
                boolean gotIllegalAccessException = false;
                try {
                    callMethod(o2, "privateMethod", false);
                } catch (IllegalAccessException e) {
                    gotIllegalAccessException = true;
                }
                assertTrue(gotIllegalAccessException);
                // The private method from original Outer has been
                // delegated. The delegate generated should have the
                // same access.
                gotIllegalAccessException = false;
                try {
                    assertEquals("outerPrivateMethod", callMethod(o2, "privateMethod_Original", false));
                } catch (IllegalAccessException e) {
                    gotIllegalAccessException = true;
                }
                assertTrue(gotIllegalAccessException);
                // Check the inner class. Since it's not a static inner class, we need
                // to use the hidden constructor that takes the outer class as first parameter.
                Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
                Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
                Object i2 = innerCons.newInstance(o2);
                assertNotNull(i2);
                // The original Inner.get returns 3+10+20,
                // but the delegate makes it return 6+10+20
                assertEquals(6 + 10 + 20, callGet(i2, 10, 20));
                assertEquals(3 + 10 + 20, callGet_Original(i2, 10, 20));
            }
        };
        cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
        cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
        cl2.testModifiedInstance();
    } catch (Throwable t) {
        throw dumpGeneratedClass(t, cl2);
    }
}
Also used : Constructor(java.lang.reflect.Constructor) ClassWriter(org.objectweb.asm.ClassWriter) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ClassReader(org.objectweb.asm.ClassReader) OuterClass(com.android.tools.layoutlib.create.dataclass.OuterClass) StaticInnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.StaticInnerClass) InnerClass(com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

ClassWriter (org.objectweb.asm.ClassWriter)471 ClassReader (org.objectweb.asm.ClassReader)275 MethodVisitor (org.objectweb.asm.MethodVisitor)115 Test (org.junit.Test)94 ClassVisitor (org.objectweb.asm.ClassVisitor)82 ClassNode (org.objectweb.asm.tree.ClassNode)70 IOException (java.io.IOException)57 SemanticVersioningClassVisitor (org.apache.aries.versioning.utils.SemanticVersioningClassVisitor)52 Label (org.objectweb.asm.Label)51 HashSet (java.util.HashSet)37 Method (java.lang.reflect.Method)36 BinaryCompatibilityStatus (org.apache.aries.versioning.utils.BinaryCompatibilityStatus)32 Type (org.objectweb.asm.Type)30 File (java.io.File)27 InvocationTargetException (java.lang.reflect.InvocationTargetException)27 FieldVisitor (org.objectweb.asm.FieldVisitor)26 InputStream (java.io.InputStream)25 MethodNode (org.objectweb.asm.tree.MethodNode)25 OuterClass (com.android.tools.layoutlib.create.dataclass.OuterClass)23 InnerClass (com.android.tools.layoutlib.create.dataclass.OuterClass.InnerClass)23