Skip to content

chore: bump napi submodule: non-zero heap_size_limit on QuickJS - #145

Closed
Arshia001 wants to merge 2 commits into
fix/wasix-skip-dgram-shared-portsfrom
fix/quickjs-heap-size-limit
Closed

Arshia001 wants to merge 2 commits into
fix/wasix-skip-dgram-shared-portsfrom
fix/quickjs-heap-size-limit

Conversation

@Arshia001

Copy link
Copy Markdown
Member

Stacked on #144. Merge bottom-up: #143#144 → this → #115.

Picks up wasmerio/napi#57 (stacked on napi#54, which #143 already pins).

Why this is needed

#144 fixes the dgram timeout, and v8-wasix goes green — but quickjs-wasix then fails at a later step it had never previously reached:

v8 heap statistics report the embedder limit stdout mismatch
expected: 'HEAP true\n'   actual: 'HEAP false\n'

This is not a regression from #144. The check was added to scripts/test-wasix-safe-mode.py on 2026-08-05 (b7b3c149) — the same day the dgram regression began aborting that job at the earlier test-suite step. Since then the smoke-test step has never run to completion on the QuickJS lane, so the check has never passed there. Skipping the dgram test is simply what let CI get far enough to see it.

Confirmed against the last green run (30567886962, 2026-07-30): the case did not exist yet, and the smoke-test step passed.

Root cause

unofficial_napi_get_heap_statistics() in the QuickJS backend memsets the struct and fills only the size fields, leaving heap_size_limit at 0. The V8 backend sets it from stats.heap_size_limit(), which is why v8-wasix was unaffected.

It can't be forwarded directly either: QuickJS spells "no limit" as malloc_limit == 0, the inverse of the N-API convention. napi#57 translates between them — a configured limit is reported as-is, an unset one reports the address-space ceiling (on wasm32, SIZE_MAX = 4 GiB − 1, exactly the linear-memory ceiling).

Per the check's own comment this is a real bug, not just a test artifact: Next.js reads the value to decide whether a worker is near its heap limit, and a zero makes its memory watchdog exit eagerly.

Verification

Rebuilt the quickjs-wasix guest with the bump; the full safe-mode suite passes:

[ok] v8 heap statistics report the embedder limit: HEAP true
All WASIX safe-mode smoke tests passed.

Values now reported under WASIX:

heap_size_limit      = 4294967295
used_heap_size       = 4107220
total_available_size = 4290860075

Picks up wasmerio/napi#57, which makes the QuickJS backend report a real
heap_size_limit instead of 0.

This unblocks the quickjs-wasix lane. scripts/test-wasix-safe-mode.py
gained a "v8 heap statistics report the embedder limit" case on
2026-08-05 (b7b3c14), the same day the dgram regression started aborting
that job at the earlier test-suite step. The smoke-test step has never
run to completion on the QuickJS lane since, so the check has never
passed there; skipping the dgram test in the parent commit is what first
let CI reach it, and it failed with

  expected: 'HEAP true\n'  actual: 'HEAP false\n'

The V8 backend was always fine, which is why v8-wasix stayed green.

With the bump the whole safe-mode suite passes locally against the
quickjs-wasix build.
child_process.exec() and execSync() do not spawn the command directly --
they run it through `/bin/sh -c`. The root package ships no shell, so
every exec() in the V8 WASIX package failed to spawn one. The QuickJS
package has declared this dependency since it was created; this one
never did.

Surfaced by test-http-chunk-problem and test-http-full-response on the
v8-wasix lane, which #115 stops skipping. Both exec an external tool and
both are written to cope with it being absent, but they never got the
chance: with no shell to resolve, the spawn failed before their callback
ran. They pass on quickjs-wasix, which has the shell.

The uncaught throw those tests hit is a second, separate bug --
proc_spawn reported ENOEXEC rather than ENOENT for an unresolvable
command, and Node only converts a known errno set into an 'error' event
(wasmerio/wasmer#6877). Either fix alone makes these two tests pass; both
are worth having, since this one also makes exec() work at all.
@syrusakbary

Copy link
Copy Markdown
Member

This PR is no longer necessary, main has napi from main (with latest changes mentioned in this PR), and we added wasmer/bash dependency as well.

We can close this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants