Search in sources :

Example 76 with IfStatement

use of io.airlift.bytecode.control.IfStatement in project trino by trinodb.

the class BytecodeUtils method handleNullValue.

public static BytecodeNode handleNullValue(Scope scope, LabelNode label, Class<?> returnType, List<Class<?>> stackArgsToPop, boolean clearNullFlag) {
    Variable wasNull = scope.getVariable("wasNull");
    BytecodeBlock nullCheck = new BytecodeBlock().setDescription("ifWasNullGoto").append(wasNull);
    String clearComment = null;
    if (clearNullFlag) {
        nullCheck.append(wasNull.set(constantFalse()));
        clearComment = "clear wasNull";
    }
    BytecodeBlock isNull = new BytecodeBlock();
    for (Class<?> parameterType : stackArgsToPop) {
        isNull.pop(parameterType);
    }
    isNull.pushJavaDefault(returnType);
    String loadDefaultComment;
    loadDefaultComment = format("loadJavaDefault(%s)", returnType.getName());
    isNull.gotoLabel(label);
    String popComment = null;
    if (!stackArgsToPop.isEmpty()) {
        popComment = format("pop(%s)", Joiner.on(", ").join(stackArgsToPop));
    }
    return new IfStatement("if wasNull then %s", Joiner.on(", ").skipNulls().join(clearComment, popComment, loadDefaultComment, "goto " + label.getLabel())).condition(nullCheck).ifTrue(isNull);
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock)

Example 77 with IfStatement

use of io.airlift.bytecode.control.IfStatement in project trino by trinodb.

the class CoalesceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext) {
    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.trino.sql.relational.RowExpression) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 78 with IfStatement

use of io.airlift.bytecode.control.IfStatement in project trino by trinodb.

the class StateCompiler method generateSerialize.

private static <T> void generateSerialize(ClassDefinition definition, CallSiteBinder binder, Class<T> clazz, List<StateField> fields) {
    Parameter state = arg("state", AccumulatorState.class);
    Parameter out = arg("out", BlockBuilder.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC), "serialize", type(void.class), state, out);
    Scope scope = method.getScope();
    BytecodeBlock serializerBody = method.getBody();
    if (fields.size() == 0) {
        serializerBody.append(out.invoke("appendNull", BlockBuilder.class).pop());
    } else if (fields.size() == 1) {
        Method getter = getGetter(clazz, getOnlyElement(fields));
        SqlTypeBytecodeExpression sqlType = constantType(binder, getOnlyElement(fields).getSqlType());
        Variable fieldValue = scope.declareVariable(getter.getReturnType(), "value");
        serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter)));
        if (!getOnlyElement(fields).isPrimitiveType()) {
            serializerBody.append(new IfStatement().condition(equal(fieldValue, constantNull(getter.getReturnType()))).ifTrue(out.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(sqlType.writeValue(out, fieldValue)));
        } else {
            // For primitive type, we need to cast here because we serialize byte fields with TINYINT/INTEGER (whose java type is long).
            serializerBody.append(sqlType.writeValue(out, fieldValue.cast(getOnlyElement(fields).getSqlType().getJavaType())));
        }
    } else if (fields.size() > 1) {
        Variable rowBuilder = scope.declareVariable(BlockBuilder.class, "rowBuilder");
        serializerBody.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class)));
        for (StateField field : fields) {
            Method getter = getGetter(clazz, field);
            SqlTypeBytecodeExpression sqlType = constantType(binder, field.getSqlType());
            Variable fieldValue = scope.createTempVariable(getter.getReturnType());
            serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter)));
            if (!field.isPrimitiveType()) {
                serializerBody.append(new IfStatement().condition(equal(fieldValue, constantNull(getter.getReturnType()))).ifTrue(rowBuilder.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(sqlType.writeValue(rowBuilder, fieldValue)));
            } else {
                // For primitive type, we need to cast here because we serialize byte fields with TINYINT/INTEGER (whose java type is long).
                serializerBody.append(sqlType.writeValue(rowBuilder, fieldValue.cast(field.getSqlType().getJavaType())));
            }
        }
        serializerBody.append(out.invoke("closeEntry", BlockBuilder.class).pop());
    }
    serializerBody.ret();
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter) Method(java.lang.reflect.Method) SqlTypeBytecodeExpression(io.trino.sql.gen.SqlTypeBytecodeExpression) BlockBuilder(io.trino.spi.block.BlockBuilder)

