Search in sources :

Example 31 with ClassDefinition

use of com.facebook.presto.bytecode.ClassDefinition in project presto by prestodb.

the class ConcatFunction method generateConcat.

private static Class<?> generateConcat(TypeSignature type, int arity) {
    checkCondition(arity <= 254, NOT_SUPPORTED, "Too many arguments for string concatenation");
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(type.getBase() + "_concat" + arity + "ScalarFunction"), type(Object.class));
    // Generate constructor
    definition.declareDefaultConstructor(a(PRIVATE));
    // Generate concat()
    List<Parameter> parameters = IntStream.range(0, arity).mapToObj(i -> arg("arg" + i, Slice.class)).collect(toImmutableList());
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "concat", type(Slice.class), parameters);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable result = scope.declareVariable(Slice.class, "result");
    body.append(invokeStatic(ConcatFunction.class, "concat", Slice.class, BytecodeExpressions.newArray(ParameterizedType.type(Slice[].class), parameters))).retObject();
    return defineClass(definition, Object.class, ImmutableMap.of(), new DynamicClassLoader(ConcatFunction.class.getClassLoader()));
}
Also used : FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) IntStream(java.util.stream.IntStream) MethodHandle(java.lang.invoke.MethodHandle) FunctionKind(com.facebook.presto.spi.function.FunctionKind) Slice(io.airlift.slice.Slice) VarcharType.createUnboundedVarcharType(com.facebook.presto.common.type.VarcharType.createUnboundedVarcharType) BytecodeExpressions(com.facebook.presto.bytecode.expression.BytecodeExpressions) PRIVATE(com.facebook.presto.bytecode.Access.PRIVATE) PrestoException(com.facebook.presto.spi.PrestoException) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) TypeSignature(com.facebook.presto.common.type.TypeSignature) Access.a(com.facebook.presto.bytecode.Access.a) DEFAULT_NAMESPACE(com.facebook.presto.metadata.BuiltInTypeAndFunctionNamespaceManager.DEFAULT_NAMESPACE) ImmutableList(com.google.common.collect.ImmutableList) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) Reflection.methodHandle(com.facebook.presto.util.Reflection.methodHandle) Slices(io.airlift.slice.Slices) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) INVALID_FUNCTION_ARGUMENT(com.facebook.presto.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT) CompilerUtils.makeClassName(com.facebook.presto.util.CompilerUtils.makeClassName) RETURN_NULL_ON_NULL(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.NullConvention.RETURN_NULL_ON_NULL) UsedByGeneratedCode(com.facebook.presto.annotation.UsedByGeneratedCode) Failures.checkCondition(com.facebook.presto.util.Failures.checkCondition) PUBLIC(com.facebook.presto.bytecode.Access.PUBLIC) Variable(com.facebook.presto.bytecode.Variable) CompilerUtils.defineClass(com.facebook.presto.util.CompilerUtils.defineClass) BoundVariables(com.facebook.presto.metadata.BoundVariables) Parameter(com.facebook.presto.bytecode.Parameter) ImmutableMap(com.google.common.collect.ImmutableMap) SqlScalarFunction(com.facebook.presto.metadata.SqlScalarFunction) Collections.nCopies(java.util.Collections.nCopies) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) VARBINARY(com.facebook.presto.common.type.VarbinaryType.VARBINARY) DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) SqlFunctionVisibility(com.facebook.presto.spi.function.SqlFunctionVisibility) ArgumentProperty.valueTypeArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty.valueTypeArgumentProperty) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) List(java.util.List) FINAL(com.facebook.presto.bytecode.Access.FINAL) STATIC(com.facebook.presto.bytecode.Access.STATIC) Scope(com.facebook.presto.bytecode.Scope) NOT_SUPPORTED(com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED) Signature(com.facebook.presto.spi.function.Signature) BytecodeExpressions.invokeStatic(com.facebook.presto.bytecode.expression.BytecodeExpressions.invokeStatic) Parameter.arg(com.facebook.presto.bytecode.Parameter.arg) ParameterizedType(com.facebook.presto.bytecode.ParameterizedType) DynamicClassLoader(com.facebook.presto.bytecode.DynamicClassLoader) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Slice(io.airlift.slice.Slice) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition)

Example 32 with ClassDefinition

use of com.facebook.presto.bytecode.ClassDefinition in project presto by prestodb.

the class ArrayToArrayCast method generateArrayCast.

