use of com.facebook.presto.bytecode.BytecodeBlock in project presto by prestodb.
the class ForLoop method accept.
@Override
public void accept(MethodVisitor visitor, MethodGenerationContext generationContext) {
checkState(!condition.isEmpty(), "ForLoop does not have a condition set");
BytecodeBlock block = new BytecodeBlock();
block.append(new BytecodeBlock().setDescription("initialize").append(initialize));
block.visitLabel(beginLabel).append(new BytecodeBlock().setDescription("condition").append(condition)).ifFalseGoto(endLabel);
block.append(new BytecodeBlock().setDescription("body").append(body));
block.visitLabel(continueLabel).append(new BytecodeBlock().setDescription("update").append(update)).gotoLabel(beginLabel).visitLabel(endLabel);
block.accept(visitor, generationContext);
}
use of com.facebook.presto.bytecode.BytecodeBlock in project presto by prestodb.
the class CastBytecodeExpression method generateBytecode.
private static BytecodeBlock generateBytecode(ParameterizedType sourceType, ParameterizedType targetType) {
BytecodeBlock block = new BytecodeBlock();
switch(getTypeKind(sourceType)) {
case PRIMITIVE:
switch(getTypeKind(targetType)) {
case PRIMITIVE:
castPrimitiveToPrimitive(block, sourceType.getPrimitiveType(), targetType.getPrimitiveType());
return block;
case BOXED_PRIMITVE:
checkArgument(sourceType.getPrimitiveType() == unwrapPrimitiveType(targetType), "Type %s can not be cast to %s", sourceType, targetType);
return block.invokeStatic(targetType, "valueOf", targetType, sourceType);
case OTHER:
checkArgument(OBJECT_TYPE.equals(targetType), "Type %s can not be cast to %s", sourceType, targetType);
Class<?> sourceClass = sourceType.getPrimitiveType();
return block.invokeStatic(wrap(sourceClass), "valueOf", wrap(sourceClass), sourceClass).checkCast(targetType);
}
case BOXED_PRIMITVE:
switch(getTypeKind(targetType)) {
case PRIMITIVE:
checkArgument(unwrapPrimitiveType(sourceType) == targetType.getPrimitiveType(), "Type %s can not be cast to %s", sourceType, targetType);
return block.invokeVirtual(sourceType, targetType.getPrimitiveType().getSimpleName() + "Value", targetType);
case BOXED_PRIMITVE:
checkArgument(sourceType.equals(targetType), "Type %s can not be cast to %s", sourceType, targetType);
return block;
case OTHER:
return block.checkCast(targetType);
}
case OTHER:
switch(getTypeKind(targetType)) {
case PRIMITIVE:
checkArgument(OBJECT_TYPE.equals(sourceType), "Type %s can not be cast to %s", sourceType, targetType);
return block.checkCast(wrap(targetType.getPrimitiveType())).invokeVirtual(wrap(targetType.getPrimitiveType()), targetType.getPrimitiveType().getSimpleName() + "Value", targetType.getPrimitiveType());
case BOXED_PRIMITVE:
case OTHER:
return block.checkCast(targetType);
}
}
throw new UnsupportedOperationException("unexpected enum value");
}
use of com.facebook.presto.bytecode.BytecodeBlock in project presto by prestodb.
the class IfCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext context, Type returnType, List<RowExpression> arguments) {
Preconditions.checkArgument(arguments.size() == 3);
Variable wasNull = context.wasNull();
BytecodeBlock condition = new BytecodeBlock().append(context.generate(arguments.get(0))).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()));
return new IfStatement().condition(condition).ifTrue(context.generate(arguments.get(1))).ifFalse(context.generate(arguments.get(2)));
}
use of com.facebook.presto.bytecode.BytecodeBlock in project presto by prestodb.
the class InCodeGenerator method buildInCase.
private static BytecodeBlock buildInCase(BytecodeGeneratorContext generatorContext, Scope scope, Type type, LabelNode caseLabel, LabelNode matchLabel, LabelNode noMatchLabel, Collection<BytecodeNode> testValues, boolean checkForNulls) {
// caseWasNull is set to true the first time a null in `testValues` is encountered
Variable caseWasNull = null;
if (checkForNulls) {
caseWasNull = scope.createTempVariable(boolean.class);
}
BytecodeBlock caseBlock = new BytecodeBlock().visitLabel(caseLabel);
if (checkForNulls) {
caseBlock.putVariable(caseWasNull, false);
}
LabelNode elseLabel = new LabelNode("else");
BytecodeBlock elseBlock = new BytecodeBlock().visitLabel(elseLabel);
Variable wasNull = generatorContext.wasNull();
if (checkForNulls) {
elseBlock.append(wasNull.set(caseWasNull));
}
elseBlock.gotoLabel(noMatchLabel);
ScalarFunctionImplementation operator = generatorContext.getRegistry().getScalarFunctionImplementation(internalOperator(EQUAL, BOOLEAN, ImmutableList.of(type, type)));
Binding equalsFunction = generatorContext.getCallSiteBinder().bind(operator.getMethodHandle());
BytecodeNode elseNode = elseBlock;
for (BytecodeNode testNode : testValues) {
LabelNode testLabel = new LabelNode("test");
IfStatement test = new IfStatement();
test.condition().visitLabel(testLabel).dup(type.getJavaType()).append(testNode);
if (checkForNulls) {
IfStatement wasNullCheck = new IfStatement("if wasNull, set caseWasNull to true, clear wasNull, pop 2 values of type, and goto next test value");
wasNullCheck.condition(wasNull);
wasNullCheck.ifTrue(new BytecodeBlock().append(caseWasNull.set(constantTrue())).append(wasNull.set(constantFalse())).pop(type.getJavaType()).pop(type.getJavaType()).gotoLabel(elseLabel));
test.condition().append(wasNullCheck);
}
test.condition().append(invoke(equalsFunction, EQUAL.name()));
test.ifTrue().gotoLabel(matchLabel);
test.ifFalse(elseNode);
elseNode = test;
elseLabel = testLabel;
}
caseBlock.append(elseNode);
return caseBlock;
}
use of com.facebook.presto.bytecode.BytecodeBlock in project presto by prestodb.
the class BytecodeExpressionVisitor method visitConstant.
@Override
public BytecodeNode visitConstant(ConstantExpression constant, Scope scope) {
Object value = constant.getValue();
Class<?> javaType = constant.getType().getJavaType();
BytecodeBlock block = new BytecodeBlock();
if (value == null) {
return block.comment("constant null").append(scope.getVariable("wasNull").set(constantTrue())).pushJavaDefault(javaType);
}
// use LDC for primitives (boolean, short, int, long, float, double)
block.comment("constant " + constant.getType().getTypeSignature());
if (javaType == boolean.class) {
return block.append(loadBoolean((Boolean) value));
}
if (javaType == byte.class || javaType == short.class || javaType == int.class) {
return block.append(loadInt(((Number) value).intValue()));
}
if (javaType == long.class) {
return block.append(loadLong((Long) value));
}
if (javaType == float.class) {
return block.append(loadFloat((Float) value));
}
if (javaType == double.class) {
return block.append(loadDouble((Double) value));
}
if (javaType == String.class) {
return block.append(loadString((String) value));
}
if (javaType == void.class) {
return block;
}
// bind constant object directly into the call-site using invoke dynamic
Binding binding = callSiteBinder.bind(value, constant.getType().getJavaType());
return new BytecodeBlock().setDescription("constant " + constant.getType()).comment(constant.toString()).append(loadConstant(binding));
}
Aggregations