use of com.facebook.presto.bytecode.Variable in project presto by prestodb.
the class BytecodeUtils method unboxPrimitiveIfNecessary.
public static BytecodeBlock unboxPrimitiveIfNecessary(Scope scope, Class<?> boxedType) {
BytecodeBlock block = new BytecodeBlock();
LabelNode end = new LabelNode("end");
Class<?> unboxedType = Primitives.unwrap(boxedType);
Variable wasNull = scope.getVariable("wasNull");
if (unboxedType.isPrimitive()) {
LabelNode notNull = new LabelNode("notNull");
block.dup(boxedType).ifNotNullGoto(notNull).append(wasNull.set(constantTrue())).comment("swap boxed null with unboxed default").pop(boxedType).pushJavaDefault(unboxedType).gotoLabel(end).visitLabel(notNull).append(unboxPrimitive(unboxedType));
} else {
block.dup(boxedType).ifNotNullGoto(end).append(wasNull.set(constantTrue()));
}
block.visitLabel(end);
return block;
}
use of com.facebook.presto.bytecode.Variable in project presto by prestodb.
the class BytecodeUtils method handleNullValue.
public static BytecodeNode handleNullValue(Scope scope, LabelNode label, Class<?> methodReturnType, List<Class<?>> stackArgsToPop, Optional<Variable> outputBlockVariable, boolean clearNullFlag) {
if (outputBlockVariable.isPresent()) {
checkArgument(methodReturnType == void.class);
}
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);
}
String loadDefaultOrAppendNullComment;
if (!outputBlockVariable.isPresent()) {
isNull.pushJavaDefault(methodReturnType);
loadDefaultOrAppendNullComment = format("loadJavaDefault(%s)", methodReturnType.getName());
} else {
isNull.append(outputBlockVariable.get().invoke("appendNull", BlockBuilder.class).pop());
loadDefaultOrAppendNullComment = "appendNullToOutputBlock";
}
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, loadDefaultOrAppendNullComment, "goto " + label.getLabel())).condition(nullCheck).ifTrue(isNull);
}
use of com.facebook.presto.bytecode.Variable in project presto by prestodb.
the class CoalesceCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
Variable wasNull = generatorContext.wasNull();
LabelNode endLabel = new LabelNode("end");
BytecodeBlock block = new BytecodeBlock();
// Generate all but the last one.
for (RowExpression expression : arguments.subList(0, arguments.size() - 1)) {
block.append(generatorContext.generate(expression, Optional.empty()));
// Check if null
IfStatement ifStatement = new IfStatement().condition(wasNull);
ifStatement.ifTrue().pop(returnType.getJavaType()).append(wasNull.set(constantFalse()));
ifStatement.ifFalse().gotoLabel(endLabel);
block.append(ifStatement);
}
// Just return the last one here if control reaches here.
block.append(generatorContext.generate(arguments.get(arguments.size() - 1), Optional.empty()));
block.visitLabel(endLabel);
outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
return block;
}
use of com.facebook.presto.bytecode.Variable in project presto by prestodb.
the class AccumulatorCompiler method generateGroupedEvaluateFinal.
private static void generateGroupedEvaluateFinal(ClassDefinition definition, List<FieldDefinition> stateFields, MethodHandle outputFunction, CallSiteBinder callSiteBinder) {
Parameter groupId = arg("groupId", int.class);
Parameter out = arg("out", BlockBuilder.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC), "evaluateFinal", type(void.class), groupId, out);
BytecodeBlock body = method.getBody();
Variable thisVariable = method.getThis();
List<BytecodeExpression> states = new ArrayList<>();
for (FieldDefinition stateField : stateFields) {
BytecodeExpression state = thisVariable.getField(stateField);
body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class)));
states.add(state);
}
body.comment("output(state_0, state_1, ..., out)");
states.forEach(body::append);
body.append(out);
body.append(invoke(callSiteBinder.bind(outputFunction), "output"));
body.ret();
}
use of com.facebook.presto.bytecode.Variable in project presto by prestodb.
the class AccumulatorCompiler method generateConstructor.
private static void generateConstructor(ClassDefinition definition, List<StateFieldAndDescriptor> stateFieldAndDescriptors, List<FieldDefinition> inputChannelFields, FieldDefinition maskChannelField, List<FieldDefinition> lambdaProviderFields, boolean grouped) {
Parameter stateDescriptors = arg("stateDescriptors", type(List.class, AccumulatorStateDescriptor.class));
Parameter inputChannels = arg("inputChannels", type(List.class, Integer.class));
Parameter maskChannel = arg("maskChannel", type(Optional.class, Integer.class));
Parameter lambdaProviders = arg("lambdaProviders", type(List.class, LambdaProvider.class));
MethodDefinition method = definition.declareConstructor(a(PUBLIC), stateDescriptors, inputChannels, maskChannel, lambdaProviders);
BytecodeBlock body = method.getBody();
Variable thisVariable = method.getThis();
body.comment("super();").append(thisVariable).invokeConstructor(Object.class);
for (int i = 0; i < stateFieldAndDescriptors.size(); i++) {
body.append(thisVariable.setField(stateFieldAndDescriptors.get(i).getStateSerializerField(), stateDescriptors.invoke("get", Object.class, constantInt(i)).cast(AccumulatorStateDescriptor.class).invoke("getSerializer", AccumulatorStateSerializer.class)));
body.append(thisVariable.setField(stateFieldAndDescriptors.get(i).getStateFactoryField(), stateDescriptors.invoke("get", Object.class, constantInt(i)).cast(AccumulatorStateDescriptor.class).invoke("getFactory", AccumulatorStateFactory.class)));
}
for (int i = 0; i < lambdaProviderFields.size(); i++) {
body.append(thisVariable.setField(lambdaProviderFields.get(i), lambdaProviders.invoke("get", Object.class, constantInt(i)).cast(LambdaProvider.class)));
}
body.append(thisVariable.setField(maskChannelField, invokeStatic(type(CompilerOperations.class), "optionalChannelToIntOrNegative", type(int.class), ImmutableList.of(type(Optional.class, Integer.class)), generateRequireNotNull(maskChannel))));
// Validate inputChannels argument list
body.append(generateRequireNotNull(inputChannels)).push(inputChannelFields.size()).invokeStatic(type(CompilerOperations.class), "validateChannelsListLength", type(void.class), ImmutableList.of(type(List.class, Integer.class), type(int.class)));
// Initialize inputChannels fields
if (!inputChannelFields.isEmpty()) {
// Assign each inputChannel field from the list or assign -1 if the input list is empty (eg: intermediate aggregations don't use the input parameters)
BytecodeBlock assignFromList = new BytecodeBlock().comment("(this.inputChannel = %s.get(i), ...)", inputChannels.getName());
BytecodeBlock assignNegative = new BytecodeBlock().comment("(this.inputChannel = -1, ...)");
for (int i = 0; i < inputChannelFields.size(); i++) {
FieldDefinition inputChannelField = inputChannelFields.get(i);
assignFromList.append(thisVariable.setField(inputChannelField, inputChannels.invoke("get", Object.class, constantInt(i)).cast(int.class)));
assignNegative.append(thisVariable.setField(inputChannelField, constantInt(-1)));
}
body.append(new IfStatement("if(%s.isEmpty())", inputChannels.getName()).condition(new BytecodeBlock().append(inputChannels).invokeInterface(List.class, "isEmpty", boolean.class)).ifTrue(assignNegative).ifFalse(assignFromList));
}
String createState;
if (grouped) {
createState = "createGroupedState";
} else {
createState = "createSingleState";
}
for (StateFieldAndDescriptor stateFieldAndDescriptor : stateFieldAndDescriptors) {
FieldDefinition stateField = stateFieldAndDescriptor.getStateField();
BytecodeExpression stateFactory = thisVariable.getField(stateFieldAndDescriptor.getStateFactoryField());
body.append(thisVariable.setField(stateField, stateFactory.invoke(createState, Object.class).cast(stateField.getType())));
}
body.ret();
}
Aggregations