Example usage for org.objectweb.asm Opcodes H_NEWINVOKESPECIAL

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

Introduction

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

Prototype

int H_NEWINVOKESPECIAL

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

Click Source Link

Usage

From source file:com.devexperts.usages.ClassUsagesAnalyzer.java

License:Open Source License

private void markHandleUse(Handle handle, Member usedFrom, UseKind useKind) {
    markTypeUse(Type.getType(handle.getDesc()), usedFrom, useKind);
    String className = Type.getType(handle.getOwner()).getClassName();
    switch (handle.getTag()) {
    case Opcodes.H_GETFIELD:
    case Opcodes.H_GETSTATIC:
    case Opcodes.H_PUTFIELD:
    case Opcodes.H_PUTSTATIC:
        markMemberUse(className, handle.getName(), usedFrom, useKind);
        break;/* w w  w.j  a va  2s .  co  m*/
    case Opcodes.H_INVOKEVIRTUAL:
    case Opcodes.H_INVOKESTATIC:
    case Opcodes.H_INVOKESPECIAL:
    case Opcodes.H_NEWINVOKESPECIAL:
    case Opcodes.H_INVOKEINTERFACE:
        markMemberUse(className, Member.methodMemberName(handle.getName(), Type.getType(handle.getDesc())),
                usedFrom, useKind);
    }
}

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

License:Open Source License

private static void appendHandle(final StringBuilder sb, final Handle h) {
    switch (h.getTag()) {
    case Opcodes.H_GETFIELD:
        sb.append("getfield");
        break;//  w w  w .  j  a  v a 2 s. c  o m
    case Opcodes.H_GETSTATIC:
        sb.append("getstatic");
        break;
    case Opcodes.H_PUTFIELD:
        sb.append("putfield");
        break;
    case Opcodes.H_PUTSTATIC:
        sb.append("putstatic");
        break;
    case Opcodes.H_INVOKEINTERFACE:
        sb.append("interface");
        break;
    case Opcodes.H_INVOKESPECIAL:
        sb.append("special");
        break;
    case Opcodes.H_INVOKESTATIC:
        sb.append("static");
        break;
    case Opcodes.H_INVOKEVIRTUAL:
        sb.append("virtual");
        break;
    case Opcodes.H_NEWINVOKESPECIAL:
        sb.append("new_special");
        break;
    default:
        assert false;
        break;
    }
    sb.append(" '");
    sb.append(h.getName());
    sb.append("'");
}

From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java

License:Open Source License

@Override
public void visitEnd() {
    for (Map.Entry<Handle, MethodReferenceBridgeInfo> bridge : bridgeMethods.entrySet()) {
        Handle original = bridge.getKey();
        Handle neededMethod = bridge.getValue().bridgeMethod();
        checkState(//from   www .  ja  va2s.co m
                neededMethod.getTag() == Opcodes.H_INVOKESTATIC
                        || neededMethod.getTag() == Opcodes.H_INVOKEVIRTUAL,
                "Cannot generate bridge method %s to reach %s", neededMethod, original);
        checkState(bridge.getValue().referenced() != null, "Need referenced method %s to generate bridge %s",
                original, neededMethod);

        int access = Opcodes.ACC_BRIDGE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL;
        if (neededMethod.getTag() == Opcodes.H_INVOKESTATIC) {
            access |= Opcodes.ACC_STATIC;
        }
        MethodVisitor bridgeMethod = super.visitMethod(access, neededMethod.getName(), neededMethod.getDesc(),
                (String) null, toInternalNames(bridge.getValue().referenced().getExceptionTypes()));

        // Bridge is a factory method calling a constructor
        if (original.getTag() == Opcodes.H_NEWINVOKESPECIAL) {
            bridgeMethod.visitTypeInsn(Opcodes.NEW, original.getOwner());
            bridgeMethod.visitInsn(Opcodes.DUP);
        }

        int slot = 0;
        if (neededMethod.getTag() != Opcodes.H_INVOKESTATIC) {
            bridgeMethod.visitVarInsn(Opcodes.ALOAD, slot++);
        }
        Type neededType = Type.getMethodType(neededMethod.getDesc());
        for (Type arg : neededType.getArgumentTypes()) {
            bridgeMethod.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot);
            slot += arg.getSize();
        }
        bridgeMethod.visitMethodInsn(invokeOpcode(original), original.getOwner(), original.getName(),
                original.getDesc(), original.isInterface());
        bridgeMethod.visitInsn(neededType.getReturnType().getOpcode(Opcodes.IRETURN));

        bridgeMethod.visitMaxs(0, 0); // rely on class writer to compute these
        bridgeMethod.visitEnd();
    }
    super.visitEnd();
}

