Search in sources :

Example 86 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class RuntimeRepo method findClass0.

@Override
protected ClassNode findClass0(String internalName) {
    ClassReader cr;
    try {
        cr = new ClassReader(internalName);
    } catch (Exception ex) {
        return null;
    }
    ClassNode node = new ClassNode();
    cr.accept(node, 0);
    return node;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassReader(org.objectweb.asm.ClassReader) IOException(java.io.IOException)

Example 87 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project SpecialSource by md-5.

the class CachingRepo method findClass.

@Override
public final ClassNode findClass(String internalName) {
    ClassNode fromCache = cache.getIfPresent(internalName);
    if (fromCache != null) {
        return fromCache;
    }
    ClassNode found = findClass0(internalName);
    if (found != null) {
        cache.put(internalName, found);
        return found;
    }
    return null;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode)

Example 88 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project drill by apache.

the class TestClassTransformation method testScalarReplacementWithArrayAssignment.

@Test
public void testScalarReplacementWithArrayAssignment() throws Exception {
    ClassTransformer.ClassNames classNames = new ClassTransformer.ClassNames("org.apache.drill.CompileClassWithArraysAssignment");
    String entireClass = DrillFileUtils.getResourceAsString(DrillFileUtils.SEPARATOR + classNames.slash + ".java");
    sessionOptions.setLocalOption(ClassCompilerSelector.JAVA_COMPILER_DEBUG_OPTION, false);
    List<String> compilers = Arrays.asList(ClassCompilerSelector.CompilerPolicy.JANINO.name(), ClassCompilerSelector.CompilerPolicy.JDK.name());
    for (String compilerName : compilers) {
        sessionOptions.setLocalOption(ClassCompilerSelector.JAVA_COMPILER_OPTION, compilerName);
        QueryClassLoader queryClassLoader = new QueryClassLoader(config, sessionOptions);
        byte[][] implementationClasses = queryClassLoader.getClassByteCode(classNames, entireClass);
        ClassNode originalClass = AsmUtil.classFromBytes(implementationClasses[0], ClassReader.EXPAND_FRAMES);
        ClassNode transformedClass = new ClassNode();
        DrillCheckClassAdapter mergeGenerator = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, transformedClass), true);
        originalClass.accept(new ValueHolderReplacementVisitor(mergeGenerator, true));
        if (!AsmUtil.isClassOk(logger, classNames.dot, transformedClass)) {
            throw new IllegalStateException(String.format("Problem found after transforming %s", classNames.dot));
        }
        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        transformedClass.accept(writer);
        byte[] outputClass = writer.toByteArray();
        queryClassLoader.injectByteCode(classNames.dot, outputClass);
        Class<?> transformedClazz = queryClassLoader.findClass(classNames.dot);
        transformedClazz.getMethod("doSomething").invoke(null);
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ValueHolderReplacementVisitor(org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor) ClassWriter(org.objectweb.asm.ClassWriter) Test(org.junit.Test)

Example 89 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project drill by apache.

the class AsmUtil method classFromBytes.

/**
 * Create a ClassNode from bytecode.
 *
 * @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;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassReader(org.objectweb.asm.ClassReader)

Example 90 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project drill by apache.

the class ClassTransformer method getImplementationClass.

public Class<?> getImplementationClass(final QueryClassLoader classLoader, final TemplateClassDefinition<?> templateDefinition, final String entireClass, final String materializedClassName) throws ClassTransformationException {
    // unfortunately, this hasn't been set up at construction time, so we have to do it here
    final ScalarReplacementOption scalarReplacementOption = ScalarReplacementOption.fromString(optionManager.getOption(ExecConstants.SCALAR_REPLACEMENT_VALIDATOR));
    try {
        final long t1 = System.nanoTime();
        final ClassSet set = new ClassSet(null, templateDefinition.getTemplateClassName(), materializedClassName);
        final byte[][] implementationClasses = classLoader.getClassByteCode(set.generated, entireClass);
        long totalBytecodeSize = 0;
        Map<String, Pair<byte[], ClassNode>> classesToMerge = Maps.newHashMap();
        for (byte[] clazz : implementationClasses) {
            totalBytecodeSize += clazz.length;
            final ClassNode node = AsmUtil.classFromBytes(clazz, ClassReader.EXPAND_FRAMES);
            if (!AsmUtil.isClassOk(logger, "implementationClasses", node)) {
                throw new IllegalStateException("Problem found with implementationClasses");
            }
            classesToMerge.put(node.name, Pair.of(clazz, node));
        }
        final LinkedList<ClassSet> names = Lists.newLinkedList();
        final Set<ClassSet> namesCompleted = Sets.newHashSet();
        names.add(set);
        while (!names.isEmpty()) {
            final ClassSet nextSet = names.removeFirst();
            if (namesCompleted.contains(nextSet)) {
                continue;
            }
            final ClassNames nextPrecompiled = nextSet.precompiled;
            final byte[] precompiledBytes = byteCodeLoader.getClassByteCodeFromPath(nextPrecompiled.clazz);
            final ClassNames nextGenerated = nextSet.generated;
            // keeps only classes that have not be merged
            Pair<byte[], ClassNode> classNodePair = classesToMerge.remove(nextGenerated.slash);
            final ClassNode generatedNode;
            if (classNodePair != null) {
                generatedNode = classNodePair.getValue();
            } else {
                generatedNode = null;
            }
            /*
         * TODO
         * We're having a problem with some cases of scalar replacement, but we want to get
         * the code in so it doesn't rot anymore.
         *
         *  Here, we use the specified replacement option. The loop will allow us to retry if
         *  we're using TRY.
         */
            MergedClassResult result = null;
            boolean scalarReplace = scalarReplacementOption != ScalarReplacementOption.OFF && entireClass.length() < MAX_SCALAR_REPLACE_CODE_SIZE;
            while (true) {
                try {
                    result = MergeAdapter.getMergedClass(nextSet, precompiledBytes, generatedNode, scalarReplace);
                    break;
                } catch (RuntimeException e) {
                    // if we had a problem without using scalar replacement, then rethrow
                    if (!scalarReplace) {
                        throw e;
                    }
                    // if we did try to use scalar replacement, decide if we need to retry or not
                    if (scalarReplacementOption == ScalarReplacementOption.ON) {
                        // option is forced on, so this is a hard error
                        throw e;
                    }
                    /*
             * We tried to use scalar replacement, with the option to fall back to not using it.
             * Log this failure before trying again without scalar replacement.
             */
                    logger.info("scalar replacement failure (retrying)\n", e);
                    scalarReplace = false;
                }
            }
            for (String s : result.innerClasses) {
                s = s.replace(DrillFileUtils.SEPARATOR_CHAR, '.');
                names.add(nextSet.getChild(s));
            }
            classLoader.injectByteCode(nextGenerated.dot, result.bytes);
            namesCompleted.add(nextSet);
        }
        // adds byte code of the classes that have not been merged to make them accessible for outer class
        for (Map.Entry<String, Pair<byte[], ClassNode>> clazz : classesToMerge.entrySet()) {
            classLoader.injectByteCode(clazz.getKey().replace(DrillFileUtils.SEPARATOR_CHAR, '.'), clazz.getValue().getKey());
        }
        Class<?> c = classLoader.findClass(set.generated.dot);
        if (templateDefinition.getExternalInterface().isAssignableFrom(c)) {
            logger.debug("Compiled and merged {}: bytecode size = {}, time = {} ms.", c.getSimpleName(), DrillStringUtils.readable(totalBytecodeSize), (System.nanoTime() - t1 + 500_000) / 1_000_000);
            return c;
        }
        throw new ClassTransformationException("The requested class did not implement the expected interface.");
    } catch (CompileException | IOException | ClassNotFoundException e) {
        throw new ClassTransformationException(String.format("Failure generating transformation classes for value: \n %s", entireClass), e);
    }
}
Also used : CompileException(org.codehaus.commons.compiler.CompileException) Pair(org.apache.commons.lang3.tuple.Pair) ClassNode(org.objectweb.asm.tree.ClassNode) ClassTransformationException(org.apache.drill.exec.exception.ClassTransformationException) IOException(java.io.IOException) Map(java.util.Map) MergedClassResult(org.apache.drill.exec.compile.MergeAdapter.MergedClassResult)

Aggregations

ClassNode (org.objectweb.asm.tree.ClassNode)323 ClassReader (org.objectweb.asm.ClassReader)148 MethodNode (org.objectweb.asm.tree.MethodNode)120 ClassWriter (org.objectweb.asm.ClassWriter)70 IOException (java.io.IOException)44 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)37 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)34 InsnList (org.objectweb.asm.tree.InsnList)29 FieldNode (org.objectweb.asm.tree.FieldNode)28 ArrayList (java.util.ArrayList)27 Test (org.junit.Test)26 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)26 Label (org.objectweb.asm.Label)21 InputStream (java.io.InputStream)20 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)18 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)18 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)17 InsnNode (org.objectweb.asm.tree.InsnNode)17 Method (java.lang.reflect.Method)16 List (java.util.List)16