mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-04 08:04:37 +08:00
A union of two or more class arms and at most two unit arms (`A | B`, `A | B | undefined`, sum types over classes) now holds the instance pointer instead of a reference-counted %ScrUnion box, as unions of records already do. NULL and the null sentinel encode the unit arms. The arm of a value is the arm whose preorder interval holds the instance's class id. On 64-bit targets, hierarchy members already keep their class id in the high half of the rc word, or in the 32-bit header of ProgramLifetime classes. A standalone class that is an arm of such a union now keeps its id the same way and counts in the low half; the count reaches the immortal all-ones value instead of wrapping, as for hierarchy members. Each union has a tag helper that narrowing checks inline. Unions over the same classes share one retain, release and trace: retain and release use the shared 32-bit count, and only a release of the last reference dispatches on the arm to that class's release. Unions over ProgramLifetime classes retain and release nothing. When one arm carries a collector header, every class of every arm's hierarchy does. Arms may not extend one another, and must all be compact or all keep the rc word, and all be ProgramLifetime classes or none. 32-bit targets, library builds, lifetime-region programs, debug builds, and unions used as Map keys or Set elements keep boxes.