use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.
the class NotBytecodeExpression method getBytecode.
@Override
public BytecodeNode getBytecode(MethodGenerationContext generationContext) {
LabelNode trueLabel = new LabelNode("true");
LabelNode endLabel = new LabelNode("end");
return new BytecodeBlock().append(value).ifTrueGoto(trueLabel).push(true).gotoLabel(endLabel).visitLabel(trueLabel).push(false).visitLabel(endLabel);
}
use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.
the class OrBytecodeExpression method getBytecode.
@Override
public BytecodeNode getBytecode(MethodGenerationContext generationContext) {
LabelNode trueLabel = new LabelNode("true");
LabelNode endLabel = new LabelNode("end");
return new BytecodeBlock().append(left).ifTrueGoto(trueLabel).append(right).ifTrueGoto(trueLabel).push(false).gotoLabel(endLabel).visitLabel(trueLabel).push(true).visitLabel(endLabel);
}
use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.
the class PageProcessorCompiler method generateProcessMethod.
private static void generateProcessMethod(ClassDefinition classDefinition, RowExpression filter, List<RowExpression> projections, List<MethodDefinition> projectionMethods) {
Parameter session = arg("session", ConnectorSession.class);
Parameter page = arg("page", Page.class);
Parameter start = arg("start", int.class);
Parameter end = arg("end", int.class);
Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(int.class), session, page, start, end, pageBuilder);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable thisVariable = method.getThis();
// extract blocks
List<Integer> allInputChannels = getInputChannels(concat(projections, ImmutableList.of(filter)));
ImmutableMap.Builder<Integer, Variable> builder = ImmutableMap.builder();
for (int channel : allInputChannels) {
Variable blockVariable = scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel)));
builder.put(channel, blockVariable);
}
Map<Integer, Variable> channelBlocks = builder.build();
Map<RowExpression, List<Variable>> expressionInputBlocks = getExpressionInputBlocks(projections, filter, channelBlocks);
// projection body
Variable position = scope.declareVariable(int.class, "position");
BytecodeBlock project = new BytecodeBlock().append(pageBuilder.invoke("declarePosition", void.class));
for (int projectionIndex = 0; projectionIndex < projections.size(); projectionIndex++) {
RowExpression projection = projections.get(projectionIndex);
project.append(invokeProject(thisVariable, session, expressionInputBlocks.get(projection), position, pageBuilder, constantInt(projectionIndex), projectionMethods.get(projectionIndex)));
}
LabelNode done = new LabelNode("done");
// for loop loop body
ForLoop loop = new ForLoop().initialize(position.set(start)).condition(lessThan(position, end)).update(position.set(add(position, constantInt(1)))).body(new BytecodeBlock().append(new IfStatement().condition(pageBuilder.invoke("isFull", boolean.class)).ifTrue(jump(done))).append(new IfStatement().condition(invokeFilter(thisVariable, session, expressionInputBlocks.get(filter), position)).ifTrue(project)));
body.append(loop).visitLabel(done).append(position.ret());
}
use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.
the class SwitchCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
// TODO: compile as
/*
hashCode = hashCode(<value>)
// all constant expressions before a non-constant
switch (hashCode) {
case ...:
if (<value> == <constant1>) {
...
}
else if (<value> == <constant2>) {
...
}
else if (...) {
}
case ...:
...
}
if (<value> == <non-constant1>) {
...
}
else if (<value> == <non-constant2>) {
...
}
...
// repeat with next sequence of constant expressions
*/
Scope scope = generatorContext.getScope();
// process value, else, and all when clauses
RowExpression value = arguments.get(0);
BytecodeNode valueBytecode = generatorContext.generate(value);
BytecodeNode elseValue;
List<RowExpression> whenClauses;
RowExpression last = arguments.get(arguments.size() - 1);
if (last instanceof CallExpression && ((CallExpression) last).getSignature().getName().equals("WHEN")) {
whenClauses = arguments.subList(1, arguments.size());
elseValue = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pushJavaDefault(returnType.getJavaType());
} else {
whenClauses = arguments.subList(1, arguments.size() - 1);
elseValue = generatorContext.generate(last);
}
// determine the type of the value and result
Class<?> valueType = value.getType().getJavaType();
// evaluate the value and store it in a variable
LabelNode nullValue = new LabelNode("nullCondition");
Variable tempVariable = scope.createTempVariable(valueType);
BytecodeBlock block = new BytecodeBlock().append(valueBytecode).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, nullValue, void.class, valueType)).putVariable(tempVariable);
BytecodeNode getTempVariableNode = VariableInstruction.loadVariable(tempVariable);
// build the statements
elseValue = new BytecodeBlock().visitLabel(nullValue).append(elseValue);
// reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
for (RowExpression clause : Lists.reverse(whenClauses)) {
Preconditions.checkArgument(clause instanceof CallExpression && ((CallExpression) clause).getSignature().getName().equals("WHEN"));
RowExpression operand = ((CallExpression) clause).getArguments().get(0);
RowExpression result = ((CallExpression) clause).getArguments().get(1);
// call equals(value, operand)
Signature equalsFunction = generatorContext.getRegistry().resolveOperator(OperatorType.EQUAL, ImmutableList.of(value.getType(), operand.getType()));
// TODO: what if operand is null? It seems that the call will return "null" (which is cleared below)
// and the code only does the right thing because the value in the stack for that scenario is
// Java's default for boolean == false
// This code should probably be checking for wasNull after the call and "failing" the equality
// check if wasNull is true
BytecodeNode equalsCall = generatorContext.generateCall(equalsFunction.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(equalsFunction), ImmutableList.of(generatorContext.generate(operand), getTempVariableNode));
BytecodeBlock condition = new BytecodeBlock().append(equalsCall).append(generatorContext.wasNull().set(constantFalse()));
elseValue = new IfStatement("when").condition(condition).ifTrue(generatorContext.generate(result)).ifFalse(elseValue);
}
return block.append(elseValue);
}
use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.
the class ComparisonBytecodeExpression method getBytecode.
@Override
public BytecodeNode getBytecode(MethodGenerationContext generationContext) {
BytecodeBlock block = new BytecodeBlock().append(left).append(right);
if (comparisonInstruction != null) {
block.append(comparisonInstruction);
}
LabelNode noMatch = new LabelNode("no_match");
LabelNode end = new LabelNode("end");
return block.append(new JumpInstruction(noMatchJumpInstruction, noMatch)).push(true).gotoLabel(end).append(noMatch).push(false).append(end);
}
Aggregations