Example usage for org.objectweb.asm Opcodes H_INVOKEINTERFACE

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

Introduction

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

Prototype

int H_INVOKEINTERFACE

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

Click Source Link

Usage

From source file:org.springsource.loaded.support.Java8.java

License:Apache License

public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,
        Class<?> executorClass) throws Exception {
    MethodHandles.Lookup caller = (MethodHandles.Lookup) lookup;

    ClassLoader callerLoader = caller.lookupClass().getClassLoader();

    int descriptorStart = indyNameAndDescriptor.indexOf('(');
    String invokedName = indyNameAndDescriptor.substring(0, descriptorStart);
    MethodType invokedType = MethodType
            .fromMethodDescriptorString(indyNameAndDescriptor.substring(descriptorStart), callerLoader);

    // Use bsmArgs to build the parameters 
    MethodType samMethodType = MethodType.fromMethodDescriptorString((((Type) bsmArgs[0]).getDescriptor()),
            callerLoader);/*from   w  w w.  ja v  a  2 s  . com*/
    String execClassName = executorClass.getName();
    Handle bsmArgsHandle = (Handle) bsmArgs[1];
    Class<?> lookupClass = caller.lookupClass();
    String owner = bsmArgsHandle.getOwner();
    if (!execClassName.startsWith(owner.replace('/', '.'))
            && bsmArgsHandle.getTag() != Opcodes.H_INVOKEINTERFACE) {
        executorClass = null;
        lookupClass = Class.forName(owner.replace('/', '.'));
    }
    String name = bsmArgsHandle.getName();
    String descriptor = bsmArgsHandle.getDesc();
    MethodType implMethodType = MethodType.fromMethodDescriptorString(descriptor, callerLoader);
    // Looking up the lambda$run method in the caller class (note the caller class is the executor, which gets us around the
    // problem of having to hack into LambdaMetafactory to intercept reflection)
    MethodHandle implMethod = null;
    switch (bsmArgsHandle.getTag()) {
    case Opcodes.H_INVOKESTATIC:
        implMethod = caller.in(lookupClass).findStatic(lookupClass, name, implMethodType);
        break;
    case Opcodes.H_INVOKESPECIAL:
        // If there is an executor, the lambda function is actually modified from 'private instance' to 'public static' so adjust lookup. The method 
        // will be static with a new leading parameter.
        if (executorClass == null) {
            // TODO is final parameter here correct?
            implMethod = caller.in(lookupClass).findSpecial(lookupClass, name, implMethodType,
                    caller.lookupClass());
        } else {
            implMethod = caller.in(lookupClass).findStatic(lookupClass, name, MethodType
                    .fromMethodDescriptorString("(L" + owner + ";" + descriptor.substring(1), callerLoader));
        }
        break;
    case Opcodes.H_INVOKEVIRTUAL:
        // If there is an executor, the lambda function is actually modified from 'private instance' to 'public static' so adjust lookup. The method 
        // will be static with a new leading parameter.
        if (executorClass == null) {
            // TODO when can this scenario occur? Aren't we only here if reloading has happened?
            implMethod = caller.in(lookupClass).findVirtual(lookupClass, name, implMethodType);
        } else {
            implMethod = caller.in(lookupClass).findStatic(lookupClass, name, MethodType
                    .fromMethodDescriptorString("(L" + owner + ";" + descriptor.substring(1), callerLoader));
        }
        break;
    case Opcodes.H_INVOKEINTERFACE:
        Class<?> targetType = Class.forName(bsmArgsHandle.getOwner().replace('/', '.'), true, callerLoader);

        for (Method m : targetType.getMethods()) {
            if (org.objectweb.asm.Type.getMethodDescriptor(m).equals(bsmArgsHandle.getDesc())) {
                implMethod = caller.unreflect(targetType.getMethod(name, m.getParameterTypes()));
                break;
            }
        }
        break;
    default:
        throw new IllegalStateException("nyi " + bsmArgsHandle.getTag());
    }

    MethodType instantiatedMethodType = MethodType
            .fromMethodDescriptorString((((Type) bsmArgs[2]).getDescriptor()), callerLoader);

    return LambdaMetafactory.metafactory(caller, invokedName, invokedType, samMethodType, implMethod,
            instantiatedMethodType);
}

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:/*  w  ww.  java 2s.c o  m*/
        throw new IllegalArgumentException("Unknown handle tag: " + handle.getTag());
    }
}