Search in sources :

Example 91 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class TryCastFunction method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) {
    Type fromType = boundVariables.getTypeVariable("F");
    Type toType = boundVariables.getTypeVariable("T");
    Class<?> returnType = Primitives.wrap(toType.getJavaType());
    List<Boolean> nullableArguments;
    MethodHandle tryCastHandle;
    if (fromType.equals(UNKNOWN)) {
        nullableArguments = ImmutableList.of(true);
        tryCastHandle = dropArguments(constant(returnType, null), 0, Void.class);
    } else {
        // the resulting method needs to return a boxed type
        Signature signature = functionRegistry.getCoercion(fromType, toType);
        ScalarFunctionImplementation implementation = functionRegistry.getScalarFunctionImplementation(signature);
        nullableArguments = implementation.getNullableArguments();
        MethodHandle coercion = implementation.getMethodHandle();
        coercion = coercion.asType(methodType(returnType, coercion.type()));
        MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class);
        tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler);
    }
    return new ScalarFunctionImplementation(true, nullableArguments, tryCastHandle, isDeterministic());
}
Also used : MethodType.methodType(java.lang.invoke.MethodType.methodType) Type(com.facebook.presto.spi.type.Type) Signature(com.facebook.presto.metadata.Signature) TypeSignature.parseTypeSignature(com.facebook.presto.spi.type.TypeSignature.parseTypeSignature) MethodHandle(java.lang.invoke.MethodHandle)

Example 92 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class ZipFunction method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) {
    List<Type> types = this.typeParameters.stream().map(boundVariables::getTypeVariable).collect(toImmutableList());
    List<Boolean> nullableArguments = types.stream().map(type -> false).collect(toImmutableList());
    List<Class<?>> javaArgumentTypes = types.stream().map(type -> Block.class).collect(toImmutableList());
    MethodHandle methodHandle = METHOD_HANDLE.bindTo(types).asVarargsCollector(Block[].class).asType(methodType(Block.class, javaArgumentTypes));
    return new ScalarFunctionImplementation(false, nullableArguments, methodHandle, isDeterministic());
}
Also used : TypeSignature(com.facebook.presto.spi.type.TypeSignature) IntStream(java.util.stream.IntStream) MethodType.methodType(java.lang.invoke.MethodType.methodType) MethodHandle(java.lang.invoke.MethodHandle) Block(com.facebook.presto.spi.block.Block) BoundVariables(com.facebook.presto.metadata.BoundVariables) TypeManager(com.facebook.presto.spi.type.TypeManager) SqlScalarFunction(com.facebook.presto.metadata.SqlScalarFunction) FunctionRegistry(com.facebook.presto.metadata.FunctionRegistry) Signature(com.facebook.presto.metadata.Signature) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder) RowType(com.facebook.presto.type.RowType) FunctionKind(com.facebook.presto.metadata.FunctionKind) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) String.join(java.lang.String.join) Reflection.methodHandle(com.facebook.presto.util.Reflection.methodHandle) Type(com.facebook.presto.spi.type.Type) BlockBuilderStatus(com.facebook.presto.spi.block.BlockBuilderStatus) Optional(java.util.Optional) TypeSignature.parseTypeSignature(com.facebook.presto.spi.type.TypeSignature.parseTypeSignature) ImmutableCollectors.toImmutableList(com.facebook.presto.util.ImmutableCollectors.toImmutableList) UsedByGeneratedCode(com.facebook.presto.annotation.UsedByGeneratedCode) MethodType.methodType(java.lang.invoke.MethodType.methodType) RowType(com.facebook.presto.type.RowType) Type(com.facebook.presto.spi.type.Type) Block(com.facebook.presto.spi.block.Block) MethodHandle(java.lang.invoke.MethodHandle)

Example 93 with MethodHandle

use of java.lang.invoke.MethodHandle in project presto by prestodb.

the class RowToJsonCast method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) {
    checkArgument(arity == 1, "Expected arity to be 1");
    Type type = boundVariables.getTypeVariable("T");
    MethodHandle methodHandle = METHOD_HANDLE.bindTo(type);
    return new ScalarFunctionImplementation(false, ImmutableList.of(false), methodHandle, isDeterministic());
}
Also used : Type(com.facebook.presto.spi.type.Type) OperatorType(com.facebook.presto.spi.function.OperatorType) MethodHandle(java.lang.invoke.MethodHandle)

Example 94 with MethodHandle

use of java.lang.invoke.MethodHandle in project elasticsearch by elastic.

the class Definition method addMethodInternal.