From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java

License:Open Source License

/**
 * Makes {@link #visitEnd} generate a bridge method for the given method handle if the
 * referenced method will be invisible to the generated lambda class.
 *
 * @return struct containing either {@code invokedMethod} or {@code invokedMethod} and a handle
 *     representing the bridge method that will be generated for {@code invokedMethod}.
 *///ww  w. ja v a  2s . c  om
private MethodReferenceBridgeInfo queueUpBridgeMethodIfNeeded(Handle invokedMethod)
        throws ClassNotFoundException {
    if (invokedMethod.getName().startsWith("lambda$")) {
        // We adjust lambda bodies to be visible
        return MethodReferenceBridgeInfo.noBridge(invokedMethod);
    }

    // invokedMethod is a method reference if we get here
    Executable invoked = findTargetMethod(invokedMethod);
    if (isVisibleToLambdaClass(invoked, invokedMethod.getOwner())) {
        // Referenced method is visible to the generated class, so nothing to do
        return MethodReferenceBridgeInfo.noBridge(invokedMethod);
    }

    // We need a bridge method if we get here
    checkState(!isInterface, "%s is an interface and shouldn't need bridge to %s", internalName, invokedMethod);
    checkState(!invokedMethod.isInterface(), "%s's lambda classes can't see interface method: %s", internalName,
            invokedMethod);
    MethodReferenceBridgeInfo result = bridgeMethods.get(invokedMethod);
    if (result != null) {
        return result; // we're already queued up a bridge method for this method reference
    }

    String name = uniqueInPackage(internalName, "bridge$lambda$" + bridgeMethods.size());
    Handle bridgeMethod;
    switch (invokedMethod.getTag()) {
    case Opcodes.H_INVOKESTATIC:
        bridgeMethod = new Handle(invokedMethod.getTag(), internalName, name, invokedMethod.getDesc(),
                /*itf*/ false);
        break;
    case Opcodes.H_INVOKEVIRTUAL:
    case Opcodes.H_INVOKESPECIAL: // we end up calling these using invokevirtual
        bridgeMethod = new Handle(Opcodes.H_INVOKEVIRTUAL, internalName, name, invokedMethod.getDesc(),
                /*itf*/ false);
        break;
    case Opcodes.H_NEWINVOKESPECIAL: {
        // Call invisible constructor through generated bridge "factory" method, so we need to
        // compute the descriptor for the bridge method from the constructor's descriptor
        String desc = Type.getMethodDescriptor(Type.getObjectType(invokedMethod.getOwner()),
                Type.getArgumentTypes(invokedMethod.getDesc()));
        bridgeMethod = new Handle(Opcodes.H_INVOKESTATIC, internalName, name, desc, /*itf*/ false);
        break;
    }
    case Opcodes.H_INVOKEINTERFACE:
        // Shouldn't get here
    default:
        throw new UnsupportedOperationException("Cannot bridge " + invokedMethod);
    }
    result = MethodReferenceBridgeInfo.bridge(invokedMethod, invoked, bridgeMethod);
    MethodReferenceBridgeInfo old = bridgeMethods.put(invokedMethod, result);
    checkState(old == null, "Already had bridge %s so we don't also want %s", old, result);
    return result;
}

From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java

License:Open Source License

