mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-25 06:24:27 +08:00
Sort ShapeHost's members and the lowerer's mode options by name (#1370)
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user