Search in sources :

Example 36 with BytecodeNode

use of com.facebook.presto.bytecode.BytecodeNode 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 37 with BytecodeNode

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

the class TestSetVariableBytecodeExpression method testGetField.

@Test
public void testGetField() throws Exception {
    Function<Scope, BytecodeNode> nodeGenerator = scope -> {
        Variable point = scope.declareVariable(Point.class, "point");
        BytecodeExpression setPoint = point.set(newInstance(Point.class, constantInt(3), constantInt(7)));
        assertEquals(setPoint.toString(), "point = new Point(3, 7);");
        return new BytecodeBlock().append(setPoint).append(point.ret());
    };
    assertBytecodeNode(nodeGenerator, type(Point.class), new Point(3, 7));
}
Also used : BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) Variable(com.facebook.presto.bytecode.Variable) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) Scope(com.facebook.presto.bytecode.Scope) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) BytecodeExpressions.constantInt(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantInt) Assert.assertEquals(org.testng.Assert.assertEquals) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Test(org.testng.annotations.Test) Point(java.awt.Point) BytecodeExpressions.newInstance(com.facebook.presto.bytecode.expression.BytecodeExpressions.newInstance) Function(java.util.function.Function) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) Point(java.awt.Point) Test(org.testng.annotations.Test)

Example 38 with BytecodeNode

use of com.facebook.presto.bytecode.BytecodeNode 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 39 with BytecodeNode

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

the class JoinCompiler method generateCompareSortChannelPositionsMethod.

private static void generateCompareSortChannelPositionsMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<FieldDefinition> channelFields, Optional<Integer> sortChannel) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightBlockIndex = arg("rightBlockIndex", int.class);
    Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
    MethodDefinition compareMethod = classDefinition.declareMethod(a(PUBLIC), "compareSortChannelPositions", type(int.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
    if (!sortChannel.isPresent()) {
        compareMethod.getBody().append(newInstance(UnsupportedOperationException.class)).throwObject();
        return;
    }
    Variable thisVariable = compareMethod.getThis();
    int index = sortChannel.get();
    BytecodeExpression type = constantType(callSiteBinder, types.get(index));
    BytecodeExpression leftBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
    BytecodeExpression rightBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
    BytecodeNode comparison = type.invoke("compareTo", int.class, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition).ret();
    compareMethod.getBody().append(comparison);
}
Also used : Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 40 with BytecodeNode

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

the class JoinCompiler method generatePositionEqualsRowMethod.

private static void generatePositionEqualsRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, boolean ignoreNulls) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter rightPage = arg("rightPage", Page.class);
    MethodDefinition positionEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsRowIgnoreNulls" : "positionEqualsRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, rightPage);
    Variable thisVariable = positionEqualsRowMethod.getThis();
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
        BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index));
        BytecodeNode equalityCondition;
        if (ignoreNulls) {
            equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
        } else {
            equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
        }
        LabelNode checkNextField = new LabelNode("checkNextField");
        positionEqualsRowMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
    }
    positionEqualsRowMethod.getBody().push(true).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Aggregations

BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)42 Variable (com.facebook.presto.bytecode.Variable)33 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)29 IfStatement (com.facebook.presto.bytecode.control.IfStatement)23 Scope (com.facebook.presto.bytecode.Scope)21 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)19 Parameter (com.facebook.presto.bytecode.Parameter)16 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)12 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)7 ForLoop (com.facebook.presto.bytecode.control.ForLoop)7 RowExpression (com.facebook.presto.sql.relational.RowExpression)7 ArrayList (java.util.ArrayList)6 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)5 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)5 Block (com.facebook.presto.common.block.Block)5 Type (com.facebook.presto.common.type.Type)5 FunctionHandle (com.facebook.presto.spi.function.FunctionHandle)5 RowExpression (com.facebook.presto.spi.relation.RowExpression)5 SqlTypeBytecodeExpression (com.facebook.presto.sql.gen.SqlTypeBytecodeExpression)5 ImmutableList (com.google.common.collect.ImmutableList)5