Example usage for org.objectweb.asm Opcodes ACC_BRIDGE

List of usage examples for org.objectweb.asm Opcodes ACC_BRIDGE

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ACC_BRIDGE.

Prototype

int ACC_BRIDGE

To view the source code for org.objectweb.asm Opcodes ACC_BRIDGE.

Click Source Link

Usage

From source file:asm.FindCallers.java

License:Apache License

@Override
public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4) {
    if ((arg0 & Opcodes.ACC_BRIDGE) == Opcodes.ACC_BRIDGE
            && (arg0 & Opcodes.ACC_SYNTHETIC) == Opcodes.ACC_SYNTHETIC) {
        return null;
    }//from   ww  w.  jav a 2  s.  c om

    this.currentMethod = new Annotated(className, baseClass, arg1, arg2,
            (arg0 & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC);
    return super.visitMethod(arg0, arg1, arg2, arg3, arg4);
}

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 w  w. j a va  2  s  .c om
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.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.
 *///from   w ww.j  a v  a 2s .  c  om
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:com.android.build.gradle.internal.incremental.IncrementalSupportVisitor.java

License:Apache License

/**
 * Find a suitable parent for a method reference. The method owner is not always a valid
 * parent to dispatch to. For instance, take the following example :
 * <code>// w  w w.ja  v  a 2  s .c  o  m
 * package a;
 * public class A {
 *     public void publicMethod();
 * }
 *
 * package a;
 * class B extends A {
 *     public void publicMethod();
 * }
 *
 * package b;
 * public class C extends B {
 *     ...
 * }
 * </code>
 * when instrumenting C, the first method reference for "publicMethod" is on class B which we
 * cannot invoke directly since it's present on a private package B which is not located in the
 * same package as C. However C can still call the "publicMethod" since it's defined on A which
 * is a public class.
 *
 * We cannot just blindly take the top most definition of "publicMethod" hoping this is the
 * accessible one since you can very well do :
 * <code>
 * package a;
 * class A {
 *     public void publicMethod();
 * }
 *
 * package a;
 * public class B extends A {
 *     public void publicMethod();
 * }
 *
 * package b;
 * public class C extends B {
 *     ...
 * }
 * </code>
 *
 * In that case, the top most parent class is the one defined the unaccessible method reference.
 *
 * Therefore, the solution is to walk up the hierarchy until we find the same method defined on
 * an accessible class, if we cannot find such a method, the suitable parent is the parent class
 * of the visited class which is legal (but might consume a DEX id).
 *
 * @param methodReference the method reference to find a suitable parent for.
 * @return the parent class name
 */
@NonNull
String findParentClassForMethod(@NonNull MethodReference methodReference) {
    logger.verbose("MethodRef %1$s access(%2$s) -> owner %3$s access(%4$s)", methodReference.method.name,
            methodReference.method.access, methodReference.owner.name, methodReference.owner.access);
    // if the method owner class is accessible from the visited class, just use that.
    if (isParentClassVisible(methodReference.owner, classNode)) {
        return methodReference.owner.name;
    }
    logger.verbose("Found an inaccessible methodReference %1$s", methodReference.method.name);
    // walk up the hierarchy, starting at the method reference owner.
    Iterator<ClassNode> parentIterator = parentNodes.iterator();
    ClassNode parent = parentIterator.next();
    while (!parent.name.equals(methodReference.owner.name) && parentIterator.hasNext()) {
        parent = parentIterator.next();
    }
    while (parentIterator.hasNext()) {
        ClassNode node = parentIterator.next();
        // check that this parent is visible, there might be several layers of package
        // private classes.
        if (isParentClassVisible(node, classNode)) {
            //noinspection unchecked: ASM API
            for (MethodNode methodNode : (List<MethodNode>) node.methods) {
                // do not reference bridge methods, they might not be translated into dex, or
                // might disappear in the next javac compiler for that use case.
                if (methodNode.name.equals(methodReference.method.name)
                        && methodNode.desc.equals(methodReference.method.desc)
                        && (methodNode.access & (Opcodes.ACC_BRIDGE | Opcodes.ACC_ABSTRACT)) == 0) {
                    logger.verbose("Using class %1$s for dispatching %2$s:%3$s", node.name,
                            methodReference.method.name, methodReference.method.desc);
                    return node.name;
                }
            }
        }
    }
    logger.verbose("Using immediate parent for dispatching %1$s", methodReference.method.desc);
    return classNode.superName;
}

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

License:Apache License

/**
 * Defines when a method access flags are compatible with InstantRun technology.
 *
 * - If the method is a bridge method, we do not enable it for instantReload.
 *   it is most likely only calling a twin method (same name, same parameters).
 * - if the method is abstract or native, we don't add a redirection.
 *
 * @param access the method access flags
 * @return true if the method should be InstantRun enabled, false otherwise.
 *//*from   w w w.  j  a v  a  2 s. co  m*/
protected static boolean isAccessCompatibleWithInstantRun(int access) {
    return (access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_BRIDGE | Opcodes.ACC_NATIVE)) == 0;
}