private Executable findTargetMethod(Handle invokedMethod) throws ClassNotFoundException {
    Type descriptor = Type.getMethodType(invokedMethod.getDesc());
    Class<?> owner = loadFromInternal(invokedMethod.getOwner());
    if (invokedMethod.getTag() == Opcodes.H_NEWINVOKESPECIAL) {
        for (Constructor<?> c : owner.getDeclaredConstructors()) {
            if (Type.getType(c).equals(descriptor)) {
                return c;
            }/*from  w  ww  .j  av a 2  s .co  m*/
        }
    } else {
        for (Method m : owner.getDeclaredMethods()) {
            if (m.getName().equals(invokedMethod.getName()) && Type.getType(m).equals(descriptor)) {
                return m;
            }
        }
    }
    throw new IllegalArgumentException("Referenced method not found: " + invokedMethod);
}

From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java

License:Open Source License

static int invokeOpcode(Handle invokedMethod) {
    switch (invokedMethod.getTag()) {
    case Opcodes.H_INVOKESTATIC:
        return Opcodes.INVOKESTATIC;
    case Opcodes.H_INVOKEVIRTUAL:
        return Opcodes.INVOKEVIRTUAL;
    case Opcodes.H_INVOKESPECIAL:
    case Opcodes.H_NEWINVOKESPECIAL: // Must be preceded by NEW
        return Opcodes.INVOKESPECIAL;
    case Opcodes.H_INVOKEINTERFACE:
        return Opcodes.INVOKEINTERFACE;
    default:/* w ww .  j a v a2 s .com*/
        throw new UnsupportedOperationException("Don't know how to call " + invokedMethod);
    }
}

From source file:de.thetaphi.forbiddenapis.ClassScanner.java

