Skip to content

Fix compat with quickjs ng 0.16 - #1115

Merged
xeioex merged 3 commits into
nginx:masterfrom
xeioex:fix-compat-with-quickjs-ng-0.16
Aug 20, 2026
Merged

Fix compat with quickjs ng 0.16#1115
xeioex merged 3 commits into
nginx:masterfrom
xeioex:fix-compat-with-quickjs-ng-0.16

Conversation

@xeioex

@xeioex xeioex commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread src/qjs.c Outdated
@xeioex
xeioex force-pushed the fix-compat-with-quickjs-ng-0.16 branch from eec38c7 to 4dc76b8 Compare August 16, 2026 20:53
xeioex added 2 commits August 17, 2026 09:33
Two separate problems prevented njs from working with the recent
quickjs-ng releases.

JS_NewArrayBuffer() has grown a "max_len" argument and its free callback
has become a realloc one.  The calls are wrapped now, the callback has
to implement the whole realloc contract, because transfer() reallocates
the data even for a buffer which is not resizable.

The class ids used by njs started at 64, while the engine reserves the
ids below JS_CLASS_INIT_COUNT, which has reached 67.  JS_NewClass()
failed with a collision and the context could not be created.  The ids
are moved above the engine range and the remaining unchecked
JS_NewClass() calls now report the failure.

This fixes nginx#1113 issue on Github.
An error created outside of a JS frame, from a fetch() completion
callback for instance, records an empty stack.  Up to QuickJS-NG 0.15.1
deleting the recorded "stack" property let the engine attach a real one
where the error was thrown.  Since 0.16.0 the stack is kept in the error
internal data behind an accessor, the property to delete no longer
exists and the empty stack became final.

JS_NewError() is JS_NewObjectClass() plus the stack recording, and the
first half alone is reachable through the public API.  Creating the
object that way records nothing, so the engine attaches the stack at the
throw site.  This works the same way for every supported engine, hence
the feature test is gone.
@xeioex
xeioex force-pushed the fix-compat-with-quickjs-ng-0.16 branch from 4dc76b8 to d000dcc Compare August 17, 2026 16:40
@xeioex
xeioex requested a review from VadimZhestikov August 17, 2026 16:57
@sindhushiv sindhushiv added the njs label Aug 18, 2026
A static library has to be asked for explicitly since 0.16.0, otherwise
the library is installed as a shared object outside of the loader search
path, the configure test binary fails to start and the library is
reported as not working.
@xeioex
xeioex force-pushed the fix-compat-with-quickjs-ng-0.16 branch from d000dcc to 75e2606 Compare August 20, 2026 15:55

@VadimZhestikov VadimZhestikov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Minor observations (non-blocking)

  1. The 128 offset is heuristic, not future-proof. It's JS_CLASS_INIT_COUNT (67)
    plus headroom, and the comment says as much. If a future quickjs-ng grows
    JS_CLASS_INIT_COUNT past 128, or heavy dynamic class allocation reaches 128
    before njs registers, the collision returns. It's the one thing to re-check on
    future engine bumps. A compile-time guard would be ideal but JS_CLASS_INIT_COUNT
    isn't a stable public constant, so the pragmatic fixed offset is acceptable.
  2. Commit 2 also changes behavior on older engines (it removed the version gate),
    now always using the JS_NewObjectClass path. It's sound by construction (the
    JS_NewError == JS_NewObjectClass + stack invariant holds across versions) and CI
    covers older engines — I verified it on 0.16.2 but didn't run an older build.
  3. External-buffer + transfer() at the same length moves the pool-backed pointer
    into a new ArrayBuffer (engine won't free it — correct). The "retained past its
    pool" lifetime concern there is the pre-existing external-buffer class (the
    #1112/N2 territory), not introduced by this PR.

@github-project-automation github-project-automation Bot moved this from New to In Review in NGINX OSS Unified Workspace Aug 20, 2026
@xeioex
xeioex merged commit 3e02ae0 into nginx:master Aug 20, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Done in NGINX OSS Unified Workspace Aug 20, 2026
@xeioex
xeioex deleted the fix-compat-with-quickjs-ng-0.16 branch August 20, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants