use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.
the class RowIndeterminateOperator method generateIndeterminate.
private static Class<?> generateIndeterminate(Type type, FunctionAndTypeManager functionAndTypeManager) {
CallSiteBinder binder = new CallSiteBinder();
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("RowIndeterminateOperator"), type(Object.class));
Parameter value = arg("value", type.getJavaType());
Parameter isNull = arg("isNull", boolean.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "indeterminate", type(boolean.class), value, isNull);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
body.append(wasNull.set(constantFalse()));
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder);
LabelNode end = new LabelNode("end");
List<Type> fieldTypes = type.getTypeParameters();
boolean hasUnknownFields = fieldTypes.stream().anyMatch(fieldType -> fieldType.equals(UNKNOWN));
body.append(new IfStatement("if isNull is true...").condition(isNull).ifTrue(new BytecodeBlock().push(true).gotoLabel(end)));
if (hasUnknownFields) {
// if the current field type is UNKNOWN which means this field is null, directly return true
body.push(true).gotoLabel(end);
} else {
for (int i = 0; i < fieldTypes.size(); i++) {
IfStatement ifNullField = new IfStatement("if the field is null...");
ifNullField.condition(value.invoke("isNull", boolean.class, constantInt(i))).ifTrue(new BytecodeBlock().push(true).gotoLabel(end));
FunctionHandle functionHandle = functionAndTypeManager.resolveOperator(INDETERMINATE, fromTypes(fieldTypes.get(i)));
JavaScalarFunctionImplementation function = functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle);
BytecodeExpression element = constantType(binder, fieldTypes.get(i)).getValue(value, constantInt(i));
ifNullField.ifFalse(new IfStatement("if the field is not null but indeterminate...").condition(invokeFunction(scope, cachedInstanceBinder, functionAndTypeManager.getFunctionMetadata(functionHandle).getName().getObjectName(), function, element)).ifTrue(new BytecodeBlock().push(true).gotoLabel(end)));
body.append(ifNullField);
}
// if none of the fields is indeterminate, then push false
body.push(false);
}
body.visitLabel(end).retBoolean();
// create constructor
MethodDefinition constructorDefinition = definition.declareConstructor(a(PUBLIC));
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
constructorBody.ret();
return defineClass(definition, Object.class, binder.getBindings(), RowIndeterminateOperator.class.getClassLoader());
}
use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.
the class AbstractGreatestLeast method generate.
private Class<?> generate(List<Class<?>> javaTypes, Type type, MethodHandle compareMethod) {
checkCondition(javaTypes.size() <= 127, NOT_SUPPORTED, "Too many arguments for function call %s()", getSignature().getNameSuffix());
String javaTypeName = javaTypes.stream().map(Class::getSimpleName).collect(joining());
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(javaTypeName + "$" + getSignature().getNameSuffix()), type(Object.class));
definition.declareDefaultConstructor(a(PRIVATE));
List<Parameter> parameters = IntStream.range(0, javaTypes.size()).mapToObj(i -> arg("arg" + i, javaTypes.get(i))).collect(toImmutableList());
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), getSignature().getNameSuffix(), type(javaTypes.get(0)), parameters);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
CallSiteBinder binder = new CallSiteBinder();
if (type.getTypeSignature().getBase().equals(StandardTypes.DOUBLE)) {
for (Parameter parameter : parameters) {
body.append(parameter);
body.append(invoke(binder.bind(CHECK_NOT_NAN.bindTo(getSignature().getNameSuffix())), "checkNotNaN"));
}
}
Variable value = scope.declareVariable(javaTypes.get(0), "value");
body.append(value.set(parameters.get(0)));
for (int i = 1; i < javaTypes.size(); i++) {
body.append(new IfStatement().condition(new BytecodeBlock().append(parameters.get(i)).append(value).append(invoke(binder.bind(compareMethod), "compare"))).ifTrue(value.set(parameters.get(i))));
}
body.append(value.ret());
return defineClass(definition, Object.class, binder.getBindings(), new DynamicClassLoader(getClass().getClassLoader()));
}
use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.
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()));
}
use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.
the class StateCompiler method generateDeserialize.
private static <T> void generateDeserialize(ClassDefinition definition, CallSiteBinder binder, Class<T> clazz, List<StateField> fields) {
Parameter block = arg("block", Block.class);
Parameter index = arg("index", int.class);
Parameter state = arg("state", Object.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC), "deserialize", type(void.class), block, index, state);
BytecodeBlock deserializerBody = method.getBody();
Scope scope = method.getScope();
if (fields.size() == 1) {
StateField field = getOnlyElement(fields);
Method setter = getSetter(clazz, field);
if (!field.isPrimitiveType()) {
deserializerBody.append(new IfStatement().condition(block.invoke("isNull", boolean.class, index)).ifTrue(state.cast(setter.getDeclaringClass()).invoke(setter, constantNull(field.getType()))).ifFalse(state.cast(setter.getDeclaringClass()).invoke(setter, constantType(binder, field.getSqlType()).getValue(block, index))));
} else {
// For primitive type, we need to cast here because we serialize byte fields with TINYINT/INTEGER (whose java type is long).
deserializerBody.append(state.cast(setter.getDeclaringClass()).invoke(setter, constantType(binder, field.getSqlType()).getValue(block, index).cast(field.getType())));
}
} else if (fields.size() > 1) {
Variable row = scope.declareVariable(Block.class, "row");
deserializerBody.append(row.set(block.invoke("getBlock", Block.class, index)));
int position = 0;
for (StateField field : fields) {
Method setter = getSetter(clazz, field);
if (!field.isPrimitiveType()) {
deserializerBody.append(new IfStatement().condition(row.invoke("isNull", boolean.class, constantInt(position))).ifTrue(state.cast(setter.getDeclaringClass()).invoke(setter, constantNull(field.getType()))).ifFalse(state.cast(setter.getDeclaringClass()).invoke(setter, constantType(binder, field.getSqlType()).getValue(row, constantInt(position)))));
} else {
// For primitive type, we need to cast here because we serialize byte fields with TINYINT/INTEGER (whose java type is long).
deserializerBody.append(state.cast(setter.getDeclaringClass()).invoke(setter, constantType(binder, field.getSqlType()).getValue(row, constantInt(position)).cast(field.getType())));
}
position++;
}
}
deserializerBody.ret();
}
use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.
the class PageProcessorCompiler method getBytecodeFilterOnRLE.
private static BytecodeBlock getBytecodeFilterOnRLE(Parameter session, Scope scope, Variable blockVariable) {
Variable positionCount = scope.getVariable("positionCount");
Variable thisVariable = scope.getThis();
BytecodeBlock ifFilterOnRLEBlock = new BytecodeBlock();
Variable rleBlock = scope.declareVariable("rleBlock", ifFilterOnRLEBlock, blockVariable.cast(RunLengthEncodedBlock.class));
Variable rleValue = scope.declareVariable("rleValue", ifFilterOnRLEBlock, rleBlock.invoke("getValue", Block.class));
ifFilterOnRLEBlock.append(new IfStatement().condition(invokeFilter(thisVariable, session, singletonList(rleValue), constantInt(0))).ifTrue(invokeStatic(IntStream.class, "range", IntStream.class, constantInt(0), positionCount).invoke("toArray", int[].class).ret()).ifFalse(newArray(type(int[].class), constantInt(0)).ret()));
return ifFilterOnRLEBlock;
}
Aggregations