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

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

Introduction

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

Prototype

public void goTo(final Label label) 

Source Link

Document

Generates the instruction to jump to the given label.

Usage

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

License:Apache License

/**
 * Generates method body for encoding Collection value. The logic is like this:
 *
 * <pre>/*from   ww w  .j av a 2  s .  c  o m*/
 * {@code
 *
 * encoder.writeInt(collection.size());
 * for (T element : collection) {
 *   encodeElement(element, encoder, elementSchema, seenRefs);
 * }
 * if (collection.size() > 0) {
 *   encoder.writeInt(0);
 * }
 * }
 * </pre>
 * @param mg
 * @param componentType
 * @param componentSchema
 * @param value
 * @param encoder
 */
private void encodeCollection(GeneratorAdapter mg, TypeToken<?> componentType, Schema componentSchema,
        int value, int encoder, int schemaLocal, int seenRefs) {
    // Encode and store the collection length locally
    mg.loadArg(value);
    mg.invokeInterface(Type.getType(Collection.class), getMethod(int.class, "size"));
    int length = mg.newLocal(Type.INT_TYPE);
    mg.storeLocal(length);

    mg.loadArg(encoder);
    mg.loadLocal(length);
    mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class));
    mg.pop();

    // Store the component schema
    mg.loadArg(schemaLocal);
    mg.invokeVirtual(Type.getType(Schema.class), getMethod(Schema.class, "getComponentSchema"));
    int componentSchemaLocal = mg.newLocal(Type.getType(Schema.class));
    mg.storeLocal(componentSchemaLocal);

    // Store the iterator
    int iterator = mg.newLocal(Type.getType(Iterator.class));
    mg.loadArg(value);
    mg.invokeInterface(Type.getType(Collection.class), getMethod(Iterator.class, "iterator"));
    mg.storeLocal(iterator);

    // For loop with iterator. Encode each component
    Label beginFor = mg.mark();
    Label endFor = mg.newLabel();
    mg.loadLocal(iterator);
    mg.invokeInterface(Type.getType(Iterator.class), getMethod(boolean.class, "hasNext"));
    mg.ifZCmp(GeneratorAdapter.EQ, endFor);

    // Call the encode method for encoding the element.
    mg.loadThis();

    mg.loadLocal(iterator);
    mg.invokeInterface(Type.getType(Iterator.class), getMethod(Object.class, "next"));
    doCast(mg, componentType, componentSchema);
    mg.loadArg(encoder);
    mg.loadLocal(componentSchemaLocal);
    mg.loadArg(seenRefs);
    mg.invokeVirtual(classType, getEncodeMethod(componentType, componentSchema));
    mg.goTo(beginFor);

    mg.mark(endFor);

    // if length > 0, write out 0 at the end of array.
    Label zeroLength = mg.newLabel();
    mg.loadLocal(length);
    mg.ifZCmp(GeneratorAdapter.LE, zeroLength);
    encodeInt(mg, 0, encoder);
    mg.mark(zeroLength);
}

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

License:Apache License

/**
 * Generates method body for encoding array value. The logic is similar to the one in
 * {@link #encodeCollection}, with collection size replaced with array length.
 *
 * @param mg/*from ww w . j  a v a 2 s.c  o m*/
 * @param componentType
 * @param componentSchema
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeArray(GeneratorAdapter mg, TypeToken<?> componentType, Schema componentSchema, int value,
        int encoder, int schemaLocal, int seenRefs) {
    // Encode and store the array length locally
    mg.loadArg(value);
    mg.arrayLength();
    int length = mg.newLocal(Type.INT_TYPE);
    mg.storeLocal(length);

    mg.loadArg(encoder);
    mg.loadLocal(length);
    mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class));
    mg.pop();

    // Store the component schema
    mg.loadArg(schemaLocal);
    mg.invokeVirtual(Type.getType(Schema.class), getMethod(Schema.class, "getComponentSchema"));
    int componentSchemaLocal = mg.newLocal(Type.getType(Schema.class));
    mg.storeLocal(componentSchemaLocal);

    // for (int idx = 0; idx < array.length; idx++)
    mg.push(0);
    int idx = mg.newLocal(Type.INT_TYPE);
    mg.storeLocal(idx);
    Label beginFor = mg.mark();
    Label endFor = mg.newLabel();
    mg.loadLocal(idx);
    mg.loadLocal(length);
    mg.ifICmp(GeneratorAdapter.GE, endFor);

    // Call encode method to encode array[idx]
    mg.loadThis();
    mg.loadArg(value);
    mg.loadLocal(idx);
    TypeToken<?> callTypeToken = getCallTypeToken(componentType, componentSchema);
    mg.arrayLoad(Type.getType(callTypeToken.getRawType()));
    mg.loadArg(encoder);
    mg.loadLocal(componentSchemaLocal);
    mg.loadArg(seenRefs);
    mg.invokeVirtual(classType, getEncodeMethod(componentType, componentSchema));

    mg.iinc(idx, 1);
    mg.goTo(beginFor);
    mg.mark(endFor);

    // if length > 0, write out 0 at the end of array.
    Label zeroLength = mg.newLabel();
    mg.loadLocal(length);
    mg.ifZCmp(GeneratorAdapter.LE, zeroLength);
    encodeInt(mg, 0, encoder);
    mg.mark(zeroLength);
}

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

