Search in sources :

Example 26 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class CoalesceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
    List<BytecodeNode> operands = new ArrayList<>();
    for (RowExpression expression : arguments) {
        operands.add(generatorContext.generate(expression));
    }
    Variable wasNull = generatorContext.wasNull();
    BytecodeNode nullValue = new BytecodeBlock().append(wasNull.set(constantTrue())).pushJavaDefault(returnType.getJavaType());
    // reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
    for (BytecodeNode operand : Lists.reverse(operands)) {
        IfStatement ifStatement = new IfStatement();
        ifStatement.condition().append(operand).append(wasNull);
        // if value was null, pop the null value, clear the null flag, and process the next operand
        ifStatement.ifTrue().pop(returnType.getJavaType()).append(wasNull.set(constantFalse())).append(nullValue);
        nullValue = ifStatement;
    }
    return nullValue;
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) ArrayList(java.util.ArrayList) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.prestosql.spi.relation.RowExpression) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 27 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class AndCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments) {
    Preconditions.checkArgument(arguments.size() == 2);
    Variable wasNull = generator.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("AND").setDescription("AND");
    BytecodeNode left = generator.generate(arguments.get(0));
    BytecodeNode right = generator.generate(arguments.get(1));
    block.append(left);
    IfStatement ifLeftIsNull = new IfStatement("if left wasNull...").condition(wasNull);
    LabelNode end = new LabelNode("end");
    ifLeftIsNull.ifTrue().comment("clear the null flag, pop left value off stack, and push left null flag on the stack (true)").append(wasNull.set(constantFalse())).pop(// discard left value
    arguments.get(0).getType().getJavaType()).push(true);
    LabelNode leftIsTrue = new LabelNode("leftIsTrue");
    ifLeftIsNull.ifFalse().comment("if left is false, push false, and goto end").ifTrueGoto(leftIsTrue).push(false).gotoLabel(end).comment("left was true; push left null flag on the stack (false)").visitLabel(leftIsTrue).push(false);
    block.append(ifLeftIsNull);
    // At this point we know the left expression was either NULL or TRUE.  The stack contains a single boolean
    // value for this expression which indicates if the left value was NULL.
    // eval right!
    block.append(right);
    IfStatement ifRightIsNull = new IfStatement("if right wasNull...");
    ifRightIsNull.condition().append(wasNull);
    // this leaves a single boolean on the stack which is ignored since the value in NULL
    ifRightIsNull.ifTrue().comment("right was null, pop the right value off the stack; wasNull flag remains set to TRUE").pop(arguments.get(1).getType().getJavaType());
    LabelNode rightIsTrue = new LabelNode("rightIsTrue");
    ifRightIsNull.ifFalse().comment("if right is false, pop left null flag off stack, push false and goto end").ifTrueGoto(rightIsTrue).pop(boolean.class).push(false).gotoLabel(end).comment("right was true; store left null flag (on stack) in wasNull variable, and push true").visitLabel(rightIsTrue).putVariable(wasNull).push(true);
    block.append(ifRightIsNull).visitLabel(end);
    return block;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 28 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class BetweenCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
    checkArgument(functionHandle == null, "functionHandle is null here");
    RowExpression value = arguments.get(0);
    RowExpression min = arguments.get(1);
    RowExpression max = arguments.get(2);
    Variable firstValue = generatorContext.getScope().createTempVariable(value.getType().getJavaType());
    VariableReferenceExpression valueReference = createTempVariableReferenceExpression(firstValue, value.getType());
    SpecialForm newExpression = new SpecialForm(BETWEEN_AND, BOOLEAN, call(GREATER_THAN_OR_EQUAL.getFunctionName().getObjectName(), generatorContext.getFunctionManager().resolveOperatorFunctionHandle(GREATER_THAN_OR_EQUAL, TypeSignatureProvider.fromTypes(value.getType(), min.getType())), BOOLEAN, valueReference, min), call(LESS_THAN_OR_EQUAL.getFunctionName().getObjectName(), generatorContext.getFunctionManager().resolveOperatorFunctionHandle(LESS_THAN_OR_EQUAL, TypeSignatureProvider.fromTypes(value.getType(), min.getType())), BOOLEAN, valueReference, max));
    LabelNode done = new LabelNode("done");
    // push value arg on the stack
    BytecodeBlock block = new BytecodeBlock().comment("check if value is null").append(generatorContext.generate(value)).append(ifWasNullPopAndGoto(generatorContext.getScope(), done, boolean.class, value.getType().getJavaType())).putVariable(firstValue).append(generatorContext.generate(newExpression)).visitLabel(done);
    return block;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) Variable(io.airlift.bytecode.Variable) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) RowExpressionCompiler.createTempVariableReferenceExpression(io.prestosql.sql.gen.RowExpressionCompiler.createTempVariableReferenceExpression) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.prestosql.spi.relation.RowExpression) SpecialForm(io.prestosql.spi.relation.SpecialForm)

