in java/fury-core/src/main/java/org/apache/fury/codegen/ExpressionOptimizer.java [82:152]
public static Expression invokeGenerated(
CodegenContext ctx,
LinkedHashSet<Expression> cutPoint,
Expression groupExpressions,
String modifier,
String methodPrefix,
boolean inlineInvoke) {
LinkedHashMap<Expression, Reference> cutExprMap = new LinkedHashMap<>();
for (Expression expression : cutPoint) {
if (expression == null) {
continue;
}
Preconditions.checkArgument(
expression.type() != PRIMITIVE_VOID_TYPE, "Cut on block is not supported currently.");
String param = ctx.newName(getRawType(expression.type()));
cutExprMap.put(expression, new Reference(param, expression.type()));
}
// iterate groupExpressions dag to update cutoff point to `Reference`.
new ExpressionVisitor()
.traverseExpression(
groupExpressions,
exprSite -> {
if (cutPoint.contains((exprSite.current))) {
Reference newExpr = cutExprMap.get(exprSite.current);
if (exprSite.current != newExpr) {
exprSite.update(newExpr);
}
return false;
} else {
return true;
}
});
// copy variable names so that to avoid new variable name conflict with generated class
// instance field name.
CodegenContext codegenContext =
new CodegenContext(ctx.getPackage(), ctx.getValNames(), ctx.getImports());
for (Reference reference : cutExprMap.values()) {
Preconditions.checkArgument(codegenContext.containName(reference.name()));
}
String methodName = ctx.newName(methodPrefix);
String code = groupExpressions.genCode(codegenContext).code();
code = codegenContext.optimizeMethodCode(code);
ArrayList<Object> formalParams = new ArrayList<>();
ArrayList<Expression> actualParams = new ArrayList<>();
for (Map.Entry<Expression, Reference> entry : cutExprMap.entrySet()) {
Expression expr = entry.getKey();
Reference ref = entry.getValue();
formalParams.add(getRawType(ref.type()));
formalParams.add(ref.name());
actualParams.add(expr);
}
ctx.addMethod(
modifier, methodName, code, getRawType(groupExpressions.type()), formalParams.toArray());
if (inlineInvoke) {
return Expression.Invoke.inlineInvoke(
new Reference("this"),
methodName,
groupExpressions.type(),
false,
actualParams.toArray(new Expression[0]));
} else {
return new Expression.Invoke(
new Reference("this"),
methodName,
"",
groupExpressions.type(),
false,
false,
actualParams.toArray(new Expression[0]));
}
}