Skip to content

Commit 140961d

Browse files
authored
feat: support WasmEdge (#93)
* feat: support WasmEdge * tweak ci script Signed-off-by: spacewander <[email protected]>
1 parent e6a8009 commit 140961d

File tree

12 files changed

+844
-6
lines changed

12 files changed

+844
-6
lines changed

.github/workflows/test.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ on:
88

99
jobs:
1010
test:
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
vm:
15+
- wasmedge
16+
- wasmtime
1117
runs-on: "ubuntu-20.04"
1218
env:
1319
OPENRESTY_PREFIX: "/usr/local/openresty"
@@ -52,16 +58,18 @@ jobs:
5258
5359
- name: Install
5460
run: |
61+
./install-wasmedge.sh
62+
5563
wget https://raw.githubusercontent.com/api7/apisix-build-tools/master/build-apisix-base.sh
5664
chmod +x build-apisix-base.sh
5765
OR_PREFIX=$OPENRESTY_PREFIX CC="clang -fsanitize=address -fcolor-diagnostics -Qunused-arguments" \
5866
cc_opt="-Werror -fsanitize=undefined" \
59-
ld_opt="-lubsan" \
67+
ld_opt="-lubsan -Wl,-rpath,$OPENRESTY_PREFIX/wasmedge/lib" \
6068
./build-apisix-base.sh latest
6169
6270
- name: Script
6371
run: |
6472
sudo chown -R runner:root ~/.cache
6573
make build.all.testdata
6674
export PATH=$OPENRESTY_PREFIX/nginx/sbin:$PATH
67-
WASM_VM=wasmtime prove -I. -Itest-nginx/lib -r t/
75+
WASM_VM=${{ matrix.vm }} prove -I. -Itest-nginx/lib -r t/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
wasmtime-*-c-api
44
wasmtime-*-c-api.tar.xz
55
wasmtime-c-api
6+
wasmedge/
67
*.wasm
78
*.wasm.map
89
*.wat

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ RUST_DIR = $(wildcard t/testdata/rust/*)
2020
install:
2121
$(INSTALL) -m 664 lib/resty/*.lua $(OPENRESTY_PREFIX)/lualib/resty/
2222
cp -r ./wasmtime-c-api $(OPENRESTY_PREFIX)/
23+
cp -r ./wasmedge $(OPENRESTY_PREFIX)/
2324

2425
.PHONY: build.go.testdata
2526
build.go.testdata:

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,26 @@ export wasmtime_prefix=/path/to/wasm-nginx-module/wasmtime-c-api
3434
--with-ld-opt="-Wl,-rpath,${wasmtime_prefix}/lib" \
3535
```
3636

37+
* Download WasmEdge with the `./install-wasmedge.sh`.
38+
Remember to add the `$HOME/.wasmedge/lib` to the library search path when you build Nginx, for instance,
39+
40+
```
41+
./configure ... \
42+
--with-ld-opt="-Wl,-rpath,${HOME}/.wasmedge/lib" \
43+
```
44+
3745
## Directives
3846

3947
### wasm_vm
4048

41-
**syntax:** *wasm_vm wasmtime*
49+
**syntax:** *wasm_vm wasmtime|wasmedge*
4250

4351
**default:** -
4452

4553
**context:** *http*
4654

47-
Select the Wasm VM. Currently, only wasmtime is supported.
48-
If the directive is not set, the Wasm VM won't be enabled.
55+
Select the WASM VM. Currently, only wasmtime and WasmEdge are supported.
56+
If the directive is not set, the WASM VM won't be enabled.
4957

5058
## Methods
5159

config

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ ngx_module_libs=" \
3636
-L$ngx_addon_dir/wasmtime-c-api/lib -lwasmtime \
3737
"
3838

39+
if [ -d $ngx_addon_dir/wasmedge ]; then
40+
# if wasmedge is installed
41+
wasmedge_path=$ngx_addon_dir/wasmedge
42+
ngx_module_srcs=" \
43+
$ngx_module_srcs \
44+
$ngx_addon_dir/src/vm/wasmedge.c \
45+
"
46+
ngx_module_incs=" \
47+
$ngx_module_incs \
48+
$wasmedge_path/include \
49+
"
50+
ngx_module_libs=" \
51+
$ngx_module_libs \
52+
-L$wasmedge_path/lib -lwasmedge_c \
53+
"
54+
55+
echo "Build with WasmEdge enabled"
56+
have=NGX_WASM_HAVE_WASMEDGE . auto/have
57+
fi
58+
3959
. auto/module
4060

4161
ngx_addon_name=$ngx_module_name

gen_wasm_host_api.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,31 @@ def predefined_macro(vm):
103103
wasm_valkind_t param_type[MAX_WASM_API_ARG];
104104
} ngx_wasm_wasmtime_host_api_t;
105105
106+
"""
107+
elif vm == "wasmedge":
108+
vm_def = """
109+
#define DEFINE_WASM_API(NAME, ARG_CHECK) \\
110+
static WasmEdge_Result wasmedge_##NAME( \\
111+
void *Data, \\
112+
WasmEdge_MemoryInstanceContext *MemCxt, \\
113+
const WasmEdge_Value *In, \\
114+
WasmEdge_Value *Out \\
115+
) { \\
116+
ARG_CHECK \\
117+
Out[0] = WasmEdge_ValueGenI32(res); \\
118+
return WasmEdge_Result_Success; \\
119+
}
120+
#define DEFINE_WASM_NAME(NAME, ARG) \\
121+
{ngx_string(#NAME), wasmedge_##NAME, ARG},
122+
123+
124+
typedef struct {
125+
ngx_str_t name;
126+
WasmEdge_HostFunc_t cb;
127+
int8_t param_num;
128+
enum WasmEdge_ValType param_type[MAX_WASM_API_ARG];
129+
} ngx_wasm_wasmedge_host_api_t;
130+
106131
"""
107132

108133
for i in range(max_wasm_api_arg + 1):
@@ -118,6 +143,8 @@ def predefined_macro(vm):
118143
param_s = ""
119144
if vm == "wasmtime":
120145
kind = "WASM_I32"
146+
else:
147+
kind = "WasmEdge_ValType_I32"
121148
for j in range(1, i + 1):
122149
if j % 5 == 1:
123150
param_s += " "
@@ -133,6 +160,8 @@ def predefined_macro(vm):
133160
for j in range(i):
134161
if vm == "wasmtime":
135162
vm_def += " int32_t p%d = args[%d].of.i32; \\\n" % (j, j)
163+
elif vm == "wasmedge":
164+
vm_def += " int32_t p%d = WasmEdge_ValueGetI32(In[%d]); \\\n" % (j, j)
136165
param_s = ", ".join('p' + str(j) for j in range(i))
137166
vm_def += " int32_t res = NAME(%s);\n" % (param_s)
138167
return vm_def
@@ -222,3 +251,15 @@ def get_host_apis(src_dir):
222251
wasm_api_def=wasmtime_def,
223252
max_wasm_api_arg=max_wasm_api_arg,
224253
))
254+
255+
wasmedge_def = predefined_macro("wasmedge")
256+
wasmedge_def += api_def + "\n\nstatic ngx_wasm_wasmedge_host_api_t host_apis[] = {\n"
257+
wasmedge_def += name_def
258+
with open(os.path.join(src_dir, "ngx_http_wasm_api_wasmedge.h"), 'w') as f:
259+
f.write(s.substitute(
260+
header=header,
261+
vm_header="#include <wasmedge/wasmedge.h>",
262+
vm_api_header_name="NGX_HTTP_WASM_API_WASMEDGE_H",
263+
wasm_api_def=wasmedge_def,
264+
max_wasm_api_arg=max_wasm_api_arg,
265+
))

install-wasmedge.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
set -euo pipefail -x
17+
18+
if echo "int main(void) {}" | gcc -o /dev/null -v -x c - &> /dev/stdout| grep collect | tr -s " " "\012" | grep musl; then
19+
# skip if the libc is musl
20+
exit 0
21+
fi
22+
23+
curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- -e none -p ./wasmedge -v 0.10.0-alpha.1

0 commit comments

Comments
 (0)