implements PR-05.2
This commit is contained in:
parent
541ada32a1
commit
9c294774db
@ -183,14 +183,18 @@ public final class PbsFrontendCompiler {
|
||||
final NameTable nameTable,
|
||||
final DiagnosticSink diagnostics) {
|
||||
final var normalizedModuleKey = moduleKey == null ? "" : moduleKey;
|
||||
final var hostByMethodName = new HashMap<String, IRReservedMetadata.HostMethodBinding>();
|
||||
final var hostByMethodName = new HashMap<NameId, List<IRReservedMetadata.HostMethodBinding>>();
|
||||
for (final var hostBinding : reservedMetadata.hostMethodBindings()) {
|
||||
hostByMethodName.put(hostBinding.sourceMethodName(), hostBinding);
|
||||
hostByMethodName
|
||||
.computeIfAbsent(nameTable.register(hostBinding.sourceMethodName()), ignored -> new ArrayList<>())
|
||||
.add(hostBinding);
|
||||
}
|
||||
final var intrinsicByMethodName = new HashMap<String, IRReservedMetadata.IntrinsicSurface>();
|
||||
final var intrinsicByMethodName = new HashMap<NameId, List<IRReservedMetadata.IntrinsicSurface>>();
|
||||
for (final var builtinType : reservedMetadata.builtinTypeSurfaces()) {
|
||||
for (final var intrinsicSurface : builtinType.intrinsics()) {
|
||||
intrinsicByMethodName.put(intrinsicSurface.sourceMethodName(), intrinsicSurface);
|
||||
intrinsicByMethodName
|
||||
.computeIfAbsent(nameTable.register(intrinsicSurface.sourceMethodName()), ignored -> new ArrayList<>())
|
||||
.add(intrinsicSurface);
|
||||
}
|
||||
}
|
||||
final var callableIdTable = new CallableTable();
|
||||
@ -591,13 +595,41 @@ public final class PbsFrontendCompiler {
|
||||
private void lowerCallsite(
|
||||
final PbsAst.CallExpr callExpr,
|
||||
final ExecutableLoweringContext context) {
|
||||
final var calleeName = extractSimpleCalleeName(callExpr.callee());
|
||||
if (calleeName == null || calleeName.isBlank()) {
|
||||
final var calleeIdentity = resolveCalleeIdentity(callExpr.callee(), context.nameTable());
|
||||
if (calleeIdentity == null) {
|
||||
reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
final var host = context.hostByMethodName().get(calleeName);
|
||||
if (host != null) {
|
||||
final var callableCandidates = context.callableIdsByNameAndArity().get(
|
||||
new CallableResolutionKey(calleeIdentity.nameId(), callExpr.arguments().size()));
|
||||
final var hostCandidates = context.hostByMethodName().getOrDefault(calleeIdentity.nameId(), List.of());
|
||||
final var intrinsicCandidates = context.intrinsicByMethodName().getOrDefault(calleeIdentity.nameId(), List.of());
|
||||
|
||||
var categoryCount = 0;
|
||||
if (callableCandidates != null && !callableCandidates.isEmpty()) {
|
||||
categoryCount++;
|
||||
}
|
||||
if (!hostCandidates.isEmpty()) {
|
||||
categoryCount++;
|
||||
}
|
||||
if (!intrinsicCandidates.isEmpty()) {
|
||||
categoryCount++;
|
||||
}
|
||||
if (categoryCount == 0) {
|
||||
reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
if (categoryCount > 1) {
|
||||
reportUnsupportedLowering("executable lowering found ambiguous callsite category", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hostCandidates.isEmpty()) {
|
||||
if (hostCandidates.size() > 1) {
|
||||
reportUnsupportedLowering("executable lowering found ambiguous host binding identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
final var host = hostCandidates.getFirst();
|
||||
context.instructions().add(new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.CALL_HOST,
|
||||
"",
|
||||
@ -613,8 +645,12 @@ public final class PbsFrontendCompiler {
|
||||
return;
|
||||
}
|
||||
|
||||
final var intrinsic = context.intrinsicByMethodName().get(calleeName);
|
||||
if (intrinsic != null) {
|
||||
if (!intrinsicCandidates.isEmpty()) {
|
||||
if (intrinsicCandidates.size() > 1) {
|
||||
reportUnsupportedLowering("executable lowering found ambiguous intrinsic identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
final var intrinsic = intrinsicCandidates.getFirst();
|
||||
context.instructions().add(new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.CALL_INTRINSIC,
|
||||
"",
|
||||
@ -628,21 +664,19 @@ public final class PbsFrontendCompiler {
|
||||
return;
|
||||
}
|
||||
|
||||
final var candidateCallableIds = context.callableIdsByNameAndArity().get(
|
||||
new CallableResolutionKey(context.nameTable().register(calleeName), callExpr.arguments().size()));
|
||||
if (candidateCallableIds == null || candidateCallableIds.isEmpty()) {
|
||||
reportUnsupportedLowering("executable lowering requires resolvable callee identity", callExpr.span(), context);
|
||||
if (callableCandidates == null || callableCandidates.isEmpty()) {
|
||||
reportUnsupportedLowering("executable lowering requires resolvable callable identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
if (candidateCallableIds.size() > 1) {
|
||||
if (callableCandidates.size() > 1) {
|
||||
reportUnsupportedLowering("executable lowering found ambiguous callable identity", callExpr.span(), context);
|
||||
return;
|
||||
}
|
||||
final var calleeCallableId = candidateCallableIds.getFirst();
|
||||
final var calleeCallableId = callableCandidates.getFirst();
|
||||
context.instructions().add(new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.CALL_FUNC,
|
||||
context.moduleKey(),
|
||||
calleeName,
|
||||
calleeIdentity.displayName(),
|
||||
calleeCallableId,
|
||||
null,
|
||||
null,
|
||||
@ -651,6 +685,21 @@ public final class PbsFrontendCompiler {
|
||||
callExpr.span()));
|
||||
}
|
||||
|
||||
private CalleeIdentity resolveCalleeIdentity(
|
||||
final PbsAst.Expression callee,
|
||||
final NameTable nameTable) {
|
||||
return switch (callee) {
|
||||
case PbsAst.IdentifierExpr identifierExpr ->
|
||||
new CalleeIdentity(nameTable.register(identifierExpr.name()), identifierExpr.name());
|
||||
case PbsAst.MemberExpr memberExpr ->
|
||||
new CalleeIdentity(nameTable.register(memberExpr.memberName()), memberExpr.memberName());
|
||||
case PbsAst.BindExpr bindExpr ->
|
||||
new CalleeIdentity(nameTable.register(bindExpr.functionName()), bindExpr.functionName());
|
||||
case PbsAst.GroupExpr groupExpr -> resolveCalleeIdentity(groupExpr.expression(), nameTable);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private void emitJump(
|
||||
final IRBackendExecutableFunction.InstructionKind jumpKind,
|
||||
final String targetLabel,
|
||||
@ -701,16 +750,6 @@ public final class PbsFrontendCompiler {
|
||||
span);
|
||||
}
|
||||
|
||||
private String extractSimpleCalleeName(final PbsAst.Expression callee) {
|
||||
return switch (callee) {
|
||||
case PbsAst.IdentifierExpr identifierExpr -> identifierExpr.name();
|
||||
case PbsAst.MemberExpr memberExpr -> memberExpr.memberName();
|
||||
case PbsAst.BindExpr bindExpr -> bindExpr.functionName();
|
||||
case PbsAst.GroupExpr groupExpr -> extractSimpleCalleeName(groupExpr.expression());
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private int analyzeMaxStackSlots(
|
||||
final ReadOnlyList<IRBackendExecutableFunction.Instruction> instructions,
|
||||
final int returnSlots) {
|
||||
@ -812,8 +851,8 @@ public final class PbsFrontendCompiler {
|
||||
private final String moduleKey;
|
||||
private final DiagnosticSink diagnostics;
|
||||
private final NameTable nameTable;
|
||||
private final Map<String, IRReservedMetadata.HostMethodBinding> hostByMethodName;
|
||||
private final Map<String, IRReservedMetadata.IntrinsicSurface> intrinsicByMethodName;
|
||||
private final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName;
|
||||
private final Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName;
|
||||
private final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity;
|
||||
private final Map<CallableId, Integer> returnSlotsByCallableId;
|
||||
private final IntrinsicTable intrinsicIdTable;
|
||||
@ -825,8 +864,8 @@ public final class PbsFrontendCompiler {
|
||||
final String moduleKey,
|
||||
final DiagnosticSink diagnostics,
|
||||
final NameTable nameTable,
|
||||
final Map<String, IRReservedMetadata.HostMethodBinding> hostByMethodName,
|
||||
final Map<String, IRReservedMetadata.IntrinsicSurface> intrinsicByMethodName,
|
||||
final Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName,
|
||||
final Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName,
|
||||
final Map<CallableResolutionKey, List<CallableId>> callableIdsByNameAndArity,
|
||||
final Map<CallableId, Integer> returnSlotsByCallableId,
|
||||
final IntrinsicTable intrinsicIdTable) {
|
||||
@ -852,11 +891,11 @@ public final class PbsFrontendCompiler {
|
||||
return nameTable;
|
||||
}
|
||||
|
||||
private Map<String, IRReservedMetadata.HostMethodBinding> hostByMethodName() {
|
||||
private Map<NameId, List<IRReservedMetadata.HostMethodBinding>> hostByMethodName() {
|
||||
return hostByMethodName;
|
||||
}
|
||||
|
||||
private Map<String, IRReservedMetadata.IntrinsicSurface> intrinsicByMethodName() {
|
||||
private Map<NameId, List<IRReservedMetadata.IntrinsicSurface>> intrinsicByMethodName() {
|
||||
return intrinsicByMethodName;
|
||||
}
|
||||
|
||||
@ -911,6 +950,11 @@ public final class PbsFrontendCompiler {
|
||||
int arity) {
|
||||
}
|
||||
|
||||
private record CalleeIdentity(
|
||||
NameId nameId,
|
||||
String displayName) {
|
||||
}
|
||||
|
||||
private static final class ExecutableLoweringAnalysisException extends RuntimeException {
|
||||
private ExecutableLoweringAnalysisException(final String message) {
|
||||
super(message);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user