mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-25 06:24:27 +08:00
- mapType back-references mint placeholder shapes/unions finalized at frame exit; identity is per checker type, and context-sensitive (generic/mixin) knots stay fenced - every type walk survives cyclic shape graphs: coinductive JSON/dyn-safety predicates, guarded formatIrType/jsvalLiftable, cycle headers via the existing collector fixpoint on both backends - JSON.stringify throws V8's byte-exact circular TypeError (hop lines, ellipsis rule); cyclic values crossing into checked-dynamic slots trap instead of hanging - console.log/util.inspect render <ref *N>/[Circular *N] exactly (SEMANTICS 129 resolved; depth:null lowers) and deepStrictEqual terminates through Node's pair memo - corpus 2480-2488 green on C, LLVM, and the sanitized RC-audit lane, which proves child->parent cycles collect
32 lines
1.2 KiB
TypeScript
32 lines
1.2 KiB
TypeScript
// Runtime REFERENCE CYCLES through recursive record types: children
|
|
// pointing back at ancestors. Reference counting alone cannot free these;
|
|
// the cycle collector must — the sanitized lane's RC audit is the proof
|
|
// (this program leaks nothing).
|
|
interface TreeNode { label: string; children: TreeNode[] }
|
|
|
|
function makeCycle(tag: string): TreeNode {
|
|
const parent: TreeNode = { label: "p" + tag, children: [] };
|
|
const child: TreeNode = { label: "c" + tag, children: [] };
|
|
parent.children.push(child);
|
|
child.children.push(parent); // the back edge closes the cycle
|
|
return parent;
|
|
}
|
|
|
|
// Churn: many dead cycles, none reachable after the loop.
|
|
let survivors = 0;
|
|
for (let i = 0; i < 200; i++) {
|
|
const p = makeCycle(String(i));
|
|
if (p.children.length === 1) survivors += 1;
|
|
}
|
|
console.log(survivors);
|
|
|
|
// A live cycle read through both directions, then dropped before exit.
|
|
const ring = makeCycle("live");
|
|
console.log(ring.label, ring.children[0].label);
|
|
console.log(ring.children[0].children[0] === ring);
|
|
|
|
// Self-loop: a node whose child is itself.
|
|
const solo: TreeNode = { label: "solo", children: [] };
|
|
solo.children.push(solo);
|
|
console.log(solo.children[0] === solo, solo.children[0].label);
|