}
// If the expression is a primitive op compile it as an unboxed op.
//We would not want to directly call primitive operators when doing function tracing.
//This will have the effect of ensuring that they get traced when called.
BasicOpTuple bot;
if (LECCMachineConfiguration.generateDirectPrimOpCalls() &&
(bot = BasicOpTuple.isBasicOp(e)) != null) {
// We need to be sure that the primitiveness of the operation/foreign function and the
// desired unbox type match. For example an operation that produces an int can either unbox to
// an int or an Object.
if (bot.getPrimitiveOp() == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
// We know that this is an unboxed argument to a CAL function.
// The unboxed value cannot be void. If we are calling a foreign
// function with return type of void we can't do a direct call. We
// need to call the CAL wrapper function which will return the CAL
// equivalent to void. i.e. Unit
ForeignFunctionInfo ffi = bot.getForeignFunctionInfo();
Class<?> foreignReturnType = SCJavaDefn.getJavaReturnType(ffi);
verifyUnboxType(unboxType, JavaTypeName.make(foreignReturnType));
if(foreignReturnType.equals(void.class)) {
// This is the special case of a void foreign function. The return type needs to
// be converted to the CAL Unit type.
// Compile the expression strictly, this will result in an RTValue which can be unboxed to the int equivalent
// of the unit type.
ExpressionContextPair argResult = genS_E (e, variableContext);
return new ExpressionContextPair(SCJavaDefn.unboxValue (unboxType, argResult.getJavaExpression()), argResult.getContextBlock());
} else if (bot.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
throw new CodeGenerationException ("PRIMOP_EAGER encountered in generateUnboxedArgument.");
} else if (foreignReturnType.isPrimitive() == primitiveUnboxType){
// Using unsafeCoerce and input/output we can get CAL code that corresponds to
// treating primitives as objects and vice versa. For example the Java primitive int and
// the Java class Integer get equated.
// We need to check that the foreign type of the expression being compiled has the same
// primitiveness as the unboxed type we are trying to generate.
return generatePrimitiveOp(e, false, Scheme.E_SCHEME, variableContext);
} else {
throw new CodeGenerationException ("Primitivenes mismatch in " + getModuleName() + "." + getFunctionName() + " in generateUnboxedArgument. Expression is " + foreignReturnType.toString() + " expected type is " + unboxType);
}
} else {
if (bot.getPrimitiveOp() != PrimOps.PRIMOP_OBJECT_TO_CAL_VALUE &&
bot.getPrimitiveOp() != PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
verifyUnboxType (unboxType, PrimOp.getTypeNameForPrimOp(bot.getPrimitiveOp()));
return generatePrimitiveOp(e, false, Scheme.E_SCHEME, variableContext);
}
}
}