License:Apache License

/**
 * Generates method body for encoding map value. The logic is like this:
 *
 * <pre>/*from   ww w . j  av  a 2 s  .c  om*/
 * {@code
 *
 * encoder.writeInt(map.size();
 *
 * for (Map.Entry<Key, Value> entry : map.entrySet()) {
 *   encodeKey(entry.getKey(), encoder, keySchema, seenRefs);
 *   encodeValue(entry.getValue(), encoder, valueSchema, seenRefs);
 * }
 *
 * if (map.size() > 0) {
 *   encoder.writeInt(0);
 * }
 * }
 * </pre>
 *
 * @param mg
 * @param keyType
 * @param valueType
 * @param keySchema
 * @param valueSchema
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeMap(GeneratorAdapter mg, TypeToken<?> keyType, TypeToken<?> valueType, Schema keySchema,
        Schema valueSchema, int value, int encoder, int schemaLocal, int seenRefs) {
    // Encode and store the map length locally
    mg.loadArg(value);
    mg.invokeInterface(Type.getType(Map.class), getMethod(int.class, "size"));
    int length = mg.newLocal(Type.INT_TYPE);
    mg.storeLocal(length);

    mg.loadArg(encoder);
    mg.loadLocal(length);
    mg.invokeInterface(Type.getType(Encoder.class), getMethod(Encoder.class, "writeInt", int.class));
    mg.pop();

    // Stores the key and value schema
    mg.loadArg(schemaLocal);
    mg.invokeVirtual(Type.getType(Schema.class), getMethod(Map.Entry.class, "getMapSchema"));
    mg.dup();

    int keySchemaLocal = mg.newLocal(Type.getType(Schema.class));
    mg.invokeInterface(Type.getType(Map.Entry.class), getMethod(Object.class, "getKey"));
    mg.checkCast(Type.getType(Schema.class));
    mg.storeLocal(keySchemaLocal);

    int valueSchemaLocal = mg.newLocal(Type.getType(Schema.class));
    mg.invokeInterface(Type.getType(Map.Entry.class), getMethod(Object.class, "getValue"));
    mg.checkCast(Type.getType(Schema.class));
    mg.storeLocal(valueSchemaLocal);

    // Store the entry set iterator
    int iterator = mg.newLocal(Type.getType(Iterator.class));
    mg.loadArg(value);
    mg.invokeInterface(Type.getType(Map.class), getMethod(Set.class, "entrySet"));
    mg.invokeInterface(Type.getType(Set.class), getMethod(Iterator.class, "iterator"));
    mg.storeLocal(iterator);

    // For loop the entry set iterator, encode each key-value pairs
    Label beginFor = mg.mark();
    Label endFor = mg.newLabel();
    mg.loadLocal(iterator);
    mg.invokeInterface(Type.getType(Iterator.class), getMethod(boolean.class, "hasNext"));
    mg.ifZCmp(GeneratorAdapter.EQ, endFor);

    int entry = mg.newLocal(Type.getType(Map.Entry.class));
    mg.loadLocal(iterator);
    mg.invokeInterface(Type.getType(Iterator.class), getMethod(Object.class, "next"));
    mg.checkCast(Type.getType(Map.Entry.class));
    mg.storeLocal(entry);

    // encode key
    mg.loadThis();
    mg.loadLocal(entry);
    mg.invokeInterface(Type.getType(Map.Entry.class), getMethod(Object.class, "getKey"));
    doCast(mg, keyType, keySchema);
    mg.loadArg(encoder);
    mg.loadLocal(keySchemaLocal);
    mg.loadArg(seenRefs);
    mg.invokeVirtual(classType, getEncodeMethod(keyType, keySchema));

    // encode value
    mg.loadThis();
    mg.loadLocal(entry);
    mg.invokeInterface(Type.getType(Map.Entry.class), getMethod(Object.class, "getValue"));
    doCast(mg, valueType, valueSchema);
    mg.loadArg(encoder);
    mg.loadLocal(valueSchemaLocal);
    mg.loadArg(seenRefs);
    mg.invokeVirtual(classType, getEncodeMethod(valueType, valueSchema));

    mg.goTo(beginFor);
    mg.mark(endFor);

    // if length > 0, write out 0 at the end of map
    Label zeroLength = mg.newLabel();
    mg.loadLocal(length);
    mg.ifZCmp(GeneratorAdapter.LE, zeroLength);
    encodeInt(mg, 0, encoder);
    mg.mark(zeroLength);
}

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

License:Apache License

/**
 * Generates method body for encoding union schema. Union schema is used for representing object references that
 * could be {@code null}./*  w  w w .j a va 2s. c o m*/
 * @param mg
 * @param outputType
 * @param schema
 * @param value
 * @param encoder
 * @param schemaLocal
 * @param seenRefs
 */
private void encodeUnion(GeneratorAdapter mg, TypeToken<?> outputType, Schema schema, int value, int encoder,
        int schemaLocal, int seenRefs) {
    Label nullLabel = mg.newLabel();
    Label endLabel = mg.newLabel();
    mg.loadArg(value);

    mg.ifNull(nullLabel);
    // Not null, write out 0 and then encode the value
    encodeInt(mg, 0, encoder);

    mg.loadThis();
    mg.loadArg(value);
    doCast(mg, outputType, schema.getUnionSchema(0));
    mg.loadArg(encoder);
    mg.loadArg(schemaLocal);
    mg.push(0);
    mg.invokeVirtual(Type.getType(Schema.class), getMethod(Schema.class, "getUnionSchema", int.class));
    mg.loadArg(seenRefs);
    mg.invokeVirtual(classType, getEncodeMethod(outputType, schema.getUnionSchema(0)));

    mg.goTo(endLabel);

    mg.mark(nullLabel);
    // Null, write out 1
    encodeInt(mg, 1, encoder);
    mg.mark(endLabel);
}

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

License:Apache License

private void initializeReflectionField(GeneratorAdapter mg, Field field) {
    /*/*  w  w w.  j  a  va2  s .c o m*/
     Save the reflected Field object for accessing private field.
     try {
       Field field = Fields.findField(classType, "fieldName");
       field.setAccessible(true);
            
       this.field = field;
     } catch (Exception e) {
       throw Throwables.propagate(e);
     }
    */
    Label beginTry = mg.newLabel();
    Label endTry = mg.newLabel();
    Label catchHandle = mg.newLabel();
    mg.visitTryCatchBlock(beginTry, endTry, catchHandle, Type.getInternalName(Exception.class));
    mg.mark(beginTry);

    // Field field = Fields.findField(classType, "fieldName")
    mg.loadArg(0);
    mg.push(field.getName());
    mg.invokeStatic(Type.getType(Fields.class),
            getMethod(Field.class, "findField", java.lang.reflect.Type.class, String.class));
    mg.dup();

    // field.setAccessible(true);
    mg.push(true);
    mg.invokeVirtual(Type.getType(Field.class), getMethod(void.class, "setAccessible", boolean.class));

    // this.field = field;
    // need to swap the this reference and the one in top stack (from dup() ).
    mg.loadThis();
    mg.swap();
    mg.putField(Type.getObjectType(className), "field", Type.getType(Field.class));
    mg.mark(endTry);
    Label endCatch = mg.newLabel();
    mg.goTo(endCatch);
    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.mark(endCatch);
}

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

License:Apache License

private void initializeReflectionField(GeneratorAdapter mg, Field field) {
    /*/*from ww w . j  a va2s .co m*/
     Save the reflected Field object for accessing private field.
     try {
       Field field = Fields.findField(classType, "fieldName");
       field.setAccessible(true);
            
       this.field = field;
     } catch (Exception e) {
       throw Throwables.propagate(e);
     }
    */
    Label beginTry = mg.newLabel();
    Label endTry = mg.newLabel();
    Label catchHandle = mg.newLabel();
    mg.visitTryCatchBlock(beginTry, endTry, catchHandle, Type.getInternalName(Exception.class));
    mg.mark(beginTry);

    // Field field = findField(classType, "fieldName")
    mg.loadArg(0);
    mg.push(field.getName());
    mg.invokeStatic(Type.getType(Fields.class),
            getMethod(Field.class, "findField", TypeToken.class, String.class));
    mg.dup();

    // field.setAccessible(true);
    mg.push(true);
    mg.invokeVirtual(Type.getType(Field.class), getMethod(void.class, "setAccessible", boolean.class));

    // this.field = field;
    // need to swap the this reference and the one in top stack (from dup() ).
    mg.loadThis();
    mg.swap();
    mg.putField(Type.getObjectType(className), "field", Type.getType(Field.class));
    mg.mark(endTry);
    Label endCatch = mg.newLabel();
    mg.goTo(endCatch);
    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.mark(endCatch);
}

From source file:com.android.build.gradle.internal.incremental.ConstructorArgsRedirection.java

License:Apache License

@Override
protected void restore(GeneratorAdapter mv, List<Type> args) {
    // At this point, init$args has been called and the result Object is on the stack.
    // The value of that Object is Object[] with exactly n + 1 elements.
    // The first element is a string with the qualified name of the constructor to call.
    // The remaining elements are the constructtor arguments.

    // Create a new local that holds the result of init$args call.
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    int constructorArgs = mv.newLocal(Type.getType("[Ljava/lang/Object;"));
    mv.storeLocal(constructorArgs);/*w w w. j  ava2  s.  co  m*/

    // Reinstate local values
    mv.loadLocal(locals);
    int stackIndex = 0;
    for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) {
        Type arg = args.get(arrayIndex);
        // Do not restore "this"
        if (arrayIndex > 0) {
            // duplicates the array
            mv.dup();
            // index in the array of objects to restore the boxed parameter.
            mv.push(arrayIndex);
            // get it from the array
            mv.arrayLoad(Type.getType(Object.class));
            // unbox the argument
            ByteCodeUtils.unbox(mv, arg);
            // restore the argument
            mv.visitVarInsn(arg.getOpcode(Opcodes.ISTORE), stackIndex);
        }
        // stack index must progress according to the parameter type we just processed.
        stackIndex += arg.getSize();
    }
    // pops the array
    mv.pop();

    // Push a null for the marker parameter.
    mv.loadLocal(constructorArgs);
    mv.visitInsn(Opcodes.ACONST_NULL);

    // Invoke the constructor
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, thisClassName, "<init>", DISPATCHING_THIS_SIGNATURE, false);

    mv.goTo(end.getLabel());
}

