Search in sources :

Example 66 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 67 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 68 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project robovm by robovm.

the class ObjCBlockPlugin method createBlockMarshaler.

private String createBlockMarshaler(Config config, Clazz clazz, final SootMethod targetMethod, Type[] actualGenericTypes, soot.Type[] actualRawTypes, soot.Type[] unboxedTypes, Map<String, Integer> blockTypeIds, String[][] targetMethodAnnotations) throws IOException {
    if (targetMethod.getDeclaringClass().getName().equals("java.lang.Runnable") && targetMethod.getName().equals("run")) {
        return RUNNABLE_AS_OBJC_BLOCK_MARSHALER;
    }
    String targetMethodKey = getTargetMethodKey(targetMethod, actualRawTypes, targetMethodAnnotations);
    Integer id = blockTypeIds.get(targetMethodKey);
    if (id != null) {
        // Already generated
        return getBlockMarshalerName(clazz, id);
    }
    id = blockTypeIds.size();
    blockTypeIds.put(targetMethodKey, id);
    final String blockMarshalerName = getBlockMarshalerName(clazz, id);
    final String targetInterfaceName = Types.getInternalName(targetMethod.getDeclaringClass());
    // We use RunnableAsObjCBlockMarshaler as template
    Clazz templateMarshaler = config.getClazzes().load(RUNNABLE_AS_OBJC_BLOCK_MARSHALER);
    final Set<String> usedBoxMethods = new HashSet<>();
    final Set<String> usedUnboxMethods = new HashSet<>();
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    generateTargetMethod(blockMarshalerName, targetMethod, actualGenericTypes, actualRawTypes, unboxedTypes, usedBoxMethods, usedUnboxMethods, cw);
    generateBridgeMethod(actualGenericTypes, unboxedTypes, targetMethodAnnotations, cw);
    generateCallbackMethod(blockMarshalerName, targetMethod, actualGenericTypes, actualRawTypes, unboxedTypes, usedBoxMethods, usedUnboxMethods, targetMethodAnnotations, cw);
    ClassReader classReader = new ClassReader(templateMarshaler.getBytes());
    classReader.accept(new ClassVisitor(ASM4, cw) {

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, blockMarshalerName, signature, superName, new String[] { targetInterfaceName });
        }

        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {
        // Ignore
        }

        @Override
        public void visitSource(String source, String debug) {
        // Ignore
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            switch(name) {
                case "run":
                case "invoke":
                case "invoked":
                    // Skip all these
                    return null;
                case "box":
                    if (!usedBoxMethods.contains(desc)) {
                        return null;
                    }
                    break;
                case "unbox":
                    if (!usedUnboxMethods.contains(desc)) {
                        return null;
                    }
                    break;
            }
            desc = desc.replace("java/lang/Runnable", targetInterfaceName);
            signature = null;
            // RunnableAsObjCBlockMarshaler to the blockMarshalerName
            return new MethodVisitor(ASM4, super.visitMethod(access, name, desc, signature, exceptions)) {

                @Override
                public void visitLdcInsn(Object cst) {
                    if (cst instanceof org.objectweb.asm.Type) {
                        if (((org.objectweb.asm.Type) cst).getSort() == org.objectweb.asm.Type.OBJECT) {
                            String internalName = ((org.objectweb.asm.Type) cst).getInternalName();
                            if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(internalName)) {
                                cst = org.objectweb.asm.Type.getObjectType(blockMarshalerName);
                            }
                        }
                    }
                    super.visitLdcInsn(cst);
                }

                @Override
                public void visitTypeInsn(int opcode, String type) {
                    if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(type)) {
                        type = blockMarshalerName;
                    } else if ("java/lang/Runnable".equals(type)) {
                        type = targetInterfaceName;
                    }
                    super.visitTypeInsn(opcode, type);
                }

                @Override
                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                    if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(owner)) {
                        owner = blockMarshalerName;
                    }
                    super.visitFieldInsn(opcode, owner, name, desc);
                }

                @Override
                public void visitMethodInsn(int opcode, String owner, String name, String desc) {
                    if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(owner)) {
                        owner = blockMarshalerName;
                    }
                    super.visitMethodInsn(opcode, owner, name, desc);
                }

                @Override
                public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                // Ignored
                }

                @Override
                public void visitLineNumber(int line, Label start) {
                // Ignored
                }
            };
        }
    }, 0);
    cw.visitInnerClass(blockMarshalerName, clazz.getInternalName(), blockMarshalerName.substring(clazz.getInternalName().length() + 1), ACC_PUBLIC + ACC_STATIC);
    cw.visitEnd();
    File f = clazz.getPath().getGeneratedClassFile(blockMarshalerName);
    FileUtils.writeByteArrayToFile(f, cw.toByteArray());
    // The marshaler class is created after the class is compiled.
    // This prevents the triggering of a recompile of the class.
    f.setLastModified(clazz.lastModified());
    return blockMarshalerName;
}
Also used : Label(org.objectweb.asm.Label) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) SootTypeType(org.robovm.compiler.util.generic.SootTypeType) WildcardType(org.robovm.compiler.util.generic.WildcardType) SootMethodType(org.robovm.compiler.util.generic.SootMethodType) SootClassType(org.robovm.compiler.util.generic.SootClassType) ByteType(soot.ByteType) Type(org.robovm.compiler.util.generic.Type) DoubleType(soot.DoubleType) GenericArrayType(org.robovm.compiler.util.generic.GenericArrayType) FloatType(soot.FloatType) IntType(soot.IntType) ImplForType(org.robovm.compiler.util.generic.ImplForType) CharType(soot.CharType) LongType(soot.LongType) ParameterizedType(org.robovm.compiler.util.generic.ParameterizedType) PrimType(soot.PrimType) VoidType(soot.VoidType) ClassReader(org.objectweb.asm.ClassReader) Clazz(org.robovm.compiler.clazz.Clazz) File(java.io.File) HashSet(java.util.HashSet)

