use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class JoinCompiler method generateConstructor.
private static void generateConstructor(ClassDefinition classDefinition, List<Integer> joinChannels, FieldDefinition sizeField, FieldDefinition instanceSizeField, List<FieldDefinition> channelFields, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
Parameter channels = arg("channels", type(List.class, type(List.class, Block.class)));
Parameter hashChannel = arg("hashChannel", type(OptionalInt.class));
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), channels, hashChannel);
Variable thisVariable = constructorDefinition.getThis();
Variable blockIndex = constructorDefinition.getScope().declareVariable(int.class, "blockIndex");
BytecodeBlock constructor = constructorDefinition.getBody().comment("super();").append(thisVariable).invokeConstructor(Object.class);
constructor.comment("this.size = INSTANCE_SIZE").append(thisVariable.setField(sizeField, getStatic(instanceSizeField)));
constructor.comment("Set channel fields");
for (int index = 0; index < channelFields.size(); index++) {
BytecodeExpression channel = channels.invoke("get", Object.class, constantInt(index)).cast(type(List.class, Block.class));
constructor.append(thisVariable.setField(channelFields.get(index), channel));
BytecodeBlock loopBody = new BytecodeBlock();
constructor.comment("for(blockIndex = 0; blockIndex < channel.size(); blockIndex++) { size += channel.get(i).getRetainedSizeInBytes() }").append(new ForLoop().initialize(blockIndex.set(constantInt(0))).condition(new BytecodeBlock().append(blockIndex).append(channel.invoke("size", int.class)).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(blockIndex, (byte) 1)).body(loopBody));
loopBody.append(thisVariable).append(thisVariable).getField(sizeField).append(channel.invoke("get", Object.class, blockIndex).cast(type(Block.class)).invoke("getRetainedSizeInBytes", long.class)).longAdd().putField(sizeField);
}
constructor.comment("Set join channel fields");
for (int index = 0; index < joinChannelFields.size(); index++) {
BytecodeExpression joinChannel = channels.invoke("get", Object.class, constantInt(joinChannels.get(index))).cast(type(List.class, Block.class));
constructor.append(thisVariable.setField(joinChannelFields.get(index), joinChannel));
}
constructor.comment("Set hashChannel");
constructor.append(new IfStatement().condition(hashChannel.invoke("isPresent", boolean.class)).ifTrue(thisVariable.setField(hashChannelField, channels.invoke("get", Object.class, hashChannel.invoke("getAsInt", int.class)))).ifFalse(thisVariable.setField(hashChannelField, constantNull(hashChannelField.getType()))));
constructor.ret();
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class CursorProcessorCompiler method generateFilterMethod.
private void generateFilterMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, RowExpression filter) {
Parameter session = arg("session", ConnectorSession.class);
Parameter cursor = arg("cursor", RecordCursor.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), session, cursor);
method.comment("Filter: %s", filter);
Scope scope = method.getScope();
Variable wasNullVariable = scope.declareVariable(type(boolean.class), "wasNull");
RowExpressionCompiler compiler = new RowExpressionCompiler(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cursor), metadata, compiledLambdaMap, new ClassContext(classDefinition, scope, (newFilterName, rowExpressionCompiler, generator, subFilter, callerScope) -> {
MethodDefinition newFilterMethod = classDefinition.declareMethod(a(PUBLIC), newFilterName, type(boolean.class), ImmutableList.<Parameter>builder().add(session).add(cursor).build());
newFilterMethod.comment("Filter: %s", subFilter.toString());
Scope innerScope = newFilterMethod.getScope();
Variable wasNullVariable1 = innerScope.declareVariable(type(boolean.class), "wasNull");
LabelNode end1 = new LabelNode("end");
BytecodeGeneratorContext generatorContext = new BytecodeGeneratorContext(rowExpressionCompiler, innerScope, callSiteBinder, cachedInstanceBinder, metadata.getFunctionAndTypeManager());
newFilterMethod.getBody().comment("boolean wasNull = false;").putVariable(wasNullVariable1, false).comment("evaluate filter: " + subFilter).append(generator.generateExpression(null, generatorContext, subFilter.getType(), subFilter.getArguments())).comment("if (wasNull) return false;").getVariable(wasNullVariable1).ifFalseGoto(end1).pop(boolean.class).push(false).visitLabel(end1).retBoolean();
/* Call the sub-method: Important use caller scope to pass parameters to new function */
BytecodeBlock block = new BytecodeBlock().setDescription("INVOKE " + newFilterName);
LabelNode endCall = new LabelNode("end");
block.append(callerScope.getThis()).getVariable(session).getVariable(cursor).invokeVirtual(classDefinition.getType(), newFilterName, type(boolean.class), type(ConnectorSession.class), type(RecordCursor.class));
block.visitLabel(endCall);
return block;
}));
LabelNode end = new LabelNode("end");
method.getBody().comment("boolean wasNull = false;").putVariable(wasNullVariable, false).comment("evaluate filter: " + filter).append(compiler.compile(filter, scope)).comment("if (wasNull) return false;").getVariable(wasNullVariable).ifFalseGoto(end).pop(boolean.class).push(false).visitLabel(end).retBoolean();
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class IfCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext context, Type returnType, List<RowExpression> arguments) {
Preconditions.checkArgument(arguments.size() == 3);
Variable wasNull = context.wasNull();
BytecodeBlock condition = new BytecodeBlock().append(context.generate(arguments.get(0))).comment("... and condition value was not null").append(wasNull).invokeStatic(CompilerOperations.class, "not", boolean.class, boolean.class).invokeStatic(CompilerOperations.class, "and", boolean.class, boolean.class, boolean.class).append(wasNull.set(constantFalse()));
return new IfStatement().condition(condition).ifTrue(context.generate(arguments.get(1))).ifFalse(context.generate(arguments.get(2)));
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class RowConstructorCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext context, Type rowType, List<RowExpression> arguments) {
BytecodeBlock block = new BytecodeBlock().setDescription("Constructor for " + rowType.toString());
CallSiteBinder binder = context.getCallSiteBinder();
Scope scope = context.getScope();
List<Type> types = rowType.getTypeParameters();
block.comment("Create new RowBlockBuilder; beginBlockEntry;");
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
block.append(blockBuilder.set(constantType(binder, rowType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
block.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
for (int i = 0; i < arguments.size(); ++i) {
Type fieldType = types.get(i);
Variable field = scope.createTempVariable(fieldType.getJavaType());
block.comment("Clean wasNull and Generate + " + i + "-th field of row");
block.append(context.wasNull().set(constantFalse()));
block.append(context.generate(arguments.get(i)));
block.putVariable(field);
block.append(new IfStatement().condition(context.wasNull()).ifTrue(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, fieldType).writeValue(singleRowBlockWriter, field).pop()));
}
block.comment("closeEntry; slice the SingleRowBlock; wasNull = false;");
block.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
block.append(constantType(binder, rowType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class));
block.append(context.wasNull().set(constantFalse()));
return block;
}
use of io.airlift.bytecode.BytecodeBlock in project hetu-core by openlookeng.
the class BytecodeUtils method generateWrite.
public static BytecodeNode generateWrite(CallSiteBinder callSiteBinder, Scope scope, Variable wasNullVariable, Type type) {
Class<?> valueJavaType = type.getJavaType();
if (!valueJavaType.isPrimitive() && valueJavaType != Slice.class) {
valueJavaType = Object.class;
}
String methodName = "write" + Primitives.wrap(valueJavaType).getSimpleName();
// the stack contains [output, value]
// We should be able to insert the code to get the output variable and compute the value
// at the right place instead of assuming they are in the stack. We should also not need to
// use temp variables to re-shuffle the stack to the right shape before Type.writeXXX is called
// Unfortunately, because of the assumptions made by try_cast, we can't get around it yet.
// TODO: clean up once try_cast is fixed
Variable tempValue = scope.createTempVariable(valueJavaType);
Variable tempOutput = scope.createTempVariable(BlockBuilder.class);
return new BytecodeBlock().comment("if (wasNull)").append(new IfStatement().condition(wasNullVariable).ifTrue(new BytecodeBlock().comment("output.appendNull();").pop(valueJavaType).invokeInterface(BlockBuilder.class, "appendNull", BlockBuilder.class).pop()).ifFalse(new BytecodeBlock().comment("%s.%s(output, %s)", type.getTypeSignature(), methodName, valueJavaType.getSimpleName()).putVariable(tempValue).putVariable(tempOutput).append(loadConstant(callSiteBinder.bind(type, Type.class))).getVariable(tempOutput).getVariable(tempValue).invokeInterface(Type.class, methodName, void.class, BlockBuilder.class, valueJavaType)));
}
Aggregations