private void addMethodInternal(String struct, String name, boolean augmentation, Type rtn, Type[] args) {
    final Struct owner = structsMap.get(struct);
    if (owner == null) {
        throw new IllegalArgumentException("Owner struct [" + struct + "] not defined" + " for method [" + name + "].");
    }
    if (!name.matches("^[_a-zA-Z][_a-zA-Z0-9]*$")) {
        throw new IllegalArgumentException("Invalid method name" + " [" + name + "] with the struct [" + owner.name + "].");
    }
    MethodKey methodKey = new MethodKey(name, args.length);
    if (owner.constructors.containsKey(methodKey)) {
        throw new IllegalArgumentException("Constructors and methods" + " may not have the same signature [" + methodKey + "] within the same struct" + " [" + owner.name + "].");
    }
    if (owner.staticMethods.containsKey(methodKey) || owner.methods.containsKey(methodKey)) {
        throw new IllegalArgumentException("Duplicate method signature [" + methodKey + "] found within the struct [" + owner.name + "].");
    }
    final Class<?> implClass;
    final Class<?>[] params;
    if (augmentation == false) {
        implClass = owner.clazz;
        params = new Class<?>[args.length];
        for (int count = 0; count < args.length; ++count) {
            params[count] = args[count].clazz;
        }
    } else {
        implClass = Augmentation.class;
        params = new Class<?>[args.length + 1];
        params[0] = owner.clazz;
        for (int count = 0; count < args.length; ++count) {
            params[count + 1] = args[count].clazz;
        }
    }
    final java.lang.reflect.Method reflect;
    try {
        reflect = implClass.getMethod(name, params);
    } catch (NoSuchMethodException exception) {
        throw new IllegalArgumentException("Method [" + name + "] not found for class [" + implClass.getName() + "]" + " with arguments " + Arrays.toString(params) + ".");
    }
    if (!reflect.getReturnType().equals(rtn.clazz)) {
        throw new IllegalArgumentException("Specified return type class [" + rtn.clazz + "]" + " does not match the found return type class [" + reflect.getReturnType() + "] for the" + " method [" + name + "]" + " within the struct [" + owner.name + "].");
    }
    final org.objectweb.asm.commons.Method asm = org.objectweb.asm.commons.Method.getMethod(reflect);
    MethodHandle handle;
    try {
        handle = MethodHandles.publicLookup().in(implClass).unreflect(reflect);
    } catch (final IllegalAccessException exception) {
        throw new IllegalArgumentException("Method [" + name + "]" + " not found for class [" + implClass.getName() + "]" + " with arguments " + Arrays.toString(params) + ".");
    }
    final int modifiers = reflect.getModifiers();
    final Method method = new Method(name, owner, augmentation, rtn, Arrays.asList(args), asm, modifiers, handle);
    if (augmentation == false && java.lang.reflect.Modifier.isStatic(modifiers)) {
        owner.staticMethods.put(methodKey, method);
    } else {
        owner.methods.put(methodKey, method);
    }
}
Also used : MethodHandle(java.lang.invoke.MethodHandle)

Example 95 with MethodHandle

use of java.lang.invoke.MethodHandle in project elasticsearch by elastic.

the class Def method lookupReferenceInternal.

/** Returns a method handle to an implementation of clazz, given method reference signature. */
private static MethodHandle lookupReferenceInternal(Lookup lookup, Definition.Type clazz, String type, String call, Class<?>... captures) throws Throwable {
    final FunctionRef ref;
    if ("this".equals(type)) {
        // user written method
        Method interfaceMethod = clazz.struct.getFunctionalMethod();
        if (interfaceMethod == null) {
            throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + "to [" + clazz.name + "], not a functional interface");
        }
        int arity = interfaceMethod.arguments.size() + captures.length;
        final MethodHandle handle;
        try {
            MethodHandle accessor = lookup.findStaticGetter(lookup.lookupClass(), getUserFunctionHandleFieldName(call, arity), MethodHandle.class);
            handle = (MethodHandle) accessor.invokeExact();
        } catch (NoSuchFieldException | IllegalAccessException e) {
            // because the arity does not match the expected interface type.
            if (call.contains("$")) {
                throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name + "] in [" + clazz.clazz + "]");
            }
            throw new IllegalArgumentException("Unknown call [" + call + "] with [" + arity + "] arguments.");
        }
        ref = new FunctionRef(clazz, interfaceMethod, handle, captures.length);
    } else {
        // whitelist lookup
        ref = new FunctionRef(clazz, type, call, captures.length);
    }
    final CallSite callSite;
    if (ref.needsBridges()) {
        callSite = LambdaMetafactory.altMetafactory(lookup, ref.invokedName, ref.invokedType, ref.samMethodType, ref.implMethod, ref.samMethodType, LambdaMetafactory.FLAG_BRIDGES, 1, ref.interfaceMethodType);
    } else {
        callSite = LambdaMetafactory.altMetafactory(lookup, ref.invokedName, ref.invokedType, ref.samMethodType, ref.implMethod, ref.samMethodType, 0);
    }
    return callSite.dynamicInvoker().asType(MethodType.methodType(clazz.clazz, captures));
}
Also used : CallSite(java.lang.invoke.CallSite) Method(org.elasticsearch.painless.Definition.Method) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MethodHandle (java.lang.invoke.MethodHandle)302 Test (org.junit.Test)101 MethodType (java.lang.invoke.MethodType)44 Type (com.facebook.presto.spi.type.Type)37 Method (java.lang.reflect.Method)18 OperatorType (com.facebook.presto.spi.function.OperatorType)14 MethodHandles (java.lang.invoke.MethodHandles)13 DynamicClassLoader (com.facebook.presto.bytecode.DynamicClassLoader)11 Signature (com.facebook.presto.metadata.Signature)10 CallSite (java.lang.invoke.CallSite)10 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)9 ImmutableList (com.google.common.collect.ImmutableList)9 List (java.util.List)8 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)7 TypeSignature.parseTypeSignature (com.facebook.presto.spi.type.TypeSignature.parseTypeSignature)7 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)6 Parameter (com.facebook.presto.bytecode.Parameter)6 PrestoException (com.facebook.presto.spi.PrestoException)6 ComponentInjectionException (org.neo4j.kernel.api.exceptions.ComponentInjectionException)6 ProcedureException (org.neo4j.kernel.api.exceptions.ProcedureException)6