private static void declareBlockVariables(RowExpression expression, Parameter page, Scope scope, BytecodeBlock body) { for (int channel : getInputChannels(expression)) { scope.declareVariable("block_" + channel, body, page.invoke("getBlock", Block.class, constantInt(channel))); } }
for (int i = 0; i < stateCount; i++) { Class<?> scratchStateClass = stateFieldAndDescriptors.get(i).getStateDescriptor().getFactory().getSingleStateClass(); scratchStates.add(scope.declareVariable(scratchStateClass, "scratchState_" + i)); block = ImmutableList.of(scope.getVariable("block")); Variable columnarRow = scope.declareVariable(ColumnarRow.class, "columnarRow"); body.append(columnarRow.set( invokeStatic(ColumnarRow.class, "toColumnarRow", ColumnarRow.class, scope.getVariable("block")))); Variable columnBlock = scope.declareVariable(Block.class, "columnBlock_" + i); body.append(columnBlock.set( columnarRow.invoke("getField", Block.class, constantInt(i)))); Variable position = scope.declareVariable(int.class, "position"); for (int i = 0; i < stateCount; i++) { FieldDefinition stateFactoryField = stateFieldAndDescriptors.get(i).getStateFactoryField(); for (FieldDefinition stateField : stateFields) { if (grouped) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); loopBody.append(thisVariable.getField(stateField).invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position))); loopBody.append(scope.getThis().getField(lambdaProviderFields.get(i)) .invoke("getLambda", Object.class) .cast(lambdaInterfaces.get(i))); .condition(not(scope.getVariable("groupIdsBlock").invoke("isNull", boolean.class, position))) .ifTrue(loopBody);
scope.declareVariable("wasNull", body, constantFalse()); RowExpressionCompiler compiler = new RowExpressionCompiler( callSiteBinder, compiledLambdaMap); Variable outputBlockVariable = scope.createTempVariable(BlockBuilder.class); body.append(outputBlockVariable.set(thisVariable.getField(blockBuilder))) .append(compiler.compile(projection, scope, Optional.of(outputBlockVariable)))
private static void generateSetGroupIdFromGroupIdsBlock(Scope scope, List<FieldDefinition> stateFields, BytecodeBlock block) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); Variable position = scope.getVariable("position"); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = scope.getThis().getField(stateField); block.append(state.invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position))); } }
Scope scope = context.getScope(); Variable wasNull = scope.getVariable("wasNull"); for (RowExpression captureExpression : captureExpressions) { Class<?> valueType = Primitives.wrap(captureExpression.getType().getJavaType()); Variable valueVariable = scope.createTempVariable(valueType); block.append(context.generate(captureExpression, Optional.empty())); block.append(boxPrimitiveIfNecessary(scope, valueType)); .add(scope.getThis(), scope.getVariable("session")) .addAll(captureVariableBuilder.build()) .build();
BytecodeBlock body = method.getBody(); Variable blockBuilderVariable = scope.declareVariable(BlockBuilder.class, "blockBuilder"); CallSiteBinder binder = new CallSiteBinder(); Variable argument = scope.getVariable("arg" + i); IfStatement ifStatement = new IfStatement() .condition(equal(argument, constantNull(stackTypes.get(i))))
private static RowExpressionVisitor<BytecodeNode, Scope> fieldReferenceCompiler(CallSiteBinder callSiteBinder) { return new InputReferenceCompiler( (scope, field) -> scope.getVariable("block_" + field), (scope, field) -> scope.getVariable("position"), callSiteBinder); } }
public static BytecodeExpression invokeFunction(Scope scope, CachedInstanceBinder cachedInstanceBinder, String name, ScalarFunctionImplementation function, List<BytecodeExpression> parameters) { requireNonNull(scope, "scope is null"); requireNonNull(function, "function is null"); Optional<BytecodeNode> instance = Optional.empty(); if (function.getInstanceFactory().isPresent()) { FieldDefinition field = cachedInstanceBinder.getCachedInstance(function.getInstanceFactory().get()); instance = Optional.of(scope.getThis().getField(field)); } return new InvokeFunctionBytecodeExpression(scope, cachedInstanceBinder.getCallSiteBinder(), name, function, instance, parameters); }
Variable tempVariable = scope.createTempVariable(valueType); BytecodeBlock block = new BytecodeBlock() .append(valueBytecode)
public ScopeContext(Scope scope) { this.scope = scope; this.variables = ImmutableList.copyOf(scope.getVariables()); }
public MethodDefinition( ClassDefinition declaringClass, EnumSet<Access> access, String name, ParameterizedType returnType, Iterable<Parameter> parameters) { checkArgument(Iterables.size(parameters) <= 254, "Too many parameters for method"); this.declaringClass = declaringClass; body = new BytecodeBlock(); this.access = access; this.name = name; if (returnType != null) { this.returnType = returnType; } else { this.returnType = type(void.class); } this.parameters = ImmutableList.copyOf(parameters); this.parameterTypes = Lists.transform(this.parameters, Parameter::getType); this.parameterAnnotations = ImmutableList.copyOf(transform(parameters, input -> new ArrayList<>())); Optional<ParameterizedType> thisType = Optional.empty(); if (!declaringClass.isInterface() && !access.contains(STATIC)) { thisType = Optional.of(declaringClass.getType()); } scope = new Scope(thisType, parameters); }
Variable page = scope.getVariable("page"); Variable positionVariable = scope.declareVariable(int.class, "position"); Variable rowsVariable = scope.declareVariable(int.class, "rows");
private static void generateEnsureCapacity(Scope scope, List<FieldDefinition> stateFields, BytecodeBlock block) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); for (FieldDefinition stateField : stateFields) { BytecodeExpression state = scope.getThis().getField(stateField); block.append(state.invoke("ensureCapacity", void.class, groupIdsBlock.invoke("getGroupCount", long.class))); } }
public BytecodeGeneratorContext( RowExpressionCompiler rowExpressionCompiler, Scope scope, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, FunctionRegistry registry) { requireNonNull(rowExpressionCompiler, "bytecodeGenerator is null"); requireNonNull(cachedInstanceBinder, "cachedInstanceBinder is null"); requireNonNull(scope, "scope is null"); requireNonNull(callSiteBinder, "callSiteBinder is null"); requireNonNull(registry, "registry is null"); this.rowExpressionCompiler = rowExpressionCompiler; this.scope = scope; this.callSiteBinder = callSiteBinder; this.cachedInstanceBinder = cachedInstanceBinder; this.registry = registry; this.wasNull = scope.getVariable("wasNull"); }
Scope scope = context.getScope(); Variable wasNull = scope.getVariable("wasNull"); for (RowExpression captureExpression : captureExpressions) { Class<?> valueType = Primitives.wrap(captureExpression.getType().getJavaType()); Variable valueVariable = scope.createTempVariable(valueType); block.append(context.generate(captureExpression)); block.append(boxPrimitiveIfNecessary(scope, valueType)); .add(scope.getThis(), scope.getVariable("session")) .addAll(captureVariableBuilder.build()) .build();
/** * Generates a function call with null handling, automatic binding of session parameter, etc. */ public BytecodeNode generateCall( String name, ScalarFunctionImplementation function, List<BytecodeNode> arguments, Optional<OutputBlockVariableAndType> outputBlockVariableAndType) { Optional<BytecodeNode> instance = Optional.empty(); if (function.getInstanceFactory().isPresent()) { FieldDefinition field = cachedInstanceBinder.getCachedInstance(function.getInstanceFactory().get()); instance = Optional.of(scope.getThis().getField(field)); } return generateInvocation(scope, name, function, instance, arguments, callSiteBinder, outputBlockVariableAndType); }
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class); Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class); block.append(blockBuilder.set( constantType(binder, rowType).invoke( Variable field = scope.createTempVariable(fieldType.getJavaType()); block.comment("Clean wasNull and Generate + " + i + "-th field of row"); block.append(context.wasNull().set(constantFalse()));
Variable map = methodDefinition.getScope().declareVariable( "map", methodDefinition.getBody(),
for (int i = 0; i < stateCount; i++) { Class<?> scratchStateClass = stateFieldAndDescriptors.get(i).getStateDescriptor().getFactory().getSingleStateClass(); scratchStates.add(scope.declareVariable(scratchStateClass, "scratchState_" + i)); block = ImmutableList.of(scope.getVariable("block")); Variable columnarRow = scope.declareVariable(ColumnarRow.class, "columnarRow"); body.append(columnarRow.set( invokeStatic(ColumnarRow.class, "toColumnarRow", ColumnarRow.class, scope.getVariable("block")))); Variable columnBlock = scope.declareVariable(Block.class, "columnBlock_" + i); body.append(columnBlock.set( columnarRow.invoke("getField", Block.class, constantInt(i)))); Variable position = scope.declareVariable(int.class, "position"); for (int i = 0; i < stateCount; i++) { FieldDefinition stateFactoryField = stateFieldAndDescriptors.get(i).getStateFactoryField(); for (FieldDefinition stateField : stateFields) { if (grouped) { Variable groupIdsBlock = scope.getVariable("groupIdsBlock"); loopBody.append(thisVariable.getField(stateField).invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position))); loopBody.append(scope.getThis().getField(lambdaProviderFields.get(i)) .invoke("getLambda", Object.class) .cast(lambdaInterfaces.get(i))); .condition(not(scope.getVariable("groupIdsBlock").invoke("isNull", boolean.class, position))) .ifTrue(loopBody);
Method getter = getGetter(clazz, getOnlyElement(fields)); SqlTypeBytecodeExpression sqlType = constantType(binder, getOnlyElement(fields).getSqlType()); Variable fieldValue = scope.declareVariable(getter.getReturnType(), "value"); serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter))); if (!getOnlyElement(fields).isPrimitiveType()) { Variable rowBuilder = scope.declareVariable(BlockBuilder.class, "rowBuilder"); serializerBody.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class))); for (StateField field : fields) { Method getter = getGetter(clazz, field); SqlTypeBytecodeExpression sqlType = constantType(binder, field.getSqlType()); Variable fieldValue = scope.createTempVariable(getter.getReturnType()); serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter))); if (!field.isPrimitiveType()) {