private static Class<?> generateArrayCast(TypeManager typeManager, FunctionMetadata elementCastFunctionMetadata, JavaScalarFunctionImplementation elementCast) {
    CallSiteBinder binder = new CallSiteBinder();
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(Joiner.on("$").join("ArrayCast", elementCastFunctionMetadata.getArgumentTypes().get(0), elementCastFunctionMetadata.getReturnType())), type(Object.class));
    Parameter properties = arg("properties", SqlFunctionProperties.class);
    Parameter value = arg("value", Block.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "castArray", type(Block.class), properties, value);
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
    body.append(wasNull.set(constantBoolean(false)));
    // cast map elements
    Type fromElementType = typeManager.getType(elementCastFunctionMetadata.getArgumentTypes().get(0));
    Type toElementType = typeManager.getType(elementCastFunctionMetadata.getReturnType());
    CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder);
    ArrayMapBytecodeExpression newArray = ArrayGeneratorUtils.map(scope, cachedInstanceBinder, fromElementType, toElementType, value, elementCastFunctionMetadata.getName().getObjectName(), elementCast);
    // return the block
    body.append(newArray.ret());
    MethodDefinition constructorDefinition = definition.declareConstructor(a(PUBLIC));
    BytecodeBlock constructorBody = constructorDefinition.getBody();
    Variable thisVariable = constructorDefinition.getThis();
    constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
    cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
    constructorBody.ret();
    return defineClass(definition, Object.class, binder.getBindings(), ArrayToArrayCast.class.getClassLoader());
}
Also used : ArrayMapBytecodeExpression(com.facebook.presto.sql.gen.ArrayMapBytecodeExpression) Signature.typeVariable(com.facebook.presto.spi.function.Signature.typeVariable) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) CastType(com.facebook.presto.metadata.CastType) Type(com.facebook.presto.common.type.Type) CachedInstanceBinder(com.facebook.presto.sql.gen.CachedInstanceBinder) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Block(com.facebook.presto.common.block.Block)

Example 33 with ClassDefinition

use of com.facebook.presto.bytecode.ClassDefinition in project presto by prestodb.

the class ArrayTransformFunction method generateTransform.

private static Class<?> generateTransform(Type inputType, Type outputType) {
    CallSiteBinder binder = new CallSiteBinder();
    Class<?> inputJavaType = Primitives.wrap(inputType.getJavaType());
    Class<?> outputJavaType = Primitives.wrap(outputType.getJavaType());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("ArrayTransform"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    // define createPageBuilder
    MethodDefinition createPageBuilderMethod = definition.declareMethod(a(PUBLIC, STATIC), "createPageBuilder", type(PageBuilder.class));
    createPageBuilderMethod.getBody().append(newInstance(PageBuilder.class, constantType(binder, new ArrayType(outputType)).invoke("getTypeParameters", List.class)).ret());
    // define transform method
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    Parameter block = arg("block", Block.class);
    Parameter function = arg("function", UnaryFunctionInterface.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "transform", type(Block.class), ImmutableList.of(pageBuilder, block, function));
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable positionCount = scope.declareVariable(int.class, "positionCount");
    Variable position = scope.declareVariable(int.class, "position");
    Variable blockBuilder = scope.declareVariable(BlockBuilder.class, "blockBuilder");
    Variable inputElement = scope.declareVariable(inputJavaType, "inputElement");
    Variable outputElement = scope.declareVariable(outputJavaType, "outputElement");
    // invoke block.getPositionCount()
    body.append(positionCount.set(block.invoke("getPositionCount", int.class)));
    // reset page builder if it is full
    body.append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(pageBuilder.invoke("reset", void.class)));
    // get block builder
    body.append(blockBuilder.set(pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, constantInt(0))));
    BytecodeNode loadInputElement;
    if (!inputType.equals(UNKNOWN)) {
        loadInputElement = new IfStatement().condition(block.invoke("isNull", boolean.class, position)).ifTrue(inputElement.set(constantNull(inputJavaType))).ifFalse(inputElement.set(constantType(binder, inputType).getValue(block, position).cast(inputJavaType)));
    } else {
        loadInputElement = new BytecodeBlock().append(inputElement.set(constantNull(inputJavaType)));
    }
    BytecodeNode writeOutputElement;
    if (!outputType.equals(UNKNOWN)) {
        writeOutputElement = new IfStatement().condition(equal(outputElement, constantNull(outputJavaType))).ifTrue(blockBuilder.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, outputType).writeValue(blockBuilder, outputElement.cast(outputType.getJavaType())));
    } else {
        writeOutputElement = new BytecodeBlock().append(blockBuilder.invoke("appendNull", BlockBuilder.class).pop());
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(incrementVariable(position, (byte) 1)).body(new BytecodeBlock().append(loadInputElement).append(outputElement.set(function.invoke("apply", Object.class, inputElement.cast(Object.class)).cast(outputJavaType))).append(writeOutputElement)));
    body.append(pageBuilder.invoke("declarePositions", void.class, positionCount));
    body.append(blockBuilder.invoke("getRegion", Block.class, subtract(blockBuilder.invoke("getPositionCount", int.class), positionCount), positionCount).ret());
    return defineClass(definition, Object.class, binder.getBindings(), ArrayTransformFunction.class.getClassLoader());
}
Also used : Signature.typeVariable(com.facebook.presto.spi.function.Signature.typeVariable) Variable(com.facebook.presto.bytecode.Variable) VariableInstruction.incrementVariable(com.facebook.presto.bytecode.instruction.VariableInstruction.incrementVariable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) PageBuilder(com.facebook.presto.common.PageBuilder) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) ArrayType(com.facebook.presto.common.type.ArrayType) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Block(com.facebook.presto.common.block.Block) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BlockBuilder(com.facebook.presto.common.block.BlockBuilder)

