private static RowExpressionVisitor<BytecodeNode, Scope> fieldReferenceCompiler(CallSiteBinder callSiteBinder) { return new InputReferenceCompiler( (scope, field) -> scope.getVariable("block_" + field), (scope, field) -> scope.getVariable("position"), callSiteBinder); } }
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"); }
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))); } }
static BytecodeNode generateWrite(BytecodeGeneratorContext context, Type returnType, Variable outputBlock) { return BytecodeUtils.generateWrite( context.getCallSiteBinder(), context.getScope(), context.getScope().getVariable("wasNull"), returnType, outputBlock); } }
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))); } }
Variable wasNull = scope.getVariable("wasNull");
Scope scope = context.getScope(); Variable wasNull = scope.getVariable("wasNull"); .add(scope.getThis(), scope.getVariable("session")) .addAll(captureVariableBuilder.build()) .build();
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Context context) { BytecodeNode inputReferenceBytecode = fieldReferenceCompiler.visitInputReference(node, context.getScope()); if (!context.getOutputBlockVariable().isPresent()) { return inputReferenceBytecode; } return new BytecodeBlock() .append(inputReferenceBytecode) .append(generateWrite( callSiteBinder, context.getScope(), context.getScope().getVariable("wasNull"), node.getType(), context.getOutputBlockVariable().get())); }
@Override public BytecodeNode visitVariableReference(VariableReferenceExpression reference, Context context) { BytecodeNode variableReferenceByteCode = fieldReferenceCompiler.visitVariableReference(reference, context.getScope()); if (!context.getOutputBlockVariable().isPresent()) { return variableReferenceByteCode; } return new BytecodeBlock() .append(variableReferenceByteCode) .append(generateWrite( callSiteBinder, context.getScope(), context.getScope().getVariable("wasNull"), reference.getType(), context.getOutputBlockVariable().get())); } }
private InputReferenceNode(CallSiteBinder callSiteBinder, Scope scope, Type type, BytecodeExpression block, BytecodeExpression position) { // Generate body based on block and position Variable wasNullVariable = scope.getVariable("wasNull"); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition(block.invoke("isNull", boolean.class, position)); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); String methodName = "get" + Primitives.wrap(javaType).getSimpleName(); ifStatement.ifFalse(constantType(callSiteBinder, type).invoke(methodName, javaType, block, position)); this.body = ifStatement; this.block = block; this.position = position; }
Variable argument = scope.getVariable("arg" + i); IfStatement ifStatement = new IfStatement() .condition(equal(argument, constantNull(stackTypes.get(i))))
block = ImmutableList.of(scope.getVariable("block")); invokeStatic(ColumnarRow.class, "toColumnarRow", ColumnarRow.class, scope.getVariable("block")))); 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))); .condition(not(scope.getVariable("groupIdsBlock").invoke("isNull", boolean.class, position))) .ifTrue(loopBody);
BytecodeBlock condition = new BytecodeBlock().append(scope.getVariable("wasNull"));
@Override public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) { int field = node.getField(); Type type = node.getType(); Variable wasNullVariable = scope.getVariable("wasNull"); Class<?> javaType = type.getJavaType(); if (!javaType.isPrimitive() && javaType != Slice.class) { javaType = Object.class; } IfStatement ifStatement = new IfStatement(); ifStatement.condition() .setDescription(format("cursor.get%s(%d)", type, field)) .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "isNull", boolean.class, int.class); ifStatement.ifTrue() .putVariable(wasNullVariable, true) .pushJavaDefault(javaType); ifStatement.ifFalse() .getVariable(cursorVariable) .push(field) .invokeInterface(RecordCursor.class, "get" + Primitives.wrap(javaType).getSimpleName(), javaType, int.class); return ifStatement; }
Variable page = scope.getVariable("page"); Variable positionVariable = scope.declareVariable(int.class, "position"); Variable rowsVariable = scope.declareVariable(int.class, "rows");
public static BytecodeBlock unboxPrimitiveIfNecessary(Scope scope, Class<?> boxedType) { BytecodeBlock block = new BytecodeBlock(); LabelNode end = new LabelNode("end"); Class<?> unboxedType = Primitives.unwrap(boxedType); Variable wasNull = scope.getVariable("wasNull"); if (unboxedType.isPrimitive()) { LabelNode notNull = new LabelNode("notNull"); block.dup(boxedType) .ifNotNullGoto(notNull) .append(wasNull.set(constantTrue())) .comment("swap boxed null with unboxed default") .pop(boxedType) .pushJavaDefault(unboxedType) .gotoLabel(end) .visitLabel(notNull) .append(unboxPrimitive(unboxedType)); } else { block.dup(boxedType) .ifNotNullGoto(end) .append(wasNull.set(constantTrue())); } block.visitLabel(end); return block; }
if (value == null) { block.comment("constant null") .append(context.getScope().getVariable("wasNull").set(constantTrue())) .pushJavaDefault(javaType); callSiteBinder, context.getScope(), context.getScope().getVariable("wasNull"), constant.getType(), context.getOutputBlockVariable().get()));
private static BytecodeBlock generateBlockNonNullPositionForLoop(Scope scope, Variable positionVariable, BytecodeBlock loopBody) { Variable rowsVariable = scope.declareVariable(int.class, "rows"); Variable blockVariable = scope.getVariable("block"); BytecodeBlock block = new BytecodeBlock() .append(blockVariable) .invokeInterface(Block.class, "getPositionCount", int.class) .putVariable(rowsVariable); IfStatement ifStatement = new IfStatement("if(!block.isNull(position))") .condition(new BytecodeBlock() .append(blockVariable) .append(positionVariable) .invokeInterface(Block.class, "isNull", boolean.class, int.class)) .ifFalse(loopBody); block.append(new ForLoop() .initialize(positionVariable.set(constantInt(0))) .condition(new BytecodeBlock() .append(positionVariable) .append(rowsVariable) .invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)) .update(new BytecodeBlock().incrementVariable(positionVariable, (byte) 1)) .body(ifStatement)); return block; }
private static FieldDefinition generateGroupedField(ClassDefinition definition, MethodDefinition constructor, MethodDefinition ensureCapacity, StateField stateField) { Class<?> bigArrayType = getBigArrayType(stateField.getType()); FieldDefinition field = definition.declareField(a(PRIVATE), UPPER_CAMEL.to(LOWER_CAMEL, stateField.getName()) + "Values", bigArrayType); // Generate getter MethodDefinition getter = definition.declareMethod(a(PUBLIC), stateField.getGetterName(), type(stateField.getType())); getter.getBody() .append(getter.getThis().getField(field).invoke( "get", stateField.getType(), getter.getThis().invoke("getGroupId", long.class)) .ret()); // Generate setter Parameter value = arg("value", stateField.getType()); MethodDefinition setter = definition.declareMethod(a(PUBLIC), stateField.getSetterName(), type(void.class), value); setter.getBody() .append(setter.getThis().getField(field).invoke( "set", void.class, setter.getThis().invoke("getGroupId", long.class), value)) .ret(); Scope ensureCapacityScope = ensureCapacity.getScope(); ensureCapacity.getBody() .append(ensureCapacity.getThis().getField(field).invoke("ensureCapacity", void.class, ensureCapacityScope.getVariable("size"))); // Initialize field in constructor constructor.getBody() .append(constructor.getThis().setField(field, newInstance(field.getType(), stateField.initialValueExpression()))); return field; }
private static void pushStackType(Scope scope, BytecodeBlock block, Type sqlType, BytecodeBlock getBlockBytecode, Class<?> parameter, CallSiteBinder callSiteBinder) Variable position = scope.getVariable("position"); if (parameter == long.class) { block.comment("%s.getLong(block, position)", sqlType.getTypeSignature())