Vtables store the borrowing body of a method whose slot borrows its
parameters, but that decision lived in private emitter state, so the
self-hosting layout fixture kept emitting owned entries and no longer
matched production (`@sc_f_...` vs `@sc_bf_...`).
Move the decision into VirtualBorrows (virtual-borrows.ts), used by the
emitter and by the fixture, which now runs the same call-lifetimes
analysis. The slot lookup narrows explicitly instead of combining a
union with `&&`/`||`, which the self-hosted subset rejects (SC1090). The
abstract-slot emission case now expects the borrowing body, since its
implementation borrows its receiver.
emitLlvmLayouts now takes the whole-program int32 slot facts, but the
self-hosting layout fixture never passed them and only imported the
Int32Slots type, so the self-compiled stage could not represent
`Int32Slots | undefined` (SC2009). Compute them with analyzeInt32Slots
like the emitter does, so the fixture compiles statically and its native
output mirrors production int32 field storage.
WalkerHost now carries the nullable-union registry and the record-field ABSENT test; the natively compiled layout/metadata fixture builds them the same way the emitter does.
Every console.log/error/warn line and process.stdout/stderr.write chunk
is still submitted before the call returns, as in Node. On POSIX
executables, each one now goes out as exactly one write(2) on fd 1 or 2.
Before, it went through C stdio, which cost a copy into the stdio
buffer, one stream call per argument, separator, and newline, and a
flush. stderr is unbuffered, so console.error made one write(2) per
piece: 3 writes per line on average in the probe.
- The line renders into a 2 KiB stack buffer (heap above that). A large
single string goes out with writev and no copy.
- Short writes continue and EINTR retries. Other errors (EAGAIN, EPIPE,
EBADF) return errno with the rest dropped, which is what the stdio
flush did. console still ignores them, and SIGPIPE behavior is
unchanged.
- Runtime-internal bytes still in the C stdout buffer are flushed first
(__fpending on Linux, the FILE fields on Darwin, an unconditional
flush elsewhere), so stdout order and merged 2>&1 order are kept.
- Windows, WASI, and library artifacts keep the C stream path, now fed
one formatted chunk per call.
Tests: corpus 4294 covers line sizes across the stack buffer and the
64 KiB stdio buffer. New console-io harness cases cover stdout and
stderr merged into one pipe and into one file (byte-compared with
Node), and console.log after the stdout reader closes (EPIPE).
Linux sandbox, ns per line (median of 9 launches, 200k lines; scriptc
includes ~1 ms startup). All outputs byte-identical to Node.
probe target node prev cand
p-str pipe 4040 1323 1239
p-str file 3092 849 790
p-str null 2193 319 283
p-args pipe 6168 1440 1228
p-args file 4896 925 802
p-args null 3916 389 292
p-write pipe 2889 1328 1197
p-write file 2267 809 769
p-write null 1577 297 265
p-err pipe 4672 3253 1132
p-err file 3478 2042 717
p-err null 2614 562 232
log-lines pipe 4958 1490 1356
log-lines file 3885 966 877
log-lines null 2983 425 368
strace -c (pipe): p-err went from 600,000 to 200,000 write calls. The
other probes stay at one write per line.
Re-lands perf/h30-inline-rc (00051ca0, 40398773, 07972360) behind the
speed posture. With inline RC on, every mirrored runtime RC family
retains inline and releases inline down to the rc == 1 / new cycle
candidate slow path (shapes.ts INLINE_RC_FAMILIES). Release emission is
unchanged: ShapeHost.rcHelpers is null unless LlvmTargetOptions.inlineRc
is set, and every retain/release (including capture boxes) stays a
runtime call; the %ScrMapRc type is only emitted with inline RC.
- index.ts and native/prepare.ts pass inlineRc for speed executables,
speed object/asm emission, and speed library profiles.
- scr_runtime.h keeps H30's static asserts for the mirrored header and
trace-slot offsets (no code change; the rebuilt macOS pack's manifest is
identical to the baseline's).
- Tests: shapes.test.ts pins release symbols and H30's speed fast paths
and header offsets; emitter.test.ts pins that release IR is unchanged
and speed routes releases through the helpers. The differential harness
gains `// @optimization: speed` (and a SCRIPTC_TEST_OPTIMIZATION=speed
lane); corpus 4032 pins every mirrored family under speed.
Release executables stay byte-identical to the stack tip (14/14
workloads, macOS).
Multi-megabyte end(data) and chunked write() bodies under a slow raw
reader force partial vectored sends; the driver checks framing, length,
and digest of every response against Node.
The full emitter inlines the small-object allocator on 64-bit host targets,
so the self-hosting layout fixture's host enables inlineAlloc for 64-bit
requests (as emitLlvmModule does), and the recursive-records case no longer
asserts the width-specific free path (64-bit pushes onto the allocator's
free list; 32-bit calls scr_cyc_free).
(Split from the stack's later "Update self-hosting emission cases for
acyclic proofs and inline allocation"; the acyclic-proof half moves to the
construction-only acyclic change.)
- Preserve callback identity, receiver binding, and class references across unions and collections.
- Track record field presence independently of undefined values and improve native runtime behavior.
- Expand differential coverage and streamline CI bootstrap and compiler rebuild checks.
- Add native worker execution with isolated module state, structured messages, and lifecycle controls.
- Support shared buffers and integer atomics with coordinated runtime ownership and cancellation.
- Extend compiler, runtime-pack, differential, and compatibility coverage for native concurrency.
- Defer empty callback storage while preserving method and prototype updates.
- Reuse source and node-handle information within compiler snapshots.
- Coalesce small checker requests and avoid response copies.
- Derive builtin call names from shared signatures and keep call semantics with their ABI contracts.
- Separate runtime dependency detection, exception metadata, and library policy from the core IR while preserving existing exports.
- Enforce the frontend signature boundary and validate native compilation and policy behavior.
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks.
- Preserve compiler import boundaries and protected fixtures while cleaning up lint findings.
- Standardize source formatting and validate import, fixture, and embedded-source protections.
- Separate conversion planning, helper generation, and timer lowering into focused modules.
- Share array, closure, record projection, and builtin dispatch logic, including timer namespace calls.
- Validate shared helpers with native correctness and differential coverage.
- Read binary and text files into owned storage across filesystem entry points.
- Extend integer inference through module initialization and filtered processing loops.
- Preserve shared bindings, byte views, and filesystem error behavior.
- Support boolean, bigint, and mixed value keys in native Maps and Sets.
- Reuse key hashes and copy collections directly into compact storage.
- Preserve collection identity, ordering, iteration, and ownership behavior.
* Add Node 24 filesystem link support
* Use executable extensions in Windows link fixtures
* Remove Windows links without walking their targets
* Match Windows symlink inference and Buffer validation
* Match Node Windows symlink paths and fallback state
* Preserve Windows errors when following filesystem links
* feat: support Node 24 filesystem timestamp operations
* test: record frontend baselines for timestamp fixtures
* test: link timestamp validation into the runtime smoke test
* Add Node 24 URL factories and shared parsing
* Clarify URL fixture name and remaining refusal coverage
* Update island URL test for protocol-relative resolution
* Expand Node 24 filesystem descriptor and FileHandle support
* Preserve filesystem options getter evaluation and record fixture baselines
* Normalize the known Linux fiber warning in npm stderr comparisons
* Speed up native compiler traversal and union handling
* Index live deferred initializer placeholders per worklist pass
* Record preflight baseline for deferred registry corpus