Example 34 with ClassDefinition

use of com.facebook.presto.bytecode.ClassDefinition in project presto by prestodb.

the class BytecodeExpressionAssertions method execute.

public static Object execute(Function<Scope, BytecodeNode> nodeGenerator, ParameterizedType returnType, Optional<ClassLoader> parentClassLoader) throws Exception {
    ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("Test"), type(Object.class));
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC, STATIC), "test", returnType);
    BytecodeNode node = nodeGenerator.apply(method.getScope());
    method.getBody().append(node);
    String tree = dumpBytecodeTree(classDefinition);
    if (DUMP_BYTECODE_TREE.get()) {
        System.out.println(tree);
    }
    ClassLoader classLoader = parentClassLoader.orElse(BytecodeExpressionAssertions.class.getClassLoader());
    return classGenerator(classLoader).defineClass(classDefinition, Object.class).getMethod("test").invoke(null);
}
Also used : MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition)

Example 35 with ClassDefinition

use of com.facebook.presto.bytecode.ClassDefinition in project presto by prestodb.

the class PageFunctionCompiler method compileProjectionInternal.

private Supplier<PageProjection> compileProjectionInternal(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, List<RowExpression> projections, boolean isOptimizeCommonSubExpression, Optional<String> classNameSuffix) {
    requireNonNull(projections, "projections is null");
    checkArgument(!projections.isEmpty() && projections.stream().allMatch(projection -> projection instanceof CallExpression || projection instanceof SpecialFormExpression));
    PageFieldsToInputParametersRewriter.Result result = rewritePageFieldsToInputParameters(projections);
    List<RowExpression> rewrittenExpression = result.getRewrittenExpressions();
    CallSiteBinder callSiteBinder = new CallSiteBinder();
    // generate Work
    ClassDefinition pageProjectionWorkDefinition = definePageProjectWorkClass(sqlFunctionProperties, sessionFunctions, rewrittenExpression, callSiteBinder, isOptimizeCommonSubExpression, classNameSuffix);
    Class<? extends Work> pageProjectionWorkClass;
    try {
        pageProjectionWorkClass = defineClass(pageProjectionWorkDefinition, Work.class, callSiteBinder.getBindings(), getClass().getClassLoader());
    } catch (PrestoException prestoException) {
        throw prestoException;
    } catch (Exception e) {
        throw new PrestoException(COMPILER_ERROR, e);
    }
    return () -> new GeneratedPageProjection(rewrittenExpression, rewrittenExpression.stream().allMatch(determinismEvaluator::isDeterministic), result.getInputChannels(), constructorMethodHandle(pageProjectionWorkClass, List.class, SqlFunctionProperties.class, Page.class, SelectedPositions.class));
}
Also used : SqlFunctionProperties(com.facebook.presto.common.function.SqlFunctionProperties) RowExpression(com.facebook.presto.spi.relation.RowExpression) PrestoException(com.facebook.presto.spi.PrestoException) GeneratedPageProjection(com.facebook.presto.operator.project.GeneratedPageProjection) Page(com.facebook.presto.common.Page) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) PrestoException(com.facebook.presto.spi.PrestoException) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) PageFieldsToInputParametersRewriter(com.facebook.presto.operator.project.PageFieldsToInputParametersRewriter) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) SelectedPositions(com.facebook.presto.operator.project.SelectedPositions) Work(com.facebook.presto.operator.Work) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression)

Aggregations

ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)45 CallSiteBinder (com.facebook.presto.bytecode.CallSiteBinder)27 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)26 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)25 Parameter (com.facebook.presto.bytecode.Parameter)23 Variable (com.facebook.presto.bytecode.Variable)21 Scope (com.facebook.presto.bytecode.Scope)19 ImmutableList (com.google.common.collect.ImmutableList)18 List (java.util.List)14 IfStatement (com.facebook.presto.bytecode.control.IfStatement)13 Block (com.facebook.presto.common.block.Block)11 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)11 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)10 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)10 BlockBuilder (com.facebook.presto.common.block.BlockBuilder)9 Type (com.facebook.presto.common.type.Type)9 PrestoException (com.facebook.presto.spi.PrestoException)9 PUBLIC (com.facebook.presto.bytecode.Access.PUBLIC)8 Access.a (com.facebook.presto.bytecode.Access.a)8 ParameterizedType.type (com.facebook.presto.bytecode.ParameterizedType.type)8