Example usage for org.objectweb.asm.commons GeneratorAdapter getField

List of usage examples for org.objectweb.asm.commons GeneratorAdapter getField

Introduction

In this page you can find the example usage for org.objectweb.asm.commons GeneratorAdapter getField.

Prototype

public void getField(final Type owner, final String name, final Type type) 

Source Link

Document

Generates the instruction to push the value of a non static field on the stack.

Usage

From source file:co.cask.cdap.app.runtime.spark.SparkRunnerClassLoader.java

License:Apache License

/**
 * Defines the org.apache.spark.deploy.yarn.Client class with rewriting of the createConfArchive method to
 * workaround the SPARK-13441 bug.//  w w  w  .j  ava2 s  .c om
 */
private Class<?> defineClient(String name, InputStream createConfArchive)
        throws IOException, ClassNotFoundException {
    // 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 findClass(name);
    }

    ClassReader cr = new ClassReader(createConfArchive);
    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);

    byte[] byteCode = cw.toByteArray();
    return defineClass(name, byteCode, 0, byteCode.length);
}

From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates the {@link DatumWriter#encode(Object, co.cask.cdap.common.io.Encoder)} method.
 * @param outputType Type information of the data type for output
 * @param schema Schema to use for output.
 *//*from w  ww .j  a v  a 2s  . co  m*/
private void generateEncode(TypeToken<?> outputType, Schema schema) {
    TypeToken<?> callOutputType = getCallTypeToken(outputType, schema);

    Method encodeMethod = getMethod(void.class, "encode", callOutputType.getRawType(), Encoder.class);

    if (!Object.class.equals(callOutputType.getRawType())) {
        // Generate the synthetic method for the bridging
        Method method = getMethod(void.class, "encode", Object.class, Encoder.class);
        GeneratorAdapter mg = new GeneratorAdapter(
                Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, method, null,
                new Type[] { Type.getType(IOException.class) }, classWriter);

        mg.loadThis();
        mg.loadArg(0);
        mg.checkCast(Type.getType(callOutputType.getRawType()));
        mg.loadArg(1);
        mg.invokeVirtual(classType, encodeMethod);
        mg.returnValue();
        mg.endMethod();
    }

    // Generate the top level public encode method
    String methodSignature = null;
    if (callOutputType.getType() instanceof ParameterizedType) {
        methodSignature = Signatures.getMethodSignature(encodeMethod, callOutputType, null);
    }
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, encodeMethod, methodSignature,
            new Type[] { Type.getType(IOException.class) }, classWriter);

    // Delegate to the actual encode method(value, encoder, schema, Sets.newIdentityHashSet());
    mg.loadThis();
    mg.loadArg(0);
    mg.loadArg(1);
    mg.loadThis();
    mg.getField(classType, "schema", Type.getType(Schema.class));
    // seenRefs Set
    mg.invokeStatic(Type.getType(Sets.class), getMethod(Set.class, "newIdentityHashSet"));
    mg.invokeVirtual(classType, getEncodeMethod(outputType, schema));
    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates method body for encoding java class. If the class given is an interface,
 * getter method will be used to access the field values, otherwise, it will assumes
 * fields are public./*from   www . j a v  a  2  s.  co m*/
 *
 * @param mg
 * @param schema
 * @param outputType
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder,
        int schemaLocal, int seenRefs) {

    try {
        Class<?> rawType = outputType.getRawType();

        // Record type might be defined by the user, hence need to preserve class loading of it
        preservedClasses.add(rawType);
        boolean isInterface = rawType.isInterface();

        /*
          Check for circular reference
          if (value != null && !seenRefs.add(value)) {
             throw new IOException(...);
          }
        */
        Label notSeen = mg.newLabel();
        mg.loadArg(value);
        mg.ifNull(notSeen);
        mg.loadArg(seenRefs);
        mg.loadArg(value);
        mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class));
        mg.ifZCmp(GeneratorAdapter.NE, notSeen);
        mg.throwException(Type.getType(IOException.class), "Circular reference not supported.");
        mg.mark(notSeen);

        // Store the list of schema fields.
        mg.loadArg(schemaLocal);
        mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields"));
        int fieldSchemas = mg.newLocal(Type.getType(List.class));
        mg.storeLocal(fieldSchemas);

        // For each field, call the encode method for the field
        List<Schema.Field> fields = schema.getFields();
        for (int i = 0; i < fields.size(); i++) {
            Schema.Field field = fields.get(i);

            TypeToken<?> fieldType;

            // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema());
            if (isInterface) {
                mg.loadThis();
                mg.loadArg(value);
                Method getter = getGetter(outputType, field.getName());
                fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType());
                mg.invokeInterface(Type.getType(rawType), getter);
            } else {
                fieldType = outputType
                        .resolveType(Fields.findField(outputType.getType(), field.getName()).getGenericType());
                fieldAccessorRequests.put(outputType, field.getName());
                mg.loadThis();
                mg.dup();
                mg.getField(classType, getFieldAccessorName(outputType, field.getName()),
                        Type.getType(FieldAccessor.class));
                mg.loadArg(value);
                mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType));
                if (!fieldType.getRawType().isPrimitive()) {
                    doCast(mg, fieldType, field.getSchema());
                }
            }
            mg.loadArg(encoder);
            mg.loadLocal(fieldSchemas);
            mg.push(i);
            mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class));
            mg.checkCast(Type.getType(Schema.Field.class));
            mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema"));
            mg.loadArg(seenRefs);
            mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema()));
        }
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates the try-catch block that wrap around the given reflection method call.
 * @param method The method to be called within the try-catch block.
 *//* ww  w  .  j  av  a  2  s.  c  om*/
