block.append(context.generate(captureExpression, Optional.empty())); block.append(boxPrimitiveIfNecessary(scope, valueType)); block.putVariable(valueVariable); block.append(wasNull.set(constantFalse())); captureVariableBuilder.add(valueVariable);
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; }
block.putVariable(wasNull, false); block.append(generator.generate(arguments.get(0), Optional.empty())).putVariable(rowBlock); ifRowBlockIsNull.ifTrue() .comment("if row block is null, push null to the stack and goto 'end' label (return)") .putVariable(wasNull, true) .pushJavaDefault(javaType) .gotoLabel(end); .putVariable(wasNull, true) .pushJavaDefault(javaType); .comment("otherwise call type.getTYPE(rowBlock, index)") .append(value) .putVariable(wasNull, false);
@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; }
body.append(compiler.compile(filter, scope, Optional.empty())) .putVariable(result) .append(and(not(wasNullVariable), result).ret()); return method;
private static void generateHashRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes) { Parameter position = arg("position", int.class); Parameter page = arg("blocks", Page.class); MethodDefinition hashRowMethod = classDefinition.declareMethod(a(PUBLIC), "hashRow", type(long.class), position, page); Variable resultVariable = hashRowMethod.getScope().declareVariable(long.class, "result"); hashRowMethod.getBody().push(0L).putVariable(resultVariable); for (int index = 0; index < joinChannelTypes.size(); index++) { BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index)); BytecodeExpression block = page.invoke("getBlock", Block.class, constantInt(index)); hashRowMethod .getBody() .getVariable(resultVariable) .push(31L) .append(OpCode.LMUL) .append(typeHashCode(type, block, position)) .append(OpCode.LADD) .putVariable(resultVariable); } hashRowMethod .getBody() .getVariable(resultVariable) .retLong(); }
.putVariable(result) .append(new IfStatement() .condition(wasNullVariable)
.invokeVirtual(Optional.class, "orElse", Object.class, Object.class) .checkCast(Block.class) .putVariable(masksBlock); .invokeVirtual(Integer.class, "intValue", int.class) .invokeVirtual(Page.class, "getBlock", Block.class, int.class) .putVariable(parameterVariables.get(i));
.ifFalse(new BytecodeBlock() .comment("%s.%s(output, %s)", type.getTypeSignature(), methodName, valueJavaType.getSimpleName()) .putVariable(tempValue) .append(loadConstant(callSiteBinder.bind(type, Type.class))) .getVariable(outputBlockVariable)
.append(ifWasNullPopAndGoto(scope, notMatch, void.class)) .dup(first.getType().getJavaType()) .putVariable(firstValue);
.comment("right was false; store left null flag (on stack) in wasNull variable, and push false") .visitLabel(rightIsTrue) .putVariable(wasNull) .push(false);
.comment("right was true; store left null flag (on stack) in wasNull variable, and push true") .visitLabel(rightIsTrue) .putVariable(wasNull) .push(true);
hashPositionMethod.getBody().push(0L).putVariable(resultVariable); .append(typeHashCode(type, block, blockPosition)) .append(OpCode.LADD) .putVariable(resultVariable);
private static CompiledLambda defineLambdaMethod( RowExpressionCompiler innerExpressionCompiler, ClassDefinition classDefinition, String methodName, List<Parameter> inputParameters, LambdaDefinitionExpression lambda) { checkCondition(inputParameters.size() <= 254, NOT_SUPPORTED, "Too many arguments for lambda expression"); Class<?> returnType = Primitives.wrap(lambda.getBody().getType().getJavaType()); MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), methodName, type(returnType), inputParameters); Scope scope = method.getScope(); Variable wasNull = scope.declareVariable(boolean.class, "wasNull"); BytecodeNode compiledBody = innerExpressionCompiler.compile(lambda.getBody(), scope, Optional.empty()); method.getBody() .putVariable(wasNull, false) .append(compiledBody) .append(boxPrimitiveIfNecessary(scope, returnType)) .ret(returnType); Handle lambdaAsmHandle = new Handle( Opcodes.H_INVOKEVIRTUAL, method.getThis().getType().getClassName(), method.getName(), method.getMethodDescriptor(), false); return new CompiledLambda( lambdaAsmHandle, method.getReturnType(), method.getParameterTypes()); }
private void generateProjectMethod( ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, String methodName, RowExpression projection) { Parameter session = arg("session", ConnectorSession.class); Parameter cursor = arg("cursor", RecordCursor.class); Parameter output = arg("output", BlockBuilder.class); MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), methodName, type(void.class), session, cursor, output); method.comment("Projection: %s", projection.toString()); Scope scope = method.getScope(); Variable wasNullVariable = scope.declareVariable(type(boolean.class), "wasNull"); RowExpressionCompiler compiler = new RowExpressionCompiler( callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cursor), metadata.getFunctionRegistry(), compiledLambdaMap); method.getBody() .comment("boolean wasNull = false;") .putVariable(wasNullVariable, false) .comment("evaluate projection: " + projection.toString()) .append(compiler.compile(projection, scope, Optional.of(output))) .ret(); }
caseBlock.putVariable(caseWasNull, false); elseBlock.append(new BytecodeBlock() .append(generatorContext.generateCall(isIndeterminateSignature.getName(), isIndeterminateFunction, ImmutableList.of(value))) .putVariable(wasNull));
block.append(context.wasNull().set(constantFalse())); block.append(context.generate(arguments.get(i), Optional.empty())); block.putVariable(field); block.append(new IfStatement() .condition(context.wasNull())
method.getBody() .comment("boolean wasNull = false;") .putVariable(wasNullVariable, false) .comment("evaluate filter: " + filter) .append(compiler.compile(filter, scope, Optional.empty()))
.putVariable(completedPositionsVariable, 0) .comment("boolean finished = false;") .putVariable(finishedVariable, false); .condition(cursor.invoke("advanceNextPosition", boolean.class)) .ifFalse(new BytecodeBlock() .putVariable(finishedVariable, true) .gotoLabel(done))) .comment("do the projection")
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; }