Skip to content

Commit 62e1ead

Browse files
committed
Modules: introduced QuickJS engine.
"js_engine" directive is introduced which sets JavaScript engine. When the module is built with QuickJS library "js_engine qjs;" sets QuickJS engine for the current block. By default njs engine is used. For example, nginx.conf: location /a { js_engine qjs; # will be handled by QuickJS js_content main.handler; } location /b { # will be handled by njs js_content main.handler; } QuickJS engine implements drop-in replacement for nginx/njs objects with the following exceptions: * nginx module API to be added later: ngx.fetch(), ngx.shared.dict. * Built-in modules to be added later: fs, crypto, WebCrypto, xml. * NJS specific API: njs.dump(), njs.on(), console.dump(). * js_preload_object directive.
1 parent 399acf6 commit 62e1ead

30 files changed

+6688
-259
lines changed

.github/workflows/check-pr.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,68 @@ jobs:
8484
TEST_NGINX_BINARY: "${{ github.workspace }}/nginx-source/objs/nginx"
8585
TEST_NGINX_GLOBALS: "load_module ${{ github.workspace }}/nginx-source/objs/ngx_http_js_module.so; load_module ${{ github.workspace }}/nginx-source/objs/ngx_stream_js_module.so;"
8686
TEST_NGINX_VERBOSE: 1
87+
88+
- name: Create LSAN suppression file
89+
run: |
90+
cat << EOF > lsan_suppressions.txt
91+
leak:ngx_event_process_init
92+
EOF
93+
94+
- name: Configure and build nginx and njs modules with quickjs, static modules
95+
run: |
96+
cd nginx-source
97+
$NGINX_CONFIGURE_CMD --with-cc-opt="$CC_OPT -I${{ github.workspace }}/quickjs -fsanitize=address" --with-ld-opt="$LD_OPT -L${{ github.workspace }}/quickjs -fsanitize=address" --add-module=../nginx || cat objs/autoconf.err
98+
$MAKE_UTILITY -j$(nproc)
99+
100+
- name: Test njs modules, static modules
101+
run: |
102+
ulimit -c unlimited
103+
prove -v -j$(nproc) -Inginx-tests/lib --state=save nginx/t . || prove -v -Inginx-tests/lib --state=failed
104+
env:
105+
TEST_NGINX_BINARY: "${{ github.workspace }}/nginx-source/objs/nginx"
106+
TEST_NGINX_VERBOSE: 1
107+
ASAN_OPTIONS: "detect_odr_violation=0:report_globals=0"
108+
LSAN_OPTIONS: "suppressions=${{ github.workspace }}/lsan_suppressions.txt"
109+
110+
- name: Test njs modules (js_engine qjs), static modules
111+
run: |
112+
ulimit -c unlimited
113+
prove -v -j$(nproc) -Inginx-tests/lib --state=save nginx/t . || prove -v -Inginx-tests/lib --state=failed
114+
env:
115+
TEST_NGINX_BINARY: "${{ github.workspace }}/nginx-source/objs/nginx"
116+
TEST_NGINX_GLOBALS_HTTP: "js_engine qjs;"
117+
TEST_NGINX_GLOBALS_STREAM: "js_engine qjs;"
118+
TEST_NGINX_VERBOSE: 1
119+
ASAN_OPTIONS: "detect_odr_violation=0:report_globals=0"
120+
LSAN_OPTIONS: "suppressions=${{ github.workspace }}/lsan_suppressions.txt"
121+
122+
- name: Configure and build nginx and njs modules with quickjs, dynamic modules
123+
run: |
124+
cd nginx-source
125+
$NGINX_CONFIGURE_CMD --with-debug --with-cc-opt="$CC_OPT -I${{ github.workspace }}/quickjs -fsanitize=address" --with-ld-opt="$LD_OPT -L${{ github.workspace }}/quickjs -fsanitize=address" --add-dynamic-module=../nginx || cat objs/autoconf.err
126+
$MAKE_UTILITY -j$(nproc) modules
127+
$MAKE_UTILITY -j$(nproc)
128+
129+
- name: Test njs modules, dynamic modules
130+
run: |
131+
ulimit -c unlimited
132+
prove -v -j$(nproc) -Inginx-tests/lib --state=save nginx/t . || prove -v -Inginx-tests/lib --state=failed
133+
env:
134+
TEST_NGINX_BINARY: "${{ github.workspace }}/nginx-source/objs/nginx"
135+
TEST_NGINX_GLOBALS: "load_module ${{ github.workspace }}/nginx-source/objs/ngx_http_js_module.so; load_module ${{ github.workspace }}/nginx-source/objs/ngx_stream_js_module.so;"
136+
TEST_NGINX_VERBOSE: 1
137+
ASAN_OPTIONS: "detect_odr_violation=0:report_globals=0:fast_unwind_on_malloc=0"
138+
LSAN_OPTIONS: "suppressions=${{ github.workspace }}/lsan_suppressions.txt"
139+
140+
- name: Test njs modules (js_engine qjs), dynamic modules
141+
run: |
142+
ulimit -c unlimited
143+
prove -v -j$(nproc) -Inginx-tests/lib --state=save nginx/t . || prove -v -Inginx-tests/lib --state=failed
144+
env:
145+
TEST_NGINX_BINARY: "${{ github.workspace }}/nginx-source/objs/nginx"
146+
TEST_NGINX_GLOBALS: "load_module ${{ github.workspace }}/nginx-source/objs/ngx_stream_js_module.so; load_module ${{ github.workspace }}/nginx-source/objs/ngx_http_js_module.so;"
147+
TEST_NGINX_GLOBALS_HTTP: "js_engine qjs;"
148+
TEST_NGINX_GLOBALS_STREAM: "js_engine qjs;"
149+
TEST_NGINX_VERBOSE: 1
150+
ASAN_OPTIONS: "detect_odr_violation=0:report_globals=0:fast_unwind_on_malloc=0"
151+
LSAN_OPTIONS: "suppressions=${{ github.workspace }}/lsan_suppressions.txt"

nginx/config

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ngx_addon_name="ngx_js_module"
33
NJS_OPENSSL=${NJS_OPENSSL:-YES}
44
NJS_LIBXSLT=${NJS_LIBXSLT:-YES}
55
NJS_ZLIB=${NJS_ZLIB:-YES}
6+
NJS_QUICKJS=${NJS_QUICKJS:-YES}
67

78
NJS_DEPS="$ngx_addon_dir/ngx_js.h \
89
$ngx_addon_dir/ngx_js_fetch.h \
@@ -12,9 +13,78 @@ NJS_SRCS="$ngx_addon_dir/ngx_js.c \
1213
$ngx_addon_dir/ngx_js_regex.c \
1314
$ngx_addon_dir/ngx_js_shared_dict.c"
1415

16+
QJS_DEPS=""
17+
QJS_SRCS=""
18+
1519
NJS_OPENSSL_LIB=
1620
NJS_XSLT_LIB=
1721
NJS_ZLIB_LIB=
22+
NJS_QUICKJS_LIB=
23+
NJS_QUICKJS_INC=
24+
NJS_HAVE_QUICKJS=
25+
26+
if [ $NJS_QUICKJS != NO ]; then
27+
28+
ngx_feature="QuickJS library -lquickjs.lto"
29+
ngx_feature_name=NJS_HAVE_QUICKJS
30+
ngx_feature_run=yes
31+
ngx_feature_incs="#if defined(__GNUC__) && (__GNUC__ >= 8)
32+
#pragma GCC diagnostic push
33+
#pragma GCC diagnostic ignored \"-Wcast-function-type\"
34+
#endif
35+
36+
#include <quickjs.h>"
37+
ngx_feature_path=""
38+
ngx_feature_libs="-lquickjs.lto -lm -ldl -lpthread"
39+
ngx_feature_test="JSRuntime *rt;
40+
41+
rt = JS_NewRuntime();
42+
(void) JS_GetClassID;
43+
JS_FreeRuntime(rt);
44+
return 0;"
45+
. auto/feature
46+
47+
if [ $ngx_found = no ]; then
48+
ngx_feature="QuickJS library -lquickjs"
49+
ngx_feature_libs="-lquickjs -lm -ldl -lpthread"
50+
51+
. auto/feature
52+
fi
53+
54+
if [ $ngx_found = no ]; then
55+
ngx_feature="QuickJS library -I/usr/include/quickjs/ -L/usr/lib/quickjs/ -lquickjs.lto"
56+
ngx_feature_path="/usr/include/quickjs/"
57+
ngx_feature_libs="-L/usr/lib/quickjs/ -lquickjs.lto -lm -ldl -lpthread"
58+
59+
. auto/feature
60+
fi
61+
62+
if [ $ngx_found = no ]; then
63+
ngx_feature="QuickJS library -I/usr/include/quickjs/ -L/usr/lib/quickjs/ -lquickjs"
64+
ngx_feature_libs="-L/usr/lib/quickjs/ -lquickjs -lm -ldl -lpthread"
65+
66+
. auto/feature
67+
fi
68+
69+
if [ $ngx_found = yes ]; then
70+
71+
ngx_feature="QuickJS JS_NewTypedArray()"
72+
ngx_feature_test="(void) JS_NewTypedArray;
73+
return 0;"
74+
75+
. auto/feature
76+
77+
if [ $ngx_found = yes ]; then
78+
have=NJS_HAVE_QUICKJS_NEW_TYPED_ARRAY . auto/have
79+
fi
80+
81+
NJS_HAVE_QUICKJS=YES
82+
NJS_QUICKJS_LIB="$ngx_feature_libs"
83+
NJS_QUICKJS_INC="$ngx_feature_path"
84+
85+
echo " enabled QuickJS engine"
86+
fi
87+
fi
1888

1989
if [ $NJS_OPENSSL != NO ]; then
2090
NJS_OPENSSL_LIB=OPENSSL
@@ -37,17 +107,30 @@ if [ $NJS_ZLIB != NO ]; then
37107
have=NJS_HAVE_ZLIB . auto/have
38108
NJS_SRCS="$NJS_SRCS $ngx_addon_dir/../external/njs_zlib_module.c"
39109

110+
if [ "$NJS_HAVE_QUICKJS" = "YES" ]; then
111+
NJS_SRCS="$NJS_SRCS $ngx_addon_dir/../external/qjs_zlib_module.c"
112+
fi
113+
40114
echo " enabled zlib module"
41115
fi
42116

117+
118+
NJS_ENGINE_DEP="$ngx_addon_dir/../build/libnjs.a"
119+
NJS_ENGINE_LIB="$ngx_addon_dir/../build/libnjs.a"
120+
if [ "$NJS_HAVE_QUICKJS" = "YES" ]; then
121+
NJS_ENGINE_DEP="$ngx_addon_dir/../build/libqjs.a"
122+
NJS_ENGINE_LIB="$ngx_addon_dir/../build/libnjs.a $ngx_addon_dir/../build/libqjs.a"
123+
fi
124+
43125
if [ $HTTP != NO ]; then
44126
ngx_module_type=HTTP_AUX_FILTER
45127
ngx_module_name=ngx_http_js_module
46-
ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build"
47-
ngx_module_deps="$ngx_addon_dir/../build/libnjs.a $NJS_DEPS"
48-
ngx_module_srcs="$ngx_addon_dir/ngx_http_js_module.c $NJS_SRCS"
128+
ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build \
129+
$NJS_QUICKJS_INC"
130+
ngx_module_deps="$NJS_ENGINE_DEP $NJS_DEPS $QJS_DEPS"
131+
ngx_module_srcs="$ngx_addon_dir/ngx_http_js_module.c $NJS_SRCS $QJS_SRCS"
49132
ngx_module_libs="PCRE $NJS_OPENSSL_LIB $NJS_XSLT_LIB $NJS_ZLIB_LIB \
50-
$ngx_addon_dir/../build/libnjs.a -lm"
133+
$NJS_QUICKJS_LIB $NJS_ENGINE_LIB -lm"
51134

52135
. auto/module
53136

@@ -59,11 +142,12 @@ fi
59142
if [ $STREAM != NO ]; then
60143
ngx_module_type=STREAM
61144
ngx_module_name=ngx_stream_js_module
62-
ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build"
63-
ngx_module_deps="$ngx_addon_dir/../build/libnjs.a $NJS_DEPS"
64-
ngx_module_srcs="$ngx_addon_dir/ngx_stream_js_module.c $NJS_SRCS"
145+
ngx_module_incs="$ngx_addon_dir/../src $ngx_addon_dir/../build \
146+
$NJS_QUICKJS_INC"
147+
ngx_module_deps="$NJS_ENGINE_DEP $NJS_DEPS $QJS_DEPS"
148+
ngx_module_srcs="$ngx_addon_dir/ngx_stream_js_module.c $NJS_SRCS $QJS_SRCS"
65149
ngx_module_libs="PCRE $NJS_OPENSSL_LIB $NJS_XSLT_LIB $NJS_ZLIB_LIB \
66-
$ngx_addon_dir/../build/libnjs.a -lm"
150+
$NJS_QUICKJS_LIB $NJS_ENGINE_LIB -lm"
67151

68152
. auto/module
69153
fi

nginx/config.make

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@ cat << END >> $NGX_MAKEFILE
33
$ngx_addon_dir/../build/libnjs.a: $NGX_MAKEFILE
44
cd $ngx_addon_dir/.. \\
55
&& if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
6-
&& CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-libxml2 --no-zlib --no-pcre \\
6+
&& CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl \\
7+
--no-libxml2 --no-zlib --no-pcre --no-quickjs \\
78
&& \$(MAKE) libnjs
89

10+
$ngx_addon_dir/../build/libqjs.a: $NGX_MAKEFILE
11+
cd $ngx_addon_dir/.. \\
12+
&& if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
13+
&& CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl \\
14+
--no-libxml2 --no-zlib --no-pcre \\
15+
&& \$(MAKE) libnjs libqjs
16+
917
END

0 commit comments

Comments
 (0)