Search in sources :

Example 71 with Type

use of org.objectweb.asm.Type in project cdap by caskdata.

the class SparkClassRewriter method rewriteClient.

/**
   * Defines the org.apache.spark.deploy.yarn.Client class with rewriting of the createConfArchive method to
   * workaround the SPARK-13441 bug.
   */
@Nullable
private byte[] rewriteClient(InputStream byteCodeStream) throws IOException {
    // We only need to rewrite if listing either HADOOP_CONF_DIR or YARN_CONF_DIR return null.
    boolean needRewrite = false;
    for (String env : ImmutableList.of("HADOOP_CONF_DIR", "YARN_CONF_DIR")) {
        String value = System.getenv(env);
        if (value != null) {
            File path = new File(value);
            if (path.isDirectory() && path.listFiles() == null) {
                needRewrite = true;
                break;
            }
        }
    }
    // If rewrite is not needed
    if (!needRewrite) {
        return null;
    }
    ClassReader cr = new ClassReader(byteCodeStream);
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {

        @Override
        public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) {
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            // Only rewrite the createConfArchive method
            if (!"createConfArchive".equals(name)) {
                return mv;
            }
            // Check if it's a recognizable return type.
            // Spark 1.5+ return type is File
            boolean isReturnFile = Type.getReturnType(desc).equals(Type.getType(File.class));
            Type optionType = Type.getObjectType("scala/Option");
            if (!isReturnFile) {
                // Spark 1.4 return type is Option<File>
                if (!Type.getReturnType(desc).equals(optionType)) {
                    // Unknown type. Not going to modify the code.
                    return mv;
                }
            }
            // Generate this for Spark 1.5+
            // return SparkRuntimeUtils.createConfArchive(this.sparkConf, SPARK_CONF_FILE,
            //                                            LOCALIZED_CONF_DIR, LOCALIZED_CONF_DIR_ZIP);
            // Generate this for Spark 1.4
            // return Option.apply(SparkRuntimeUtils.createConfArchive(this.sparkConf, SPARK_CONF_FILE,
            //                                                         LOCALIZED_CONF_DIR, LOCALIZED_CONF_DIR_ZIP));
            GeneratorAdapter mg = new GeneratorAdapter(mv, access, name, desc);
            // load this.sparkConf to the stack
            mg.loadThis();
            mg.getField(Type.getObjectType("org/apache/spark/deploy/yarn/Client"), "sparkConf", SPARK_CONF_TYPE);
            // push three constants to the stack
            mg.visitLdcInsn(SPARK_CONF_FILE);
            mg.visitLdcInsn(LOCALIZED_CONF_DIR);
            mg.visitLdcInsn(LOCALIZED_CONF_DIR_ZIP);
            // call SparkRuntimeUtils.createConfArchive, return a File and leave it in stack
            Type stringType = Type.getType(String.class);
            mg.invokeStatic(SPARK_RUNTIME_UTILS_TYPE, new Method("createConfArchive", Type.getType(File.class), new Type[] { SPARK_CONF_TYPE, stringType, stringType, stringType }));
            if (isReturnFile) {
                // Spark 1.5+ return type is File, hence just return the File from the stack
                mg.returnValue();
                mg.endMethod();
            } else {
                // Spark 1.4 return type is Option<File>
                // return Option.apply(<file from stack>);
                // where the file is actually just popped from the stack
                mg.invokeStatic(optionType, new Method("apply", optionType, new Type[] { Type.getType(Object.class) }));
                mg.checkCast(optionType);
                mg.returnValue();
                mg.endMethod();
            }
            return null;
        }
    }, ClassReader.EXPAND_FRAMES);
    return cw.toByteArray();
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor) Method(org.objectweb.asm.commons.Method) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor) Type(org.objectweb.asm.Type) ClassReader(org.objectweb.asm.ClassReader) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) File(java.io.File) Nullable(javax.annotation.Nullable)

Example 72 with Type

use of org.objectweb.asm.Type in project sling by apache.

the class GenerateAdapterMetadataMojo method parseAdapterAnnotation.

@SuppressWarnings("unchecked")
private void parseAdapterAnnotation(final AnnotationNode annotation, final ClassNode annotatedClass, final Map<String, Object> adaptableDescription) throws JsonException {
    String condition = null;
    List<Type> adapterClasses = null;
    final List<?> values = annotation.values;
    final Iterator<?> it = values.iterator();
    while (it.hasNext()) {
        final Object name = it.next();
        final Object value = it.next();
        if (StringUtils.isEmpty(condition)) {
            condition = String.format(DEFAULT_CONDITION, getSimpleName(annotatedClass));
        }
        if ("condition".equals(name)) {
            condition = (String) value;
        } else if ("value".equals(name)) {
            adapterClasses = (List<Type>) value;
        }
    }
    if (adapterClasses == null) {
        throw new IllegalArgumentException("Adapter annotation is malformed. Expecting a list of adapter classes");
    }
    for (final Type adapterClass : adapterClasses) {
        JsonSupport.accumulate(adaptableDescription, condition, adapterClass.getClassName());
    }
}
Also used : Type(org.objectweb.asm.Type) List(java.util.List)

Example 73 with Type

use of org.objectweb.asm.Type in project android_frameworks_base by crdroidandroid.

the class DelegateMethodAdapter method generateDelegateCode.

