use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class ConcatFunction method generateConcat.
private static Class<?> generateConcat(TypeSignature type, int arity) {
checkCondition(arity <= 254, NOT_SUPPORTED, "Too many arguments for string concatenation");
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(type.getBase() + "_concat" + arity + "ScalarFunction"), type(Object.class));
// Generate constructor
definition.declareDefaultConstructor(a(PRIVATE));
// Generate concat()
List<Parameter> parameters = IntStream.range(0, arity).mapToObj(i -> arg("arg" + i, Slice.class)).collect(toImmutableList());
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "concat", type(Slice.class), parameters);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable length = scope.declareVariable(int.class, "length");
body.append(length.set(constantInt(0)));
for (int i = 0; i < arity; ++i) {
body.append(length.set(generateCheckedAdd(length, parameters.get(i).invoke("length", int.class))));
}
Variable result = scope.declareVariable(Slice.class, "result");
body.append(result.set(invokeStatic(Slices.class, "allocate", Slice.class, length)));
Variable position = scope.declareVariable(int.class, "position");
body.append(position.set(constantInt(0)));
for (int i = 0; i < arity; ++i) {
body.append(result.invoke("setBytes", void.class, position, parameters.get(i)));
body.append(position.set(add(position, parameters.get(i).invoke("length", int.class))));
}
body.getVariable(result).retObject();
return defineClass(definition, Object.class, ImmutableMap.of(), new DynamicClassLoader(ConcatFunction.class.getClassLoader()));
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class ArrayToArrayCast method generateArrayCast.
private static Class<?> generateArrayCast(TypeManager typeManager, FunctionMetadata elementCastFunctionMetadata, BuiltInScalarFunctionImplementation elementCast) {
CallSiteBinder binder = new CallSiteBinder();
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(Joiner.on("$").join("ArrayCast", elementCastFunctionMetadata.getArgumentTypes().get(0), elementCastFunctionMetadata.getReturnType())), type(Object.class));
Parameter session = arg("session", ConnectorSession.class);
Parameter value = arg("value", Block.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "castArray", type(Block.class), session, value);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable wasNull = scope.declareVariable(boolean.class, "wasNull");
body.append(wasNull.set(constantBoolean(false)));
// cast map elements
Type fromElementType = typeManager.getType(elementCastFunctionMetadata.getArgumentTypes().get(0));
Type toElementType = typeManager.getType(elementCastFunctionMetadata.getReturnType());
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(definition, binder);
ArrayMapBytecodeExpression newArray = ArrayGeneratorUtils.map(scope, cachedInstanceBinder, fromElementType, toElementType, value, elementCastFunctionMetadata.getName().getObjectName(), elementCast);
// return the block
body.append(newArray.ret());
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(), ArrayToArrayCast.class.getClassLoader());
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class AbstractMinMaxBy method generateCombineMethod.
private void generateCombineMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
Parameter state = arg("state", stateClass);
Parameter otherState = arg("otherState", stateClass);
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "combine", type(void.class), state, otherState);
Class<?> keyJavaType = keyType.getJavaType();
BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, otherState.invoke("getFirst", keyJavaType))).append(state.invoke("setFirstNull", void.class, otherState.invoke("isFirstNull", boolean.class))).append(state.invoke("setSecondNull", void.class, otherState.invoke("isSecondNull", boolean.class)));
if (valueType.getJavaType().isPrimitive()) {
ifBlock.append(state.invoke("setSecond", void.class, otherState.invoke("getSecond", valueType.getJavaType())));
} else {
ifBlock.append(new BytecodeBlock().append(state.invoke("setSecondBlock", void.class, otherState.invoke("getSecondBlock", Block.class))).append(state.invoke("setSecondPosition", void.class, otherState.invoke("getSecondPosition", int.class))));
}
method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(otherState.invoke("isFirstNull", boolean.class)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, otherState.invoke("getFirst", keyJavaType), state.invoke("getFirst", keyJavaType))))).ifTrue(ifBlock)).ret();
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class AccumulatorCompiler method generateInputForLoop.
private static BytecodeBlock generateInputForLoop(List<FieldDefinition> stateField, List<ParameterMetadata> parameterMetadatas, MethodHandle inputFunction, Scope scope, List<Variable> parameterVariables, List<Class<?>> lambdaInterfaces, List<FieldDefinition> lambdaProviderFields, Variable masksBlock, CallSiteBinder callSiteBinder, boolean grouped) {
// For-loop over rows
Variable page = scope.getVariable("page");
Variable positionVariable = scope.declareVariable(int.class, "position");
Variable rowsVariable = scope.declareVariable(int.class, "rows");
BytecodeBlock block = new BytecodeBlock().append(page).invokeVirtual(Page.class, "getPositionCount", int.class).putVariable(rowsVariable).initializeVariable(positionVariable);
BytecodeNode loopBody = generateInvokeInputFunction(scope, stateField, positionVariable, parameterVariables, parameterMetadatas, lambdaInterfaces, lambdaProviderFields, inputFunction, callSiteBinder, grouped);
// Wrap with null checks
List<Boolean> nullable = new ArrayList<>();
for (ParameterMetadata metadata : parameterMetadatas) {
switch(metadata.getParameterType()) {
case INPUT_CHANNEL:
case BLOCK_INPUT_CHANNEL:
nullable.add(false);
break;
case NULLABLE_BLOCK_INPUT_CHANNEL:
nullable.add(true);
break;
// do nothing
default:
}
}
checkState(nullable.size() == parameterVariables.size(), "Number of parameters does not match");
for (int i = 0; i < parameterVariables.size(); i++) {
if (!nullable.get(i)) {
Variable variableDefinition = parameterVariables.get(i);
loopBody = new IfStatement("if(!%s.isNull(position))", variableDefinition.getName()).condition(new BytecodeBlock().getVariable(variableDefinition).getVariable(positionVariable).invokeInterface(Block.class, "isNull", boolean.class, int.class)).ifFalse(loopBody);
}
}
loopBody = new IfStatement("if(testMask(%s, position))", masksBlock.getName()).condition(new BytecodeBlock().getVariable(masksBlock).getVariable(positionVariable).invokeStatic(CompilerOperations.class, "testMask", boolean.class, Block.class, int.class)).ifTrue(loopBody);
block.append(new ForLoop().initialize(new BytecodeBlock().putVariable(positionVariable, 0)).condition(new BytecodeBlock().getVariable(positionVariable).getVariable(rowsVariable).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(positionVariable, (byte) 1)).body(loopBody));
return block;
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class AccumulatorCompiler method generateGroupedEvaluateIntermediate.
private static void generateGroupedEvaluateIntermediate(ClassDefinition definition, List<StateFieldAndDescriptor> stateFieldAndDescriptors) {
Parameter groupId = arg("groupId", int.class);
Parameter out = arg("out", BlockBuilder.class);
MethodDefinition method = definition.declareMethod(a(PUBLIC), "evaluateIntermediate", type(void.class), groupId, out);
Variable thisVariable = method.getThis();
BytecodeBlock body = method.getBody();
if (stateFieldAndDescriptors.size() == 1) {
BytecodeExpression stateSerializer = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateSerializerField());
BytecodeExpression state = thisVariable.getField(getOnlyElement(stateFieldAndDescriptors).getStateField());
body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class))).append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), out)).ret();
} else {
Variable rowBuilder = method.getScope().declareVariable(BlockBuilder.class, "rowBuilder");
body.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class)));
for (int i = 0; i < stateFieldAndDescriptors.size(); i++) {
BytecodeExpression stateSerializer = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateSerializerField());
BytecodeExpression state = thisVariable.getField(stateFieldAndDescriptors.get(i).getStateField());
body.append(state.invoke("setGroupId", void.class, groupId.cast(long.class))).append(stateSerializer.invoke("serialize", void.class, state.cast(Object.class), rowBuilder));
}
body.append(out.invoke("closeEntry", BlockBuilder.class).pop()).ret();
}
}
Aggregations