Parameter parameter = parameterAndType.getParameter(); Class<?> type = parameterAndType.getType(); return new BytecodeBlock() .append(parameter) .append(unboxPrimitiveIfNecessary(context, type));
public BytecodeNode produceBlockAndPosition() { BytecodeBlock blockAndPosition = new BytecodeBlock(); blockAndPosition.append(block); blockAndPosition.append(position); return blockAndPosition; } }
public static BytecodeNode boxPrimitive(Class<?> type) { BytecodeBlock block = new BytecodeBlock().comment("box primitive"); if (type == long.class) { return block.invokeStatic(Long.class, "valueOf", Long.class, long.class); } if (type == double.class) { return block.invokeStatic(Double.class, "valueOf", Double.class, double.class); } if (type == boolean.class) { return block.invokeStatic(Boolean.class, "valueOf", Boolean.class, boolean.class); } if (type.isPrimitive()) { throw new UnsupportedOperationException("not yet implemented: " + type); } return NOP; }
public static BytecodeNode unboxPrimitive(Class<?> unboxedType) { BytecodeBlock block = new BytecodeBlock().comment("unbox primitive"); if (unboxedType == long.class) { return block.invokeVirtual(Long.class, "longValue", long.class); } if (unboxedType == double.class) { return block.invokeVirtual(Double.class, "doubleValue", double.class); } if (unboxedType == boolean.class) { return block.invokeVirtual(Boolean.class, "booleanValue", boolean.class); } throw new UnsupportedOperationException("not yet implemented: " + unboxedType); }
@Override public BytecodeNode visitVariableReference(VariableReferenceExpression reference, Scope context) { ParameterAndType parameterAndType = parameterMap.get(reference.getName()); Parameter parameter = parameterAndType.getParameter(); Class<?> type = parameterAndType.getType(); return new BytecodeBlock() .append(parameter) .append(unboxPrimitiveIfNecessary(context, type)); } };
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext context, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) { Preconditions.checkArgument(arguments.size() == 3); Variable wasNull = context.wasNull(); BytecodeBlock condition = new BytecodeBlock() .append(context.generate(arguments.get(0), Optional.empty())) .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())); BytecodeBlock block = new BytecodeBlock() .append(new IfStatement() .condition(condition) .ifTrue(context.generate(arguments.get(1), Optional.empty())) .ifFalse(context.generate(arguments.get(2), Optional.empty()))); outputBlockVariable.ifPresent(output -> block.append(generateWrite(context, returnType, output))); return block; } }
@Override public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) { RowExpression argument = arguments.get(0); Signature function = generatorContext .getRegistry() .getCoercion(argument.getType(), returnType); BytecodeBlock block = new BytecodeBlock() .append(generatorContext.generateCall( function.getName(), generatorContext.getRegistry().getScalarFunctionImplementation(function), ImmutableList.of(generatorContext.generate(argument, Optional.empty())))); outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output))); return block; } }
return NOP; BytecodeBlock notNull = new BytecodeBlock().comment("box primitive"); Class<?> expectedCurrentStackType; if (type == Long.class) { BytecodeBlock condition = new BytecodeBlock().append(scope.getVariable("wasNull")); BytecodeBlock wasNull = new BytecodeBlock() .pop(expectedCurrentStackType) .pushNull()
@Override public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) { Preconditions.checkArgument(arguments.size() == 1); RowExpression argument = arguments.get(0); if (argument.getType().equals(UNKNOWN)) { return loadBoolean(true); } BytecodeNode value = generatorContext.generate(argument, Optional.empty()); // evaluate the expression, pop the produced value, and load the null flag Variable wasNull = generatorContext.wasNull(); BytecodeBlock block = new BytecodeBlock() .comment("is null") .append(value) .pop(argument.getType().getJavaType()) .append(wasNull); // clear the null flag block.append(wasNull.set(constantFalse())); outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output))); return block; } }
@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())); } }
@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())); }
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; }
BytecodeNode nullValue = new BytecodeBlock() .append(wasNull.set(constantTrue())) .pushJavaDefault(returnType.getJavaType()); BytecodeBlock block = new BytecodeBlock() .append(nullValue); outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
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)
SortOrder sortOrder = sortOrders.get(i); BytecodeBlock block = new BytecodeBlock() .setDescription("compare channel " + sortChannel + " " + sortOrder);
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; }
@Override public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext context, Type rowType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) BytecodeBlock block = new BytecodeBlock().setDescription("Constructor for " + rowType.toString()); CallSiteBinder binder = context.getCallSiteBinder(); Scope scope = context.getScope();
private void generateOutputMethod(ClassDefinition definition, CallSiteBinder binder, Type valueType, Class<?> stateClass) { Parameter state = arg("state", stateClass); Parameter out = arg("out", BlockBuilder.class); MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "output", type(void.class), state, out); IfStatement ifStatement = new IfStatement() .condition(or(state.invoke("isFirstNull", boolean.class), state.invoke("isSecondNull", boolean.class))) .ifTrue(new BytecodeBlock().append(out.invoke("appendNull", BlockBuilder.class)).pop()); SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType); BytecodeExpression getValueExpression; if (valueType.getJavaType().isPrimitive()) { getValueExpression = state.invoke("getSecond", valueType.getJavaType()); } else { getValueExpression = valueSqlType.getValue(state.invoke("getSecondBlock", Block.class), state.invoke("getSecondPosition", int.class)); } ifStatement.ifFalse(valueSqlType.writeValue(out, getValueExpression)); method.getBody().append(ifStatement).ret(); } }
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(); }
SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType); BytecodeBlock ifBlock = new BytecodeBlock() .append(state.invoke("setFirst", void.class, keySqlType.getValue(key, position))) .append(state.invoke("setFirstNull", void.class, constantBoolean(false))) setValueNode = new BytecodeBlock() .append(state.invoke("setSecondBlock", void.class, value)) .append(state.invoke("setSecondPosition", void.class, position));