private void invokeReflection(Method method, String signature) {
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, method, signature, new Type[0], classWriter);
    /**
     * try {
     *   // Call method
     * } catch (IllegalAccessException e) {
     *   throw Throwables.propagate(e);
     * }
     */
    Label beginTry = mg.newLabel();
    Label endTry = mg.newLabel();
    Label catchHandle = mg.newLabel();
    mg.visitTryCatchBlock(beginTry, endTry, catchHandle, Type.getInternalName(IllegalAccessException.class));
    mg.mark(beginTry);
    mg.loadThis();
    mg.getField(Type.getObjectType(className), "field", Type.getType(Field.class));
    mg.loadArgs();
    mg.invokeVirtual(Type.getType(Field.class), method);
    mg.mark(endTry);
    mg.returnValue();
    mg.mark(catchHandle);
    int exception = mg.newLocal(Type.getType(IllegalAccessException.class));
    mg.storeLocal(exception);
    mg.loadLocal(exception);
    mg.invokeStatic(Type.getType(Throwables.class),
            getMethod(RuntimeException.class, "propagate", Throwable.class));
    mg.throwException();
    mg.endMethod();

}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates a getter that get the value by directly accessing the class field.
 * @param field The reflection field object.
 *///from ww w  . ja v a 2s  . co  m
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();
}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates the primitive getter (getXXX) based on the field type.
 * @param field The reflection field object.
 *//*w w  w  . java  2s .co  m*/
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();
}