License:Apache License

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature,
        String[] exceptions) {/* w  w  w .j  a  v  a2s  .  co  m*/
    currentGroupId++;
    if (classSuppressed) {
        return null;
    }
    return new MethodVisitor(Opcodes.ASM5) {
        private final Method myself = new Method(name, desc);
        private final boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
        private int lineNo = -1;

        {
            // only check signature, if method is not synthetic
            if ((access & Opcodes.ACC_SYNTHETIC) == 0) {
                reportMethodViolation(checkDescriptor(desc), "method declaration");
            }
            if (this.isDeprecated) {
                maybeSuppressCurrentGroup(DEPRECATED_TYPE);
                reportMethodViolation(checkType(DEPRECATED_TYPE), "deprecation on method declaration");
            }
        }

        private String checkMethodAccess(String owner, Method method) {
            String violation = checkClassUse(owner, "class/interface");
            if (violation != null) {
                return violation;
            }
            final String printout = forbiddenMethods.get(owner + '\000' + method);
            if (printout != null) {
                return "Forbidden method invocation: " + printout;
            }
            final ClassSignature c = lookup.lookupRelatedClass(owner);
            if (c != null && !c.methods.contains(method)) {
                if (c.superName != null && (violation = checkMethodAccess(c.superName, method)) != null) {
                    return violation;
                }
                // JVM spec says: interfaces after superclasses
                if (c.interfaces != null) {
                    for (String intf : c.interfaces) {
                        if (intf != null && (violation = checkMethodAccess(intf, method)) != null) {
                            return violation;
                        }
                    }
                }
            }
            return null;
        }

        private String checkFieldAccess(String owner, String field) {
            String violation = checkClassUse(owner, "class/interface");
            if (violation != null) {
                return violation;
            }
            final String printout = forbiddenFields.get(owner + '\000' + field);
            if (printout != null) {
                return "Forbidden field access: " + printout;
            }
            final ClassSignature c = lookup.lookupRelatedClass(owner);
            if (c != null && !c.fields.contains(field)) {
                if (c.interfaces != null) {
                    for (String intf : c.interfaces) {
                        if (intf != null && (violation = checkFieldAccess(intf, field)) != null) {
                            return violation;
                        }
                    }
                }
                // JVM spec says: superclasses after interfaces
                if (c.superName != null && (violation = checkFieldAccess(c.superName, field)) != null) {
                    return violation;
                }
            }
            return null;
        }

        private String checkHandle(Handle handle, boolean checkLambdaHandle) {
            switch (handle.getTag()) {
            case Opcodes.H_GETFIELD:
            case Opcodes.H_PUTFIELD:
            case Opcodes.H_GETSTATIC:
            case Opcodes.H_PUTSTATIC:
                return checkFieldAccess(handle.getOwner(), handle.getName());
            case Opcodes.H_INVOKEVIRTUAL:
            case Opcodes.H_INVOKESTATIC:
            case Opcodes.H_INVOKESPECIAL:
            case Opcodes.H_NEWINVOKESPECIAL:
            case Opcodes.H_INVOKEINTERFACE:
                final Method m = new Method(handle.getName(), handle.getDesc());
                if (checkLambdaHandle && handle.getOwner().equals(internalMainClassName)
                        && handle.getName().startsWith(LAMBDA_METHOD_NAME_PREFIX)) {
                    // as described in <http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html>,
                    // we will record this metafactory call as "lambda" invokedynamic,
                    // so we can assign the called lambda with the same groupId like *this* method:
                    lambdas.put(m, currentGroupId);
                }
                return checkMethodAccess(handle.getOwner(), m);
            }
            return null;
        }

        private String checkConstant(Object cst, boolean checkLambdaHandle) {
            if (cst instanceof Type) {
                return checkType((Type) cst);
            } else if (cst instanceof Handle) {
                return checkHandle((Handle) cst, checkLambdaHandle);
            }
            return null;
        }

        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            if (this.isDeprecated && DEPRECATED_DESCRIPTOR.equals(desc)) {
                // don't report 2 times!
                return null;
            }
            final Type type = Type.getType(desc);
            maybeSuppressCurrentGroup(type);
            reportMethodViolation(checkAnnotationDescriptor(type, visible), "annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "parameter annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "type annotation on method declaration");
            return null;
        }

        @Override
        public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start,
                Label[] end, int[] index, String desc, boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc,
                boolean visible) {
            reportMethodViolation(checkAnnotationDescriptor(Type.getType(desc), visible),
                    "annotation in method body");
            return null;
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
            reportMethodViolation(checkMethodAccess(owner, new Method(name, desc)), "method body");
        }

        @Override
        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
            reportMethodViolation(checkFieldAccess(owner, name), "method body");
        }

        @Override
        public void visitTypeInsn(int opcode, String type) {
            if (opcode == Opcodes.ANEWARRAY) {
                reportMethodViolation(checkType(Type.getObjectType(type)), "method body");
            }
        }

        @Override
        public void visitMultiANewArrayInsn(String desc, int dims) {
            reportMethodViolation(checkDescriptor(desc), "method body");
        }

        @Override
        public void visitLdcInsn(Object cst) {
            reportMethodViolation(checkConstant(cst, false), "method body");
        }

        @Override
        public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
            final boolean isLambdaMetaFactory = LAMBDA_META_FACTORY_INTERNALNAME.equals(bsm.getOwner());
            reportMethodViolation(checkHandle(bsm, false), "method body");
            for (final Object cst : bsmArgs) {
                reportMethodViolation(checkConstant(cst, isLambdaMetaFactory), "method body");
            }
        }

        private String getHumanReadableMethodSignature() {
            final Type[] args = Type.getType(myself.getDescriptor()).getArgumentTypes();
            final StringBuilder sb = new StringBuilder(myself.getName()).append('(');
            boolean comma = false;
            for (final Type t : args) {
                if (comma)
                    sb.append(',');
                sb.append(t.getClassName());
                comma = true;
            }
            sb.append(')');
            return sb.toString();
        }

        private void reportMethodViolation(String violation, String where) {
            if (violation != null) {
                violations.add(new ForbiddenViolation(currentGroupId, myself, violation,
                        String.format(Locale.ENGLISH, "%s of '%s'", where, getHumanReadableMethodSignature()),
                        lineNo));
            }
        }

        @Override
        public void visitLineNumber(int lineNo, Label start) {
            this.lineNo = lineNo;
        }
    };
}

From source file:org.elasticsearch.painless.FunctionRef.java

License:Apache License

/**
 * Creates a new FunctionRef (already resolved)
 * @param expected interface type to implement
 * @param method functional interface method
 * @param impl implementation method/*w  w w  .jav  a 2  s .  c o m*/
 * @param numCaptures number of captured arguments
 */
