Search in sources :

Example 11 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project cdap by caskdata.

the class FieldAccessorGenerator method directGetter.

/**
   * Generates a getter that get the value by directly accessing the class field.
   * @param field The reflection field object.
   */
private void directGetter(Field field) {
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(Object.class, "get", Object.class), getterSignature(), new Type[0], classWriter);
    // Simply access by field
    // return ((classType)object).fieldName;
    mg.loadArg(0);
    mg.checkCast(Type.getType(field.getDeclaringClass()));
    mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    if (field.getType().isPrimitive()) {
        mg.valueOf(Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Example 12 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project cdap by caskdata.

the class FieldAccessorGenerator method generateConstructor.

private void generateConstructor(Field field) {
    if (isPrivate) {
        classWriter.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "field", Type.getDescriptor(Field.class), null, null).visitEnd();
    }
    // Constructor(Type classType)
    Method constructor = getMethod(void.class, "<init>", java.lang.reflect.Type.class);
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, null, new Type[0], classWriter);
    mg.loadThis();
    mg.loadArg(0);
    mg.invokeConstructor(Type.getType(AbstractFieldAccessor.class), constructor);
    if (isPrivate) {
        initializeReflectionField(mg, field);
    }
    mg.returnValue();
    mg.endMethod();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method)

Example 13 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project cdap by caskdata.

the class FieldAccessorGenerator method primitiveGetter.

/**
   * Generates the primitive getter (getXXX) based on the field type.
   * @param field The reflection field object.
   */
private void primitiveGetter(Field field) {
    String typeName = field.getType().getName();
    String methodName = String.format("get%c%s", Character.toUpperCase(typeName.charAt(0)), typeName.substring(1));
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(field.getType(), methodName, Object.class), null, new Type[0], classWriter);
    if (isPrivate) {
        // get the value using the generic Object get(Object) method and unbox the value
        mg.loadThis();
        mg.loadArg(0);
        mg.invokeVirtual(Type.getObjectType(className), getMethod(Object.class, "get", Object.class));
        mg.unbox(Type.getType(field.getType()));
    } else {
        // Simply access the field.
        mg.loadArg(0);
        mg.checkCast(Type.getType(field.getDeclaringClass()));
        mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Example 14 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project cdap by caskdata.

the class FieldAccessorGenerator method primitiveSetter.

/**
   * Generates the primitive setter (setXXX) based on the field type.
   * @param field The reflection field object.
   */
private void primitiveSetter(Field field) {
    String typeName = field.getType().getName();
    String methodName = String.format("set%c%s", Character.toUpperCase(typeName.charAt(0)), typeName.substring(1));
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(void.class, methodName, Object.class, field.getType()), null, new Type[0], classWriter);
    if (isPrivate) {
        // set the value using the generic void get(Object, Object) method with boxing the value.
        mg.loadThis();
        mg.loadArgs();
        mg.valueOf(Type.getType(field.getType()));
        mg.invokeVirtual(Type.getObjectType(className), getMethod(void.class, "set", Object.class, Object.class));
    } else {
        // Simply access the field.
        mg.loadArg(0);
        mg.checkCast(Type.getType(field.getDeclaringClass()));
        mg.loadArg(1);
        mg.putField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Example 15 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter 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)

Aggregations

GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)33 Method (org.objectweb.asm.commons.Method)24 Type (org.objectweb.asm.Type)14 Label (org.objectweb.asm.Label)8 ClassWriter (org.objectweb.asm.ClassWriter)7 MethodVisitor (org.objectweb.asm.MethodVisitor)7 IOException (java.io.IOException)5 ClassReader (org.objectweb.asm.ClassReader)5 ClassVisitor (org.objectweb.asm.ClassVisitor)4 Schema (co.cask.cdap.api.data.schema.Schema)3 TypeToken (com.google.common.reflect.TypeToken)2 InvocationHandler (java.lang.reflect.InvocationHandler)2 ArrayList (java.util.ArrayList)2 Set (java.util.Set)2 SchemaHash (co.cask.cdap.api.data.schema.SchemaHash)1 MetricsContext (co.cask.cdap.api.metrics.MetricsContext)1 Encoder (co.cask.cdap.common.io.Encoder)1 Throwables (com.google.common.base.Throwables)1 Sets (com.google.common.collect.Sets)1 File (java.io.File)1