// Instance of this class for each supercombinator it
// represents.
for (final MachineFunction mf : functions.getTopLevelCALFunctions()) {
final int functionIndex = functions.getFunctionIndex(mf.getName());
final JavaExpression initializer;
if (functions.getNFunctions() <= 1) {
initializer = new ClassInstanceCreationExpression(
className);
} else {
initializer = new ClassInstanceCreationExpression(
className,
new JavaExpression[]{LiteralWrapper.make(Integer.valueOf(functionIndex)),
LiteralWrapper.make(Integer.valueOf(mf.getArity()))},
new JavaTypeName[]{JavaTypeName.INT,
JavaTypeName.INT});
}
final String fieldName = CALToJavaNames.getInstanceFieldName(mf.getQualifiedName(), module);
final int instanceModifiers;
if (mf.getArity() == 0) {
//for a CAF or a zero-arity function, the instance field will never be referred to directly outside the class
//so declare them private for safety sake.
instanceModifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
} else {
instanceModifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
}
final JavaFieldDeclaration instanceDeclaration =
new JavaFieldDeclaration(instanceModifiers,
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,