Example 29 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class StateCompiler method generateGetSerializedType.

private static void generateGetSerializedType(ClassDefinition definition, List<StateField> fields, CallSiteBinder callSiteBinder) {
    BytecodeBlock body = definition.declareMethod(a(PUBLIC), "getSerializedType", type(Type.class)).getBody();
    Type type;
    if (fields.size() > 1) {
        List<Type> types = fields.stream().map(StateField::getSqlType).collect(toImmutableList());
        type = RowType.anonymous(types);
    } else if (fields.size() == 1) {
        type = getOnlyElement(fields).getSqlType();
    } else {
        type = UNKNOWN;
    }
    body.comment("return %s", type.getTypeSignature()).append(constantType(callSiteBinder, type)).retObject();
}
Also used : SqlTypeBytecodeExpression.constantType(io.prestosql.sql.gen.SqlTypeBytecodeExpression.constantType) RowType(io.prestosql.spi.type.RowType) Type(io.prestosql.spi.type.Type) BytecodeBlock(io.airlift.bytecode.BytecodeBlock)

Example 30 with BytecodeBlock

use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.

the class ArrayConstructor method generateArrayConstructor.

private static Class<?> generateArrayConstructor(List<Class<?>> stackTypes, Type elementType) {
    checkCondition(stackTypes.size() <= 254, NOT_SUPPORTED, "Too many arguments for array constructor");
    List<String> stackTypeNames = stackTypes.stream().map(Class::getSimpleName).collect(toImmutableList());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(Joiner.on("").join(stackTypeNames) + "ArrayConstructor"), type(Object.class));
    // Generate constructor
    definition.declareDefaultConstructor(a(PRIVATE));
    // Generate arrayConstructor()
    ImmutableList.Builder<Parameter> parameters = ImmutableList.builder();
    for (int i = 0; i < stackTypes.size(); i++) {
        Class<?> stackType = stackTypes.get(i);
        parameters.add(arg("arg" + i, stackType));
    }
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "arrayConstructor", type(Block.class), parameters.build());
    Scope scope = method.getScope();
    BytecodeBlock body = method.getBody();
    Variable blockBuilderVariable = scope.declareVariable(BlockBuilder.class, "blockBuilder");
    CallSiteBinder binder = new CallSiteBinder();
    BytecodeExpression createBlockBuilder = blockBuilderVariable.set(constantType(binder, elementType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(stackTypes.size())));
    body.append(createBlockBuilder);
    for (int i = 0; i < stackTypes.size(); i++) {
        Variable argument = scope.getVariable("arg" + i);
        IfStatement ifStatement = new IfStatement().condition(equal(argument, constantNull(stackTypes.get(i)))).ifTrue(blockBuilderVariable.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, elementType).writeValue(blockBuilderVariable, argument.cast(elementType.getJavaType())));
        body.append(ifStatement);
    }
    body.append(blockBuilderVariable.invoke("build", Block.class).ret());
    return defineClass(definition, Object.class, binder.getBindings(), new DynamicClassLoader(ArrayConstructor.class.getClassLoader()));
}
Also used : DynamicClassLoader(io.airlift.bytecode.DynamicClassLoader) Variable(io.airlift.bytecode.Variable) Signature.typeVariable(io.prestosql.spi.function.Signature.typeVariable) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ClassDefinition(io.airlift.bytecode.ClassDefinition) IfStatement(io.airlift.bytecode.control.IfStatement) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) CallSiteBinder(io.prestosql.sql.gen.CallSiteBinder) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.prestosql.spi.block.Block) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) BlockBuilder(io.prestosql.spi.block.BlockBuilder)

Aggregations

BytecodeBlock (io.airlift.bytecode.BytecodeBlock)129 Variable (io.airlift.bytecode.Variable)112 MethodDefinition (io.airlift.bytecode.MethodDefinition)81 Parameter (io.airlift.bytecode.Parameter)73 IfStatement (io.airlift.bytecode.control.IfStatement)69 Scope (io.airlift.bytecode.Scope)56 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)36 BytecodeNode (io.airlift.bytecode.BytecodeNode)31 ClassDefinition (io.airlift.bytecode.ClassDefinition)29 LabelNode (io.airlift.bytecode.instruction.LabelNode)29 ImmutableList (com.google.common.collect.ImmutableList)25 ArrayList (java.util.ArrayList)23 ForLoop (io.airlift.bytecode.control.ForLoop)19 FieldDefinition (io.airlift.bytecode.FieldDefinition)18 Type (io.prestosql.spi.type.Type)15 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)14 Block (io.prestosql.spi.block.Block)14 List (java.util.List)13 BlockBuilder (io.prestosql.spi.block.BlockBuilder)12 Block (io.trino.spi.block.Block)12