use of io.airlift.bytecode.Variable in project hetu-core by openlookeng.
the class LambdaBytecodeGenerator method compileLambdaProvider.
public static Class<? extends LambdaProvider> compileLambdaProvider(LambdaDefinitionExpression lambdaExpression, Metadata metadata, Class<?> lambdaInterface) {
ClassDefinition lambdaProviderClassDefinition = new ClassDefinition(a(PUBLIC, Access.FINAL), makeClassName("LambdaProvider"), type(Object.class), type(LambdaProvider.class));
FieldDefinition sessionField = lambdaProviderClassDefinition.declareField(a(PRIVATE), "session", ConnectorSession.class);
CallSiteBinder callSiteBinder = new CallSiteBinder();
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(lambdaProviderClassDefinition, callSiteBinder);
Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(lambdaProviderClassDefinition, callSiteBinder, cachedInstanceBinder, lambdaExpression, metadata);
MethodDefinition method = lambdaProviderClassDefinition.declareMethod(a(PUBLIC), "getLambda", type(Object.class), ImmutableList.of());
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
scope.declareVariable("wasNull", body, constantFalse());
scope.declareVariable("session", body, method.getThis().getField(sessionField));
RowExpressionCompiler rowExpressionCompiler = new RowExpressionCompiler(callSiteBinder, cachedInstanceBinder, variableReferenceCompiler(ImmutableMap.of()), metadata, compiledLambdaMap);
BytecodeGeneratorContext generatorContext = new BytecodeGeneratorContext(rowExpressionCompiler, scope, callSiteBinder, cachedInstanceBinder, metadata.getFunctionAndTypeManager());
body.append(generateLambda(generatorContext, ImmutableList.of(), compiledLambdaMap.get(lambdaExpression), lambdaInterface)).retObject();
// constructor
Parameter sessionParameter = arg("session", ConnectorSession.class);
MethodDefinition constructorDefinition = lambdaProviderClassDefinition.declareConstructor(a(PUBLIC), sessionParameter);
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable constructorThisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(constructorThisVariable).invokeConstructor(Object.class).append(constructorThisVariable.setField(sessionField, sessionParameter));
cachedInstanceBinder.generateInitializations(constructorThisVariable, constructorBody);
constructorBody.ret();
return defineClass(lambdaProviderClassDefinition, LambdaProvider.class, callSiteBinder.getBindings(), AccumulatorCompiler.class.getClassLoader());
}
use of io.airlift.bytecode.Variable in project hetu-core by openlookeng.
the class LambdaBytecodeGenerator method generateLambda.
public static BytecodeNode generateLambda(BytecodeGeneratorContext context, List<RowExpression> captureExpressions, CompiledLambda compiledLambda, Class<?> lambdaInterface) {
if (!lambdaInterface.isAnnotationPresent(FunctionalInterface.class)) {
// lambdaInterface is checked to be annotated with FunctionalInterface when generating ScalarFunctionImplementation
throw new VerifyException("lambda should be generated as class annotated with FunctionalInterface");
}
BytecodeBlock block = new BytecodeBlock().setDescription("Partial apply");
Scope scope = context.getScope();
Variable wasNull = scope.getVariable("wasNull");
// generate values to be captured
ImmutableList.Builder<BytecodeExpression> captureVariableBuilder = ImmutableList.builder();
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));
block.putVariable(valueVariable);
block.append(wasNull.set(constantFalse()));
captureVariableBuilder.add(valueVariable);
}
List<BytecodeExpression> captureVariables = ImmutableList.<BytecodeExpression>builder().add(scope.getThis(), scope.getVariable("session")).addAll(captureVariableBuilder.build()).build();
Type instantiatedMethodAsmType = getMethodType(compiledLambda.getReturnType().getAsmType(), compiledLambda.getParameterTypes().stream().skip(// skip capture variables and ConnectorSession
captureExpressions.size() + 1).map(ParameterizedType::getAsmType).collect(toImmutableList()).toArray(new Type[0]));
block.append(invokeDynamic(LAMBDA_CAPTURE_METHOD, ImmutableList.of(getType(getSingleApplyMethod(lambdaInterface)), compiledLambda.getLambdaAsmHandle(), instantiatedMethodAsmType), "apply", type(lambdaInterface), captureVariables));
return block;
}
use of io.airlift.bytecode.Variable in project hetu-core by openlookeng.
the class LambdaBytecodeGenerator method defineLambdaMethod.
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);
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());
}
use of io.airlift.bytecode.Variable in project hetu-core by openlookeng.
the class CursorProcessorCompiler method generateMethods.
@Override
public void generateMethods(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, RowExpression filter, List<RowExpression> projections) {
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder);
generateProcessMethod(classDefinition, projections.size());
Map<LambdaDefinitionExpression, CompiledLambda> filterCompiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, filter, "filter");
generateFilterMethod(classDefinition, callSiteBinder, cachedInstanceBinder, filterCompiledLambdaMap, filter);
for (int i = 0; i < projections.size(); i++) {
String methodName = "project_" + i;
Map<LambdaDefinitionExpression, CompiledLambda> projectCompiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, projections.get(i), methodName);
generateProjectMethod(classDefinition, callSiteBinder, cachedInstanceBinder, projectCompiledLambdaMap, methodName, projections.get(i));
}
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC));
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
constructorBody.ret();
}
use of io.airlift.bytecode.Variable in project hetu-core by openlookeng.
the class CursorProcessorCompiler method fieldReferenceCompiler.
private static RowExpressionVisitor<BytecodeNode, Scope> fieldReferenceCompiler(Variable cursorVariable) {
return new RowExpressionVisitor<BytecodeNode, Scope>() {
@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(String.format(Locale.ROOT, "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;
}
@Override
public BytecodeNode visitCall(CallExpression call, Scope scope) {
throw new UnsupportedOperationException("not yet implemented");
}
@Override
public BytecodeNode visitSpecialForm(SpecialForm specialForm, Scope context) {
throw new UnsupportedOperationException("not yet implemented");
}
@Override
public BytecodeNode visitConstant(ConstantExpression literal, Scope scope) {
throw new UnsupportedOperationException("not yet implemented");
}
@Override
public BytecodeNode visitLambda(LambdaDefinitionExpression lambda, Scope context) {
throw new UnsupportedOperationException();
}
@Override
public BytecodeNode visitVariableReference(VariableReferenceExpression reference, Scope context) {
throw new UnsupportedOperationException();
}
};
}
Aggregations