public FunctionRef(Definition.Type expected, Definition.Method method, Definition.Method impl,
        int numCaptures) {
    // e.g. compareTo
    invokedName = method.name;
    // e.g. (Object)Comparator
    MethodType implType = impl.getMethodType();
    // only include captured parameters as arguments
    invokedType = MethodType.methodType(expected.clazz,
            implType.dropParameterTypes(numCaptures, implType.parameterCount()));
    // e.g. (Object,Object)int
    interfaceMethodType = method.getMethodType().dropParameterTypes(0, 1);

    final int tag;
    if ("<init>".equals(impl.name)) {
        tag = Opcodes.H_NEWINVOKESPECIAL;
    } else if (Modifier.isStatic(impl.modifiers)) {
        tag = Opcodes.H_INVOKESTATIC;
    } else if (impl.owner.clazz.isInterface()) {
        tag = Opcodes.H_INVOKEINTERFACE;
    } else {
        tag = Opcodes.H_INVOKEVIRTUAL;
    }
    final String owner;
    final boolean ownerIsInterface;
    if (impl.owner == null) {
        // owner == null: script class itself
        ownerIsInterface = false;
        owner = WriterConstants.CLASS_TYPE.getInternalName();
    } else if (impl.augmentation) {
        ownerIsInterface = false;
        owner = WriterConstants.AUGMENTATION_TYPE.getInternalName();
    } else {
        ownerIsInterface = impl.owner.clazz.isInterface();
        owner = impl.owner.type.getInternalName();
    }
    implMethodASM = new Handle(tag, owner, impl.name, impl.method.getDescriptor(), ownerIsInterface);
    implMethod = impl.handle;

    // remove any prepended captured arguments for the 'natural' signature.
    samMethodType = adapt(interfaceMethodType, impl.getMethodType().dropParameterTypes(0, numCaptures));
}

From source file:org.teavm.parsing.ProgramParser.java

License:Apache License

private static MethodHandle parseHandle(Handle handle) {
    switch (handle.getTag()) {
    case Opcodes.H_GETFIELD:
        return MethodHandle.fieldGetter(handle.getOwner().replace('/', '.'), handle.getName(),
                ValueType.parse(handle.getDesc()));
    case Opcodes.H_GETSTATIC:
        return MethodHandle.staticFieldGetter(handle.getOwner().replace('/', '.'), handle.getName(),
                ValueType.parse(handle.getDesc()));
    case Opcodes.H_PUTFIELD:
        return MethodHandle.fieldSetter(handle.getOwner().replace('/', '.'), handle.getName(),
                ValueType.parse(handle.getDesc()));
    case Opcodes.H_PUTSTATIC:
        return MethodHandle.staticFieldSetter(handle.getOwner().replace('/', '.'), handle.getName(),
                ValueType.parse(handle.getDesc()));
    case Opcodes.H_INVOKEVIRTUAL:
        return MethodHandle.virtualCaller(handle.getOwner().replace('/', '.'), handle.getName(),
                MethodDescriptor.parseSignature(handle.getDesc()));
    case Opcodes.H_INVOKESTATIC:
        return MethodHandle.staticCaller(handle.getOwner().replace('/', '.'), handle.getName(),
                MethodDescriptor.parseSignature(handle.getDesc()));
    case Opcodes.H_INVOKESPECIAL:
        return MethodHandle.specialCaller(handle.getOwner().replace('/', '.'), handle.getName(),
                MethodDescriptor.parseSignature(handle.getDesc()));
    case Opcodes.H_NEWINVOKESPECIAL:
        return MethodHandle.constructorCaller(handle.getOwner().replace('/', '.'), handle.getName(),
                MethodDescriptor.parseSignature(handle.getDesc()));
    case Opcodes.H_INVOKEINTERFACE:
        return MethodHandle.interfaceCaller(handle.getOwner().replace('/', '.'), handle.getName(),
                MethodDescriptor.parseSignature(handle.getDesc()));
    default:// www. j a  va  2  s .c  om
        throw new IllegalArgumentException("Unknown handle tag: " + handle.getTag());
    }
}