// return a boxed version of the field.
JavaExpression jf;
if (fieldStrictness[i] && SCJavaDefn.canTypeBeUnboxed(fieldTypes[i])) {
jf = new JavaField.Instance (null, javaFieldNames[i], SCJavaDefn.typeExprToTypeName(fieldTypes[i]));
jf = SCJavaDefn.boxExpression(fieldTypes[i], jf);
javaMethod.addStatement(new ReturnStatement(jf));
} else {
JavaField field = new JavaField.Instance (null, javaFieldNames[i], JavaTypeNames.RTVALUE);
jf = field;
if (!fieldStrictness[i]) {
// We have a non-strict field of type RTValue. In order to reduce space usage
// we want to update the field value to be the result of the original suspension.
// If the field value is an RTResultFunction we want to re-assign the field with
// a call to 'getValue()'.
// For example:
//public final RTValue get_head() {
// RTValue field;
// if ((field = _head) instanceof RTResultFunction) {
// return (_head = field.getValue());
// }
// return field;
//}
String localName = javaFieldNames[i]+"$";
LocalVariable localVariable = new LocalVariable(localName, JavaTypeNames.RTVALUE);
LocalVariableDeclaration localDeclaration = new LocalVariableDeclaration(localVariable);
javaMethod.addStatement(localDeclaration);
Assignment localAssignment = new Assignment(localVariable, field);
InstanceOf checkType = new InstanceOf(localAssignment, JavaTypeNames.RTRESULT_FUNCTION);
MethodInvocation getValue = new MethodInvocation.Instance(localVariable, "getValue", JavaTypeNames.RTVALUE, MethodInvocation.InvocationType.VIRTUAL);
Assignment fieldAssignment = new Assignment(field, getValue);
ReturnStatement returnNewVal = new ReturnStatement(fieldAssignment);
IfThenElseStatement ifThen = new IfThenElseStatement(checkType, returnNewVal);
javaMethod.addStatement(ifThen);
javaMethod.addStatement(new ReturnStatement (localVariable));
} else {
// The field is strict and therefore already in WHNF.
javaMethod.addStatement(new ReturnStatement(jf));
}
}
// If the field type is primitive and strict we want to generate
// a method that retrieves the field as an unboxed value.
if (SCJavaDefn.canTypeBeUnboxed(fieldTypes[i]) && dc.isArgStrict((i))) {
returnType = SCJavaDefn.typeExprToTypeName(fieldTypes[i]);
methodName = methodName + "_As_" + SCJavaDefn.getNameForPrimitive(returnType);
// If all the fields with this name/type combination across all DCs are strict we
// don't need an RTExecutionContext passed to the getter.
javaMethod = new JavaMethod (modifiers, returnType, methodName);
javaClassRep.addMethod(javaMethod);
// Add the throws declaration
javaMethod.addThrows(JavaTypeName.CAL_EXECUTOR_EXCEPTION);
if (fieldStrictness[i]) {
jf = new JavaField.Instance (null, javaFieldNames[i], returnType);
} else {
// This is an error. We should only get to this point if all
// instances of this field/type are strict across all DCs.
throw new CodeGenerationException ("Attempt to generate unboxed accessor on lazy field " + javaFieldNames[i] + " for DC " + dc.getName());
}
javaMethod.addStatement(new ReturnStatement(jf));
}
}