Example 79 with IfStatement

use of io.airlift.bytecode.control.IfStatement in project trino by trinodb.

the class StateCompiler method generateCopy.

private static void generateCopy(ClassDefinition definition, List<StateField> fields, List<FieldDefinition> fieldDefinitions) {
    MethodDefinition copy = definition.declareMethod(a(PUBLIC), "copy", type(AccumulatorState.class));
    Variable thisVariable = copy.getThis();
    BytecodeBlock body = copy.getBody();
    List<BytecodeExpression> fieldCopyExpressions = new ArrayList<>();
    for (int i = 0; i < fields.size(); i++) {
        Optional<BytecodeExpression> fieldCopy = copyField(thisVariable, fieldDefinitions.get(i), fields.get(i).getType());
        if (fieldCopy.isEmpty()) {
            body.append(newInstance(UnsupportedOperationException.class, constantString(format("copy not supported for %s (cannot copy field of type %s)", definition.getName(), fields.get(i).getType())))).throwObject();
            return;
        }
        fieldCopyExpressions.add(fieldCopy.get());
    }
    Variable instanceCopy = copy.getScope().declareVariable(definition.getType(), "instanceCopy");
    body.append(instanceCopy.set(newInstance(definition.getType())));
    for (int i = 0; i < fieldDefinitions.size(); i++) {
        FieldDefinition fieldDefinition = fieldDefinitions.get(i);
        Class<?> type = fields.get(i).getType();
        if (type == long.class || type == double.class || type == boolean.class || type == byte.class || type == int.class) {
            body.append(instanceCopy.setField(fieldDefinition, fieldCopyExpressions.get(i)));
        } else {
            body.append(new IfStatement("if field value is null").condition(isNull(thisVariable.getField(fieldDefinition))).ifTrue(instanceCopy.setField(fieldDefinition, thisVariable.getField(fieldDefinition))).ifFalse(instanceCopy.setField(fieldDefinition, fieldCopyExpressions.get(i))));
        }
    }
    copy.getBody().append(instanceCopy.ret());
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) AccumulatorState(io.trino.spi.function.AccumulatorState) Variable(io.airlift.bytecode.Variable) MethodDefinition(io.airlift.bytecode.MethodDefinition) FieldDefinition(io.airlift.bytecode.FieldDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) SqlTypeBytecodeExpression(io.trino.sql.gen.SqlTypeBytecodeExpression)

Aggregations

IfStatement (io.airlift.bytecode.control.IfStatement)79 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)69 Variable (io.airlift.bytecode.Variable)68 MethodDefinition (io.airlift.bytecode.MethodDefinition)43 Scope (io.airlift.bytecode.Scope)42 Parameter (io.airlift.bytecode.Parameter)38 BytecodeNode (io.airlift.bytecode.BytecodeNode)26 ForLoop (io.airlift.bytecode.control.ForLoop)20 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)20 LabelNode (io.airlift.bytecode.instruction.LabelNode)18 ClassDefinition (io.airlift.bytecode.ClassDefinition)14 ImmutableList (com.google.common.collect.ImmutableList)12 Block (io.prestosql.spi.block.Block)12 Block (io.trino.spi.block.Block)11 Type (io.prestosql.spi.type.Type)10 ArrayList (java.util.ArrayList)10 VariableInstruction.incrementVariable (io.airlift.bytecode.instruction.VariableInstruction.incrementVariable)8 BlockBuilder (io.prestosql.spi.block.BlockBuilder)8 CallSiteBinder (io.prestosql.sql.gen.CallSiteBinder)8 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)7