The data-shape check answered a type that refers back to a type still
being checked as a data shape and recorded that answer before the
outer check finished. With `Branch { child: Tree; handle: Handle }` and
`Tree { parent: Branch | null }`, checking Branch first recorded Tree as
a data shape, and Tree was re-exported although Branch reaches an
interface with a method. The check now walks every type reachable from
the queried one before it records any of them as a data shape, and
records the types on the path to a non-data type as non-data.
The toolchain integrity test builds a runtime pack manifest by hand. It
still declared ABI 23 after the runtime ABI moved to 24, so the staging
check rejected the pack instead of staging it.
An array constructed with a known element count of up to 16 (array
literals, copies, slices and the arrays the runtime builds) keeps its
slots in its own block, as empty arrays built for appends already do, so
it costs one allocation and one free.
scr_arr_make_ops is inlined into its two constructors, so the size class
of scr_arr_new_ops_small folds to a table index. It writes the element
ops id with the other header fields and records ops past the registry
in the array's ext after the storage is set up: the ext pointer precedes
the dense allocation, so inline slots must move out before the ext is
created.
- A local `export { Kind }` of a name the declaration file imports
(`import type { Kind } from "./kinds"`) now resolves like
`export { Kind } from "./kinds"`; it was dropped.
- The typedefs now reach a runtime entry outside the .js/.cjs rewrite
path (an .mjs file).
- Only data shapes are re-exported: an interface, type alias or enum
with no method, call or construct signature, function type or other
computed type, whose referenced types are data shapes too. An
interface with methods describes the package's JavaScript objects and
stays as the JavaScript types it (@opentelemetry/api's Counter).
- NPM_STATIC_TYPES_SUFFIX moves to npm-static.ts, so that module does
not import the syntax modules (the self-hosted frontend tests compile
it natively).
A class carries the collector header when any class in its hierarchy can
be on a cycle, so instances of classes whose own fields hold nothing
cycle-capable were buffered as candidates and walked by every level. Such
an object has no traced children and is never on a cycle.
Their descriptors now name scr_cyc_no_children, and they are allocated
with buf set to SCR_CYC_ACYCLIC. That value has the buffered bit set, so
a release that leaves the object alive makes no call; scr_cyc_is_buffered
is false for it, and an emitted death or publication mark takes the object
out of a candidate buffer only when buf is below -1. A pass that walks
such an object as a child restores the value when it survives.
The runtime call reads the cert and key options before the SNICallback,
so a cert or key initializer after the callback that reassigned the
callback's binding changed the callback the server used, and the server
could serve the wrong certificate. When SNICallback comes before a cert
or key entry, the callback is now saved just before the next of them is
evaluated. With the callback read in order, a callback expression with
side effects lowers instead of being refused.
A counted for loop needs a stable limit to run its counter in integer
storage. Array lengths qualified when the loop provably keeps them, but
a string's length did not, so `for (let i = 0; i < s.length; i++)`
kept a double counter and evaluated the length, through the UTF-16
mapping of a non-ASCII string, on every iteration. A string's length
cannot change, so it is now stable whenever the string's binding is
not rebound in the loop or boxed.
dyn.nameClassPrototype sets the class name on a class's runtime prototype
object and stores no property. The int32 field analysis did not list it as
read-only, so every program that gave a class a runtime prototype counted a
dynamic store that can name any property, and the number fields of every
class reaching dynamic code were stored as doubles.
The type mapper maps the type inferred from an empty object literal to the
empty record as an arm of an unreduced union and to a checked-dynamic
value elsewhere, but both answers shared one memo entry. Once the type had
been mapped on its own, a union such as `typeof empty | DataView` reused
the dynamic answer for its arm and refused (SC2009). The memo key now
includes whether the mapping is for such an arm.
The compiler compiles itself natively, and an empty array in an object
literal took number[] there, so the enum entry did not match the
declaration record. The coverage snapshot of native-npm-imports now
counts one dynamic-tier statement instead of three: the program's
`const point: Vector` takes the interface from the package's .d.ts
instead of any.
The compiler's own source has 24 likely-hot functions that use untyped
values, so its self-builds now print SC6101. The native bootstrap
contracts compare stderr exactly; the rebuilds of the compiler entry pass
--no-dynamic-tier-warning, which changes no IR or LLVM output.
On the error path, a callback's result reads from a checked-dynamic
slot. Passing it on into a Buffer parameter still handed over the
adapter's original value, so after `if (!out) out = Buffer.from(...)`
a typed callee received the absent Buffer instead of the fallback and
crashed. The forward now tests the slot: while it holds undefined the
callee gets the absent Buffer, and otherwise the Buffer the slot holds.