From source file:com.changingbits.Builder.java

License:Apache License

private void buildAsm(GeneratorAdapter gen, Node node, int uptoLocal) {

    if (node.outputs != null) {
        //System.out.println("gen outputs=" + node.outputs);
        // Increment any range outputs at the current node:
        for (int range : node.outputs) {
            // Load arg 1 (the int[] answers):
            gen.loadArg(1);//from   w  ww  .j a  v  a 2  s.c om
            // Load the index we will store to
            gen.loadLocal(uptoLocal, Type.INT_TYPE);
            // The range value we will store:
            gen.push(range);
            // Store it
            gen.arrayStore(Type.INT_TYPE);
            // Increment our upto:
            gen.iinc(uptoLocal, 1);
        }
    }

    if (node.left != null && (node.left.hasOutputs || node.right.hasOutputs)) {
        assert node.left.end + 1 == node.right.start;
        if (node.left.hasOutputs && node.right.hasOutputs) {
            // 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);
            buildAsm(gen, node.right, uptoLocal);
            gen.goTo(labelEnd);
            gen.visitLabel(labelLeft);
            buildAsm(gen, node.left, uptoLocal);
            gen.visitLabel(labelEnd);
        } else if (node.left.hasOutputs) {
            // Recurse only on left
            Label labelEnd = new Label();
            gen.loadArg(0);
            gen.push(node.left.end);

            gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.GT, labelEnd);
            buildAsm(gen, node.left, uptoLocal);
            gen.visitLabel(labelEnd);
        } else {
            // Recurse only on right
            Label labelEnd = new Label();
            gen.loadArg(0);
            gen.push(node.left.end);

            gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelEnd);
            buildAsm(gen, node.right, uptoLocal);
            gen.visitLabel(labelEnd);
        }
    }
}

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;//from   w ww .  j  a  va  2 s  .  c om

    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);
    }
}

From source file:com.changingbits.Builder.java

License:Apache License

private void buildCounterAsm(GeneratorAdapter gen, Node node, boolean sawOutputs) {

    sawOutputs |= node.outputs != null;//from   w  w w .j  a v  a  2 s. 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);
        buildCounterAsm(gen, node.right, sawOutputs);
        gen.goTo(labelEnd);
        gen.visitLabel(labelLeft);
        buildCounterAsm(gen, node.left, sawOutputs);
        gen.visitLabel(labelEnd);
    } else if (sawOutputs) {
        // leaf: elementaryCounts[node.leafIndex]++
        gen.loadThis();
        gen.getField(BASE_LONG_RANGE_COUNTER_TYPE, "elementaryCounts", INT_ARRAY_TYPE);
        gen.push(node.leafIndex);
        gen.dup2();
        gen.arrayLoad(Type.INT_TYPE);
        gen.push(1);
        gen.visitInsn(Opcodes.IADD);
        gen.arrayStore(Type.INT_TYPE);
    }
}