implements PR-08.2
This commit is contained in:
parent
40188b67ab
commit
0490f64870
@ -19,6 +19,7 @@ import p.studio.compiler.source.identifiers.CallableShapeId;
|
|||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
import p.studio.compiler.source.identifiers.NameId;
|
import p.studio.compiler.source.identifiers.NameId;
|
||||||
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
import p.studio.compiler.source.identifiers.TypeSurfaceId;
|
||||||
import p.studio.compiler.source.tables.CallableShapeTable;
|
import p.studio.compiler.source.tables.CallableShapeTable;
|
||||||
@ -26,6 +27,7 @@ import p.studio.compiler.source.tables.CallableSignatureRef;
|
|||||||
import p.studio.compiler.source.tables.CallableTable;
|
import p.studio.compiler.source.tables.CallableTable;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
import p.studio.compiler.source.tables.IntrinsicTable;
|
import p.studio.compiler.source.tables.IntrinsicTable;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
import p.studio.compiler.source.tables.NameTable;
|
import p.studio.compiler.source.tables.NameTable;
|
||||||
import p.studio.compiler.source.tables.TypeSurfaceTable;
|
import p.studio.compiler.source.tables.TypeSurfaceTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
@ -71,7 +73,16 @@ public final class PbsFrontendCompiler {
|
|||||||
? PbsParser.ParseMode.INTERFACE_MODULE
|
? PbsParser.ParseMode.INTERFACE_MODULE
|
||||||
: PbsParser.ParseMode.ORDINARY;
|
: PbsParser.ParseMode.ORDINARY;
|
||||||
final var ast = PbsParser.parse(tokens, fileId, diagnostics, parseMode);
|
final var ast = PbsParser.parse(tokens, fileId, diagnostics, parseMode);
|
||||||
final var irBackendFile = compileParsedFile(fileId, ast, diagnostics, sourceKind, "", hostAdmissionContext, nameTable);
|
final var irBackendFile = compileParsedFile(
|
||||||
|
fileId,
|
||||||
|
ast,
|
||||||
|
diagnostics,
|
||||||
|
sourceKind,
|
||||||
|
ModuleId.none(),
|
||||||
|
"",
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
hostAdmissionContext,
|
||||||
|
nameTable);
|
||||||
if (diagnostics.errorCount() > admissionBaseline) {
|
if (diagnostics.errorCount() > admissionBaseline) {
|
||||||
return IRBackendFile.empty(fileId);
|
return IRBackendFile.empty(fileId);
|
||||||
}
|
}
|
||||||
@ -99,7 +110,16 @@ public final class PbsFrontendCompiler {
|
|||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final SourceKind sourceKind,
|
final SourceKind sourceKind,
|
||||||
final HostAdmissionContext hostAdmissionContext) {
|
final HostAdmissionContext hostAdmissionContext) {
|
||||||
return compileParsedFile(fileId, ast, diagnostics, sourceKind, "", hostAdmissionContext, new NameTable());
|
return compileParsedFile(
|
||||||
|
fileId,
|
||||||
|
ast,
|
||||||
|
diagnostics,
|
||||||
|
sourceKind,
|
||||||
|
ModuleId.none(),
|
||||||
|
"",
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
hostAdmissionContext,
|
||||||
|
new NameTable());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRBackendFile compileParsedFile(
|
public IRBackendFile compileParsedFile(
|
||||||
@ -109,7 +129,16 @@ public final class PbsFrontendCompiler {
|
|||||||
final SourceKind sourceKind,
|
final SourceKind sourceKind,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
final HostAdmissionContext hostAdmissionContext) {
|
final HostAdmissionContext hostAdmissionContext) {
|
||||||
return compileParsedFile(fileId, ast, diagnostics, sourceKind, moduleKey, hostAdmissionContext, new NameTable());
|
return compileParsedFile(
|
||||||
|
fileId,
|
||||||
|
ast,
|
||||||
|
diagnostics,
|
||||||
|
sourceKind,
|
||||||
|
ModuleId.none(),
|
||||||
|
moduleKey,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
hostAdmissionContext,
|
||||||
|
new NameTable());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRBackendFile compileParsedFile(
|
public IRBackendFile compileParsedFile(
|
||||||
@ -117,7 +146,9 @@ public final class PbsFrontendCompiler {
|
|||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final SourceKind sourceKind,
|
final SourceKind sourceKind,
|
||||||
|
final ModuleId moduleId,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
|
final ReadOnlyList<ModuleReference> modulePool,
|
||||||
final HostAdmissionContext hostAdmissionContext,
|
final HostAdmissionContext hostAdmissionContext,
|
||||||
final NameTable nameTable) {
|
final NameTable nameTable) {
|
||||||
return compileParsedFile(
|
return compileParsedFile(
|
||||||
@ -125,7 +156,9 @@ public final class PbsFrontendCompiler {
|
|||||||
ast,
|
ast,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
sourceKind,
|
sourceKind,
|
||||||
|
moduleId,
|
||||||
moduleKey,
|
moduleKey,
|
||||||
|
modulePool,
|
||||||
hostAdmissionContext,
|
hostAdmissionContext,
|
||||||
nameTable,
|
nameTable,
|
||||||
ReadOnlyList.empty(),
|
ReadOnlyList.empty(),
|
||||||
@ -138,12 +171,16 @@ public final class PbsFrontendCompiler {
|
|||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final SourceKind sourceKind,
|
final SourceKind sourceKind,
|
||||||
|
final ModuleId moduleId,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
|
final ReadOnlyList<ModuleReference> modulePool,
|
||||||
final HostAdmissionContext hostAdmissionContext,
|
final HostAdmissionContext hostAdmissionContext,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
final ReadOnlyList<PbsAst.TopDecl> supplementalTopDecls,
|
final ReadOnlyList<PbsAst.TopDecl> supplementalTopDecls,
|
||||||
final ReadOnlyList<ImportedCallableSurface> importedCallables,
|
final ReadOnlyList<ImportedCallableSurface> importedCallables,
|
||||||
final IRReservedMetadata importedReservedMetadata) {
|
final IRReservedMetadata importedReservedMetadata) {
|
||||||
|
final var effectiveModuleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
|
final var effectiveModulePool = modulePool == null ? ReadOnlyList.<ModuleReference>empty() : modulePool;
|
||||||
final var effectiveNameTable = nameTable == null ? new NameTable() : nameTable;
|
final var effectiveNameTable = nameTable == null ? new NameTable() : nameTable;
|
||||||
final var effectiveSupplementalTopDecls = supplementalTopDecls == null
|
final var effectiveSupplementalTopDecls = supplementalTopDecls == null
|
||||||
? ReadOnlyList.<PbsAst.TopDecl>empty()
|
? ReadOnlyList.<PbsAst.TopDecl>empty()
|
||||||
@ -187,6 +224,7 @@ public final class PbsFrontendCompiler {
|
|||||||
fileId,
|
fileId,
|
||||||
ast,
|
ast,
|
||||||
effectiveSupplementalTopDecls,
|
effectiveSupplementalTopDecls,
|
||||||
|
effectiveModuleId,
|
||||||
moduleKey,
|
moduleKey,
|
||||||
effectiveReservedMetadata,
|
effectiveReservedMetadata,
|
||||||
effectiveNameTable,
|
effectiveNameTable,
|
||||||
@ -200,6 +238,7 @@ public final class PbsFrontendCompiler {
|
|||||||
functions,
|
functions,
|
||||||
executableLowering.executableFunctions(),
|
executableLowering.executableFunctions(),
|
||||||
reservedMetadata,
|
reservedMetadata,
|
||||||
|
effectiveModulePool,
|
||||||
executableLowering.callableSignatures(),
|
executableLowering.callableSignatures(),
|
||||||
executableLowering.intrinsicPool());
|
executableLowering.intrinsicPool());
|
||||||
}
|
}
|
||||||
@ -221,12 +260,14 @@ public final class PbsFrontendCompiler {
|
|||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final PbsAst.File ast,
|
final PbsAst.File ast,
|
||||||
final ReadOnlyList<PbsAst.TopDecl> supplementalTopDecls,
|
final ReadOnlyList<PbsAst.TopDecl> supplementalTopDecls,
|
||||||
|
final ModuleId moduleId,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
final IRReservedMetadata reservedMetadata,
|
final IRReservedMetadata reservedMetadata,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final ReadOnlyList<ImportedCallableSurface> importedCallables) {
|
final ReadOnlyList<ImportedCallableSurface> importedCallables) {
|
||||||
final var normalizedModuleKey = moduleKey == null ? "" : moduleKey;
|
final var normalizedModuleKey = moduleKey == null ? "" : moduleKey;
|
||||||
|
final var normalizedModuleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
final var hostByMethodName = new HashMap<NameId, List<IRReservedMetadata.HostMethodBinding>>();
|
final var hostByMethodName = new HashMap<NameId, List<IRReservedMetadata.HostMethodBinding>>();
|
||||||
for (final var hostBinding : reservedMetadata.hostMethodBindings()) {
|
for (final var hostBinding : reservedMetadata.hostMethodBindings()) {
|
||||||
hostByMethodName
|
hostByMethodName
|
||||||
@ -318,6 +359,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final var declaredFn = declaredCallable.functionDecl();
|
final var declaredFn = declaredCallable.functionDecl();
|
||||||
final var callableShapeId = callableShapeId(declaredFn, typeSurfaceTable, callableShapeTable);
|
final var callableShapeId = callableShapeId(declaredFn, typeSurfaceTable, callableShapeTable);
|
||||||
final var callableId = callableIdTable.register(
|
final var callableId = callableIdTable.register(
|
||||||
|
normalizedModuleId,
|
||||||
normalizedModuleKey,
|
normalizedModuleKey,
|
||||||
declaredCallable.callableName(),
|
declaredCallable.callableName(),
|
||||||
declaredFn.parameters().size(),
|
declaredFn.parameters().size(),
|
||||||
@ -333,6 +375,7 @@ public final class PbsFrontendCompiler {
|
|||||||
}
|
}
|
||||||
for (final var importedCallable : importedCallables) {
|
for (final var importedCallable : importedCallables) {
|
||||||
final var callableId = callableIdTable.register(
|
final var callableId = callableIdTable.register(
|
||||||
|
importedCallable.moduleId(),
|
||||||
importedCallable.moduleKey(),
|
importedCallable.moduleKey(),
|
||||||
importedCallable.callableName(),
|
importedCallable.callableName(),
|
||||||
importedCallable.arity(),
|
importedCallable.arity(),
|
||||||
@ -359,6 +402,7 @@ public final class PbsFrontendCompiler {
|
|||||||
localSlotByNameId.put(nameTable.register(fn.parameters().get(paramIndex).name()), paramIndex);
|
localSlotByNameId.put(nameTable.register(fn.parameters().get(paramIndex).name()), paramIndex);
|
||||||
}
|
}
|
||||||
final var loweringContext = new ExecutableLoweringContext(
|
final var loweringContext = new ExecutableLoweringContext(
|
||||||
|
normalizedModuleId,
|
||||||
normalizedModuleKey,
|
normalizedModuleKey,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
nameTable,
|
nameTable,
|
||||||
@ -401,6 +445,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final var end = safeToInt(fn.span().getEnd());
|
final var end = safeToInt(fn.span().getEnd());
|
||||||
executableFunctions.add(new IRBackendExecutableFunction(
|
executableFunctions.add(new IRBackendExecutableFunction(
|
||||||
fileId,
|
fileId,
|
||||||
|
normalizedModuleId,
|
||||||
normalizedModuleKey,
|
normalizedModuleKey,
|
||||||
callable.callableName(),
|
callable.callableName(),
|
||||||
functionCallableId,
|
functionCallableId,
|
||||||
@ -921,6 +966,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final var calleeCallableId = callableCandidates.getFirst();
|
final var calleeCallableId = callableCandidates.getFirst();
|
||||||
context.instructions().add(new IRBackendExecutableFunction.Instruction(
|
context.instructions().add(new IRBackendExecutableFunction.Instruction(
|
||||||
IRBackendExecutableFunction.InstructionKind.CALL_FUNC,
|
IRBackendExecutableFunction.InstructionKind.CALL_FUNC,
|
||||||
|
context.moduleId(),
|
||||||
context.moduleKey(),
|
context.moduleKey(),
|
||||||
calleeIdentity.primaryCallableDisplayName(),
|
calleeIdentity.primaryCallableDisplayName(),
|
||||||
calleeCallableId,
|
calleeCallableId,
|
||||||
@ -1292,6 +1338,7 @@ public final class PbsFrontendCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class ExecutableLoweringContext {
|
private static final class ExecutableLoweringContext {
|
||||||
|
private final ModuleId moduleId;
|
||||||
private final String moduleKey;
|
private final String moduleKey;
|
||||||
private final DiagnosticSink diagnostics;
|
private final DiagnosticSink diagnostics;
|
||||||
private final NameTable nameTable;
|
private final NameTable nameTable;
|
||||||
@ -1308,6 +1355,7 @@ public final class PbsFrontendCompiler {
|
|||||||
private int nextLabelId = 0;
|
private int nextLabelId = 0;
|
||||||
|
|
||||||
private ExecutableLoweringContext(
|
private ExecutableLoweringContext(
|
||||||
|
final ModuleId moduleId,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
final DiagnosticSink diagnostics,
|
final DiagnosticSink diagnostics,
|
||||||
final NameTable nameTable,
|
final NameTable nameTable,
|
||||||
@ -1319,6 +1367,7 @@ public final class PbsFrontendCompiler {
|
|||||||
final Map<CallableId, Integer> returnSlotsByCallableId,
|
final Map<CallableId, Integer> returnSlotsByCallableId,
|
||||||
final IntrinsicTable intrinsicIdTable,
|
final IntrinsicTable intrinsicIdTable,
|
||||||
final Map<NameId, Integer> localSlotByNameId) {
|
final Map<NameId, Integer> localSlotByNameId) {
|
||||||
|
this.moduleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
this.moduleKey = moduleKey;
|
this.moduleKey = moduleKey;
|
||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
this.nameTable = nameTable;
|
this.nameTable = nameTable;
|
||||||
@ -1332,6 +1381,10 @@ public final class PbsFrontendCompiler {
|
|||||||
this.localSlotByNameId = localSlotByNameId == null ? Map.of() : localSlotByNameId;
|
this.localSlotByNameId = localSlotByNameId == null ? Map.of() : localSlotByNameId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ModuleId moduleId() {
|
||||||
|
return moduleId;
|
||||||
|
}
|
||||||
|
|
||||||
private String moduleKey() {
|
private String moduleKey() {
|
||||||
return moduleKey;
|
return moduleKey;
|
||||||
}
|
}
|
||||||
@ -1440,11 +1493,15 @@ public final class PbsFrontendCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public record ImportedCallableSurface(
|
public record ImportedCallableSurface(
|
||||||
|
ModuleId moduleId,
|
||||||
String moduleKey,
|
String moduleKey,
|
||||||
String callableName,
|
String callableName,
|
||||||
int arity,
|
int arity,
|
||||||
int returnSlots,
|
int returnSlots,
|
||||||
String shapeSurface) {
|
String shapeSurface) {
|
||||||
|
public ImportedCallableSurface {
|
||||||
|
moduleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ExecutableLoweringAnalysisException extends RuntimeException {
|
private static final class ExecutableLoweringAnalysisException extends RuntimeException {
|
||||||
|
|||||||
@ -159,6 +159,7 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
markModulesWithLinkingErrors(diagnostics, moduleIdByFile, failedModuleIds);
|
markModulesWithLinkingErrors(diagnostics, moduleIdByFile, failedModuleIds);
|
||||||
final var moduleDependencyGraph = buildModuleDependencyGraph(parsedSourceFiles, moduleTable);
|
final var moduleDependencyGraph = buildModuleDependencyGraph(parsedSourceFiles, moduleTable);
|
||||||
final var importedSemanticContexts = buildImportedSemanticContexts(parsedSourceFiles, moduleTable);
|
final var importedSemanticContexts = buildImportedSemanticContexts(parsedSourceFiles, moduleTable);
|
||||||
|
final var canonicalModulePool = emitModulePool(moduleTable);
|
||||||
|
|
||||||
final var compiledSourceFiles = new ArrayList<CompiledSourceFile>(parsedSourceFiles.size());
|
final var compiledSourceFiles = new ArrayList<CompiledSourceFile>(parsedSourceFiles.size());
|
||||||
for (final var parsedSource : parsedSourceFiles) {
|
for (final var parsedSource : parsedSourceFiles) {
|
||||||
@ -175,7 +176,9 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
parsedSource.ast(),
|
parsedSource.ast(),
|
||||||
diagnostics,
|
diagnostics,
|
||||||
parsedSource.sourceKind(),
|
parsedSource.sourceKind(),
|
||||||
|
parsedSource.moduleId(),
|
||||||
renderModuleKey(moduleTable, parsedSource.moduleId()),
|
renderModuleKey(moduleTable, parsedSource.moduleId()),
|
||||||
|
canonicalModulePool,
|
||||||
ctx.hostAdmissionContext(),
|
ctx.hostAdmissionContext(),
|
||||||
nameTable,
|
nameTable,
|
||||||
importedSemanticContext.supplementalTopDecls(),
|
importedSemanticContext.supplementalTopDecls(),
|
||||||
@ -431,6 +434,7 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
importedCallables,
|
importedCallables,
|
||||||
importedCallableKeys,
|
importedCallableKeys,
|
||||||
new PbsFrontendCompiler.ImportedCallableSurface(
|
new PbsFrontendCompiler.ImportedCallableSurface(
|
||||||
|
importedModuleId,
|
||||||
importedModuleKey,
|
importedModuleKey,
|
||||||
localName + "." + method.name(),
|
localName + "." + method.name(),
|
||||||
method.parameters().size(),
|
method.parameters().size(),
|
||||||
@ -444,6 +448,7 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
importedCallables,
|
importedCallables,
|
||||||
importedCallableKeys,
|
importedCallableKeys,
|
||||||
new PbsFrontendCompiler.ImportedCallableSurface(
|
new PbsFrontendCompiler.ImportedCallableSurface(
|
||||||
|
importedModuleId,
|
||||||
importedModuleKey,
|
importedModuleKey,
|
||||||
localName,
|
localName,
|
||||||
functionDecl.parameters().size(),
|
functionDecl.parameters().size(),
|
||||||
@ -793,6 +798,14 @@ public class PBSFrontendPhaseService implements FrontendPhaseService {
|
|||||||
return moduleReference.project() + ":" + String.join("/", moduleReference.pathSegments().asList());
|
return moduleReference.project() + ":" + String.join("/", moduleReference.pathSegments().asList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ReadOnlyList<ModuleReference> emitModulePool(final ModuleTable moduleTable) {
|
||||||
|
final var pool = new ArrayList<ModuleReference>(moduleTable.size());
|
||||||
|
for (final var moduleId : moduleTable.identifiers()) {
|
||||||
|
pool.add(moduleTable.get(moduleId));
|
||||||
|
}
|
||||||
|
return ReadOnlyList.wrap(pool);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class MutableModuleUnit {
|
private static final class MutableModuleUnit {
|
||||||
private final ArrayList<PbsModuleVisibilityValidator.SourceFile> sources = new ArrayList<>();
|
private final ArrayList<PbsModuleVisibilityValidator.SourceFile> sources = new ArrayList<>();
|
||||||
private final ArrayList<PbsModuleVisibilityValidator.BarrelFile> barrels = new ArrayList<>();
|
private final ArrayList<PbsModuleVisibilityValidator.BarrelFile> barrels = new ArrayList<>();
|
||||||
|
|||||||
@ -6,19 +6,15 @@ import p.studio.compiler.models.IRBackend;
|
|||||||
import p.studio.compiler.models.IRBackendExecutableFunction;
|
import p.studio.compiler.models.IRBackendExecutableFunction;
|
||||||
import p.studio.compiler.source.Span;
|
import p.studio.compiler.source.Span;
|
||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
public class LowerToIRVMService {
|
public class LowerToIRVMService {
|
||||||
private static final Comparator<IRBackendExecutableFunction> FUNCTION_ORDER = Comparator
|
|
||||||
.comparing(IRBackendExecutableFunction::moduleKey)
|
|
||||||
.thenComparing(IRBackendExecutableFunction::callableName)
|
|
||||||
.thenComparingInt(function -> function.callableId().getIndex())
|
|
||||||
.thenComparingInt(IRBackendExecutableFunction::sourceStart);
|
|
||||||
|
|
||||||
private final IRVMValidator validator;
|
private final IRVMValidator validator;
|
||||||
|
|
||||||
public LowerToIRVMService() {
|
public LowerToIRVMService() {
|
||||||
@ -301,7 +297,23 @@ public class LowerToIRVMService {
|
|||||||
"frontend IRBackend entrypoint declaration is missing");
|
"frontend IRBackend entrypoint declaration is missing");
|
||||||
}
|
}
|
||||||
final var sorted = new ArrayList<>(backend.getExecutableFunctions().asList());
|
final var sorted = new ArrayList<>(backend.getExecutableFunctions().asList());
|
||||||
sorted.sort(FUNCTION_ORDER);
|
sorted.sort((left, right) -> {
|
||||||
|
final var leftModuleKey = moduleSortKey(backend, left.moduleId(), left.moduleKey());
|
||||||
|
final var rightModuleKey = moduleSortKey(backend, right.moduleId(), right.moduleKey());
|
||||||
|
final var moduleCmp = leftModuleKey.compareTo(rightModuleKey);
|
||||||
|
if (moduleCmp != 0) {
|
||||||
|
return moduleCmp;
|
||||||
|
}
|
||||||
|
final var nameCmp = left.callableName().compareTo(right.callableName());
|
||||||
|
if (nameCmp != 0) {
|
||||||
|
return nameCmp;
|
||||||
|
}
|
||||||
|
final var idCmp = Integer.compare(left.callableId().getIndex(), right.callableId().getIndex());
|
||||||
|
if (idCmp != 0) {
|
||||||
|
return idCmp;
|
||||||
|
}
|
||||||
|
return Integer.compare(left.sourceStart(), right.sourceStart());
|
||||||
|
});
|
||||||
final var entrypoints = sorted.stream()
|
final var entrypoints = sorted.stream()
|
||||||
.filter(candidate -> entryPointCallableName.equals(candidate.callableName()))
|
.filter(candidate -> entryPointCallableName.equals(candidate.callableName()))
|
||||||
.toList();
|
.toList();
|
||||||
@ -328,6 +340,27 @@ public class LowerToIRVMService {
|
|||||||
return ReadOnlyList.wrap(ordered);
|
return ReadOnlyList.wrap(ordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String moduleSortKey(
|
||||||
|
final IRBackend backend,
|
||||||
|
final ModuleId moduleId,
|
||||||
|
final String fallbackModuleKey) {
|
||||||
|
if (moduleId != null && !moduleId.isNone()) {
|
||||||
|
final var index = moduleId.getIndex();
|
||||||
|
if (index >= 0 && index < backend.getModulePool().size()) {
|
||||||
|
return canonicalModuleSortKey(backend.getModulePool().get(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fallbackModuleKey == null ? "" : fallbackModuleKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String canonicalModuleSortKey(final ModuleReference reference) {
|
||||||
|
final var joiner = new StringJoiner("/", reference.project() + ":", "");
|
||||||
|
for (final var segment : reference.pathSegments()) {
|
||||||
|
joiner.add(segment);
|
||||||
|
}
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private BytecodeModule.SourceSpan toBytecodeSpan(
|
private BytecodeModule.SourceSpan toBytecodeSpan(
|
||||||
final int fallbackFileId,
|
final int fallbackFileId,
|
||||||
final Span span) {
|
final Span span) {
|
||||||
|
|||||||
@ -7,7 +7,9 @@ import p.studio.compiler.source.Span;
|
|||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@ -199,6 +201,27 @@ class LowerToIRVMServiceTest {
|
|||||||
assertEquals(IRVMLoweringErrorCode.LOWER_IRVM_ENTRYPOINT_AMBIGUOUS, thrown.code());
|
assertEquals(IRVMLoweringErrorCode.LOWER_IRVM_ENTRYPOINT_AMBIGUOUS, thrown.code());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lowerMustUseModulePoolCanonicalIdentityForNonEntrypointOrdering() {
|
||||||
|
final var backend = IRBackend.builder()
|
||||||
|
.entryPointCallableName("frame")
|
||||||
|
.modulePool(ReadOnlyList.from(
|
||||||
|
new ModuleReference("app", ReadOnlyList.from("alpha")),
|
||||||
|
new ModuleReference("app", ReadOnlyList.from("zeta"))))
|
||||||
|
.executableFunctions(ReadOnlyList.from(
|
||||||
|
fnWithModule("helper_in_zeta", "legacy/zeta", 1, 21, ReadOnlyList.from(ret())),
|
||||||
|
fnWithModule("frame", "legacy/zeta", 1, 20, ReadOnlyList.from(ret())),
|
||||||
|
fnWithModule("helper_in_alpha", "legacy/alpha", 0, 22, ReadOnlyList.from(ret()))))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final var lowered = new LowerToIRVMService().lower(backend);
|
||||||
|
|
||||||
|
assertEquals(3, lowered.module().functions().size());
|
||||||
|
assertEquals("frame", lowered.module().functions().get(0).name());
|
||||||
|
assertEquals("helper_in_alpha", lowered.module().functions().get(1).name());
|
||||||
|
assertEquals("helper_in_zeta", lowered.module().functions().get(2).name());
|
||||||
|
}
|
||||||
|
|
||||||
private static IRBackendExecutableFunction fn(
|
private static IRBackendExecutableFunction fn(
|
||||||
final String name,
|
final String name,
|
||||||
final String moduleKey,
|
final String moduleKey,
|
||||||
@ -219,6 +242,28 @@ class LowerToIRVMServiceTest {
|
|||||||
Span.none());
|
Span.none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IRBackendExecutableFunction fnWithModule(
|
||||||
|
final String name,
|
||||||
|
final String moduleKey,
|
||||||
|
final int moduleId,
|
||||||
|
final int callableId,
|
||||||
|
final ReadOnlyList<IRBackendExecutableFunction.Instruction> instructions) {
|
||||||
|
return new IRBackendExecutableFunction(
|
||||||
|
new FileId(0),
|
||||||
|
new ModuleId(moduleId),
|
||||||
|
moduleKey,
|
||||||
|
name,
|
||||||
|
new CallableId(callableId),
|
||||||
|
0,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
4,
|
||||||
|
instructions,
|
||||||
|
Span.none());
|
||||||
|
}
|
||||||
|
|
||||||
private static IRBackendExecutableFunction.Instruction ret() {
|
private static IRBackendExecutableFunction.Instruction ret() {
|
||||||
return new IRBackendExecutableFunction.Instruction(
|
return new IRBackendExecutableFunction.Instruction(
|
||||||
IRBackendExecutableFunction.InstructionKind.RET,
|
IRBackendExecutableFunction.InstructionKind.RET,
|
||||||
|
|||||||
@ -1,7 +1,17 @@
|
|||||||
package p.studio.compiler.source.identifiers;
|
package p.studio.compiler.source.identifiers;
|
||||||
|
|
||||||
public class ModuleId extends SourceIdentifier {
|
public class ModuleId extends SourceIdentifier {
|
||||||
|
public static final ModuleId NONE = new ModuleId(-1);
|
||||||
|
|
||||||
public ModuleId(int id) {
|
public ModuleId(int id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ModuleId none() {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNone() {
|
||||||
|
return this == NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,29 @@
|
|||||||
package p.studio.compiler.source.tables;
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public record CallableSignatureRef(
|
public record CallableSignatureRef(
|
||||||
|
ModuleId moduleId,
|
||||||
String moduleKey,
|
String moduleKey,
|
||||||
String callableName,
|
String callableName,
|
||||||
int arity,
|
int arity,
|
||||||
String typeShape) {
|
String typeShape) {
|
||||||
|
|
||||||
|
public CallableSignatureRef(
|
||||||
|
final String moduleKey,
|
||||||
|
final String callableName,
|
||||||
|
final int arity,
|
||||||
|
final String typeShape) {
|
||||||
|
this(ModuleId.none(), moduleKey, callableName, arity, typeShape);
|
||||||
|
}
|
||||||
|
|
||||||
public CallableSignatureRef {
|
public CallableSignatureRef {
|
||||||
|
moduleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
|
if (!moduleId.isNone()) {
|
||||||
|
moduleId.getIndex();
|
||||||
|
}
|
||||||
moduleKey = moduleKey == null ? "" : moduleKey;
|
moduleKey = moduleKey == null ? "" : moduleKey;
|
||||||
callableName = Objects.requireNonNull(callableName, "callableName");
|
callableName = Objects.requireNonNull(callableName, "callableName");
|
||||||
typeShape = typeShape == null ? "" : typeShape;
|
typeShape = typeShape == null ? "" : typeShape;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package p.studio.compiler.source.tables;
|
package p.studio.compiler.source.tables;
|
||||||
|
|
||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
|
|
||||||
public class CallableTable extends InternTable<CallableId, CallableSignatureRef> implements CallableTableReader {
|
public class CallableTable extends InternTable<CallableId, CallableSignatureRef> implements CallableTableReader {
|
||||||
|
|
||||||
@ -13,6 +14,15 @@ public class CallableTable extends InternTable<CallableId, CallableSignatureRef>
|
|||||||
final String callableName,
|
final String callableName,
|
||||||
final int arity,
|
final int arity,
|
||||||
final String typeShape) {
|
final String typeShape) {
|
||||||
return register(new CallableSignatureRef(moduleKey, callableName, arity, typeShape));
|
return register(new CallableSignatureRef(ModuleId.none(), moduleKey, callableName, arity, typeShape));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CallableId register(
|
||||||
|
final ModuleId moduleId,
|
||||||
|
final String moduleKey,
|
||||||
|
final String callableName,
|
||||||
|
final int arity,
|
||||||
|
final String typeShape) {
|
||||||
|
return register(new CallableSignatureRef(moduleId, moduleKey, callableName, arity, typeShape));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,18 @@ import lombok.Builder;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
import p.studio.compiler.source.tables.CallableSignatureRef;
|
import p.studio.compiler.source.tables.CallableSignatureRef;
|
||||||
import p.studio.compiler.source.tables.CallableTable;
|
import p.studio.compiler.source.tables.CallableTable;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
import p.studio.compiler.source.tables.IntrinsicTable;
|
import p.studio.compiler.source.tables.IntrinsicTable;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
|
import p.studio.compiler.source.tables.ModuleTable;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
@Getter
|
@Getter
|
||||||
@ -23,6 +27,8 @@ public class IRBackend {
|
|||||||
@Builder.Default
|
@Builder.Default
|
||||||
private final ReadOnlyList<IRBackendExecutableFunction> executableFunctions = ReadOnlyList.empty();
|
private final ReadOnlyList<IRBackendExecutableFunction> executableFunctions = ReadOnlyList.empty();
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
|
private final ReadOnlyList<ModuleReference> modulePool = ReadOnlyList.empty();
|
||||||
|
@Builder.Default
|
||||||
private final ReadOnlyList<CallableSignatureRef> callableSignatures = ReadOnlyList.empty();
|
private final ReadOnlyList<CallableSignatureRef> callableSignatures = ReadOnlyList.empty();
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private final ReadOnlyList<IntrinsicReference> intrinsicPool = ReadOnlyList.empty();
|
private final ReadOnlyList<IntrinsicReference> intrinsicPool = ReadOnlyList.empty();
|
||||||
@ -37,6 +43,7 @@ public class IRBackend {
|
|||||||
private String entryPointCallableName;
|
private String entryPointCallableName;
|
||||||
private final ArrayList<IRFunction> functions = new ArrayList<>();
|
private final ArrayList<IRFunction> functions = new ArrayList<>();
|
||||||
private final ArrayList<IRBackendExecutableFunction> executableFunctions = new ArrayList<>();
|
private final ArrayList<IRBackendExecutableFunction> executableFunctions = new ArrayList<>();
|
||||||
|
private final ModuleTable moduleTable = new ModuleTable();
|
||||||
private final CallableTable callableTable = new CallableTable();
|
private final CallableTable callableTable = new CallableTable();
|
||||||
private final IntrinsicTable intrinsicTable = new IntrinsicTable();
|
private final IntrinsicTable intrinsicTable = new IntrinsicTable();
|
||||||
private final ArrayList<IRReservedMetadata.HostMethodBinding> hostMethodBindings = new ArrayList<>();
|
private final ArrayList<IRReservedMetadata.HostMethodBinding> hostMethodBindings = new ArrayList<>();
|
||||||
@ -49,10 +56,11 @@ public class IRBackend {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
functions.addAll(backendFile.functions().asList());
|
functions.addAll(backendFile.functions().asList());
|
||||||
final var callableRemap = reindexCallables(backendFile.callableSignatures());
|
final var moduleRemap = reindexModules(backendFile.modulePool());
|
||||||
|
final var callableRemap = reindexCallables(backendFile.callableSignatures(), moduleRemap);
|
||||||
final var intrinsicRemap = reindexIntrinsics(backendFile.intrinsicPool());
|
final var intrinsicRemap = reindexIntrinsics(backendFile.intrinsicPool());
|
||||||
for (final var function : backendFile.executableFunctions()) {
|
for (final var function : backendFile.executableFunctions()) {
|
||||||
executableFunctions.add(remapExecutableFunction(function, callableRemap, intrinsicRemap));
|
executableFunctions.add(remapExecutableFunction(function, moduleRemap, callableRemap, intrinsicRemap));
|
||||||
}
|
}
|
||||||
final var metadata = backendFile.reservedMetadata();
|
final var metadata = backendFile.reservedMetadata();
|
||||||
hostMethodBindings.addAll(metadata.hostMethodBindings().asList());
|
hostMethodBindings.addAll(metadata.hostMethodBindings().asList());
|
||||||
@ -68,22 +76,52 @@ public class IRBackend {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CallableId[] reindexCallables(final ReadOnlyList<CallableSignatureRef> localCallableSignatures) {
|
private ModuleId[] reindexModules(final ReadOnlyList<ModuleReference> localModulePool) {
|
||||||
|
if (localModulePool == null || localModulePool.isEmpty()) {
|
||||||
|
return new ModuleId[0];
|
||||||
|
}
|
||||||
|
final var remap = new ModuleId[localModulePool.size()];
|
||||||
|
for (var i = 0; i < localModulePool.size(); i++) {
|
||||||
|
remap[i] = moduleTable.register(localModulePool.get(i));
|
||||||
|
}
|
||||||
|
return remap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CallableId[] reindexCallables(
|
||||||
|
final ReadOnlyList<CallableSignatureRef> localCallableSignatures,
|
||||||
|
final ModuleId[] moduleRemap) {
|
||||||
if (localCallableSignatures == null || localCallableSignatures.isEmpty()) {
|
if (localCallableSignatures == null || localCallableSignatures.isEmpty()) {
|
||||||
return new CallableId[0];
|
return new CallableId[0];
|
||||||
}
|
}
|
||||||
final var remap = new CallableId[localCallableSignatures.size()];
|
final var remap = new CallableId[localCallableSignatures.size()];
|
||||||
for (var i = 0; i < localCallableSignatures.size(); i++) {
|
for (var i = 0; i < localCallableSignatures.size(); i++) {
|
||||||
remap[i] = callableTable.register(localCallableSignatures.get(i));
|
final var signature = localCallableSignatures.get(i);
|
||||||
|
final var remappedModuleId = remapModuleId(
|
||||||
|
signature.moduleId(),
|
||||||
|
signature.moduleKey(),
|
||||||
|
moduleRemap,
|
||||||
|
"callable signature");
|
||||||
|
remap[i] = callableTable.register(
|
||||||
|
remappedModuleId,
|
||||||
|
signature.moduleKey(),
|
||||||
|
signature.callableName(),
|
||||||
|
signature.arity(),
|
||||||
|
signature.typeShape());
|
||||||
}
|
}
|
||||||
return remap;
|
return remap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRBackendExecutableFunction remapExecutableFunction(
|
private IRBackendExecutableFunction remapExecutableFunction(
|
||||||
final IRBackendExecutableFunction function,
|
final IRBackendExecutableFunction function,
|
||||||
|
final ModuleId[] moduleRemap,
|
||||||
final CallableId[] callableRemap,
|
final CallableId[] callableRemap,
|
||||||
final IntrinsicId[] intrinsicRemap) {
|
final IntrinsicId[] intrinsicRemap) {
|
||||||
final var remappedInstructions = new ArrayList<IRBackendExecutableFunction.Instruction>(function.instructions().size());
|
final var remappedInstructions = new ArrayList<IRBackendExecutableFunction.Instruction>(function.instructions().size());
|
||||||
|
final var remappedFunctionModuleId = remapModuleId(
|
||||||
|
function.moduleId(),
|
||||||
|
function.moduleKey(),
|
||||||
|
moduleRemap,
|
||||||
|
"function");
|
||||||
for (final var instruction : function.instructions()) {
|
for (final var instruction : function.instructions()) {
|
||||||
final CallableId remappedCallee;
|
final CallableId remappedCallee;
|
||||||
if (instruction.calleeCallableId() == null) {
|
if (instruction.calleeCallableId() == null) {
|
||||||
@ -101,8 +139,14 @@ public class IRBackend {
|
|||||||
} else {
|
} else {
|
||||||
remappedIntrinsic = instruction.intrinsicCall();
|
remappedIntrinsic = instruction.intrinsicCall();
|
||||||
}
|
}
|
||||||
|
final var remappedCalleeModuleId = remapModuleId(
|
||||||
|
instruction.calleeModuleId(),
|
||||||
|
instruction.calleeModuleKey(),
|
||||||
|
moduleRemap,
|
||||||
|
"callee");
|
||||||
remappedInstructions.add(new IRBackendExecutableFunction.Instruction(
|
remappedInstructions.add(new IRBackendExecutableFunction.Instruction(
|
||||||
instruction.kind(),
|
instruction.kind(),
|
||||||
|
remappedCalleeModuleId,
|
||||||
instruction.calleeModuleKey(),
|
instruction.calleeModuleKey(),
|
||||||
instruction.calleeCallableName(),
|
instruction.calleeCallableName(),
|
||||||
remappedCallee,
|
remappedCallee,
|
||||||
@ -116,6 +160,7 @@ public class IRBackend {
|
|||||||
}
|
}
|
||||||
return new IRBackendExecutableFunction(
|
return new IRBackendExecutableFunction(
|
||||||
function.fileId(),
|
function.fileId(),
|
||||||
|
remappedFunctionModuleId,
|
||||||
function.moduleKey(),
|
function.moduleKey(),
|
||||||
function.callableName(),
|
function.callableName(),
|
||||||
remapCallableId(function.callableId(), callableRemap, "function"),
|
remapCallableId(function.callableId(), callableRemap, "function"),
|
||||||
@ -129,6 +174,45 @@ public class IRBackend {
|
|||||||
function.span());
|
function.span());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ModuleId remapModuleId(
|
||||||
|
final ModuleId localModuleId,
|
||||||
|
final String moduleKey,
|
||||||
|
final ModuleId[] moduleRemap,
|
||||||
|
final String label) {
|
||||||
|
if (localModuleId != null && !localModuleId.isNone()) {
|
||||||
|
final var localIndex = localModuleId.getIndex();
|
||||||
|
if (localIndex < 0 || localIndex >= moduleRemap.length) {
|
||||||
|
throw new IllegalArgumentException("invalid local " + label + " module id: " + localModuleId);
|
||||||
|
}
|
||||||
|
return moduleRemap[localIndex];
|
||||||
|
}
|
||||||
|
final var fallbackReference = moduleReferenceFromKey(moduleKey);
|
||||||
|
if (fallbackReference != null) {
|
||||||
|
return moduleTable.register(fallbackReference);
|
||||||
|
}
|
||||||
|
return ModuleId.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModuleReference moduleReferenceFromKey(final String moduleKey) {
|
||||||
|
if (moduleKey == null || moduleKey.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final var separator = moduleKey.indexOf(':');
|
||||||
|
if (separator <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final var project = moduleKey.substring(0, separator).trim();
|
||||||
|
final var rawPath = moduleKey.substring(separator + 1).trim();
|
||||||
|
if (project.isBlank()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (rawPath.isBlank()) {
|
||||||
|
return new ModuleReference(project, ReadOnlyList.empty());
|
||||||
|
}
|
||||||
|
final var segments = List.of(rawPath.split("/"));
|
||||||
|
return new ModuleReference(project, ReadOnlyList.wrap(segments));
|
||||||
|
}
|
||||||
|
|
||||||
private CallableId remapCallableId(
|
private CallableId remapCallableId(
|
||||||
final CallableId localCallableId,
|
final CallableId localCallableId,
|
||||||
final CallableId[] callableRemap,
|
final CallableId[] callableRemap,
|
||||||
@ -169,6 +253,14 @@ public class IRBackend {
|
|||||||
return ReadOnlyList.wrap(signatures);
|
return ReadOnlyList.wrap(signatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ReadOnlyList<ModuleReference> emitModulePool() {
|
||||||
|
final var modules = new ArrayList<ModuleReference>(moduleTable.size());
|
||||||
|
for (final var moduleId : moduleTable.identifiers()) {
|
||||||
|
modules.add(moduleTable.get(moduleId));
|
||||||
|
}
|
||||||
|
return ReadOnlyList.wrap(modules);
|
||||||
|
}
|
||||||
|
|
||||||
private ReadOnlyList<IntrinsicReference> emitIntrinsicPool() {
|
private ReadOnlyList<IntrinsicReference> emitIntrinsicPool() {
|
||||||
final var pool = new ArrayList<IntrinsicReference>(intrinsicTable.size());
|
final var pool = new ArrayList<IntrinsicReference>(intrinsicTable.size());
|
||||||
for (final var intrinsicId : intrinsicTable.identifiers()) {
|
for (final var intrinsicId : intrinsicTable.identifiers()) {
|
||||||
@ -183,6 +275,7 @@ public class IRBackend {
|
|||||||
.entryPointCallableName(resolveEntryPointCallableName())
|
.entryPointCallableName(resolveEntryPointCallableName())
|
||||||
.functions(ReadOnlyList.wrap(functions))
|
.functions(ReadOnlyList.wrap(functions))
|
||||||
.executableFunctions(ReadOnlyList.wrap(executableFunctions))
|
.executableFunctions(ReadOnlyList.wrap(executableFunctions))
|
||||||
|
.modulePool(emitModulePool())
|
||||||
.callableSignatures(emitCallableSignatures())
|
.callableSignatures(emitCallableSignatures())
|
||||||
.intrinsicPool(emitIntrinsicPool())
|
.intrinsicPool(emitIntrinsicPool())
|
||||||
.reservedMetadata(new IRReservedMetadata(
|
.reservedMetadata(new IRReservedMetadata(
|
||||||
@ -206,6 +299,7 @@ public class IRBackend {
|
|||||||
sb.append("IRBackend{entrypoint=").append(entryPointCallableName)
|
sb.append("IRBackend{entrypoint=").append(entryPointCallableName)
|
||||||
.append(", functions=").append(functions.size())
|
.append(", functions=").append(functions.size())
|
||||||
.append(", executableFunctions=").append(executableFunctions.size())
|
.append(", executableFunctions=").append(executableFunctions.size())
|
||||||
|
.append(", modulePool=").append(modulePool.size())
|
||||||
.append(", callableSignatures=").append(callableSignatures.size())
|
.append(", callableSignatures=").append(callableSignatures.size())
|
||||||
.append(", intrinsicPool=").append(intrinsicPool.size())
|
.append(", intrinsicPool=").append(intrinsicPool.size())
|
||||||
.append(", hostBindings=").append(reservedMetadata.hostMethodBindings().size())
|
.append(", hostBindings=").append(reservedMetadata.hostMethodBindings().size())
|
||||||
|
|||||||
@ -4,12 +4,14 @@ import p.studio.compiler.source.Span;
|
|||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public record IRBackendExecutableFunction(
|
public record IRBackendExecutableFunction(
|
||||||
FileId fileId,
|
FileId fileId,
|
||||||
|
ModuleId moduleId,
|
||||||
String moduleKey,
|
String moduleKey,
|
||||||
String callableName,
|
String callableName,
|
||||||
CallableId callableId,
|
CallableId callableId,
|
||||||
@ -22,8 +24,41 @@ public record IRBackendExecutableFunction(
|
|||||||
ReadOnlyList<Instruction> instructions,
|
ReadOnlyList<Instruction> instructions,
|
||||||
Span span) {
|
Span span) {
|
||||||
|
|
||||||
|
public IRBackendExecutableFunction(
|
||||||
|
final FileId fileId,
|
||||||
|
final String moduleKey,
|
||||||
|
final String callableName,
|
||||||
|
final CallableId callableId,
|
||||||
|
final int sourceStart,
|
||||||
|
final int sourceEnd,
|
||||||
|
final int paramSlots,
|
||||||
|
final int localSlots,
|
||||||
|
final int returnSlots,
|
||||||
|
final int maxStackSlots,
|
||||||
|
final ReadOnlyList<Instruction> instructions,
|
||||||
|
final Span span) {
|
||||||
|
this(
|
||||||
|
fileId,
|
||||||
|
ModuleId.none(),
|
||||||
|
moduleKey,
|
||||||
|
callableName,
|
||||||
|
callableId,
|
||||||
|
sourceStart,
|
||||||
|
sourceEnd,
|
||||||
|
paramSlots,
|
||||||
|
localSlots,
|
||||||
|
returnSlots,
|
||||||
|
maxStackSlots,
|
||||||
|
instructions,
|
||||||
|
span);
|
||||||
|
}
|
||||||
|
|
||||||
public IRBackendExecutableFunction {
|
public IRBackendExecutableFunction {
|
||||||
fileId = Objects.requireNonNull(fileId, "fileId");
|
fileId = Objects.requireNonNull(fileId, "fileId");
|
||||||
|
moduleId = moduleId == null ? ModuleId.none() : moduleId;
|
||||||
|
if (!moduleId.isNone()) {
|
||||||
|
moduleId.getIndex();
|
||||||
|
}
|
||||||
moduleKey = moduleKey == null ? "" : moduleKey;
|
moduleKey = moduleKey == null ? "" : moduleKey;
|
||||||
callableName = Objects.requireNonNull(callableName, "callableName");
|
callableName = Objects.requireNonNull(callableName, "callableName");
|
||||||
if (callableName.isBlank()) {
|
if (callableName.isBlank()) {
|
||||||
@ -52,6 +87,7 @@ public record IRBackendExecutableFunction(
|
|||||||
|
|
||||||
public record Instruction(
|
public record Instruction(
|
||||||
InstructionKind kind,
|
InstructionKind kind,
|
||||||
|
ModuleId calleeModuleId,
|
||||||
String calleeModuleKey,
|
String calleeModuleKey,
|
||||||
String calleeCallableName,
|
String calleeCallableName,
|
||||||
CallableId calleeCallableId,
|
CallableId calleeCallableId,
|
||||||
@ -64,13 +100,78 @@ public record IRBackendExecutableFunction(
|
|||||||
Span span) {
|
Span span) {
|
||||||
public Instruction(
|
public Instruction(
|
||||||
final InstructionKind kind,
|
final InstructionKind kind,
|
||||||
|
final ModuleId calleeModuleId,
|
||||||
final String calleeModuleKey,
|
final String calleeModuleKey,
|
||||||
final String calleeCallableName,
|
final String calleeCallableName,
|
||||||
final CallableId calleeCallableId,
|
final CallableId calleeCallableId,
|
||||||
final HostCallMetadata hostCall,
|
final HostCallMetadata hostCall,
|
||||||
final IntrinsicCallMetadata intrinsicCall,
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
final Span span) {
|
final Span span) {
|
||||||
this(kind, calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, null, null, span);
|
this(kind, calleeModuleId, calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, null, null, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction(
|
||||||
|
final InstructionKind kind,
|
||||||
|
final ModuleId calleeModuleId,
|
||||||
|
final String calleeModuleKey,
|
||||||
|
final String calleeCallableName,
|
||||||
|
final CallableId calleeCallableId,
|
||||||
|
final HostCallMetadata hostCall,
|
||||||
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
|
final Integer expectedArgSlots,
|
||||||
|
final Integer expectedRetSlots,
|
||||||
|
final Span span) {
|
||||||
|
this(kind, calleeModuleId, calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction(
|
||||||
|
final InstructionKind kind,
|
||||||
|
final ModuleId calleeModuleId,
|
||||||
|
final String calleeModuleKey,
|
||||||
|
final String calleeCallableName,
|
||||||
|
final HostCallMetadata hostCall,
|
||||||
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
|
final Span span) {
|
||||||
|
this(kind, calleeModuleId, calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, null, null, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction(
|
||||||
|
final InstructionKind kind,
|
||||||
|
final ModuleId calleeModuleId,
|
||||||
|
final String calleeModuleKey,
|
||||||
|
final String calleeCallableName,
|
||||||
|
final HostCallMetadata hostCall,
|
||||||
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
|
final Integer expectedArgSlots,
|
||||||
|
final Integer expectedRetSlots,
|
||||||
|
final Span span) {
|
||||||
|
this(kind, calleeModuleId, calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction(
|
||||||
|
final InstructionKind kind,
|
||||||
|
final String calleeModuleKey,
|
||||||
|
final String calleeCallableName,
|
||||||
|
final CallableId calleeCallableId,
|
||||||
|
final HostCallMetadata hostCall,
|
||||||
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
|
final String label,
|
||||||
|
final String targetLabel,
|
||||||
|
final Integer expectedArgSlots,
|
||||||
|
final Integer expectedRetSlots,
|
||||||
|
final Span span) {
|
||||||
|
this(kind, ModuleId.none(), calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, label, targetLabel, expectedArgSlots, expectedRetSlots, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instruction(
|
||||||
|
final InstructionKind kind,
|
||||||
|
final String calleeModuleKey,
|
||||||
|
final String calleeCallableName,
|
||||||
|
final CallableId calleeCallableId,
|
||||||
|
final HostCallMetadata hostCall,
|
||||||
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
|
final Span span) {
|
||||||
|
this(kind, ModuleId.none(), calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, null, null, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(
|
public Instruction(
|
||||||
@ -83,7 +184,7 @@ public record IRBackendExecutableFunction(
|
|||||||
final Integer expectedArgSlots,
|
final Integer expectedArgSlots,
|
||||||
final Integer expectedRetSlots,
|
final Integer expectedRetSlots,
|
||||||
final Span span) {
|
final Span span) {
|
||||||
this(kind, calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
this(kind, ModuleId.none(), calleeModuleKey, calleeCallableName, calleeCallableId, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(
|
public Instruction(
|
||||||
@ -93,7 +194,7 @@ public record IRBackendExecutableFunction(
|
|||||||
final HostCallMetadata hostCall,
|
final HostCallMetadata hostCall,
|
||||||
final IntrinsicCallMetadata intrinsicCall,
|
final IntrinsicCallMetadata intrinsicCall,
|
||||||
final Span span) {
|
final Span span) {
|
||||||
this(kind, calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, null, null, span);
|
this(kind, ModuleId.none(), calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, null, null, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction(
|
public Instruction(
|
||||||
@ -105,12 +206,16 @@ public record IRBackendExecutableFunction(
|
|||||||
final Integer expectedArgSlots,
|
final Integer expectedArgSlots,
|
||||||
final Integer expectedRetSlots,
|
final Integer expectedRetSlots,
|
||||||
final Span span) {
|
final Span span) {
|
||||||
this(kind, calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
this(kind, ModuleId.none(), calleeModuleKey, calleeCallableName, null, hostCall, intrinsicCall, null, null, expectedArgSlots, expectedRetSlots, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instruction {
|
public Instruction {
|
||||||
Objects.requireNonNull(kind, "kind");
|
Objects.requireNonNull(kind, "kind");
|
||||||
span = span == null ? Span.none() : span;
|
span = span == null ? Span.none() : span;
|
||||||
|
calleeModuleId = calleeModuleId == null ? ModuleId.none() : calleeModuleId;
|
||||||
|
if (!calleeModuleId.isNone()) {
|
||||||
|
calleeModuleId.getIndex();
|
||||||
|
}
|
||||||
calleeModuleKey = calleeModuleKey == null ? "" : calleeModuleKey;
|
calleeModuleKey = calleeModuleKey == null ? "" : calleeModuleKey;
|
||||||
calleeCallableName = calleeCallableName == null ? "" : calleeCallableName;
|
calleeCallableName = calleeCallableName == null ? "" : calleeCallableName;
|
||||||
label = label == null ? "" : label;
|
label = label == null ? "" : label;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package p.studio.compiler.models;
|
|||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.tables.CallableSignatureRef;
|
import p.studio.compiler.source.tables.CallableSignatureRef;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -12,6 +13,7 @@ public record IRBackendFile(
|
|||||||
ReadOnlyList<IRFunction> functions,
|
ReadOnlyList<IRFunction> functions,
|
||||||
ReadOnlyList<IRBackendExecutableFunction> executableFunctions,
|
ReadOnlyList<IRBackendExecutableFunction> executableFunctions,
|
||||||
IRReservedMetadata reservedMetadata,
|
IRReservedMetadata reservedMetadata,
|
||||||
|
ReadOnlyList<ModuleReference> modulePool,
|
||||||
ReadOnlyList<CallableSignatureRef> callableSignatures,
|
ReadOnlyList<CallableSignatureRef> callableSignatures,
|
||||||
ReadOnlyList<IntrinsicReference> intrinsicPool) {
|
ReadOnlyList<IntrinsicReference> intrinsicPool) {
|
||||||
public IRBackendFile {
|
public IRBackendFile {
|
||||||
@ -19,6 +21,7 @@ public record IRBackendFile(
|
|||||||
functions = functions == null ? ReadOnlyList.empty() : functions;
|
functions = functions == null ? ReadOnlyList.empty() : functions;
|
||||||
executableFunctions = executableFunctions == null ? ReadOnlyList.empty() : executableFunctions;
|
executableFunctions = executableFunctions == null ? ReadOnlyList.empty() : executableFunctions;
|
||||||
reservedMetadata = reservedMetadata == null ? IRReservedMetadata.empty() : reservedMetadata;
|
reservedMetadata = reservedMetadata == null ? IRReservedMetadata.empty() : reservedMetadata;
|
||||||
|
modulePool = modulePool == null ? ReadOnlyList.empty() : modulePool;
|
||||||
callableSignatures = callableSignatures == null ? ReadOnlyList.empty() : callableSignatures;
|
callableSignatures = callableSignatures == null ? ReadOnlyList.empty() : callableSignatures;
|
||||||
intrinsicPool = intrinsicPool == null ? ReadOnlyList.empty() : intrinsicPool;
|
intrinsicPool = intrinsicPool == null ? ReadOnlyList.empty() : intrinsicPool;
|
||||||
}
|
}
|
||||||
@ -26,17 +29,55 @@ public record IRBackendFile(
|
|||||||
public IRBackendFile(
|
public IRBackendFile(
|
||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final ReadOnlyList<IRFunction> functions) {
|
final ReadOnlyList<IRFunction> functions) {
|
||||||
this(fileId, functions, ReadOnlyList.empty(), IRReservedMetadata.empty(), ReadOnlyList.empty(), ReadOnlyList.empty());
|
this(
|
||||||
|
fileId,
|
||||||
|
functions,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
IRReservedMetadata.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IRBackendFile empty(final FileId fileId) {
|
public static IRBackendFile empty(final FileId fileId) {
|
||||||
return new IRBackendFile(fileId, ReadOnlyList.empty(), ReadOnlyList.empty(), IRReservedMetadata.empty(), ReadOnlyList.empty(), ReadOnlyList.empty());
|
return new IRBackendFile(
|
||||||
|
fileId,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
IRReservedMetadata.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRBackendFile(
|
public IRBackendFile(
|
||||||
final FileId fileId,
|
final FileId fileId,
|
||||||
final ReadOnlyList<IRFunction> functions,
|
final ReadOnlyList<IRFunction> functions,
|
||||||
final IRReservedMetadata reservedMetadata) {
|
final IRReservedMetadata reservedMetadata) {
|
||||||
this(fileId, functions, ReadOnlyList.empty(), reservedMetadata, ReadOnlyList.empty(), ReadOnlyList.empty());
|
this(
|
||||||
|
fileId,
|
||||||
|
functions,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
reservedMetadata,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRBackendFile(
|
||||||
|
final FileId fileId,
|
||||||
|
final ReadOnlyList<IRFunction> functions,
|
||||||
|
final ReadOnlyList<IRBackendExecutableFunction> executableFunctions,
|
||||||
|
final IRReservedMetadata reservedMetadata,
|
||||||
|
final ReadOnlyList<CallableSignatureRef> callableSignatures,
|
||||||
|
final ReadOnlyList<IntrinsicReference> intrinsicPool) {
|
||||||
|
this(
|
||||||
|
fileId,
|
||||||
|
functions,
|
||||||
|
executableFunctions,
|
||||||
|
reservedMetadata,
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
callableSignatures,
|
||||||
|
intrinsicPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import p.studio.compiler.source.Span;
|
|||||||
import p.studio.compiler.source.identifiers.CallableId;
|
import p.studio.compiler.source.identifiers.CallableId;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.compiler.source.identifiers.IntrinsicId;
|
import p.studio.compiler.source.identifiers.IntrinsicId;
|
||||||
|
import p.studio.compiler.source.identifiers.ModuleId;
|
||||||
import p.studio.compiler.source.tables.CallableSignatureRef;
|
import p.studio.compiler.source.tables.CallableSignatureRef;
|
||||||
import p.studio.compiler.source.tables.IntrinsicReference;
|
import p.studio.compiler.source.tables.IntrinsicReference;
|
||||||
|
import p.studio.compiler.source.tables.ModuleReference;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@ -300,4 +302,76 @@ class IRBackendExecutableContractTest {
|
|||||||
assertEquals(21, emittedInstructionSpan.getStart());
|
assertEquals(21, emittedInstructionSpan.getStart());
|
||||||
assertEquals(34, emittedInstructionSpan.getEnd());
|
assertEquals(34, emittedInstructionSpan.getEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void aggregatorMustReindexModulesIntoGlobalDensePool() {
|
||||||
|
final var fileA = new IRBackendFile(
|
||||||
|
new FileId(1),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.from(new IRBackendExecutableFunction(
|
||||||
|
new FileId(1),
|
||||||
|
new ModuleId(0),
|
||||||
|
"app:mod/a",
|
||||||
|
"entry",
|
||||||
|
new CallableId(0),
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
ReadOnlyList.from(new IRBackendExecutableFunction.Instruction(
|
||||||
|
IRBackendExecutableFunction.InstructionKind.RET,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Span.none())),
|
||||||
|
Span.none())),
|
||||||
|
IRReservedMetadata.empty(),
|
||||||
|
ReadOnlyList.from(new ModuleReference("app", ReadOnlyList.from("mod", "a"))),
|
||||||
|
ReadOnlyList.from(new CallableSignatureRef(new ModuleId(0), "app:mod/a", "entry", 0, "() -> unit")),
|
||||||
|
ReadOnlyList.empty());
|
||||||
|
final var fileB = new IRBackendFile(
|
||||||
|
new FileId(2),
|
||||||
|
ReadOnlyList.empty(),
|
||||||
|
ReadOnlyList.from(new IRBackendExecutableFunction(
|
||||||
|
new FileId(2),
|
||||||
|
new ModuleId(0),
|
||||||
|
"app:mod/b",
|
||||||
|
"aux",
|
||||||
|
new CallableId(0),
|
||||||
|
6,
|
||||||
|
10,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
ReadOnlyList.from(new IRBackendExecutableFunction.Instruction(
|
||||||
|
IRBackendExecutableFunction.InstructionKind.RET,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Span.none())),
|
||||||
|
Span.none())),
|
||||||
|
IRReservedMetadata.empty(),
|
||||||
|
ReadOnlyList.from(new ModuleReference("app", ReadOnlyList.from("mod", "b"))),
|
||||||
|
ReadOnlyList.from(new CallableSignatureRef(new ModuleId(0), "app:mod/b", "aux", 0, "() -> unit")),
|
||||||
|
ReadOnlyList.empty());
|
||||||
|
|
||||||
|
final var aggregator = IRBackend.aggregator();
|
||||||
|
aggregator.merge(fileA);
|
||||||
|
aggregator.merge(fileB);
|
||||||
|
final var backend = aggregator.emit();
|
||||||
|
|
||||||
|
assertEquals(2, backend.getModulePool().size());
|
||||||
|
assertEquals("mod", backend.getModulePool().get(0).pathSegments().get(0));
|
||||||
|
assertEquals("a", backend.getModulePool().get(0).pathSegments().get(1));
|
||||||
|
assertEquals("b", backend.getModulePool().get(1).pathSegments().get(1));
|
||||||
|
assertEquals(0, backend.getExecutableFunctions().get(0).moduleId().getIndex());
|
||||||
|
assertEquals(1, backend.getExecutableFunctions().get(1).moduleId().getIndex());
|
||||||
|
assertEquals(0, backend.getCallableSignatures().get(0).moduleId().getIndex());
|
||||||
|
assertEquals(1, backend.getCallableSignatures().get(1).moduleId().getIndex());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user