Search in sources :

Example 41 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project elasticsearch by elastic.

the class SSource method write.

public void write() {
    // Create the ClassWriter.
    int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
    int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
    String classBase = BASE_CLASS_TYPE.getInternalName();
    String className = CLASS_TYPE.getInternalName();
    String[] classInterfaces = new String[] { Type.getType(scriptInterface.getInterface()).getInternalName() };
    ClassWriter writer = new ClassWriter(classFrames);
    ClassVisitor visitor = writer;
    // if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace.
    if (settings.isPicky()) {
        visitor = new SimpleChecksAdapter(visitor);
    }
    if (debugStream != null) {
        visitor = new TraceClassVisitor(visitor, debugStream, null);
    }
    visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces);
    visitor.visitSource(Location.computeSourceName(name, source), null);
    // Write the constructor:
    MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, CONSTRUCTOR, visitor, globals.getStatements(), settings);
    constructor.visitCode();
    constructor.loadThis();
    constructor.loadArgs();
    constructor.invokeConstructor(BASE_CLASS_TYPE, CONSTRUCTOR);
    constructor.returnValue();
    constructor.endMethod();
    // Write the method defined in the interface:
    MethodWriter executeMethod = new MethodWriter(Opcodes.ACC_PUBLIC, scriptInterface.getExecuteMethod(), visitor, globals.getStatements(), settings);
    executeMethod.visitCode();
    write(executeMethod, globals);
    executeMethod.endMethod();
    // Write all functions:
    for (SFunction function : functions) {
        function.write(visitor, settings, globals);
    }
    // Write all synthetic functions. Note that this process may add more :)
    while (!globals.getSyntheticMethods().isEmpty()) {
        List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
        globals.getSyntheticMethods().clear();
        for (SFunction function : current) {
            function.write(visitor, settings, globals);
        }
    }
    // Write the constants
    if (false == globals.getConstantInitializers().isEmpty()) {
        Collection<Constant> inits = globals.getConstantInitializers().values();
        // Fields
        for (Constant constant : inits) {
            visitor.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, constant.name, constant.type.getDescriptor(), null, null).visitEnd();
        }
        // Initialize the constants in a static initializer
        final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, visitor, globals.getStatements(), settings);
        clinit.visitCode();
        for (Constant constant : inits) {
            constant.initializer.accept(clinit);
            clinit.putStatic(CLASS_TYPE, constant.name, constant.type);
        }
        clinit.returnValue();
        clinit.endMethod();
    }
    // Write any uses$varName methods for used variables
    for (org.objectweb.asm.commons.Method usesMethod : scriptInterface.getUsesMethods()) {
        MethodWriter ifaceMethod = new MethodWriter(Opcodes.ACC_PUBLIC, usesMethod, visitor, globals.getStatements(), settings);
        ifaceMethod.visitCode();
        ifaceMethod.push(reserved.getUsedVariables().contains(usesMethod.getName().substring("uses$".length())));
        ifaceMethod.returnValue();
        ifaceMethod.endMethod();
    }
    // End writing the class and store the generated bytes.
    visitor.visitEnd();
    bytes = writer.toByteArray();
}
Also used : Constant(org.elasticsearch.painless.Constant) MethodWriter(org.elasticsearch.painless.MethodWriter) ArrayList(java.util.ArrayList) ClassVisitor(org.objectweb.asm.ClassVisitor) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) SimpleChecksAdapter(org.elasticsearch.painless.SimpleChecksAdapter)

Example 42 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project gwt-test-utils by gwt-test-utils.

the class OverlayTypesRewriter method writeJsoIntf.

public byte[] writeJsoIntf(String className) {
    String desc = toDescriptor(className);
    assert jsoIntfDescs.contains(desc);
    assert jsoSuperDescs.containsKey(desc);
    List<String> superDescs = jsoSuperDescs.get(desc);
    assert superDescs != null;
    assert superDescs.size() > 0;
    // The ASM model is to chain a bunch of visitors together.
    ClassWriter writer = new ClassWriter(0);
    ClassVisitor v = writer;
    // v = new CheckClassAdapter(v);
    // v = new TraceClassVisitor(v, new PrintWriter(System.out));
    String[] interfaces;
    // TODO(bov): something better than linear?
    if (superDescs.contains("java/lang/Object")) {
        interfaces = null;
    } else {
        interfaces = superDescs.toArray(new String[superDescs.size()]);
    }
    v.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC | Opcodes.ACC_INTERFACE, desc, null, "java/lang/Object", interfaces);
    v.visitEnd();
    return writer.toByteArray();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter)

Example 43 with ClassVisitor

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

the class UDFByteCodeVerifier method verify.

public Set<String> verify(String clsName, byte[] bytes) {
    String clsNameSl = clsName.replace('.', '/');
    // it's a TreeSet for unit tests
    Set<String> errors = new TreeSet<>();
    ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5) {

        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            errors.add("field declared: " + name);
            return null;
        }

        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            if ("<init>".equals(name) && CTOR_SIG.equals(desc)) {
                if (Opcodes.ACC_PUBLIC != access)
                    errors.add("constructor not public");
                // allowed constructor - JavaUDF(TypeCodec returnCodec, TypeCodec[] argCodecs)
                return new ConstructorVisitor(errors);
            }
            if ("executeImpl".equals(name) && "(Lorg/apache/cassandra/transport/ProtocolVersion;Ljava/util/List;)Ljava/nio/ByteBuffer;".equals(desc)) {
                if (Opcodes.ACC_PROTECTED != access)
                    errors.add("executeImpl not protected");
                // the executeImpl method - ByteBuffer executeImpl(ProtocolVersion protocolVersion, List<ByteBuffer> params)
                return new ExecuteImplVisitor(errors);
            }
            if ("executeAggregateImpl".equals(name) && "(Lorg/apache/cassandra/transport/ProtocolVersion;Ljava/lang/Object;Ljava/util/List;)Ljava/lang/Object;".equals(desc)) {
                if (Opcodes.ACC_PROTECTED != access)
                    errors.add("executeAggregateImpl not protected");
                // the executeImpl method - ByteBuffer executeImpl(ProtocolVersion protocolVersion, List<ByteBuffer> params)
                return new ExecuteImplVisitor(errors);
            }
            if ("<clinit>".equals(name)) {
                errors.add("static initializer declared");
            } else {
                errors.add("not allowed method declared: " + name + desc);
                return new ExecuteImplVisitor(errors);
            }
            return null;
        }

        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            if (!JAVA_UDF_NAME.equals(superName)) {
                errors.add("class does not extend " + JavaUDF.class.getName());
            }
            if (access != (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER)) {
                errors.add("class not public final");
            }
            super.visit(version, access, name, signature, superName, interfaces);
        }

        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            if (// outerName might be null, which is true for anonymous inner classes
            clsNameSl.equals(outerName))
                errors.add("class declared as inner class");
            super.visitInnerClass(name, outerName, innerName, access);
        }
    };
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classVisitor, ClassReader.SKIP_DEBUG);
    return errors;
}
Also used : TreeSet(java.util.TreeSet) ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor)

Example 44 with ClassVisitor

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

the class Desugar method main.

public static void main(String[] args) throws Exception {
    // LambdaClassMaker generates lambda classes for us, but it does so by essentially simulating
    // the call to LambdaMetafactory that the JVM would make when encountering an invokedynamic.
    // LambdaMetafactory is in the JDK and its implementation has a property to write out ("dump")
    // generated classes, which we take advantage of here.  Set property before doing anything else
    // since the property is read in the static initializer; if this breaks we can investigate
    // setting the property when calling the tool.
    Path dumpDirectory = Files.createTempDirectory("lambdas");
    System.setProperty(LambdaClassMaker.LAMBDA_METAFACTORY_DUMPER_PROPERTY, dumpDirectory.toString());
    deleteTreeOnExit(dumpDirectory);
    if (args.length == 1 && args[0].startsWith("@")) {
        args = Files.readAllLines(Paths.get(args[0].substring(1)), ISO_8859_1).toArray(new String[0]);
    }
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
    optionsParser.setAllowResidue(false);
    optionsParser.parseAndExitUponError(args);
    Options options = optionsParser.getOptions(Options.class);
    checkState(!options.inputJars.isEmpty(), "--input is required");
    checkState(options.inputJars.size() == options.outputJars.size(), "Desugar requires the same number of inputs and outputs to pair them");
    checkState(!options.bootclasspath.isEmpty() || options.allowEmptyBootclasspath, "At least one --bootclasspath_entry is required");
    if (options.verbose) {
        System.out.printf("Lambda classes will be written under %s%n", dumpDirectory);
    }
    CoreLibraryRewriter rewriter = new CoreLibraryRewriter(options.coreLibrary ? "__desugar__/" : "");
    boolean allowDefaultMethods = options.minSdkVersion >= 24;
    boolean allowCallsToObjectsNonNull = options.minSdkVersion >= 19;
    LambdaClassMaker lambdas = new LambdaClassMaker(dumpDirectory);
    // Process each input separately
    for (InputOutputPair inputOutputPair : toInputOutputPairs(options)) {
        Path inputJar = inputOutputPair.getInput();
        IndexedJars appIndexedJar = new IndexedJars(ImmutableList.of(inputJar));
        IndexedJars appAndClasspathIndexedJars = new IndexedJars(options.classpath, appIndexedJar);
        ClassLoader loader = createClassLoader(rewriter, options.bootclasspath, appAndClasspathIndexedJars);
        try (ZipFile in = new ZipFile(inputJar.toFile());
            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(inputOutputPair.getOutput())))) {
            ClassReaderFactory readerFactory = new ClassReaderFactory((options.copyBridgesFromClasspath && !allowDefaultMethods) ? appAndClasspathIndexedJars : appIndexedJar, rewriter);
            ImmutableSet.Builder<String> interfaceLambdaMethodCollector = ImmutableSet.builder();
            // Process input Jar, desugaring as we go
            for (Enumeration<? extends ZipEntry> entries = in.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = entries.nextElement();
                try (InputStream content = in.getInputStream(entry)) {
                    // danger of accidentally uncompressed resources ending up in an .apk.
                    if (entry.getName().endsWith(".class")) {
                        ClassReader reader = rewriter.reader(content);
                        CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
                        ClassVisitor visitor = writer;
                        if (!options.onlyDesugarJavac9ForLint) {
                            if (!allowDefaultMethods) {
                                visitor = new Java7Compatibility(visitor, readerFactory);
                            }
                            visitor = new LambdaDesugaring(visitor, loader, lambdas, interfaceLambdaMethodCollector, allowDefaultMethods);
                        }
                        if (!allowCallsToObjectsNonNull) {
                            visitor = new ObjectsRequireNonNullMethodInliner(visitor);
                        }
                        reader.accept(visitor, 0);
                        writeStoredEntry(out, entry.getName(), writer.toByteArray());
                    } else {
                        // TODO(bazel-team): Avoid de- and re-compressing resource files
                        ZipEntry destEntry = new ZipEntry(entry);
                        destEntry.setCompressedSize(-1);
                        out.putNextEntry(destEntry);
                        ByteStreams.copy(content, out);
                        out.closeEntry();
                    }
                }
            }
            ImmutableSet<String> interfaceLambdaMethods = interfaceLambdaMethodCollector.build();
            checkState(!allowDefaultMethods || interfaceLambdaMethods.isEmpty(), "Desugaring with default methods enabled moved interface lambdas");
            // Write out the lambda classes we generated along the way
            ImmutableMap<Path, LambdaInfo> lambdaClasses = lambdas.drain();
            checkState(!options.onlyDesugarJavac9ForLint || lambdaClasses.isEmpty(), "There should be no lambda classes generated: %s", lambdaClasses.keySet());
            for (Map.Entry<Path, LambdaInfo> lambdaClass : lambdaClasses.entrySet()) {
                try (InputStream bytecode = Files.newInputStream(dumpDirectory.resolve(lambdaClass.getKey()))) {
                    ClassReader reader = rewriter.reader(bytecode);
                    CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
                    ClassVisitor visitor = writer;
                    if (!allowDefaultMethods) {
                        // null ClassReaderFactory b/c we don't expect to need it for lambda classes
                        visitor = new Java7Compatibility(visitor, (ClassReaderFactory) null);
                    }
                    visitor = new LambdaClassFixer(visitor, lambdaClass.getValue(), readerFactory, interfaceLambdaMethods, allowDefaultMethods);
                    // Send lambda classes through desugaring to make sure there's no invokedynamic
                    // instructions in generated lambda classes (checkState below will fail)
                    visitor = new LambdaDesugaring(visitor, loader, lambdas, null, allowDefaultMethods);
                    if (!allowCallsToObjectsNonNull) {
                        // Not sure whether there will be implicit null check emitted by javac, so we rerun
                        // the inliner again
                        visitor = new ObjectsRequireNonNullMethodInliner(visitor);
                    }
                    reader.accept(visitor, 0);
                    String filename = rewriter.unprefix(lambdaClass.getValue().desiredInternalName()) + ".class";
                    writeStoredEntry(out, filename, writer.toByteArray());
                }
            }
            Map<Path, LambdaInfo> leftBehind = lambdas.drain();
            checkState(leftBehind.isEmpty(), "Didn't process %s", leftBehind);
        }
    }
}
Also used : ZipEntry(java.util.zip.ZipEntry) ClassVisitor(org.objectweb.asm.ClassVisitor) ImmutableSet(com.google.common.collect.ImmutableSet) BufferedOutputStream(java.io.BufferedOutputStream) Path(java.nio.file.Path) InputStream(java.io.InputStream) OptionsParser(com.google.devtools.common.options.OptionsParser) ZipFile(java.util.zip.ZipFile) ZipOutputStream(java.util.zip.ZipOutputStream) ClassReader(org.objectweb.asm.ClassReader) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 45 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project groovy-core by groovy.

the class GroovySunClassLoader method loadAbstract.

private void loadAbstract() throws IOException {
    final InputStream asStream = GroovySunClassLoader.class.getClass().getClassLoader().getResourceAsStream(resName("org.codehaus.groovy.runtime.callsite.AbstractCallSite"));
    ClassReader reader = new ClassReader(asStream);
    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    final ClassVisitor cv = new ClassVisitor(4, cw) {

        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, "sun/reflect/GroovyMagic", interfaces);
        }
    };
    reader.accept(cv, ClassWriter.COMPUTE_MAXS);
    asStream.close();
    define(cw.toByteArray(), "org.codehaus.groovy.runtime.callsite.AbstractCallSite");
}
Also used : InputStream(java.io.InputStream) ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

ClassVisitor (org.objectweb.asm.ClassVisitor)75 ClassReader (org.objectweb.asm.ClassReader)52 ClassWriter (org.objectweb.asm.ClassWriter)45 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