Sort ShapeHost's members and the lowerer's mode options by name (#1370)

This commit is contained in:
Chris Tate
2026-10-19 00:59:31 -05:00
committed by GitHub
2 changed files with 68 additions and 67 deletions
+35 -35
View File
@@ -61,64 +61,64 @@ import { LlvmUnsupportedError } from "./unsupported.js";
/** What the tables need from the emitter: the extern-declaration ledger
* and the module-wide cycle/shape indexes. */
export interface ShapeHost {
declare(decl: string): void;
/** The hierarchy root of a class (a program class or a runtime base),
* or undefined for classes outside the class graph. */
classRootOf?(className: string): string | undefined;
/** Request the shared OOM abort helper (@sc_oom) — emitted once. */
needOom(): void;
/** Byte offset from an object pointer back to ScrCycHdr.buf. */
readonly cycleBufOffset: number;
declare(decl: string): void;
/** Inline the small-object allocator's fast paths (llvm/alloc.ts). */
readonly inlineAlloc?: boolean;
/** Record and class fields that store a scalar union's tag and bits
* inline (inline-unions.ts): they own nothing. */
readonly inlineUnions: InlineUnionFields;
/** The immutable ScrMapOps descriptor (scr_map.h) of a Map or Set type:
* a module constant holding the LLVM operands { key retain, key release,
* key trace, value retain, value release, value trace, union key kinds },
* or `null` when every operand is null. */
mapOps(operands: readonly string[]): string;
/** The target C ABI's `size_t` / refcount integer type. */
readonly sizeType: "i32" | "i64";
/** Byte offset from an object pointer back to ScrCycHdr.buf. */
readonly cycleBufOffset: number;
readonly tracedShapes: Set<string>;
readonly tracedUnions: Set<string>;
/** Request the shared OOM abort helper (@sc_oom) — emitted once. */
needOom(): void;
/** The next collector statistics index for an emitted ScrCycType
* descriptor (cycTypeDescriptor), counting from FIRST_EMITTED_CYC_KIND
* in emission order.
* Absent: every descriptor gets 0, which keeps no statistics. */
nextCycKind?(): number;
/** Unions represented as a nullable arm pointer (nullable-unions.ts):
* their RC and trace entry points are the arm's NULL-tolerant ones. */
readonly nullableUnions: NullableUnions;
/** Record and class fields that store a scalar union's tag and bits
* inline (inline-unions.ts): they own nothing. */
readonly inlineUnions: InlineUnionFields;
/** The zeroed `%ScrUnion` an inline store reads for a NULL dummy. */
unionNoneRef(): string;
readonly recordsById: Map<string, IrRecordShape>;
readonly recordCloneShapes: ReadonlySet<string>;
/** The program constructs lifetime regions: the ProgramLifetime classes
* allocate in regions and count references in their region chunk instead
* of being empty (llvm/regions.ts). */
regions?: RegionHooks | null;
/** The alias tag of a runtime word that lifetime-region code reads and
* writes outside every field: the chunk count, the chunk owner, the class
* cursors and scr_region_counting (", !tbaa !N", or "" in debug builds). */
regionAliasTag?(word: "count" | "owner" | "cursor" | "counting"): string;
/** Emit the live-object audit notes (`scr_obj_alloc_note` /
* `scr_obj_free_note`) in emitted new/free helpers. Only runtimes built
* with SCR_RC_AUDIT (the sanitized lane) count them; release and dev
* runtime packs define them empty, so plain builds omit the calls.
* Absent means emit. */
readonly objectAudit?: boolean;
/** Inline the small-object allocator's fast paths (llvm/alloc.ts). */
readonly inlineAlloc?: boolean;
/** Worker executables: the inline allocator state is thread-local. */
readonly threadLocalAlloc?: boolean;
/** Inline RC fast-path helpers requested so far ("<family>:<op>"); the
* emitter defines each once through {@link emitInlineRcHelpers}. Null
* keeps every retain/release a runtime call. */
readonly rcHelpers: Set<string> | null;
/** Which fast paths are inlined (see {@link InlineRcMode}). */
readonly rcMode?: InlineRcMode;
/** Define the fast-path helpers `noinline` (see {@link inlineRcOption}). */
readonly rcHelpersNoinline?: boolean;
/** The next collector statistics index for an emitted ScrCycType
* descriptor (cycTypeDescriptor), counting from FIRST_EMITTED_CYC_KIND
* in emission order.
* Absent: every descriptor gets 0, which keeps no statistics. */
nextCycKind?(): number;
/** Which fast paths are inlined (see {@link InlineRcMode}). */
readonly rcMode?: InlineRcMode;
readonly recordCloneShapes: ReadonlySet<string>;
readonly recordsById: Map<string, IrRecordShape>;
/** The alias tag of a runtime word that lifetime-region code reads and
* writes outside every field: the chunk count, the chunk owner, the class
* cursors and scr_region_counting (", !tbaa !N", or "" in debug builds). */
regionAliasTag?(word: "count" | "owner" | "cursor" | "counting"): string;
/** The program constructs lifetime regions: the ProgramLifetime classes
* allocate in regions and count references in their region chunk instead
* of being empty (llvm/regions.ts). */
regions?: RegionHooks | null;
/** The target C ABI's `size_t` / refcount integer type. */
readonly sizeType: "i32" | "i64";
/** Worker executables: the inline allocator state is thread-local. */
readonly threadLocalAlloc?: boolean;
readonly tracedShapes: Set<string>;
readonly tracedUnions: Set<string>;
/** The zeroed `%ScrUnion` an inline store reads for a NULL dummy. */
unionNoneRef(): string;
}
/** What class emission asks of lifetime regions (LifetimeRegions in
@@ -845,7 +845,25 @@ type RuntimeFenceTarget =
/** The Lowerer's pass configuration (see lowerToIr). */
export interface LowererMode {
/** Symbols whose deferred diagnostics reachable emit already flushed —
* the remainder must not report them a second time. */
alreadyFlushed?: ReadonlySet<ts.Symbol>;
/** LowerOptions.externalTypes, threaded through every lowering pass. */
externalTypes?: ReadonlyMap<string, string>;
/** LowerOptions.externalTypeSpecifiersByFile, shared by every pass. */
externalTypeSpecifiersByFile?: ReadonlyMap<string, readonly string[]>;
/** Program-validated ambient declaration symbols for each FFI name.
* Undefined in discovery's legacy call-local validation path. */
ffiBindingSymbols?: ReadonlyMap<string, ReadonlySet<ts.Symbol>>;
/** The build's outbound native FFI declarations. */
ffiImports?: readonly IrFfiImport[];
/** Statically resolved child_process.fork program roots, in stable target-id order. */
forkTargets?: readonly ts.SourceFile[];
frontendServices?: FrontendServices | undefined;
/** LoadResult.inlineRequireCycleCalls. */
inlineRequireCycleCalls?: ReadonlySet<ts.Node> | undefined;
/** LowerOptions.libraryCallbacks (see there). */
libraryCallbacks?: boolean;
projectCheckJs?: boolean;
/** Names of bodies a prior reachability pass reached; null lowers everything. */
reachable?: ReadonlySet<string> | null;
@@ -853,35 +871,17 @@ export interface LowererMode {
* always-reachable init bodies and module building, and report deferred
* collection diagnostics nothing flushed. */
remainder?: boolean;
/** Symbols whose deferred diagnostics reachable emit already flushed —
* the remainder must not report them a second time. */
alreadyFlushed?: ReadonlySet<ts.Symbol>;
/** The build's target platform (LowerOptions.targetPlatform — lowerToIr
* passes it to every pass). Defaults to the host. */
targetPlatform?: string;
/** Node's startup refusal (preflight's resolution walk / named-import
* link checks): %main opens with exactly this throw, before any
* module init — Node refuses the whole graph before anything evaluates,
* so nothing runs. */
startupCrash?: StartupCrash | null;
/** LoadResult.inlineRequireCycleCalls. */
inlineRequireCycleCalls?: ReadonlySet<ts.Node> | undefined;
/** The build's outbound native FFI declarations. */
ffiImports?: readonly IrFfiImport[];
/** LowerOptions.libraryCallbacks (see there). */
libraryCallbacks?: boolean;
/** Statically resolved child_process.fork program roots, in stable target-id order. */
forkTargets?: readonly ts.SourceFile[];
workerTargets?: readonly ts.SourceFile[];
/** Program-validated ambient declaration symbols for each FFI name.
* Undefined in discovery's legacy call-local validation path. */
ffiBindingSymbols?: ReadonlyMap<string, ReadonlySet<ts.Symbol>>;
/** LowerOptions.externalTypes, threaded through every lowering pass. */
externalTypes?: ReadonlyMap<string, string>;
/** LowerOptions.externalTypeSpecifiersByFile, shared by every pass. */
externalTypeSpecifiersByFile?: ReadonlyMap<string, readonly string[]>;
/** The build's target platform (LowerOptions.targetPlatform — lowerToIr
* passes it to every pass). Defaults to the host. */
targetPlatform?: string;
/** LowerOptions.tierMode, shared by every pass. */
tierMode?: TierMode;
workerTargets?: readonly ts.SourceFile[];
}
function directExternalTypeSpecifiersByFile(
@@ -2968,28 +2968,29 @@ export class Lowerer {
readonly moduleOrder: ts.SourceFile[],
mode: LowererMode = {},
) {
// The mode's options, sorted by name; the values derived from them follow.
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
this.externalTypes = mode.externalTypes ?? new Map();
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
this.ffiImports = mode.ffiImports ?? [];
this.forkTargets = mode.forkTargets ?? [];
this.frontendServices = mode.frontendServices;
this.inlineRequireCycleCalls = mode.inlineRequireCycleCalls ?? new Set();
this.libraryCallbacks = mode.libraryCallbacks ?? false;
this.projectCheckJs = mode.projectCheckJs ?? false;
this.reachable = mode.reachable ?? null;
this.remainder = mode.remainder ?? false;
this.tierMode = mode.tierMode ?? "auto";
this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
this.targetPlatform = mode.targetPlatform ?? process.platform;
this.startupCrash = mode.startupCrash ?? null;
this.inlineRequireCycleCalls = mode.inlineRequireCycleCalls ?? new Set();
this.projectCheckJs = mode.projectCheckJs ?? false;
this.ffiImports = mode.ffiImports ?? [];
this.libraryCallbacks = mode.libraryCallbacks ?? false;
this.targetPlatform = mode.targetPlatform ?? process.platform;
this.tierMode = mode.tierMode ?? "auto";
this.workerTargets = mode.workerTargets ?? [];
this.workerTargets.forEach((sf, id) => {
this.workerTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
});
this.forkTargets = mode.forkTargets ?? [];
this.forkTargets.forEach((sf, id) => {
this.forkTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
});
this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
this.externalTypes = mode.externalTypes ?? new Map();
this.externalTypeSpecifiersByFile =
mode.externalTypeSpecifiersByFile ?? directExternalTypeSpecifiersByFile(this.externalTypes);
this.checker = program.getTypeChecker();