From source file:com.android.build.gradle.internal2.incremental.IncrementalSupportVisitor.java

License:Apache License

/**
 * Find a suitable parent for a method reference. The method owner is not always a valid
 * parent to dispatch to. For instance, take the following example :
 * <code>/*from   w w  w . jav a  2 s. c  o m*/
 * package a;
 * public class A {
 *     public void publicMethod();
 * }
 *
 * package a;
 * class B extends A {
 *     public void publicMethod();
 * }
 *
 * package b;
 * public class C extends B {
 *     ...
 * }
 * </code>
 * when instrumenting C, the first method reference for "publicMethod" is on class B which we
 * cannot invoke directly since it's present on a private package B which is not located in the
 * same package as C. However C can still call the "publicMethod" since it's defined on A which
 * is a public class.
 *
 * We cannot just blindly take the top most definition of "publicMethod" hoping this is the
 * accessible one since you can very well do :
 * <code>
 * package a;
 * class A {
 *     public void publicMethod();
 * }
 *
 * package a;
 * public class B extends A {
 *     public void publicMethod();
 * }
 *
 * package b;
 * public class C extends B {
 *     ...
 * }
 * </code>
 *
 * In that case, the top most parent class is the one defined the unaccessible method reference.
 *
 * Therefore, the solution is to walk up the hierarchy until we find the same method defined on
 * an accessible class, if we cannot find such a method, the suitable parent is the parent class
 * of the visited class which is legal (but might consume a DEX id).
 *
 * @param methodReference the method reference to find a suitable parent for.
 * @return the parent class name
 */
@NonNull
String findParentClassForMethod(@NonNull MethodReference methodReference) {
    LOG.verbose("MethodRef %1$s access(%2$d) -> owner %3$s access(%4$d)", methodReference.method.name,
            methodReference.method.access, methodReference.owner.name, methodReference.owner.access);
    // if the method owner class is accessible from the visited class, just use that.
    if (isParentClassVisible(methodReference.owner, classNode)) {
        return methodReference.owner.name;
    }
    LOG.verbose("Found an inaccessible methodReference " + methodReference.method.name);
    // walk up the hierarchy, starting at the method reference owner.
    Iterator<ClassNode> parentIterator = parentNodes.iterator();
    ClassNode parent = parentIterator.next();
    while (!parent.name.equals(methodReference.owner.name) && parentIterator.hasNext()) {
        parent = parentIterator.next();
    }
    while (parentIterator.hasNext()) {
        ClassNode node = parentIterator.next();
        // check that this parent is visible, there might be several layers of package
        // private classes.
        if (isParentClassVisible(node, classNode)) {
            for (MethodNode methodNode : (List<MethodNode>) node.methods) {
                // do not reference bridge methods, they might not be translated into dex, or
                // might disappear in the next javac compiler for that use case.
                if (methodNode.name.equals(methodReference.method.name)
                        && methodNode.desc.equals(methodReference.method.desc)
                        && (methodNode.access & (Opcodes.ACC_BRIDGE | Opcodes.ACC_ABSTRACT)) == 0) {
                    LOG.verbose("Using class %1$s for dispatching %2$s:%3$s", node.name,
                            methodReference.method.name, methodReference.method.desc);
                    return node.name;
                }
            }
        }
    }
    LOG.verbose("Using immediate parent for dispatching %1$s", methodReference.method.desc);
    return classNode.superName;
}