From source file:co.cask.common.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates method body for encoding java class. If the class given is an interface,
 * getter method will be used to access the field values, otherwise, it will assumes
 * fields are public./*from  w w  w.  j  av  a  2  s  .  c om*/
 *
 * @param mg
 * @param schema
 * @param outputType
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder,
        int schemaLocal, int seenRefs) {

    try {
        Class<?> rawType = outputType.getRawType();

        // Record type might be defined by the user, hence need to preserve class loading of it
        preservedClasses.add(rawType);
        boolean isInterface = rawType.isInterface();

        /*
          Check for circular reference
          if (value != null && !seenRefs.add(value)) {
             throw new IOException(...);
          }
        */
        Label notSeen = mg.newLabel();
        mg.loadArg(value);
        mg.ifNull(notSeen);
        mg.loadArg(seenRefs);
        mg.loadArg(value);
        mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class));
        mg.ifZCmp(GeneratorAdapter.NE, notSeen);
        mg.throwException(Type.getType(IOException.class), "Circular reference not supported.");
        mg.mark(notSeen);

        // Store the list of schema fields.
        mg.loadArg(schemaLocal);
        mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields"));
        int fieldSchemas = mg.newLocal(Type.getType(List.class));
        mg.storeLocal(fieldSchemas);

        // For each field, call the encode method for the field
        List<Schema.Field> fields = schema.getFields();
        for (int i = 0; i < fields.size(); i++) {
            Schema.Field field = fields.get(i);

            TypeToken<?> fieldType;

            // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema());
            if (isInterface) {
                mg.loadThis();
                mg.loadArg(value);
                Method getter = getGetter(outputType, field.getName());
                fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType());
                mg.invokeInterface(Type.getType(rawType), getter);
            } else {
                fieldType = outputType
                        .resolveType(Fields.findField(outputType, field.getName()).getGenericType());
                fieldAccessorRequests.put(outputType, field.getName());
                mg.loadThis();
                mg.dup();
                mg.getField(classType, getFieldAccessorName(outputType, field.getName()),
                        Type.getType(FieldAccessor.class));
                mg.loadArg(value);
                mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType));
                if (!fieldType.getRawType().isPrimitive()) {
                    doCast(mg, fieldType, field.getSchema());
                }
            }
            mg.loadArg(encoder);
            mg.loadLocal(fieldSchemas);
            mg.push(i);
            mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class));
            mg.checkCast(Type.getType(Schema.Field.class));
            mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema"));
            mg.loadArg(seenRefs);
            mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema()));
        }
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}

