[njs] QuickJS: added support for QuickJS-NG library.
noreply at nginx.com
noreply at nginx.com
Fri Jan 24 23:13:02 UTC 2025
details: https://github.com/nginx/njs/commit/d4f12ad9a96b16bf02ac09d52908299e2bf0f431
branches: master
commit: d4f12ad9a96b16bf02ac09d52908299e2bf0f431
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue, 21 Jan 2025 17:09:06 -0800
description:
QuickJS: added support for QuickJS-NG library.
---
auto/quickjs | 72 ++++++++++++++++++++++++++++++++++++++++++++----
external/qjs_fs_module.c | 22 +++++++--------
nginx/config | 36 ++++++++++++++++++++----
nginx/config.make | 4 +--
src/qjs.h | 8 +++++-
test/shell_test.exp | 12 ++++----
6 files changed, 124 insertions(+), 30 deletions(-)
diff --git a/auto/quickjs b/auto/quickjs
index 9aeb485a..97432142 100644
--- a/auto/quickjs
+++ b/auto/quickjs
@@ -53,9 +53,19 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
. auto/feature
fi
+ if [ $njs_found = no ]; then
+ njs_feature="QuickJS-NG library -lqjs"
+ njs_feature_incs=""
+ njs_feature_libs="-lqjs -lm -ldl -lpthread"
+
+ . auto/feature
+ fi
+
+
if [ $njs_found = yes ]; then
njs_feature="QuickJS JS_GetClassID()"
+ njs_feature_name=NJS_HAVE_QUICKJS_GET_CLASS_ID
njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored \"-Wcast-function-type\"
@@ -64,7 +74,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
#include <quickjs.h>
int main() {
- (void) JS_GetClassID;
+ (void) JS_GetClassID(JS_UNDEFINED);
return 0;
}"
@@ -78,6 +88,7 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
fi
njs_feature="QuickJS JS_NewTypedArray()"
+ njs_feature_name=NJS_HAVE_QUICKJS_NEW_TYPED_ARRAY
njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored \"-Wcast-function-type\"
@@ -86,15 +97,66 @@ if [ $NJS_TRY_QUICKJS = YES ]; then
#include <quickjs.h>
int main() {
- (void) JS_NewTypedArray;
+ JSValue ta, argv;
+ JSRuntime *rt;
+ JSContext *ctx;
+
+ rt = JS_NewRuntime();
+ ctx = JS_NewContext(rt);
+ argv = JS_NewInt64(ctx, 1);
+ ta = JS_NewTypedArray(ctx, 1, &argv,
+ JS_TYPED_ARRAY_UINT8);
+ JS_FreeValue(ctx, ta);
+ JS_FreeContext(ctx);
+ JS_FreeRuntime(rt);
return 0;
}"
. auto/feature
- if [ $njs_found = yes ]; then
- njs_define=NJS_HAVE_QUICKJS_NEW_TYPED_ARRAY . auto/define
- fi
+ njs_feature="QuickJS JS_IsSameValue()"
+ njs_feature_name=NJS_HAVE_QUICKJS_IS_SAME_VALUE
+ njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored \"-Wcast-function-type\"
+ #endif
+
+ #include <quickjs.h>
+
+ int main() {
+ JSRuntime *rt;
+ JSContext *ctx;
+
+ rt = JS_NewRuntime();
+ ctx = JS_NewContext(rt);
+ (void) JS_IsSameValue(ctx, JS_UNDEFINED, JS_UNDEFINED);
+ JS_FreeContext(ctx);
+ JS_FreeRuntime(rt);
+ return 0;
+ }"
+
+ . auto/feature
+
+ njs_feature="QuickJS version"
+ njs_feature_name=NJS_QUICKJS_VERSION
+ njs_feature_run=value
+ njs_feature_test="#if defined(__GNUC__) && (__GNUC__ >= 8)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored \"-Wcast-function-type\"
+ #endif
+
+ #include <quickjs.h>
+
+ int main() {
+#if defined(QJS_VERSION_MAJOR)
+ printf(\"\\\"%s\\\"\", JS_GetVersion());
+#else
+ printf(\"\\\"Unknown\\\"\");
+#endif
+ return 0;
+ }"
+
+ . auto/feature
NJS_HAVE_QUICKJS=YES
NJS_QUICKJS_LIB="$njs_feature_libs"
diff --git a/external/qjs_fs_module.c b/external/qjs_fs_module.c
index fc2222ff..2adeef20 100644
--- a/external/qjs_fs_module.c
+++ b/external/qjs_fs_module.c
@@ -397,7 +397,7 @@ qjs_fs_access(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, mode, callback)) {
+ if (qjs_is_same_value(cx, mode, callback)) {
mode = JS_UNDEFINED;
}
}
@@ -586,7 +586,7 @@ qjs_fs_mkdir(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -894,7 +894,7 @@ qjs_fs_read_file(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -955,7 +955,7 @@ qjs_fs_read_file(JSContext *cx, JSValueConst this_val, int argc,
str.length = sb.st_size;
v = qjs_fs_fd_read(cx, fd, &str);
- if (!JS_SameValue(cx, v, JS_TRUE)) {
+ if (!qjs_is_same_value(cx, v, JS_TRUE)) {
if (JS_IsException(v)) {
result = JS_EXCEPTION;
@@ -1012,7 +1012,7 @@ qjs_fs_readlink(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -1150,7 +1150,7 @@ qjs_fs_readdir(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -1309,7 +1309,7 @@ qjs_fs_realpath(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -1655,7 +1655,7 @@ qjs_fs_rmdir(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -1817,7 +1817,7 @@ qjs_fs_stat(JSContext *cx, JSValueConst this_val, int argc, JSValueConst *argv,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
@@ -1916,7 +1916,7 @@ qjs_fs_symlink(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, type, callback)) {
+ if (qjs_is_same_value(cx, type, callback)) {
type = JS_UNDEFINED;
}
}
@@ -2168,7 +2168,7 @@ qjs_fs_write_file(JSContext *cx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
- if (JS_SameValue(cx, options, callback)) {
+ if (qjs_is_same_value(cx, options, callback)) {
options = JS_UNDEFINED;
}
}
diff --git a/nginx/config b/nginx/config
index 436f06cb..8e920477 100644
--- a/nginx/config
+++ b/nginx/config
@@ -39,7 +39,6 @@ if [ $NJS_QUICKJS != NO ]; then
ngx_feature_test="JSRuntime *rt;
rt = JS_NewRuntime();
- (void) JS_GetClassID;
JS_FreeRuntime(rt);
return 0;"
. auto/feature
@@ -66,17 +65,44 @@ if [ $NJS_QUICKJS != NO ]; then
. auto/feature
fi
+ if [ $ngx_found = no ]; then
+ ngx_feature="QuickJS-NG library -lqjs"
+ ngx_feature_path=""
+ ngx_feature_libs="-lqjs -lm -ldl -lpthread"
+
+ . auto/feature
+ fi
+
if [ $ngx_found = yes ]; then
+ ngx_feature="QuickJS JS_GetClassID()"
+ ngx_feature_name=NJS_HAVE_QUICKJS_GET_CLASS_ID
+ ngx_feature_run=no
+ ngx_feature_test="(void) JS_GetClassID(JS_UNDEFINED);"
+
+ . auto/feature
+
+ if [ $ngx_found = no ]; then
+ echo
+ echo $0: error: QuickJS library found, but JS_GetClassID\(\) is missing.
+ echo
+ exit 1;
+ fi
+
ngx_feature="QuickJS JS_NewTypedArray()"
- ngx_feature_test="(void) JS_NewTypedArray;
+ ngx_feature_name=NJS_HAVE_QUICKJS_NEW_TYPED_ARRAY
+ ngx_feature_test="JSValue argv;
+ (void) JS_NewTypedArray(NULL, 1, &argv,
+ JS_TYPED_ARRAY_UINT8);
return 0;"
. auto/feature
- if [ $ngx_found = yes ]; then
- have=NJS_HAVE_QUICKJS_NEW_TYPED_ARRAY . auto/have
- fi
+ ngx_feature="QuickJS JS_IsSameValue()"
+ ngx_feature_name=NJS_HAVE_QUICKJS_IS_SAME_VALUE
+ ngx_feature_test="(void) JS_IsSameValue(NULL, JS_UNDEFINED, JS_UNDEFINED);"
+
+ . auto/feature
NJS_HAVE_QUICKJS=YES
NJS_QUICKJS_LIB="$ngx_feature_libs"
diff --git a/nginx/config.make b/nginx/config.make
index 2fa40063..404a622b 100644
--- a/nginx/config.make
+++ b/nginx/config.make
@@ -4,14 +4,14 @@ $ngx_addon_dir/../build/libnjs.a: $NGX_MAKEFILE
cd $ngx_addon_dir/.. \\
&& if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
&& CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl \\
- --no-libxml2 --no-zlib --no-pcre --no-quickjs \\
+ --no-libxml2 --no-zlib --no-pcre --no-quickjs --ld-opt="$NGX_LD_OPT" \\
&& \$(MAKE) libnjs
$ngx_addon_dir/../build/libqjs.a: $NGX_MAKEFILE
cd $ngx_addon_dir/.. \\
&& if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
&& CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl \\
- --no-libxml2 --no-zlib --no-pcre \\
+ --no-libxml2 --no-zlib --no-pcre --ld-opt="$NGX_LD_OPT" \\
&& \$(MAKE) libnjs libqjs
END
diff --git a/src/qjs.h b/src/qjs.h
index 76bf5c3d..71dd297e 100644
--- a/src/qjs.h
+++ b/src/qjs.h
@@ -29,7 +29,6 @@
#if defined(__GNUC__) && (__GNUC__ >= 8)
#pragma GCC diagnostic pop
#endif
-#define NJS_QUICKJS_VERSION "Unknown version"
#include <pthread.h>
@@ -101,6 +100,13 @@ static inline JS_BOOL JS_IsNullOrUndefined(JSValueConst v)
}
+#ifdef NJS_HAVE_QUICKJS_IS_SAME_VALUE
+#define qjs_is_same_value(cx, a, b) JS_IsSameValue(cx, a, b)
+#else
+#define qjs_is_same_value(cx, a, b) JS_SameValue(cx, a, b)
+#endif
+
+
extern qjs_module_t *qjs_modules[];
#endif /* _QJS_H_INCLUDED_ */
diff --git a/test/shell_test.exp b/test/shell_test.exp
index b713ed09..02828270 100644
--- a/test/shell_test.exp
+++ b/test/shell_test.exp
@@ -302,11 +302,11 @@ njs_test {
njs_test {
{"function f() { return ({}.a.a); }\r\n"
- "undefined"}
- {"var e; try {f()} catch (ee) {e = ee}\r\n"
- "undefined"}
+ "undefined\r\n>> "}
+ {"var e; try {f()} catch (ee) {e = ee}; undefined\r\n"
+ "undefined\r\n>> "}
{"Object.keys(null)\r\n"
- "Thrown:\r\nTypeError: cannot convert*to object"}
+ "Thrown:\r\nTypeError: *annot convert*to object"}
{"e\r\n"
"TypeError: cannot * property *a* of undefined"}
}
@@ -382,11 +382,11 @@ njs_test {
njs_run {"-c" "setTimeout(() => {console.log('A'.repeat(1024))}, 0); ref"} \
"^Thrown:
-ReferenceError: \['\"\]ref\['\"\] is not defined.*"
+ReferenceError: .* is not defined.*"
njs_run {"-c" "setTimeout(() => {ref}, 0); setTimeout(() => {console.log('A'.repeat(1024))}, 0)"} \
"^Thrown:
-ReferenceError: \['\"\]ref\['\"\] is not defined.*"
+ReferenceError: .* is not defined.*"
njs_test {
{"setImmediate(() => { console.log('x'); return Promise.reject('xx'); })\r\n"
More information about the nginx-devel
mailing list