mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-17 05:09:24 +08:00
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
// Cycles THROUGH array elements — the collector case the REF element kind
|
|
// opens: an element points back at the array that owns it. Class instances
|
|
// are the way in (recursive record shapes are untypeable — SC2001), and
|
|
// arrays of cycle-capable elements allocate with collector headers so the
|
|
// trace can walk array -> element -> array. The sanitized lane asserts
|
|
// every dropped cycle is collected, exactly once.
|
|
class Self {
|
|
siblings: Self[];
|
|
tag: string;
|
|
constructor(tag: string) {
|
|
this.tag = tag;
|
|
this.siblings = [];
|
|
}
|
|
}
|
|
|
|
// element -> owning array (the minimal 2-cycle: arr -> s -> arr)
|
|
function ring(tag: string): number {
|
|
const arr: Self[] = [];
|
|
const s = new Self(tag);
|
|
s.siblings = arr; // s points at the array...
|
|
arr.push(s); // ...and the array owns s
|
|
return arr.length + s.siblings.length;
|
|
}
|
|
console.log(ring("a"));
|
|
for (let i = 0; i < 300; i++) ring(`r${i}`);
|
|
|
|
// two instances cross-linked through each other's element arrays, plus an
|
|
// inner array-of-arrays hop (traced arrays as elements of traced arrays)
|
|
function cross(n: number): number {
|
|
const x = new Self(`x${n}`);
|
|
const y = new Self(`y${n}`);
|
|
x.siblings.push(y);
|
|
y.siblings.push(x);
|
|
const nest: Self[][] = [[x], [y]];
|
|
return nest[0][0].siblings.length + nest[1][0].siblings.length;
|
|
}
|
|
console.log(cross(0));
|
|
for (let i = 0; i < 300; i++) cross(i);
|
|
|
|
// closure-through-record elements: record arrays whose elements capture the
|
|
// array binding (record -> closure -> box -> array -> record).
|
|
type Cb = { name: string; poke: () => number };
|
|
function viaClosure(tag: string): number {
|
|
const cbs: Cb[] = [];
|
|
cbs.push({ name: tag, poke: (): number => cbs.length });
|
|
return cbs[0].poke();
|
|
}
|
|
console.log(viaClosure("c"));
|
|
for (let i = 0; i < 300; i++) viaClosure(`c${i}`);
|
|
|
|
console.log("done");
|