argNames[arity] = SCJavaDefn.EXECUTION_CONTEXT_NAME;
argTypes[arity] = JavaTypeNames.RTEXECUTION_CONTEXT;
argValues[arity] = SCJavaDefn.EXECUTION_CONTEXT_VAR;
String methodName = "f" + arity + (strict ? "S" : "L");
JavaMethod javaMethod = new JavaMethod(modifiers, JavaTypeNames.RTVALUE, argNames, argTypes, null, methodName);
javaClassRep.addMethod(javaMethod);
// Add the throws declaration
javaMethod.addThrows(JavaTypeName.CAL_EXECUTOR_EXCEPTION);
// At this point we want to switch based on the scTag and dispatch to the appropriate
// sc specific f method.
SwitchStatement switchStatement =
new SwitchStatement(new JavaField.Instance(null, SCDefinitionBuilder.functionTagFieldName, JavaTypeName.INT));
for (int i = 0, n = javaDefns.size(); i < n; ++i) {
SCJavaDefn javaDefn = javaDefns.get(i);
if (javaDefn.getArity() != arity) {
continue;
}
if (functions.getMachineFunction(javaDefn.getFunctionName()) instanceof LECCLiftedLetVarMachineFunction) {
continue;
}
if (strict &&
javaDefn.hasStrictUnboxableArguments()) {
continue;
}
methodName = functions.getFNamePrefix(javaDefn.getFunctionName()) + "f" + arity + (strict ? "S" : "L");
MethodInvocation mi =
new MethodInvocation.Instance(
null,
methodName,
argValues,
argTypes,
JavaTypeNames.RTVALUE,
MethodInvocation.InvocationType.VIRTUAL);
switchStatement.addCase(
new SwitchStatement.IntCaseGroup(functions.getFunctionIndex(javaDefn.getFunctionName()), new ReturnStatement(mi)));
}
javaMethod.addStatement(switchStatement);
// Handle the fallthrough.
// If this is the lazy version of the 'f' method we want to defer to the
// version in the superclass (i.e. RTValue). This can occur when there
// is a lazy application of a functional argument, or an oversaturation.
if (strict) {
MethodInvocation mi =
new MethodInvocation.Static (JavaTypeNames.RTVALUE,
"badValue",
LiteralWrapper.make("Bad scTag in 'f'."),
JavaTypeName.STRING,
JavaTypeNames.RTVALUE);
javaMethod.addStatement(new ReturnStatement(mi));
} else {
MethodInvocation mi =
new MethodInvocation.Instance(
null,
"f" + arity + "L",
this.javaClassRep.getSuperclassName(),
argValues,
argTypes,
JavaTypeNames.RTVALUE,
MethodInvocation.InvocationType.SPECIAL);
javaMethod.addStatement(new JavaStatement.LineComment("This is an oversaturated lazy application."));
javaMethod.addStatement(new JavaStatement.LineComment("Usually this occurs when dealing with a lazy application of a function type argument."));
javaMethod.addStatement(new JavaStatement.LineComment("Defer to the base implementation in the super class."));
javaMethod.addStatement(new ReturnStatement(mi));
}
}