className,
fieldName,
initializer);
if (functions.getNFunctions() <= 1) {
instanceDeclaration.setJavaDoc(new JavaDocComment("Singleton instance of this class."));
} else {
instanceDeclaration.setJavaDoc(new JavaDocComment("Instance of this class representing CAL function " + mf.getName() + "."));
}
javaClassRep.addFieldDeclaration(instanceDeclaration);
}
if (sharedValues.getNStaticErrorInfo() > 0) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("ErrorInfo instances."));
}
for (final String name : sharedValues.getStaticErrorInfoNames()) {
final JavaExpression initializer = sharedValues.getStaticError(name);
final int instanceModifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
final JavaFieldDeclaration errorDeclaration = new JavaFieldDeclaration(instanceModifiers, JavaTypeName.ERRORINFO, name, initializer);
javaClassRep.addFieldDeclaration(errorDeclaration);
}
// If this function references other supercombinators we need to set
// up a field for each referenced SC, a flag to indicate the
// initialization state of the referenced SC fields, and potentially an
// object to be used as a synchronization mutex for the initialization method.
final int referencedDCModifiers = Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL;
// Create an instance field for each referenced data constructor. This will give us
// a local reference that can be used in the body function.
// e.g. RTFunction i_Foo;
if (sharedValues.getNReferencedDCs() > 0) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("Data constructor class instances for all referenced data constructors."));
}
for (final ReferencedDCInfo rfi : sharedValues.getReferencedDCs()) {
DataConstructor dc = rfi.getDC();
JavaField jf = rfi.getJField();
JavaExpression fieldInitializer;
if (dc.getArity() > 0) {
// Just invoke the regular make invocation to get the singleton SC/DC instance.
fieldInitializer =
new MethodInvocation.Static(jf.getFieldType(), "make", JavaExpression.EMPTY_JAVA_EXPRESSION_ARRAY, JavaExpression.EMPTY_TYPE_NAME_ARRAY, jf.getFieldType());
} else {
// This is a zero arity data constructor. We get the singleton instance by accessing
// the DataType class factory method if the data type has more than one zero arity DC.
TypeConstructor typeCons = dc.getTypeConstructor();
if (SCJavaDefn.isTagDC(dc, module)) {
JavaTypeName typeClass = CALToJavaNames.createTypeNameFromType(typeCons, module);
JavaTypeName tagDCTypeName = CALToJavaNames.createTypeNameForTagDCFromType(typeCons, module);
Integer ordinal = Integer.valueOf(dc.getOrdinal());
fieldInitializer = new MethodInvocation.Static(typeClass, "getTagDC", LiteralWrapper.make(ordinal), JavaTypeName.INT, tagDCTypeName);
} else {
// Just invoke the regular make invocation to get the singleton SC/DC instance.
fieldInitializer =
new MethodInvocation.Static(jf.getFieldType(), "make", JavaExpression.EMPTY_JAVA_EXPRESSION_ARRAY, JavaExpression.EMPTY_TYPE_NAME_ARRAY, jf.getFieldType());
}
}
JavaFieldDeclaration dcDeclaration =
new JavaFieldDeclaration(
referencedDCModifiers,
jf.getFieldType(),
jf.getFieldName(),
fieldInitializer);
javaClassRep.addFieldDeclaration(dcDeclaration);
}
if (functions.includesCAFs()) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("Mappings of execution context to CAF instances."));
// Add an instance field to hold a Map of
// ExecutionContext -> RTFullApp.General._0
// A map for associating instances of this SC with execution contexts.
// This is only created for CAF functions. There are two reasons why CAFs
// have an instance for each execution context. One is thread safety. The
// other is so that different threads of execution can release cached CAF
// results at will.
for (final MachineFunction mf : functions.getTopLevelCALFunctions()) {
if (mf.isCAF()) {
//we do not synchronize the instance map, but rather the methods in the CAF class that mutate it.
//this is because the make method has check-then-modify semantics, and so needs to be synchronized at the method
//level anyways.
JavaExpression instancesMapInit = new ClassInstanceCreationExpression(JavaTypeName.WEAK_HASH_MAP);
String mapPrefix = functions.getFNamePrefix(mf.getName());
JavaFieldDeclaration instancesMap =
new JavaFieldDeclaration (
Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL,
JavaTypeName.MAP,
mapPrefix + "$instancesMap",
instancesMapInit);
instancesMap.setJavaDoc(new JavaDocComment("Execution context -> instance map for " + mf.getName()));
javaClassRep.addFieldDeclaration(instancesMap);
}
}
}