binding.getType().returnType());
}
public static ByteCodeNode generateInvocation(CompilerContext context, FunctionInfo function, List<ByteCodeNode> arguments, Binding binding)
{
MethodType methodType = binding.getType();
Signature signature = function.getSignature();
Class<?> unboxedReturnType = Primitives.unwrap(methodType.returnType());
LabelNode end = new LabelNode("end");
Block block = new Block(context)
.setDescription("invoke " + signature);
List<Class<?>> stackTypes = new ArrayList<>();
int index = 0;
for (Class<?> type : methodType.parameterArray()) {
stackTypes.add(type);
if (type == ConnectorSession.class) {
block.getVariable("session");
}
else {
block.append(arguments.get(index));
if (!function.getNullableArguments().get(index)) {
block.append(ifWasNullPopAndGoto(context, end, unboxedReturnType, Lists.reverse(stackTypes)));
}
else {
block.append(boxPrimitiveIfNecessary(context, type));
block.putVariable("wasNull", false);
}
index++;
}
}
block.append(invoke(context, binding, function.getSignature()));
if (function.isNullable()) {
if (unboxedReturnType.isPrimitive()) {
LabelNode notNull = new LabelNode("notNull");
block.dup(methodType.returnType())
.ifNotNullGoto(notNull)
.putVariable("wasNull", true)
.comment("swap boxed null with unboxed default")
.pop(methodType.returnType())
.pushJavaDefault(unboxedReturnType)
.gotoLabel(end)
.visitLabel(notNull)
.append(unboxPrimitive(context, unboxedReturnType));
}
else {
block.dup(methodType.returnType())
.ifNotNullGoto(end)
.putVariable("wasNull", true);
}
}
block.visitLabel(end);