use of io.airlift.bytecode.expression.BytecodeExpression in project hetu-core by openlookeng.
the class InputReferenceCompiler method visitInputReference.
@Override
public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) {
int field = node.getField();
Type type = node.getType();
BytecodeExpression block = blockResolver.apply(scope, field);
BytecodeExpression position = positionResolver.apply(scope, field);
return generateInputReference(callSiteBinder, scope, type, block, position);
}
use of io.airlift.bytecode.expression.BytecodeExpression in project hetu-core by openlookeng.
the class JoinCompiler method generateCompareSortChannelPositionsMethod.
private static void generateCompareSortChannelPositionsMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<FieldDefinition> channelFields, Optional<Integer> sortChannel) {
Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
Parameter rightBlockIndex = arg("rightBlockIndex", int.class);
Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
MethodDefinition compareMethod = classDefinition.declareMethod(a(PUBLIC), "compareSortChannelPositions", type(int.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
if (!sortChannel.isPresent()) {
compareMethod.getBody().append(newInstance(UnsupportedOperationException.class)).throwObject();
return;
}
Variable thisVariable = compareMethod.getThis();
int index = sortChannel.get();
BytecodeExpression type = constantType(callSiteBinder, types.get(index));
BytecodeExpression leftBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
BytecodeExpression rightBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
BytecodeNode comparison = type.invoke("compareTo", int.class, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition).ret();
compareMethod.getBody().append(comparison);
}
use of io.airlift.bytecode.expression.BytecodeExpression in project hetu-core by openlookeng.
the class JoinCompiler method generateHashPositionMethod.
private static void generateHashPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
Parameter blockIndex = arg("blockIndex", int.class);
Parameter blockPosition = arg("blockPosition", int.class);
MethodDefinition hashPositionMethod = classDefinition.declareMethod(a(PUBLIC), "hashPosition", type(long.class), blockIndex, blockPosition);
Variable thisVariable = hashPositionMethod.getThis();
BytecodeExpression hashChannel = thisVariable.getField(hashChannelField);
BytecodeExpression bigintType = constantType(callSiteBinder, BigintType.BIGINT);
IfStatement ifStatement = new IfStatement();
ifStatement.condition(notEqual(hashChannel, constantNull(hashChannelField.getType())));
ifStatement.ifTrue(bigintType.invoke("getLong", long.class, hashChannel.invoke("get", Object.class, blockIndex).cast(Block.class), blockPosition).ret());
hashPositionMethod.getBody().append(ifStatement);
Variable resultVariable = hashPositionMethod.getScope().declareVariable(long.class, "result");
hashPositionMethod.getBody().push(0L).putVariable(resultVariable);
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression block = hashPositionMethod.getThis().getField(joinChannelFields.get(index)).invoke("get", Object.class, blockIndex).cast(Block.class);
hashPositionMethod.getBody().getVariable(resultVariable).push(31L).append(OpCode.LMUL).append(typeHashCode(type, block, blockPosition)).append(OpCode.LADD).putVariable(resultVariable);
}
hashPositionMethod.getBody().getVariable(resultVariable).retLong();
}
use of io.airlift.bytecode.expression.BytecodeExpression in project hetu-core by openlookeng.
the class VarArgsToArrayAdapterGenerator method generateVarArgsToArrayAdapter.
public static MethodHandleAndConstructor generateVarArgsToArrayAdapter(Class<?> returnType, Class<?> javaType, int argsLength, MethodHandle function, MethodHandle userStateFactory) {
requireNonNull(returnType, "returnType is null");
requireNonNull(javaType, "javaType is null");
requireNonNull(function, "function is null");
requireNonNull(userStateFactory, "userStateFactory is null");
checkCondition(argsLength <= 253, NOT_SUPPORTED, "Too many arguments for vararg function");
MethodType methodType = function.type();
Class<?> javaArrayType = toArrayClass(javaType);
checkArgument(methodType.returnType() == returnType, "returnType does not match");
checkArgument(methodType.parameterList().equals(ImmutableList.of(Object.class, javaArrayType)), "parameter types do not match");
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("VarArgsToListAdapter"), type(Object.class));
classDefinition.declareDefaultConstructor(a(PRIVATE));
// generate userState constructor
MethodDefinition stateFactoryDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "createState", type(VarArgsToArrayAdapterState.class));
stateFactoryDefinition.getBody().comment("create userState for current instance").append(newInstance(VarArgsToArrayAdapterState.class, loadConstant(callSiteBinder, userStateFactory, MethodHandle.class).invoke("invokeExact", Object.class), newArray(type(javaArrayType), argsLength).cast(Object.class)).ret());
// generate adapter method
ImmutableList.Builder<Parameter> parameterListBuilder = ImmutableList.builder();
parameterListBuilder.add(arg("userState", VarArgsToArrayAdapterState.class));
for (int i = 0; i < argsLength; i++) {
parameterListBuilder.add(arg("input_" + i, javaType));
}
ImmutableList<Parameter> parameterList = parameterListBuilder.build();
MethodDefinition methodDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "varArgsToArray", type(returnType), parameterList);
BytecodeBlock body = methodDefinition.getBody();
BytecodeExpression userState = parameterList.get(0).getField("userState", Object.class);
BytecodeExpression args = parameterList.get(0).getField("args", Object.class).cast(javaArrayType);
for (int i = 0; i < argsLength; i++) {
body.append(args.setElement(i, parameterList.get(i + 1)));
}
body.append(loadConstant(callSiteBinder, function, MethodHandle.class).invoke("invokeExact", returnType, userState, args).ret());
// define class
Class<?> generatedClass = defineClass(classDefinition, Object.class, callSiteBinder.getBindings(), VarArgsToArrayAdapterGenerator.class.getClassLoader());
return new MethodHandleAndConstructor(Reflection.methodHandle(generatedClass, "varArgsToArray", ImmutableList.builder().add(VarArgsToArrayAdapterState.class).addAll(nCopies(argsLength, javaType)).build().toArray(new Class<?>[argsLength])), Reflection.methodHandle(generatedClass, "createState"));
}
use of io.airlift.bytecode.expression.BytecodeExpression in project hetu-core by openlookeng.
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()));
}
Aggregations