From 9cbffbfebe63fac1d10c1a3e2018f19c20772ffe Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 16 Aug 2026 21:56:42 +0200 Subject: [PATCH 1/2] QuickJS: switch to JSReallocArrayBufferDataFunc QuickJS 0.16.0 adds support for externally managed resizable arraybuffers, with a concomitant change to the function prototype of JS_NewArrayBuffer(). Add a configure check and use the new prototype when available. Fixes: https://github.com/nginx/njs/issues/1113 Refs: https://github.com/quickjs-ng/quickjs/issues/1668 --- auto/quickjs | 32 ++++++++++++++++++++++++++++++++ external/njs_shell.c | 7 +++++++ src/qjs.c | 16 ++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/auto/quickjs b/auto/quickjs index 630f98700..6379fbe56 100644 --- a/auto/quickjs +++ b/auto/quickjs @@ -187,6 +187,38 @@ if [ $NJS_TRY_QUICKJS = YES ]; then . auto/feature + njs_feature="QuickJS sized JS_NewArrayBuffer()" + njs_feature_name=NJS_HAVE_QUICKJS_SIZED_NEW_ARRAY_BUFFER + njs_feature_test="#include + + static void *realloc_ab(JSRuntime *rt, void *opaque, + void *ptr, size_t size) { + (void) rt; + (void) opaque; + (void) ptr; + (void) size; + return 0; + } + + int main() { + JSValue ab; + JSRuntime *rt; + JSContext *ctx; + uint8_t b; + + b = 0; + rt = JS_NewRuntime(); + ctx = JS_NewContext(rt); + ab = JS_NewArrayBuffer(ctx, &b, 1, 1, realloc_ab, + NULL, 0); + JS_FreeValue(ctx, ab); + JS_FreeContext(ctx); + JS_FreeRuntime(rt); + return 0; + }" + + . auto/feature + njs_feature="QuickJS JS_NewError() attaches stack" njs_feature_run=value njs_feature_name=NJS_HAVE_QUICKJS_NEW_ERROR_STACK diff --git a/external/njs_shell.c b/external/njs_shell.c index b65b98aae..37b771936 100644 --- a/external/njs_shell.c +++ b/external/njs_shell.c @@ -2081,9 +2081,16 @@ njs_qjs_agent(void *arg) pthread_cond_signal(&console->agent_cond); pthread_mutex_unlock(&console->agent_mutex); +#ifdef NJS_HAVE_QUICKJS_SIZED_NEW_ARRAY_BUFFER + args[0] = JS_NewArrayBuffer(ctx, agent->broadcast_sab_buf, + agent->broadcast_sab_size, + agent->broadcast_sab_size, + NULL, NULL, 1); +#else args[0] = JS_NewArrayBuffer(ctx, agent->broadcast_sab_buf, agent->broadcast_sab_size, NULL, NULL, 1); +#endif args[1] = JS_NewInt32(ctx, agent->broadcast_val); ret_val = JS_Call(ctx, agent->broadcast_func, JS_UNDEFINED, diff --git a/src/qjs.c b/src/qjs.c index c8ed8eafb..1805a6ec1 100644 --- a/src/qjs.c +++ b/src/qjs.c @@ -1252,6 +1252,21 @@ qjs_typed_array_data(JSContext *ctx, JSValueConst value, njs_str_t *data) } +#ifdef NJS_HAVE_QUICKJS_SIZED_NEW_ARRAY_BUFFER +static void * +js_array_buffer_realloc(JSRuntime *rt, void *opaque, void *ptr, size_t size) +{ + return js_realloc_rt(rt, ptr, size); +} + + +JSValue +qjs_new_array_buffer(JSContext *cx, uint8_t *src, size_t len) +{ + return JS_NewArrayBuffer(cx, src, len, len, js_array_buffer_realloc, + NULL, 0); +} +#else static void js_array_buffer_free(JSRuntime *rt, void *opaque, void *ptr) { @@ -1264,6 +1279,7 @@ qjs_new_array_buffer(JSContext *cx, uint8_t *src, size_t len) { return JS_NewArrayBuffer(cx, src, len, js_array_buffer_free, NULL, 0); } +#endif JSValue From 42742cc1c4ebe05d21fb76a59bf9f5e22249319b Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 16 Aug 2026 21:56:42 +0200 Subject: [PATCH 2/2] QuickJS: don't overlap the built-in class ids It causes JSContext initialization failures with QuickJS-NG 0.16.0 and up. --- src/qjs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qjs.h b/src/qjs.h index 365361520..a10ca9c6d 100644 --- a/src/qjs.h +++ b/src/qjs.h @@ -23,7 +23,7 @@ enum { - QJS_CORE_CLASS_ID_BUFFER = 64, + QJS_CORE_CLASS_ID_BUFFER = 128, QJS_CORE_CLASS_ID_UINT8_ARRAY_CTOR, QJS_CORE_CLASS_ID_TEXT_DECODER, QJS_CORE_CLASS_ID_TEXT_ENCODER,