From source file:com.facebook.buck.jvm.java.abi.AbiFilteringClassVisitor.java

License:Apache License

private boolean shouldIncludeInnerClass(int access, String name, @Nullable String outerName) {
    if (referencedClassNames == null || referencedClassNames.contains(name)) {
        // Either it's the first pass, and we're not filtering inner classes yet,
        // or it's the second one, and this inner class is part of the ABI and should
        // therefore be included
        return true;
    }// www . j  ava2  s . com

    String currentClassName = Preconditions.checkNotNull(this.name);
    if (name.equals(currentClassName)) {
        // Must always include the entry for our own class, since that's what makes it an inner class.
        return true;
    }

    boolean isAnonymousOrLocalClass = (outerName == null);
    if (isAnonymousOrLocalClass) {
        // Anonymous and local classes are never part of the ABI.
        return false;
    }

    if ((access & (Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE)) == Opcodes.ACC_SYNTHETIC) {
        // Don't include synthetic classes
        return false;
    }

    if (currentClassName.equals(outerName)) {
        // For now, always include our own inner classes, regardless of visibility
        return true;
    }

    return false;
}

From source file:com.facebook.buck.jvm.java.abi.AbiFilteringClassVisitor.java

License:Apache License

private boolean shouldInclude(int access) {
    if ((access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) {
        return false;
    }//from  w  ww  .  j a  v  a2 s. c om

    if ((access & (Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE)) == Opcodes.ACC_SYNTHETIC) {
        return false;
    }

    return true;
}

From source file:com.facebook.buck.jvm.java.abi.SourceAbiCompatibleVisitor.java

License:Apache License

@Override
@Nullable/*from w ww. jav a2 s .  c o  m*/
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if ((access & Opcodes.ACC_BRIDGE) != 0) {
        return null;
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}

From source file:com.gargoylesoftware.js.nashorn.internal.ir.debug.NashornTextifier.java

License:Open Source License

@Override
public NashornTextifier visitMethod(final int access, final String name, final String desc,
        final String signature, final String[] exceptions) {

    graph = new Graph(name);

    final List<Label> extraLabels = cr.getExtraLabels(currentClassName, name, desc);
    this.labelIter = extraLabels == null ? null : extraLabels.iterator();

    final StringBuilder sb = new StringBuilder();

    sb.append('\n');
    if ((access & Opcodes.ACC_DEPRECATED) != 0) {
        sb.append(tab).append("// DEPRECATED\n");
    }/*from ww w .  j ava  2  s  .  com*/

    sb.append(tab).append("// access flags 0x").append(Integer.toHexString(access).toUpperCase()).append('\n');

    if (signature != null) {
        sb.append(tab);
        appendDescriptor(sb, METHOD_SIGNATURE, signature);

        final TraceSignatureVisitor v = new TraceSignatureVisitor(0);
        final SignatureReader r = new SignatureReader(signature);
        r.accept(v);
        final String genericDecl = v.getDeclaration();
        final String genericReturn = v.getReturnType();
        final String genericExceptions = v.getExceptions();

        sb.append(tab).append("// declaration: ").append(genericReturn).append(' ').append(name)
                .append(genericDecl);

        if (genericExceptions != null) {
            sb.append(" throws ").append(genericExceptions);
        }
        sb.append('\n');
    }

    sb.append(tab);
    appendAccess(sb, access);
    if ((access & Opcodes.ACC_NATIVE) != 0) {
        sb.append("native ");
    }
    if ((access & Opcodes.ACC_VARARGS) != 0) {
        sb.append("varargs ");
    }
    if ((access & Opcodes.ACC_BRIDGE) != 0) {
        sb.append("bridge ");
    }

    sb.append(name);
    appendDescriptor(sb, METHOD_DESCRIPTOR, desc);
    if (exceptions != null && exceptions.length > 0) {
        sb.append(" throws ");
        for (final String exception : exceptions) {
            appendDescriptor(sb, INTERNAL_NAME, exception);
            sb.append(' ');
        }
    }

    sb.append('\n');
    addText(sb);

    final NashornTextifier t = createNashornTextifier();
    addText(t.getText());
    return t;
}