mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
- Compile native collection views and recursive discriminated IR structures. - Preserve optional-chain behavior and union payload ownership across C and LLVM. - Exercise real IR builders and analyses in native executables with differential coverage.
74 lines
2.5 KiB
TypeScript
74 lines
2.5 KiB
TypeScript
export {};
|
|
|
|
// An optional receiver contains several array representations. Each array
|
|
// element has its own tag layout, distinct from the joined result union.
|
|
type Payload = { name: string; values: number[] };
|
|
type Source = (Payload | null)[] | (string | null)[] | undefined;
|
|
const shared: Payload = { name: "shared", values: [1] };
|
|
const records: (Payload | null)[] = [shared, null];
|
|
const strings: (string | null)[] = ["text", null];
|
|
let evaluations = 0;
|
|
let indexes = 0;
|
|
|
|
function source(mode: number): Source {
|
|
evaluations++;
|
|
if (mode === 0) return records;
|
|
if (mode === 1) return strings;
|
|
return undefined;
|
|
}
|
|
function index(value: number): number {
|
|
indexes++;
|
|
return value;
|
|
}
|
|
function show(mode: number, offset: number): void {
|
|
const value = source(mode)?.[index(offset)];
|
|
if (value === undefined) console.log("undefined");
|
|
else if (value === null) console.log("null");
|
|
else if (typeof value === "string") console.log("string", value);
|
|
else {
|
|
value.values.push(2);
|
|
console.log("payload", value.name, value.values.join(","));
|
|
}
|
|
}
|
|
for (let mode = 0; mode < 3; mode++) {
|
|
show(mode, 0);
|
|
show(mode, 1);
|
|
}
|
|
console.log("evaluations", evaluations, indexes);
|
|
console.log("shared", shared.values.join(","));
|
|
|
|
// Index evaluation may replace the receiver's original binding. The
|
|
// optional-chain guard and widened result each retain the right owner.
|
|
let active: Source = records;
|
|
function current(): Source { return active; }
|
|
function replace(): number {
|
|
active = strings;
|
|
return 0;
|
|
}
|
|
const before = current()?.[replace()];
|
|
if (before && typeof before !== "string") console.log("before", before.name);
|
|
console.log("after", current()?.[0]);
|
|
|
|
// An owned temporary array disappears after the read. The widened box
|
|
// must retain its reference payload before releasing the original box.
|
|
function fresh(mode: number): (Payload | null)[] | (string | null)[] {
|
|
if (mode === 0) return [{ name: "fresh", values: [7, 8] }];
|
|
return ["fresh text"];
|
|
}
|
|
let total = 0;
|
|
for (let i = 0; i < 200; i++) {
|
|
const value = fresh(i % 2)[0];
|
|
if (typeof value === "string") total += value.length;
|
|
else if (value !== null) total += value.values.length;
|
|
}
|
|
console.log("temporary total", total);
|
|
|
|
// A missing receiver and a present null element take different unit
|
|
// paths; a lazy default runs once for each and never for present strings.
|
|
let defaults = 0;
|
|
function fallback(): string { defaults++; return "fallback"; }
|
|
console.log(source(1)?.[0] ?? fallback());
|
|
console.log(source(1)?.[1] ?? fallback());
|
|
console.log(source(2)?.[0] ?? fallback());
|
|
console.log("defaults", defaults);
|