/**
     * Generates the new code for the method.
     * <p/>
     * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
     * (since they have no code to visit).
     * <p/>
     * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
     * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
     * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
     * this method will be invoked from {@link MethodVisitor#visitEnd()}.
     */
public void generateDelegateCode() {
    /*
         * The goal is to generate a call to a static delegate method.
         * If this method is non-static, the first parameter will be 'this'.
         * All the parameters must be passed and then the eventual return type returned.
         *
         * Example, let's say we have a method such as
         *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
         *
         * We'll want to create a body that calls a delegate method like this:
         *   TheClass_Delegate.myMethod(this, a, b, c);
         *
         * If the method is non-static and the class name is an inner class (e.g. has $ in its
         * last segment), we want to push the 'this' of the outer class first:
         *   OuterClass_InnerClass_Delegate.myMethod(
         *     OuterClass.this,
         *     OuterClass$InnerClass.this,
         *     a, b, c);
         *
         * Only one level of inner class is supported right now, for simplicity and because
         * we don't need more.
         *
         * The generated class name is the current class name with "_Delegate" appended to it.
         * One thing to realize is that we don't care about generics -- since generic types
         * are erased at build time, they have no influence on the method name being called.
         */
    // Add our annotation
    AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
    true);
    if (aw != null) {
        aw.visitEnd();
    }
    mDelWriter.visitCode();
    if (mDelegateLineNumber != null) {
        Object[] p = mDelegateLineNumber;
        mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
    }
    ArrayList<Type> paramTypes = new ArrayList<>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;
    // Check if the last segment of the class name has inner an class.
    // Right now we only support one level of inner classes.
    Type outerType = null;
    int slash = mClassName.lastIndexOf('/');
    int dol = mClassName.lastIndexOf('$');
    if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
        String outerClass = mClassName.substring(0, dol);
        outerType = Type.getObjectType(outerClass);
        // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
        delegateClassName = delegateClassName.replace('$', '_');
    }
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {
        if (outerType != null && !mIsStaticInnerClass) {
            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.
            // Push this.getField("this$0") on the call stack.
            // var 0 = this
            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
            mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
            mClassName, // field name
            "this$0", // type of the field
            outerType.getDescriptor());
            maxStack++;
            paramTypes.add(outerType);
        }
        // Push "this" for the instance method, which is always ALOAD 0
        mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }
    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }
    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
    // Invoke the static delegate
    mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
    Type returnType = Type.getReturnType(mDesc);
    mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mDelWriter.visitMaxs(maxStack, maxLocals);
    mDelWriter.visitEnd();
    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
Also used : LayoutlibDelegate(com.android.tools.layoutlib.annotations.LayoutlibDelegate) Type(org.objectweb.asm.Type) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ArrayList(java.util.ArrayList)

Example 74 with Type

use of org.objectweb.asm.Type in project android_frameworks_base by crdroidandroid.

the class AbstractClassAdapter method renameMethodDesc.

/**
     * Renames a method descriptor, i.e. applies renameType to all arguments and to the
     * return value.
     */
String renameMethodDesc(String desc) {
    if (desc == null) {
        return null;
    }
    Type[] args = Type.getArgumentTypes(desc);
    StringBuilder sb = new StringBuilder("(");
    for (Type arg : args) {
        String name = renameType(arg);
        sb.append(name);
    }
    sb.append(')');
    Type ret = Type.getReturnType(desc);
    String name = renameType(ret);
    sb.append(name);
    return sb.toString();
}
Also used : Type(org.objectweb.asm.Type)

Example 75 with Type

use of org.objectweb.asm.Type in project bytecode-viewer by Konloch.

the class Remapper method mapMethodDesc.

public String mapMethodDesc(String desc) {
    if ("()V".equals(desc)) {
        return desc;
    }
    Type[] args = Type.getArgumentTypes(desc);
    StringBuilder sb = new StringBuilder("(");
    for (int i = 0; i < args.length; i++) {
        sb.append(mapDesc(args[i].getDescriptor()));
    }
    Type returnType = Type.getReturnType(desc);
    if (returnType == Type.VOID_TYPE) {
        sb.append(")V");
        return sb.toString();
    }
    sb.append(')').append(mapDesc(returnType.getDescriptor()));
    return sb.toString();
}
Also used : Type(org.objectweb.asm.Type)

Aggregations

Type (org.objectweb.asm.Type)185 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)39 MethodVisitor (org.objectweb.asm.MethodVisitor)34 Method (org.objectweb.asm.commons.Method)28 Label (org.objectweb.asm.Label)27 ClassWriter (org.objectweb.asm.ClassWriter)16 Method (java.lang.reflect.Method)13 ArrayList (java.util.ArrayList)12 ClassReader (org.objectweb.asm.ClassReader)10 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)9 ClassVisitor (org.objectweb.asm.ClassVisitor)9 ExprString (lucee.transformer.expression.ExprString)8 ModelType (org.gradle.model.internal.type.ModelType)7 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)6 IOException (java.io.IOException)6 MethodType (java.lang.invoke.MethodType)6 HashMap (java.util.HashMap)6 List (java.util.List)6 LitString (lucee.transformer.expression.literal.LitString)6 PropertyAccessorType (org.gradle.internal.reflect.PropertyAccessorType)6