Repository navigation
contrib.host: Duktape bidirectional API, QuickJS as a host - #3487
Merged
Merged
Conversation
- Part A: Add bidirectional embedding API to contrib/host/duktape and contrib/host/js (persistent VM, dotted callbacks, typed values, global setters, and execution limit check). - Part B: Add contrib/host/quickjs as a member of the contrib/host family with shared run / run_sandboxed / run_sandboxed_with_map surface. Co-authored-by: paul-hammant <82182+paul-hammant@users.noreply.github.com>
- Part A: Add bidirectional embedding API to contrib/host/duktape and contrib/host/js (persistent VM, dotted callbacks, typed values, global setters, and execution limit check). - Part B: Add contrib/host/quickjs as a member of the contrib/host family with shared run / run_sandboxed / run_sandboxed_with_map surface. Co-authored-by: paul-hammant <82182+paul-hammant@users.noreply.github.com>
…ckJS links alone Duktape: - duktape_raise_error pushed an Error and threw at once, longjmp-ing out of the Aether callback past its defers. It now returns a sentinel and the trampoline throws once the callback has returned. - The trampoline handed the callback's return to Duktape unchanged; 2 or more is an invalid return there and a negative one a thrown error code. It now returns 1 for "the stack top" or 0. - vm_result_int / arg_int cast a JS number straight to int64_t, undefined behaviour for NaN or an out-of-range value. Non-numbers and NaN now read as 0 and out-of-range values saturate. - A thrown non-Error (`throw "x"`) read as a string result; it is now wrapped in an Error, so vm_result_type says DUKTAPE_TERR. - vm_register truncated a name of 256 characters or more to the buffer and registered the wrong name; it now refuses it. - The spec's `let keys: *StringList = [...]` compiled to an int array, so the strlist global never held strings and that assertion failed; it now builds a std.list. New cases cover each fix above, with 64-bit compares (spec.assert_eq takes int and truncated INT64_MIN to 0). - The integration script skipped where libduktape is installed with its header in /usr/include (pkg-config prints no flags there), and turned a failed harness build into a SKIP. It now detects headers separately and fails a broken build. QuickJS: - A program importing only contrib.host.quickjs failed to link (qjs_* undefined), the example included: the module now imports contrib.quickjs, whose @source compiles the engine in. The spec passed only because it imported both. - The C used qjs_global and qjs_set undeclared (an error under Apple clang and GCC 14) and declared a qjs_set_global that doesn't exist. - "run_sandboxed enforces sandbox grants" never called run_sandboxed; it is renamed for what it checks (host functions under sandbox.enforce), and a new case checks both wrappers leave the grant stack as they found it, also when the script throws. Docs: the README for QuickJS no longer claims run_sandboxed checks host functions it doesn't have; Duktape's raise_error row says when the throw happens; containment-sandbox.md lists contrib.host.js again. Changelog fragments rewritten. Every fix was undone once and its test failed; all restored pass. Duktape 7 and QuickJS 6 spec cases pass, valgrind-clean; contrib-host-check and every static gate pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two JavaScript-hosting changes, drafted by Jules (paul-hammant#45, merged here unchanged) and shaped in the commit on top.
Duktape gets Lua's bidirectional embedding API (#904): a persistent VM, Aether callbacks the script calls by dotted name (
vm_register(vm, "app.math.add", fn)), typed arguments and returns, global setters, and typed eval results with Lua's type tags.contrib.host.js(its alias) gets the same.vm_set_instruction_limithonestly reports the limit unavailable: the system libduktape this host loads is built withoutDUK_USE_EXEC_TIMEOUT_CHECK(checked against Debian's 2.7.0duk_config.h).QuickJS joins the
contrib/hostfamily.contrib.host.quickjswrapscontrib.quickjswith the surface every host shares:run,run_sandboxed,run_sandboxed_with_map,init,finalize. The engine has no file, network or OS access of its own, so grants decide only what the Aether host functions a script calls may do.contrib.quickjs's API is unchanged (sae depends on it).What the shaping commit fixes
Duktape:
raise_errorthrew at once, longjmp-ing out of the Aether callback past its defers. It now returns a sentinel and the trampoline throws after the callback has returned.vm_result_int/arg_intcast NaN or out-of-range numbers toint64_t, which is undefined behaviour. They now read 0 or saturate.throw "x"read as a string result; it now reads as an error.vm_registersilently truncated names of 256+ characters; it now refuses them./usr/include), and turned a failed harness build into a SKIP; both fixed.QuickJS:
contrib.host.quickjsfailed to link, the new example included. The module now importscontrib.quickjs, whose@sourcecompiles the engine in. (check-examplesonly type-checks host examples, so it didn't notice.)qjs_global/qjs_setundeclared, an error under Apple clang and GCC 14.run_sandboxed. It's renamed for what it checks, and a new case checks that both wrappers leave the grant stack as they found it, also when the script throws.Docs, the QuickJS README's claim about grants, and the changelog fragments are corrected.
Checked
make contrib-host-check: aether 6, duktape 7, lua 5, perl 5, python 5, quickjs 6.ae fmt,check-docs,check-changelog,check-tests,check-warnings,check-raw-calls,check-extern-widths,check-standalone,check-crypto-wipe,check-archive-exports-nozlibpass;check-examplespasses apart from a local untracked build artifact.-Wall -Wextra -Werror(QuickJS) and with no implicit declarations (Duktape).For the maintainers
contrib.host.jsstill aliases Duktape (ES5, system library). Whether it should point at QuickJS (ES2023, compiled in, no ambient OS access, the engine sae chose) is left open.🤖 Generated with Claude Code