Example 69 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project byte-buddy by raphw.

the class AbstractDynamicTypeBuilderTest method testWriterHint.

@Test
@SuppressWarnings("unchecked")
public void testWriterHint() throws Exception {
    AsmVisitorWrapper asmVisitorWrapper = mock(AsmVisitorWrapper.class);
    when(asmVisitorWrapper.wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt())).then(new Answer<ClassVisitor>() {

        @Override
        public ClassVisitor answer(InvocationOnMock invocationOnMock) throws Throwable {
            return new ClassVisitor(Opcodes.ASM5, (ClassVisitor) invocationOnMock.getArguments()[1]) {

                @Override
                public void visitEnd() {
                    MethodVisitor mv = visitMethod(Opcodes.ACC_PUBLIC, FOO, "()Ljava/lang/String;", null, null);
                    mv.visitCode();
                    mv.visitLdcInsn(FOO);
                    mv.visitInsn(Opcodes.ARETURN);
                    mv.visitMaxs(-1, -1);
                    mv.visitEnd();
                }
            };
        }
    });
    when(asmVisitorWrapper.mergeWriter(0)).thenReturn(ClassWriter.COMPUTE_MAXS);
    Class<?> type = createPlain().visit(asmVisitorWrapper).make().load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER).getLoaded();
    assertThat(type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()), is((Object) FOO));
    verify(asmVisitorWrapper).mergeWriter(0);
    verify(asmVisitorWrapper, atMost(1)).mergeReader(0);
    verify(asmVisitorWrapper).wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt());
    verifyNoMoreInteractions(asmVisitorWrapper);
}
Also used : MethodList(net.bytebuddy.description.method.MethodList) ClassVisitor(org.objectweb.asm.ClassVisitor) FieldList(net.bytebuddy.description.field.FieldList) MethodVisitor(org.objectweb.asm.MethodVisitor) InvocationOnMock(org.mockito.invocation.InvocationOnMock) AsmVisitorWrapper(net.bytebuddy.asm.AsmVisitorWrapper) TypeDescription(net.bytebuddy.description.type.TypeDescription) TypePool(net.bytebuddy.pool.TypePool) Test(org.junit.Test)

Example 70 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project byte-buddy by raphw.

the class TypeConstantAdjustmentTest method testInstrumentationLegacyClassOtherType.

@Test
public void testInstrumentationLegacyClassOtherType() throws Exception {
    ClassVisitor classVisitor = TypeConstantAdjustment.INSTANCE.wrap(mock(TypeDescription.class), this.classVisitor, mock(Implementation.Context.class), mock(TypePool.class), new FieldList.Empty<FieldDescription.InDefinedShape>(), new MethodList.Empty<MethodDescription>(), IGNORED, IGNORED);
    classVisitor.visit(ClassFileVersion.JAVA_V4.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
    MethodVisitor methodVisitor = classVisitor.visitMethod(FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
    assertThat(methodVisitor, not(this.methodVisitor));
    methodVisitor.visitLdcInsn(FOO);
    verify(this.classVisitor).visit(ClassFileVersion.JAVA_V4.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
    verify(this.classVisitor).visitMethod(FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
    verifyNoMoreInteractions(this.classVisitor);
    verify(this.methodVisitor).visitLdcInsn(FOO);
    verifyNoMoreInteractions(this.methodVisitor);
}
Also used : MethodDescription(net.bytebuddy.description.method.MethodDescription) TypeDescription(net.bytebuddy.description.type.TypeDescription) MethodList(net.bytebuddy.description.method.MethodList) ClassVisitor(org.objectweb.asm.ClassVisitor) TypePool(net.bytebuddy.pool.TypePool) FieldList(net.bytebuddy.description.field.FieldList) MethodVisitor(org.objectweb.asm.MethodVisitor) Test(org.junit.Test)

Aggregations

ClassVisitor (org.objectweb.asm.ClassVisitor)133 ClassReader (org.objectweb.asm.ClassReader)97 ClassWriter (org.objectweb.asm.ClassWriter)80 MethodVisitor (org.objectweb.asm.MethodVisitor)45 IOException (java.io.IOException)19 InputStream (java.io.InputStream)19 Type (org.objectweb.asm.Type)14 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)14 File (java.io.File)11 PrintWriter (java.io.PrintWriter)11 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)10 Label (org.objectweb.asm.Label)10 FileInputStream (java.io.FileInputStream)9 Test (org.junit.Test)9 FileOutputStream (java.io.FileOutputStream)6 FieldVisitor (org.objectweb.asm.FieldVisitor)6 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)6 ArrayList (java.util.ArrayList)5 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 FieldList (net.bytebuddy.description.field.FieldList)5