From source file:co.cask.tigon.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates the {@link DatumWriter#encode(Object, co.cask.tigon.io.Encoder)} method.
 * @param outputType Type information of the data type for output
 * @param schema Schema to use for output.
 *//*  w w  w  . j  a  va 2  s  .  c o  m*/
private void generateEncode(TypeToken<?> outputType, Schema schema) {
    TypeToken<?> callOutputType = getCallTypeToken(outputType, schema);

    Method encodeMethod = getMethod(void.class, "encode", callOutputType.getRawType(), Encoder.class);

    if (!Object.class.equals(callOutputType.getRawType())) {
        // Generate the synthetic method for the bridging
        Method method = getMethod(void.class, "encode", Object.class, Encoder.class);
        GeneratorAdapter mg = new GeneratorAdapter(
                Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, method, null,
                new Type[] { Type.getType(IOException.class) }, classWriter);

        mg.loadThis();
        mg.loadArg(0);
        mg.checkCast(Type.getType(callOutputType.getRawType()));
        mg.loadArg(1);
        mg.invokeVirtual(classType, encodeMethod);
        mg.returnValue();
        mg.endMethod();
    }

    // Generate the top level public encode method
    String methodSignature = null;
    if (callOutputType.getType() instanceof ParameterizedType) {
        methodSignature = Signatures.getMethodSignature(encodeMethod, new TypeToken[] { callOutputType, null });
    }
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, encodeMethod, methodSignature,
            new Type[] { Type.getType(IOException.class) }, classWriter);

    // Delegate to the actual encode method(value, encoder, schema, Sets.newIdentityHashSet());
    mg.loadThis();
    mg.loadArg(0);
    mg.loadArg(1);
    mg.loadThis();
    mg.getField(classType, "schema", Type.getType(Schema.class));
    // seenRefs Set
    mg.invokeStatic(Type.getType(Sets.class), getMethod(Set.class, "newIdentityHashSet"));
    mg.invokeVirtual(classType, getEncodeMethod(outputType, schema));
    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.tigon.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates method body for encoding java class. If the class given is an interface,
 * getter method will be used to access the field values, otherwise, it will assumes
 * fields are public.//from  w ww  .  j  a v  a 2 s  .c  om
 *
 * @param mg
 * @param schema
 * @param outputType
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeRecord(GeneratorAdapter mg, Schema schema, TypeToken<?> outputType, int value, int encoder,
        int schemaLocal, int seenRefs) {

    try {
        Class<?> rawType = outputType.getRawType();
        boolean isInterface = rawType.isInterface();

        /*
          Check for circular reference
          if (value != null && !seenRefs.add(value)) {
             throw new IOException(...);
          }
        */
        Label notSeen = mg.newLabel();
        mg.loadArg(value);
        mg.ifNull(notSeen);
        mg.loadArg(seenRefs);
        mg.loadArg(value);
        mg.invokeInterface(Type.getType(Set.class), getMethod(boolean.class, "add", Object.class));
        mg.ifZCmp(GeneratorAdapter.NE, notSeen);
        mg.throwException(Type.getType(IOException.class), "Circular reference not supported.");
        mg.mark(notSeen);

        // Store the list of schema fields.
        mg.loadArg(schemaLocal);
        mg.invokeVirtual(Type.getType(Schema.class), getMethod(List.class, "getFields"));
        int fieldSchemas = mg.newLocal(Type.getType(List.class));
        mg.storeLocal(fieldSchemas);

        // For each field, call the encode method for the field
        List<Schema.Field> fields = schema.getFields();
        for (int i = 0; i < fields.size(); i++) {
            Schema.Field field = fields.get(i);

            TypeToken<?> fieldType;

            // this.encodeFieldMethod(value.fieldName, encoder, fieldSchemas.get(i).getSchema());
            if (isInterface) {
                mg.loadThis();
                mg.loadArg(value);
                Method getter = getGetter(outputType, field.getName());
                fieldType = outputType.resolveType(rawType.getMethod(getter.getName()).getGenericReturnType());
                mg.invokeInterface(Type.getType(rawType), getter);
            } else {
                fieldType = outputType
                        .resolveType(Fields.findField(outputType, field.getName()).getGenericType());
                fieldAccessorRequests.put(outputType, field.getName());
                mg.loadThis();
                mg.dup();
                mg.getField(classType, getFieldAccessorName(outputType, field.getName()),
                        Type.getType(FieldAccessor.class));
                mg.loadArg(value);
                mg.invokeInterface(Type.getType(FieldAccessor.class), getAccessorMethod(fieldType));
                if (!fieldType.getRawType().isPrimitive()) {
                    doCast(mg, fieldType, field.getSchema());
                }
            }
            mg.loadArg(encoder);
            mg.loadLocal(fieldSchemas);
            mg.push(i);
            mg.invokeInterface(Type.getType(List.class), getMethod(Object.class, "get", int.class));
            mg.checkCast(Type.getType(Schema.Field.class));
            mg.invokeVirtual(Type.getType(Schema.Field.class), getMethod(Schema.class, "getSchema"));
            mg.loadArg(seenRefs);
            mg.invokeVirtual(classType, getEncodeMethod(fieldType, field.getSchema()));
        }
    } catch (Exception e) {
        throw Throwables.propagate(e);
    }
}

From source file:com.changingbits.Builder.java

License:Apache License

/** Increments counts as field members (count0, count1,
 *  ...) instead of a this.intArray[0], ... */
private void buildCounterAsm2(GeneratorAdapter gen, Node node, boolean sawOutputs) {

    sawOutputs |= node.outputs != null;/*  www .j av a 2s.co m*/

    if (node.left != null) {
        assert node.left.end + 1 == node.right.start;
        // Recurse on either left or right
        Label labelLeft = new Label();
        Label labelEnd = new Label();
        gen.loadArg(0);
        gen.push(node.left.end);

        gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelLeft);
        buildCounterAsm2(gen, node.right, sawOutputs);
        gen.goTo(labelEnd);
        gen.visitLabel(labelLeft);
        buildCounterAsm2(gen, node.left, sawOutputs);
        gen.visitLabel(labelEnd);
    } else if (sawOutputs) {
        // leaf: this.countN++
        gen.loadThis();
        gen.loadThis();
        gen.getField(COMPILED_COUNTER_CLASS2_TYPE, "count" + node.leafIndex, Type.INT_TYPE);
        gen.push(1);
        gen.visitInsn(Opcodes.IADD);
        gen.putField(COMPILED_COUNTER_CLASS2_TYPE, "count" + node.leafIndex, Type.INT_TYPE);
    }
}