diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 5d947ca8879f8a9072fe485c566204e3c2929e80..0000000000000000000000000000000000000000 --- a/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# Build and Release Folders -bin-debug/ -bin-release/ -[Oo]bj/ -[Bb]in/ - -# Other files and folders -.settings/ - -# Executables -*.swf -*.air -*.ipa -*.apk - -# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` -# should NOT be excluded as they contain compiler settings and other important -# information for Eclipse / Flash Builder. diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1 @@ + diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d02d093f4cae737cd124744192e5a04ea2a7faf1..0000000000000000000000000000000000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "njet"] - path = njet - url = https://gitee.com/njet-rd/njet.git diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f63f5a9cf3498818a73068495709cceed67efd6a..0000000000000000000000000000000000000000 --- a/LICENSE +++ /dev/null @@ -1,194 +0,0 @@ -木兰宽松许可证,第2版 - -木兰宽松许可证,第2版 - -2020年1月 http://license.coscl.org.cn/MulanPSL2 - -您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: - -0. 定义 - -“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 - -“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 - -“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 - -“法人实体” 是指提交贡献的机构及其“关联实体”。 - -“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是 -指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 - -1. 授予版权许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可 -以复制、使用、修改、分发其“贡献”,不论修改与否。 - -2. 授予专利许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定 -撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡 -献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软 -件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“ -关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或 -其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权 -行动之日终止。 - -3. 无商标许可 - -“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定 -的声明义务而必须使用除外。 - -4. 分发限制 - -您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“ -本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 - -5. 免责声明与责任限制 - -“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对 -任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于 -何种法律理论,即使其曾被建议有此种损失的可能性。 - -6. 语言 - -“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文 -版为准。 - -条款结束 - -如何将木兰宽松许可证,第2版,应用到您的软件 - -如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: - -1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; - -2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; - -3, 请将如下声明文本放入每个源文件的头部注释中。 - -Copyright (c) [Year] [name of copyright holder] -[Software Name] is licensed under Mulan PSL v2. -You can use this software according to the terms and conditions of the Mulan -PSL v2. -You may obtain a copy of Mulan PSL v2 at: - http://license.coscl.org.cn/MulanPSL2 -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -See the Mulan PSL v2 for more details. - -Mulan Permissive Software License,Version 2 - -Mulan Permissive Software License,Version 2 (Mulan PSL v2) - -January 2020 http://license.coscl.org.cn/MulanPSL2 - -Your reproduction, use, modification and distribution of the Software shall -be subject to Mulan PSL v2 (this License) with the following terms and -conditions: - -0. Definition - -Software means the program and related documents which are licensed under -this License and comprise all Contribution(s). - -Contribution means the copyrightable work licensed by a particular -Contributor under this License. - -Contributor means the Individual or Legal Entity who licenses its -copyrightable work under this License. - -Legal Entity means the entity making a Contribution and all its -Affiliates. - -Affiliates means entities that control, are controlled by, or are under -common control with the acting entity under this License, ‘control’ means -direct or indirect ownership of at least fifty percent (50%) of the voting -power, capital or other securities of controlled or commonly controlled -entity. - -1. Grant of Copyright License - -Subject to the terms and conditions of this License, each Contributor hereby -grants to you a perpetual, worldwide, royalty-free, non-exclusive, -irrevocable copyright license to reproduce, use, modify, or distribute its -Contribution, with modification or not. - -2. Grant of Patent License - -Subject to the terms and conditions of this License, each Contributor hereby -grants to you a perpetual, worldwide, royalty-free, non-exclusive, -irrevocable (except for revocation under this Section) patent license to -make, have made, use, offer for sale, sell, import or otherwise transfer its -Contribution, where such patent license is only limited to the patent claims -owned or controlled by such Contributor now or in future which will be -necessarily infringed by its Contribution alone, or by combination of the -Contribution with the Software to which the Contribution was contributed. -The patent license shall not apply to any modification of the Contribution, -and any other combination which includes the Contribution. If you or your -Affiliates directly or indirectly institute patent litigation (including a -cross claim or counterclaim in a litigation) or other patent enforcement -activities against any individual or entity by alleging that the Software or -any Contribution in it infringes patents, then any patent license granted to -you under this License for the Software shall terminate as of the date such -litigation or activity is filed or taken. - -3. No Trademark License - -No trademark license is granted to use the trade names, trademarks, service -marks, or product names of Contributor, except as required to fulfill notice -requirements in section 4. - -4. Distribution Restriction - -You may distribute the Software in any medium with or without modification, -whether in source or executable forms, provided that you provide recipients -with a copy of this License and retain copyright, patent, trademark and -disclaimer statements in the Software. - -5. Disclaimer of Warranty and Limitation of Liability - -THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR -COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT -LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING -FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO -MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGES. - -6. Language - -THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION -AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF -DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION -SHALL PREVAIL. - -END OF THE TERMS AND CONDITIONS - -How to Apply the Mulan Permissive Software License,Version 2 -(Mulan PSL v2) to Your Software - -To apply the Mulan PSL v2 to your work, for easy identification by -recipients, you are suggested to complete following three steps: - -i. Fill in the blanks in following statement, including insert your software -name, the year of the first publication of your software, and your name -identified as the copyright owner; - -ii. Create a file named "LICENSE" which contains the whole context of this -License in the first directory of your software package; - -iii. Attach the statement to the appropriate annotated syntax at the -beginning of each source file. - -Copyright (c) [Year] [name of copyright holder] -[Software Name] is licensed under Mulan PSL v2. -You can use this software according to the terms and conditions of the Mulan -PSL v2. -You may obtain a copy of Mulan PSL v2 at: - http://license.coscl.org.cn/MulanPSL2 -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -See the Mulan PSL v2 for more details. diff --git a/README.en.md b/README.en.md deleted file mode 100644 index b577982fac9f7d10ec192b987504a2948f7eb36d..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# OpenNJet-WASM - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 2a770847705507607a81aa65e952af6c42b60de2..2e1a875d9a599bbaf58d4e4d4b140aaee5a8f859 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,164 @@ -# OpenNJet-WASM +njet WASM repo -#### 介绍 -该程序是 OpenNJet 的 wasm 插件程序,支持动态引入 OpenNJet 程序中,通过使用 wasm 程序处理 http 请求 -#### 软件架构 -实现思路 -1. 在 njet 启动时创建 wasm 运行时 -2. 在 http 请求过来的时候组合相关请求参数 -3. 使用组合好的参数调用 wasm 运行时中处理方法 -4. 集成了 wasmedge 在 njet 中 -5. 用户配置时可灵活指定 wasm 文件路径及处理方法名称 + === 目录结构介绍 === -#### 安装教程 +``` +├── njet-3.1.0-wasm.diff - 基于OpenNJet v3.1.0版本 wasm patch +├── njet.conf - OpenNjet 加载wasm 配置 +├── wasm-runtime - wasm编译工具链 +├── my-wasm - 自定义wasm模块模板 +├── wasm-baselib - host api基础库编译目录 +├── README.md - readme文件 +└── wasm - patch以及基础库完整编译目录 + ├── libngxhost - host api基础库源码目录 + ├── ngx-http-vars - HTTP 变量求和计算模块 + ├── ngx-http-handler - http 请求处理模块 + └── vendor - WASI module -1. sh build.sh +``` -#### 使用说明 -无需特殊环境,和 njet 主程序相同即可 -#### 参与贡献 +=== wasm功能特性 === -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +``` + 读取njet变量 + 设置变量到njet + + 读取请求request header + 设置响应response header + + 读取请求request body + 设置响应response body + + 异步处理http请求 + + njet写日志接口 +``` + + +``` +默认提供 wasmer runtime 运行时环境 +``` + + +``` +提供两个 wasm 示例模块 + njt_http_handler: 获取HTTP请求(header/body),设置HTTP响应(header/body) + the module allows to use wasm code to implement HTTP request content handler + + njt_http_vars: HTTP arg变量求和 + the module allows to use wasm code to define HTTP request variables +``` + + +=== 源码编译环境 === +由于使用编译工具链版本依赖问题,wasm以及基础库编译最好在ubuntu20.04及以上版本环境编译 +以ubuntu20.04 环境为例,需要软件安装包 + +``` +apt-get install wget -y +apt-get install build-essential -y +apt-get install libssl-dev \ + libpcre3 \ + libpcre3-dev \ + zlib1g \ + zlib1g-dev \ + cmake -y + +apt-get install unzip -y +apt-get install gcc g++ make cmake libpcre2-dev \ + perl m4 git libtool automake \ + autoconf vim-common unzip libcap2-bin \ + cmake -y +``` + + +=== 快速开始 === + +$ 创建build 目录 + +``` + mkdir build && cd build +``` + +$ 编译wasm运行时环境以及生成wasm 文件 + +``` + cp ../build_wasm_runtimer.sh ./ + sh build_wasm_runtimer.sh +``` + +$ 编译njet 以及生成 wasm 示例模块so动态库 + +``` + cp ../build_njet.sh ./ + sh build_njet.sh +``` + +$ 需要将wasm运行时库设置到系统搜索路径(有的环境LD_LIBRARY_PATH不生效,可直接将动态库直接copy到系统搜索路径下) + +``` + LD_LIBRARY_PATH=`pwd`/wasm-micro-runtime-WAMR-1.3.2/build:$LD_LIBRARY_PATH + + 或者将动态库直接copy到系统搜索路径下(ubuntu20.04环境为例) + sudo cp `pwd`/wasm-micro-runtime-WAMR-1.3.2/build/*.so /lib/x86_64-linux-gnu/ +``` + + +$ 运行njet + +``` +njet默认安装路径为/usr/local/njet, 推荐如下结构存放配置动态库等 + sbin/njet: exec file + modules/*.so: all modules's so file, include wasm module so + logs/: log dir + conf/: all config file +``` + + +启动njet: +``` + /usr/local/njet/sbin/njet -p /usr/local/njet -c conf/njet.conf +``` + +停止njet: +``` + /usr/local/njet/sbin/njet -p /usr/local/njet -c conf/njet.conf -s stop +``` + +$ 测试wasm模块 + +njet配置启动端口8080 + + +变量求和示例: + +``` +$ curl "http://127.0.0.1:8080/?a=1&b=2&c=3" +sum('1','2','3','')=6 +``` + + +HTTP请求示例: + +``` +$ curl -s -v -X PUT -T build_njet.sh -o download.txt http://127.0.0.1:8080/wasm?body=rw + +这个示例能够读取request请求的header(foo)和body +同时将读取到的foo header数据以及body作为响应的body返回,保存到download.txt文件里 +同时在响应header部分添加hello:wasm 以及x-foo:aa + + +body=r: 表示读取request body +body=w: 表示响应body +body=rw: 表示读取request body内容并响应到response body +``` + + +FAQ: +``` + 如果使用wasmtime 运行时环境,由于环境相关版本依赖,如果在低版本系统上使用,可能需要手工编译wasmtime运行时库。 + 编译OpenNJet支持wasmtime运行时模块时,只需要将build_njet.sh 关于涉及WTIME_CAPI 宏的部分注释打开即可 +``` \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100644 index 8109f9cf1dbff0ef74b68cdde36ed4fdde618c1a..0000000000000000000000000000000000000000 --- a/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -cp -r ./njet-http-wasm-module/ ./njet/modules/ -cp -r ./wasmedge/ ./njet/auto/lib/ - -grep -qxF ". auto/lib/wasmedge/conf" njet/auto/lib/conf || echo ". auto/lib/wasmedge/conf" >> njet/auto/lib/conf - -grep -qxF ". auto/lib/wasmedge/make" njet/auto/lib/make || echo ". auto/lib/wasmedge/make" >> njet/auto/lib/make - -grep -qxF "./modules/njet-http-wasm-module" njet/modules_dynamic || echo "./modules/njet-http-wasm-module" >> njet/modules_dynamic - -cd njet && sh build_cc.sh conf make \ No newline at end of file diff --git a/build_cc.sh b/build_cc.sh new file mode 100644 index 0000000000000000000000000000000000000000..0a66bc8da539856f802c1f036a15f0bdd15c2b68 --- /dev/null +++ b/build_cc.sh @@ -0,0 +1,219 @@ +#!/bin/bash + +set -e +#NJET_CONF_PATH=/etc/njet/njet.conf +#NJET_PREFIX=/etc/njet +#NJET_SBIN_PATH=/usr/sbin/njet +#NJET_MODULES_PATH=/usr/lib/njet/modules + +NJET_CONF_PATH=/usr/local/njet/conf/njet.conf +NJET_PREFIX=/usr/local/njet +NJET_SBIN_PATH=/usr/local/njet/sbin/njet +NJET_MODULES_PATH=/usr/local/njet/modules + +GIT_TAG="" +DEBUG="False" +#WITH_TONGSUO_8_4="True" +WITH_TONGSUO_8_4="False" + +while getopts "t:d-:" option; do + case "${option}" in + -) + case "${OPTARG}" in + with_tongsuo_8_4) + WITH_TONGSUO_8_4="True" + echo "Parsing option: '--${OPTARG}'" >&2; + ;; + with_tongsuo_8_3) + WITH_TONGSUO_8_4="False" + echo "Parsing option: '--${OPTARG}'" >&2; + ;; + *) + if [ "$OPTERR" = 1 ] && [ "${optspec:0:1}" != ":" ]; then + echo "Unknown option --${OPTARG}" >&2 + echo "$0 [-t ] [-d] [--with_tongsuo_8_4(default)|--with_tongsuo_8_3] [conf[igure]|make|install|clean|release]" + exit + fi + ;; + esac;; + t) + GIT_TAG="NJT_${OPTARG}" + ;; + d) + DEBUG="True" + ;; + \?) # Invalid option + echo "Error: Invalid option" + echo "$0 [-t ] [-d] [--with_tongsuo_8_4(default)|--with_tongsuo_8_3] [conf[igure]|make|install|clean|release]" + exit;; + esac +done + +shift "$(($OPTIND - 1))" + +export LUAJIT_INC="`pwd`/luajit/src" +export LUAJIT_LIB="`pwd`/luajit/src" + +static_modules=$(grep -v "^#" modules_static) +for module in $static_modules +do + NJET_MODULES="$NJET_MODULES --add-module=${module}" +done + +dynamic_modules=$(grep -v "^#" modules_dynamic) +for module in $dynamic_modules +do + NJET_MODULES="$NJET_MODULES --add-dynamic-module=${module}" +done + + +PATH_INFO=" --conf-path=$NJET_CONF_PATH --prefix=$NJET_PREFIX --sbin-path=$NJET_SBIN_PATH --modules-path=$NJET_MODULES_PATH " + +if [ "$WITH_TONGSUO_8_4" = "True" ]; then + LIB_SRC_PATH=" --with-openssl=auto/lib/Tongsuo " +else + LIB_SRC_PATH=" --with-openssl=auto/lib/tongsuo " +fi + +# flags=" $NJET_MODULES $PATH_INFO $LIB_SRC_PATH --build=$GIT_TAG --with-stream --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-iwasm_module=dynamic --with-wasmtime_module=dynamic --with-http_wasm_var_module --with-http_wasm_content_module --with-http_wasm_filter_module --with-cc=/usr/bin/cc --with-pcre" +flags=" $NJET_MODULES $PATH_INFO $LIB_SRC_PATH --build=$GIT_TAG --with-stream --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-iwasm_module=dynamic --with-http_wasm_var_module --with-http_wasm_content_module --with-http_wasm_filter_module --with-cc=/usr/bin/cc --with-pcre" + +WTIME_VER="v25.0.0" +WAMR_VER="1.3.2" +# WTIME_CAPI="`pwd`/../wasmtime-${WTIME_VER}-x86_64-linux-c-api" +WAMR="`pwd`/../wasm-micro-runtime-WAMR-${WAMR_VER}" + +if [ "$DEBUG" = "True" ]; then + # LD_OPT="-fsanitize=address -static-libgcc -static-libasan -ldl -lm -L${WTIME_CAPI}/lib/ -L${WAMR}/build" + LD_OPT="-fsanitize=address -static-libgcc -static-libasan -ldl -lm -L${WAMR}/build" + if [ "$WITH_TONGSUO_8_4" = "True" ]; then + CC_OPT="-O0 -ggdb -Wno-deprecated-declarations -Wno-implicit-fallthrough -fsanitize=address -fno-omit-frame-pointer -static-libgcc -static-libasan -Wall -Wextra -Wshadow" + else + CC_OPT="-O0 -ggdb -fsanitize=address -fno-omit-frame-pointer -Wno-implicit-fallthrough -static-libgcc -static-libasan -Wall -Wextra -Wshadow" + fi + flags="$flags --with-debug" +else + # LD_OPT="-ldl -lm -L${WTIME_CAPI}/lib/ -L${WAMR}/build" + LD_OPT="-ldl -lm -L${WAMR}/build" + if [ "$WITH_TONGSUO_8_4" = "True" ]; then + CC_OPT="-O2 -g -Wno-implicit-fallthrough -Wno-deprecated-declarations -fPIC" + else + CC_OPT="-O2 -g -Wno-implicit-fallthrough -fPIC" + fi +fi + +#api doc make tar file +doctar=doc.tar + +if [ -f $doctar ] +then + rm $doctar +fi + +if [ -f $doctar.gz ] +then + rm $doctar.gz +fi +tar cvf $doctar doc +gzip $doctar +xxd -i $doctar.gz > src/http/njt_doc_gz.h +if [ -f $doctar ] +then + rm $doctar +fi + +if [ -f $doctar.gz ] +then + rm $doctar.gz +fi + +cdir=`cd $(dirname $0); pwd` +( + cd $cdir + set -e + for option; do + case $option in + conf*) + if [ ! -f luajit/src/libluajit-5.1.so ]; then + cd luajit;make;cd -; + cp -f luajit/src/libluajit.so luajit/src/libluajit-5.1.so + fi + + if [ "$WITH_TONGSUO_8_4" = "True" ]; then + # ./configure --with-openssl=auto/lib/Tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT -I${WTIME_CAPI}/include/ -I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + ./configure --with-openssl=auto/lib/Tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT-I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + else + # ./configure --with-openssl=auto/lib/tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT -I${WTIME_CAPI}/include/ -I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + ./configure --with-openssl=auto/lib/tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT -I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + fi + ;; + make) + make + ;; + install) + make install + cd luajit;PREFIX=${NJET_PREFIX} make install_lib;cd -; + mkdir -p ${DESTDIR}${NJET_PREFIX}/{apigw_data,lib,lualib} + cp -a build/api_gateway.db ${DESTDIR}${NJET_PREFIX}/apigw_data + cp -a lualib/lib ${DESTDIR}${NJET_PREFIX}/lualib/ + if [ -d auto/lib/modsecurity/src/.libs ]; then + cp -a auto/lib/modsecurity/src/.libs/libmodsecurity.so* ${DESTDIR}${NJET_PREFIX}/lib + fi + if [ -d auto/lib/keepalived/keepalived/emb/.libs ]; then + cp -a auto/lib/keepalived/keepalived/emb/.libs/libha_emb.so* ${DESTDIR}${NJET_PREFIX}/lib; + fi + if [ -f auto/lib/librdkafka/build/src/librdkafka.so ]; then + cp -a auto/lib/librdkafka/build/src/librdkafka.so* ${DESTDIR}${NJET_PREFIX}/lib + fi + + mkdir -p ${DESTDIR}${NJET_PREFIX}/lib/tcc + if [ -f auto/lib/tcc-0.9.26/x86-64/libtcc1.a ]; then + mkdir -p ${DESTDIR}${NJET_PREFIX}/lib/tcc/x86-64 + cp -fr auto/lib/tcc-0.9.26/libtcc1.a ${DESTDIR}${NJET_PREFIX}/lib/tcc/x86-64 + fi + if [ -f auto/lib/tcc-0.9.26/arm64/libtcc1.a ]; then + mkdir -p ${DESTDIR}${NJET_PREFIX}/lib/tcc/arm64 + cp -fr auto/lib/tcc-0.9.26/libtcc1.a ${DESTDIR}${NJET_PREFIX}/lib/tcc/arm64 + fi + if [ -f modules/njet-stream-proto-server-module/src/njt_tcc.h ]; then + mkdir -p ${DESTDIR}${NJET_PREFIX}/lib/tcc/include + cp -fr modules/njet-stream-proto-server-module/src/njt_tcc.h ${DESTDIR}${NJET_PREFIX}/lib/tcc/include + fi + cp -rf auto/lib/tcc-0.9.26/include ${DESTDIR}${NJET_PREFIX}/lib/tcc + cp -fr auto/lib/tcc-0.9.26/tcclib.h ${DESTDIR}${NJET_PREFIX}/lib/tcc/include + + cd auto/lib/luapkg; PREFIX=/usr/local CDIR_linux=njet/lualib/clib LDIR_linux=njet/lualib/lib LUA_CMODULE_DIR=${PREFIX}/${CDIR_linux} LUA_MODULE_DIR=${PREFIX}/${LDIR_linux} make install; cd -; + echo ${NJET_PREFIX}/lib > ${DESTDIR}/etc/ld.so.conf.d/njet.conf || echo "can't update ld.so.conf.d/njet.conf" + ldconfig || echo "can't run ldconfig" + ;; + clean) + rm -rf auto/lib/njetmq/build + rm -f auto/lib/keepalived/Makefile + cd auto/lib/modsecurity; make clean; cd -; + cd auto/lib/librdkafka; make clean; cd -; + cd auto/lib/luapkg; make clean; cd -; + make clean + ;; + release) + if [ -f ./objs/njet ]; then + make clean + fi + ./configure $flags + make; + cp objs/njet objs/njet.debug + objcopy --strip-unneeded ./objs/njet + ;; + modules) + if [ -f ./objs/njet ]; then + make clean + fi + ./configure $module_flags + make modules; + ;; + *) + echo "$0 [-t ] [-d] [conf[igure]|make|install|clean|release]" + ;; + esac + done + set +e +) diff --git a/build_njet.sh b/build_njet.sh new file mode 100644 index 0000000000000000000000000000000000000000..172829ab837db1c5778f140d55d550f52128e33e --- /dev/null +++ b/build_njet.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +wget --no-check-certificate https://gitee.com/njet-rd/njet/repository/archive/v3.1.0.zip +unzip v3.1.0.zip && mv njet-v3.1.0 njet +cd njet && patch -p1 -i ../../njet-3.1.0-wasm.diff +cp ../../build_cc.sh ./ +sh build_cc.sh conf make +sudo make install +cd .. +sudo cp ../njet.conf /usr/local/njet/conf/ +sudo cp -v wasm/njt-http-vars/objs/njt_http_vars.wasm /usr/local/njet/conf/ +sudo cp -v wasm/njt-http-handler/objs/njt_http_handler.wasm /usr/local/njet/conf/ \ No newline at end of file diff --git a/build_wasm_runtimer.sh b/build_wasm_runtimer.sh new file mode 100644 index 0000000000000000000000000000000000000000..fdf7d4cb0970cbd2ece0e7234c8338aff24d0526 --- /dev/null +++ b/build_wasm_runtimer.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +cp ../wasm-runtime/* ./ +tar xvf wasmtime-v25.0.0-x86_64-linux-c-api.tar.xz +tar xvf WAMR-1.3.2.tar.gz +cd wasm-micro-runtime-WAMR-1.3.2 && mkdir -p build && cd build && cmake .. && make +cd ../../ + +tar xvf wasi-sdk-24.0-x86_64-linux.tar.gz +tar xvf wasm-tools-1.217.0-x86_64-linux.tar.gz +tar xvf wit-bindgen-0.26.0-x86_64-linux.tar.gz + +cp -r ../wasm ./ +cd wasm && make clean && make all +cd .. \ No newline at end of file diff --git a/clean.sh b/clean.sh deleted file mode 100644 index a35e2e4137420f5b34ac128235ed99d833bb65e3..0000000000000000000000000000000000000000 --- a/clean.sh +++ /dev/null @@ -1,3 +0,0 @@ -cd njet -git checkout . -sh build_cc.sh clean \ No newline at end of file diff --git a/my-wasm/make.conf b/my-wasm/make.conf new file mode 100644 index 0000000000000000000000000000000000000000..438c9319ebe7e787174357922af3c8d2dc82c78d --- /dev/null +++ b/my-wasm/make.conf @@ -0,0 +1,5 @@ +TOOLSDIR=./ +SDK=wasi-sdk-24.0-x86_64-linux +WASM_TOOLS=wasm-tools-1.217.0-x86_64-linux +WIT_BINDGEN=wit-bindgen-0.26.0-x86_64-linux +MODULES_DST=/njet/conf diff --git a/my-wasm/makefile b/my-wasm/makefile new file mode 100644 index 0000000000000000000000000000000000000000..13968b838d8d4ec7b5981a2f947e3cc886855469 --- /dev/null +++ b/my-wasm/makefile @@ -0,0 +1,33 @@ +include make.conf +include rules.mk + +all: results + +parts = sum + +modules := +targets := +clean-objs := + +$(foreach p,$(parts),$(shell mkdir -p $p/objs $p/bindings)) +$(foreach p,$(parts),$(eval include $p/module.mk)) +$(foreach p,$(parts),$(eval clean_objs += $p/objs $p/bindings)) + + +results: $(targets) + +install: results + @install -v $(modules) $(MODULES_DST) + +clean: + @rm -rf $(clean_objs) + + +PROGRESS= +PROGRESS=--progress=plain + +docker: + docker build $(PROGRESS) . -t wasm-examples + +.PHONY: install clean docker + diff --git a/my-wasm/rules.mk b/my-wasm/rules.mk new file mode 100644 index 0000000000000000000000000000000000000000..513984c006fc9786f09ac0e68aa0c9914956567c --- /dev/null +++ b/my-wasm/rules.mk @@ -0,0 +1,108 @@ +# +# generic rules for building WASM +# + +CLANG=$(TOOLSDIR)/$(SDK)/bin/clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip1-clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip2-clang + +WLD=$(TOOLSDIR)/$(SDK)/bin/wasm-ld +AR=$(TOOLSDIR)/$(SDK)/bin/ar +RANLIB=$(TOOLSDIR)/$(SDK)/bin/ranlib +WTOOLS=$(TOOLSDIR)/$(WASM_TOOLS) +BG=$(TOOLSDIR)/$(WIT_BINDGEN) + +mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST))) +module = $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +WIT_OPTS=--out-dir=$(module)/bindings \ + --no-helpers \ + --no-object-file \ + --autodrop-borrows=yes + +WITDIR=wit + +OPTS=-Wall -Werror -O2 -I. -I$(module) + +LDOPTS=-Wl,--no-entry -Wl,--import-undefined -mexec-model=reactor + +HOSTLIB=sum/src/libnjthost.a + +WASI_PLUG=vendor/wasi_snapshot_preview1.proxy.wasm + +# for debug purposes: produce human-readable version of code +%.wasm.wat: %.wasm + $(WTOOLS)/wasm-tools print $^ > $@ + +src-to-obj = $(subst src/,objs/,$(subst .c,.wasm,$(filter %.c,$1))) + +world-to-fn = $(subst -,_,$1) +world-to-wit =$(WITDIR)/$(call world-to-fn,$1).wit + +# $(call wasm-component,1:srcs,2:deps,3:world) +define wasm-component + + $(eval id=$(call world-to-fn,$3)) + + targets += $(module)/objs/$(id).wasm.wat \ + $(module)/objs/$(id)-obj.wasm.wat \ + $(module)/objs/$(id)-component.wasm.wat \ + $(module)/bindings/$(id).c \ + $(module)/bindings/$(id).h + + modules += $(module)/objs/$(id).wasm + components += $(module)/objs/$(id)-component.wasm + + $(call mkbind,$3) + + # build module + $(module)/objs/$(id)-obj.wasm: $(addprefix $(module)/,$1) $(addprefix $(module)/,$2) $(module)/bindings/$(id).c $(module)/bindings/$(id).h $(HOSTLIB) + $(CLANG) $(OPTS) $(LDOPTS) -o $$@ $(addprefix $(module)/,$1) $(module)/bindings/$(id).c $(HOSTLIB) + + # embed WIT + $(module)/objs/$(id).wasm: $(module)/objs/$(id)-obj.wasm $(call world-to-wit,$3) + $(WTOOLS)/wasm-tools component embed $(WITDIR) $$< -o $$@ --world $3 + + $(module)/objs/$(id)-component.wasm: $(module)/objs/$(id).wasm + $(WTOOLS)/wasm-tools component new $$^ --adapt $(WASI_PLUG) -o $$@ + +endef + +# $(call mkbind,1:world) +define mkbind + + $(eval nm=$(call world-to-fn,$1)) + + targets += $(module)/bindings/$(nm).c \ + $(module)/bindings/$(nm).h + + $(module)/bindings/$(nm).c $(module)/bindings/$(nm).h: $(call world-to-wit,$1) + $(BG)/wit-bindgen c $(WIT_OPTS) $(WITDIR) --world $1 + +endef + + +# $(call compile-src,1:src,2:deps) +define compile-src + + targets += $(call src-to-obj,$1).wat +.//wit-bindgen-0.26.0-x86_64-linux/wit-bindgen + $(call src-to-obj,$1): $1 $2 + $(CLANG) -c $(OPTS) -fPIC -o $$@ $$< + +endef + +# $(call make-static-lib,1:name,2:srcs,3:deps) +define make-static-lib + + $(foreach item,$(addprefix $(module)/,$2),$(call compile-src,$(item),$(addprefix $(module)/,$3))) + + targets += $1 + + $1: $(call src-to-obj,$(addprefix $(module)/,$2)) + $(AR) r $$@ $$^ + $(RANLIB) $$@ + +endef + + diff --git a/my-wasm/vendor/wasi_snapshot_preview1.proxy.wasm b/my-wasm/vendor/wasi_snapshot_preview1.proxy.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7dd6ecd2a00124011a10e7fc1cd64fcb3d32e358 Binary files /dev/null and b/my-wasm/vendor/wasi_snapshot_preview1.proxy.wasm differ diff --git a/my-wasm/wasm-tools-1.217.0-x86_64-linux.tar.gz b/my-wasm/wasm-tools-1.217.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8dfce4f026b34aeb8f0ff9c30494611a4b5c2fdf Binary files /dev/null and b/my-wasm/wasm-tools-1.217.0-x86_64-linux.tar.gz differ diff --git a/my-wasm/wit-bindgen-0.26.0-x86_64-linux.tar.gz b/my-wasm/wit-bindgen-0.26.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c92d4c84c7eb86403e8f9494df28ecaa848831ee Binary files /dev/null and b/my-wasm/wit-bindgen-0.26.0-x86_64-linux.tar.gz differ diff --git a/my-wasm/wit/njt_wasi.wit b/my-wasm/wit/njt_wasi.wit new file mode 100644 index 0000000000000000000000000000000000000000..9eab45c7706b6dec0bead021909ee807eccec926 --- /dev/null +++ b/my-wasm/wit/njt_wasi.wit @@ -0,0 +1,128 @@ +package njt:wasi; + +interface host { + + // log level: matches NGX_LOG_ defines in src/core/njt_log.h + enum ll { + STDERR, EMERG, ALERT, CRIT, ERR, WARN, NOTICE, INFO, DEBUG + } +} + +interface syscall { + + // all syscalls return: + // on success: NGX_OK (zero) or positive value + // otherwise: NGX_ERROR/AGAIN... standard nginx return codes (negative) + // negative codes are expected to be returned to host as is + + open: func(name:string, ctx:s32) -> s32; + + read: func(handle:s32, buf:u32, len:u32) -> s32; + write: func(handle:s32, buf:u32, len:u32) -> s32; + + get: func(handle:s32, propid:u32, buf:u32, len:u32) -> s32; + set: func(handle:s32, propid:u32, val:u32, len:u32) -> s32; + + close: func(handle:s32) -> s32; +} + +interface http-host { + + // indexes in u32 array; array len? + enum request-meta { + ctx, method, schema, version, uri-len, addr-len, + header-count, last + } + + enum request-props { + // input + meta, self, uri, remote-addr, discard-body, var, + // output + status, content-length, ranges, header-only, reject-msg + } +} + +interface utils { + + record keyval { + key: string, + value: string + } + + strerror: func(errnum: s32) -> string; + + log-error: func(fd: s32, level: u8, errnum:s32, msg:string); + + get-env: func(fd: s32, log-fd: s32) -> result,s32>; + + list-alloc: func(fd: s32, nargs:u32, size:u32, old:u32, oldsize:u32, oldres:u32, logfd:s32) -> s32; +} + +interface http-request { + + enum schema { HTTP, HTTPS } + + enum method { + UNKNOWN, GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, + OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH, TRACE, + CONNECT + } + + enum version { VUNKNOWN, V09, V10, V11, V20, V30 } + + set-context: func(req:u32, data:u32); + get-context: func(req:u32) -> u32; + + reject: func(req:u32, status:u32, msg: string) -> s32; + + get-log: func(req:u32) -> s32; + get-method: func(req:u32) -> method; + get-schema: func(req:u32) -> schema; + get-uri: func(req:u32) -> string; + get-version: func(req:u32) -> version; + get-remote-addr: func(req:u32) -> string; + + variable: func(req:u32, key:string) -> string; + + get-header: func(req:u32, key:string) -> string; + get-header-values: func(req:u32, key:string) -> list; + + set-header: func(req:u32, key: string, value:string) -> s32; + set-header-values: func(req:u32, key:string, value: list) -> s32; + + // NEED it? variables are enough? + args-count: func(req:u32) -> u32; + arg-by-index: func(req:u32, index:u32) -> string; + arg-by-key: func(req:u32, key:string) -> string; + + handle-body: func(req:u32, enabled:u8) -> s32; + + read-body: func(req:u32, buf:u32, len:u32) -> s32; + + + set-status: func(req:u32, status:u32) -> s32; + + setup-response: func(req:u32, has-body:u8, body-len: u64) -> s32; + + // NEED IT ? param in response setup? + allow-ranges: func(req:u32); + + write-body: func(req:u32, buf:u32, len:u32) -> s32; + + // NEED it ? auto on close? + finalize: func(req:u32) -> s32; +} + +interface http-filter { + process-stream: func(fd: s32, env-fd:s32) -> s64; +} + +interface http-handler { + handle-request: func(req: s32) -> s32; + + init: func(req:u32) -> s32; + process-request-body: func(req:u32) -> s32; + setup-response: func(req:u32) -> s32; + generate-response: func(req:u32) -> s32; + finalize: func(req:u32) -> s32; +} diff --git a/njet b/njet deleted file mode 160000 index 663012b684327b0f1eb99e2c19ade72266aafc65..0000000000000000000000000000000000000000 --- a/njet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 663012b684327b0f1eb99e2c19ade72266aafc65 diff --git a/njet-3.1.0-wasm.diff b/njet-3.1.0-wasm.diff new file mode 100644 index 0000000000000000000000000000000000000000..2bdaac331fe59da1eeccad9ce6ea4c39d62b55ca --- /dev/null +++ b/njet-3.1.0-wasm.diff @@ -0,0 +1,6496 @@ +diff -urN njet/auto/modules njet-patch/auto/modules +--- njet/auto/modules 2024-11-12 11:39:20.673644340 +0800 ++++ njet-patch/auto/modules 2024-11-12 13:58:35.690380216 +0800 +@@ -56,6 +56,36 @@ + CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS" + fi + ++if [ $USE_WASMTIME != NO ]; then ++ ++ USE_WASM=YES ++ ++ njt_module_type=WASM ++ njt_module_name=njt_wasmtime_module ++ njt_module_incs= ++ njt_module_deps= ++ njt_module_srcs="src/core/njt_wasmtime_module.c" ++ njt_module_libs="-lwasmtime -lpthread -ldl" ++ njt_module_link=$USE_WASMTIME ++ ++ . auto/module ++fi ++ ++if [ $USE_IWASM != NO ]; then ++ ++ USE_WASM=YES ++ ++ njt_module_type=WASM ++ njt_module_name=njt_iwasm_module ++ njt_module_incs= ++ njt_module_deps= ++ njt_module_srcs="src/core/njt_iwasm_module.c" ++ njt_module_libs="-liwasm -lm" ++ njt_module_link=$USE_IWASM ++ ++ . auto/module ++fi ++ + if [ $DYNAMIC_POOL = YES ]; then + have=NJT_DYNAMIC_POOL . auto/have + fi +@@ -111,6 +141,12 @@ + HTTP_SRCS="$HTTP_SRCS $HTTP_HUFF_SRCS" + fi + ++ # TODO: depend on modules using this ++ if [ $USE_WASM != NO ]; then ++ HTTP_DEPS="$HTTP_DEPS src/http/njt_http_wasm_host.h" ++ HTTP_SRCS="$HTTP_SRCS src/http/njt_http_wasm_host.c" ++ fi ++ + + # the module order is important + # njt_http_static_module +@@ -423,6 +459,23 @@ + . auto/module + fi + ++ if [ $HTTP_WASM_FILTER != NO ]; then ++ ++ if [ $USE_WASM != YES ]; then ++ echo "$0: error: njt_http_wasm_filter_module requires --with-wasm" ++ exit 1 ++ fi ++ ++ njt_module_type=HTTP_AUX_FILTER ++ njt_module_name=njt_http_wasm_filter_module ++ njt_module_incs= ++ njt_module_deps= ++ njt_module_srcs=src/http/modules/njt_http_wasm_filter_module.c ++ njt_module_libs= ++ njt_module_link=YES ++ ++ . auto/module ++ fi + + njt_module_type=HTTP + +@@ -958,6 +1011,40 @@ + + . auto/module + fi ++ ++ if [ $HTTP_WASM_VAR != NO ]; then ++ ++ if [ $USE_WASM != YES ]; then ++ echo "$0: error: njt_http_wasm_var_module requires --with-wasm" ++ exit 1 ++ fi ++ ++ njt_module_name=njt_http_wasm_var_module ++ njt_module_incs= ++ njt_module_deps= ++ njt_module_srcs=src/http/modules/njt_http_wasm_var_module.c ++ njt_module_libs= ++ njt_module_link=$HTTP_WASM_VAR ++ ++ . auto/module ++ fi ++ ++ if [ $HTTP_WASM_CONTENT != NO ]; then ++ ++ if [ $USE_WASM != YES ]; then ++ echo "$0: error: njt_http_wasm_content_module requires --with-wasm" ++ exit 1 ++ fi ++ ++ njt_module_name=njt_http_wasm_content_module ++ njt_module_incs= ++ njt_module_deps= ++ njt_module_srcs=src/http/modules/njt_http_wasm_content_module.c ++ njt_module_libs= ++ njt_module_link=$HTTP_WASM_CONTENT ++ ++ . auto/module ++ fi + fi + + +@@ -1263,7 +1350,7 @@ + if test -f $njt_addon_dir/config; then + . $njt_addon_dir/config + +- echo " + $njt_addon_name was configured" ++ echo " $njt_addon_name was configured" + + else + echo "$0: error: no $njt_addon_dir/config was found" +@@ -1293,7 +1380,7 @@ + if test -f $njt_addon_dir/config; then + . $njt_addon_dir/config + +- echo " + $njt_addon_name was configured" ++ echo " $njt_addon_name was configured" + + else + echo "$0: error: no $njt_addon_dir/config was found" +@@ -1397,6 +1484,36 @@ + + modules="$CORE_MODULES $EVENT_MODULES" + ++if [ $USE_WASM = YES ]; then ++ ++ WASM_DEPS="$WASM_DEPS \ ++ src/core/njt_wasm.h \ ++ src/core/njt_wasm_handle.h \ ++ src/core/njt_wasm_log.h \ ++ src/core/njt_wasm_filter_ops.h \ ++ src/core/njt_wasm_call_env.h \ ++ src/core/njt_wasm_host.h \ ++ src/core/njt_wasi_core.h" ++ ++ WASM_SRCS="$WASM_SRCS \ ++ src/core/njt_wasm_module.c \ ++ src/core/njt_wasm_handle.c \ ++ src/core/njt_wasm_log.c \ ++ src/core/njt_wasm_filter_ops.c \ ++ src/core/njt_wasm_call_env.c \ ++ src/core/njt_wasm_host.c" ++ ++ WASM_MODULES="$WASM_MODULES njt_wasm_module njt_wasm_core_module" ++ ++ CORE_DEPS="$CORE_DEPS $WASM_DEPS" ++ CORE_INCS="$CORE_INCS $WASM_INCS" ++ CORE_SRCS="$CORE_SRCS $WASM_SRCS" ++ ++ modules="$modules $WASM_MODULES" ++ ++ have=NJT_WASM . auto/have ++fi ++ + + # thread pool module should be initialized after events + if [ $USE_THREADS = YES ]; then +@@ -1475,7 +1592,7 @@ + njt_module_incs= + njt_module_deps= + njt_module_srcs=src/misc/njt_cpp_test_module.cpp +- njt_module_libs=-lstdc++ ++ njt_module_libs=-lstdc + njt_module_link=$NJT_CPP_TEST + + . auto/module +diff -urN njet/auto/options njet-patch/auto/options +--- njet/auto/options 2024-11-12 11:39:20.673644340 +0800 ++++ njet-patch/auto/options 2024-11-12 14:05:43.516076247 +0800 +@@ -145,6 +145,13 @@ + NJT_ADDON_DEPS= + DYNAMIC_ADDONS= + ++USE_WASM=NO ++USE_IWASM=NO ++USE_WASMTIME=NO ++HTTP_WASM_VAR=NO ++HTTP_WASM_CONTENT=NO ++HTTP_WASM_FILTER=NO ++ + USE_NTLS=NO + NJT_LIBTCC=YES + +@@ -306,6 +313,9 @@ + + # STUB + --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; ++ --with-http_wasm_var_module) HTTP_WASM_VAR=YES ;; ++ --with-http_wasm_content_module) HTTP_WASM_CONTENT=YES ;; ++ --with-http_wasm_filter_module) HTTP_WASM_FILTER=YES ;; + + --with-mail) MAIL=YES ;; + --with-mail=dynamic) MAIL=DYNAMIC ;; +@@ -362,6 +372,11 @@ + + --with-compat) NJT_COMPAT=YES ;; + ++ --with-iwasm_module) USE_IWASM=YES ;; ++ --with-iwasm_module=dynamic) USE_IWASM=DYNAMIC ;; ++ --with-wasmtime_module) USE_WASMTIME=YES ;; ++ --with-wasmtime_module=dynamic) USE_WASMTIME=DYNAMIC ;; ++ + --with-ntls) USE_NTLS=YES ;; + + --with-cc=*) CC="$value" ;; +@@ -493,6 +508,9 @@ + --with-http_degradation_module enable njt_http_degradation_module + --with-http_slice_module enable njt_http_slice_module + --with-http_stub_status_module enable njt_http_stub_status_module ++ --with-http_wasm_var_module enable njt_http_wasm_var_module ++ --with-http_wasm_content_module enable njt_http_wasm_content_module ++ --with-http_wasm_filter_module enable njt_http_wasm_filter_module + + --without-http_charset_module disable njt_http_charset_module + --without-http_gzip_module disable njt_http_gzip_module +@@ -589,6 +607,11 @@ + + --with-compat dynamic modules compatibility + ++ --with-iwasm_module enable micro-wasm WASM runtime support ++ --with-iwasm_module=dynamic enable dynamic micro-wasm module ++ --with-wasmtime_module enable wasmtime WASM runtime support ++ --with-wasmtime_module=dynamic enable dynamic wasmtime module ++ + --with-ntls enable NTLS support + + --with-cc=PATH set C compiler pathname +diff -urN njet/auto/sources njet-patch/auto/sources +--- njet/auto/sources 2024-11-12 11:39:20.673644340 +0800 ++++ njet-patch/auto/sources 2024-11-12 14:06:38.446219296 +0800 +@@ -266,3 +266,9 @@ + + HTTP_HUFF_SRCS="src/http/njt_http_huff_decode.c + src/http/njt_http_huff_encode.c" ++ ++ ++WASM_MODULES= ++WASM_INCS= ++WASM_DEPS= ++WASM_SRCS= +\ No newline at end of file +diff -urN njet/build_cc.sh njet-patch/build_cc.sh +--- njet/build_cc.sh 2024-11-12 11:39:20.677644353 +0800 ++++ njet-patch/build_cc.sh 2024-11-14 10:25:22.293283150 +0800 +@@ -75,10 +75,15 @@ + LIB_SRC_PATH=" --with-openssl=auto/lib/tongsuo " + fi + +-flags=" $NJET_MODULES $PATH_INFO $LIB_SRC_PATH --build=$GIT_TAG --with-stream --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc=/usr/bin/cc --with-pcre" ++flags=" $NJET_MODULES $PATH_INFO $LIB_SRC_PATH --build=$GIT_TAG --with-stream --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-iwasm_module=dynamic --with-wasmtime_module=dynamic --with-http_wasm_var_module --with-http_wasm_content_module --with-http_wasm_filter_module --with-cc=/usr/bin/cc --with-pcre" ++ ++WTIME_VER="v25.0.0" ++WAMR_VER="1.3.2" ++WTIME_CAPI="`pwd`/../wasmtime-${WTIME_VER}-x86_64-linux-c-api" ++WAMR="`pwd`/../wasm-micro-runtime-WAMR-${WAMR_VER}" + + if [ "$DEBUG" = "True" ]; then +- LD_OPT="-fsanitize=address -static-libgcc -static-libasan -ldl -lm" ++ LD_OPT="-fsanitize=address -static-libgcc -static-libasan -ldl -lm -L${WTIME_CAPI}/lib/ -L${WAMR}/build" + if [ "$WITH_TONGSUO_8_4" = "True" ]; then + CC_OPT="-O0 -ggdb -Wno-deprecated-declarations -Wno-implicit-fallthrough -fsanitize=address -fno-omit-frame-pointer -static-libgcc -static-libasan -Wall -Wextra -Wshadow" + else +@@ -86,7 +91,7 @@ + fi + flags="$flags --with-debug" + else +- LD_OPT="-ldl -lm" ++ LD_OPT="-ldl -lm -L${WTIME_CAPI}/lib/ -L${WAMR}/build" + if [ "$WITH_TONGSUO_8_4" = "True" ]; then + CC_OPT="-O2 -g -Wno-implicit-fallthrough -Wno-deprecated-declarations -fPIC" + else +@@ -132,9 +137,9 @@ + fi + + if [ "$WITH_TONGSUO_8_4" = "True" ]; then +- ./configure --with-openssl=auto/lib/Tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT" --with-ld-opt="$LD_OPT" ++ ./configure --with-openssl=auto/lib/Tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT -I${WTIME_CAPI}/include/ -I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + else +- ./configure --with-openssl=auto/lib/tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT" --with-ld-opt="$LD_OPT" ++ ./configure --with-openssl=auto/lib/tongsuo $flags --with-openssl-opt='--strict-warnings enable-ntls' --with-ntls --with-cc-opt="$CC_OPT -I${WTIME_CAPI}/include/ -I${WAMR}/core/iwasm/include" --with-ld-opt="$LD_OPT" + fi + ;; + make) +@@ -143,7 +148,8 @@ + install) + make install + cd luajit;PREFIX=${NJET_PREFIX} make install_lib;cd -; +- mkdir -p ${DESTDIR}${NJET_PREFIX}/{lib,lualib} ++ mkdir -p ${DESTDIR}${NJET_PREFIX}/{apigw_data,lib,lualib} ++ cp -a build/api_gateway.db ${DESTDIR}${NJET_PREFIX}/apigw_data + cp -a lualib/lib ${DESTDIR}${NJET_PREFIX}/lualib/ + if [ -d auto/lib/modsecurity/src/.libs ]; then + cp -a auto/lib/modsecurity/src/.libs/libmodsecurity.so* ${DESTDIR}${NJET_PREFIX}/lib +diff -urN njet/src/core/njt_core.h njet-patch/src/core/njt_core.h +--- njet/src/core/njt_core.h 2024-11-12 11:39:20.773644657 +0800 ++++ njet-patch/src/core/njt_core.h 2024-11-12 14:08:05.484219729 +0800 +@@ -102,7 +102,9 @@ + #if (NJT_HAVE_BPF) + #include + #endif +- ++#if (NJT_WASM) ++#include ++#endif + + #define LF (u_char) '\n' + #define CR (u_char) '\r' +diff -urN njet/src/core/njt_iwasm_module.c njet-patch/src/core/njt_iwasm_module.c +--- njet/src/core/njt_iwasm_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_iwasm_module.c 2024-11-15 16:19:40.121649857 +0800 +@@ -0,0 +1,550 @@ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define njt_iwasm_err(b) njt_strnlen((u_char *) b, NJT_MAX_ERROR_STR - 1), b ++ ++ ++typedef struct { ++ size_t stack_size; ++ size_t heap_size; ++ size_t global_heap_size; ++} njt_iwasm_conf_t; ++ ++typedef struct { ++ wasm_module_inst_t instance; ++ wasm_exec_env_t exec_env; ++} njt_iwasm_instance_t; ++ ++ ++static void *njt_iwasm_create_conf(njt_cycle_t *cycle); ++static char *njt_iwasm_init_conf(njt_cycle_t *cycle, void *conf); ++ ++static njt_int_t njt_iwasm_create_runtime(njt_cycle_t *cycle); ++static void njt_iwasm_delete_runtime(njt_cycle_t *cycle); ++ ++static njt_int_t njt_iwasm_create_module(njt_cycle_t *cycle, ++ njt_wasm_module_t *wm); ++static void njt_iwasm_delete_module(njt_wasm_module_t *wm); ++ ++static njt_wasm_instance_t *njt_iwasm_create_instance(njt_wasm_module_t *wm, ++ njt_pool_t *pool, njt_log_t *log); ++static void njt_iwasm_delete_instance(njt_wasm_instance_t *wi); ++ ++static njt_int_t njt_iwasm_enter(njt_wasm_instance_t *wi, ++ njt_wasm_call_t *call); ++void *njt_iwasm_translate(njt_wasm_instance_t *wi, uint32_t addr, size_t len); ++ ++ ++static int32_t njt_iwasm_open(wasm_exec_env_t exec_env, uint32_t namebuf, ++ uint32_t len, uint32_t parent); ++static int32_t njt_iwasm_close(wasm_exec_env_t exec_env, uint32_t handle); ++static int32_t njt_iwasm_read(wasm_exec_env_t exec_env, uint32_t handle, ++ uint32_t buf, uint32_t len); ++static int32_t njt_iwasm_write(wasm_exec_env_t exec_env, uint32_t handle, ++ uint32_t buf, uint32_t len); ++static int32_t njt_iwasm_get(wasm_exec_env_t exec_env, uint32_t handle, ++ uint32_t propid, uint32_t buf, uint32_t len); ++static int32_t njt_iwasm_set(wasm_exec_env_t exec_env, uint32_t handle, ++ uint32_t propid, uint32_t buf, uint32_t len); ++ ++ ++static njt_str_t iwasm_name = njt_string("iwasm"); ++ ++static njt_command_t njt_iwasm_commands[] = { ++ ++ { njt_string("iwasm_stack_size"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1, ++ njt_conf_set_size_slot, ++ 0, ++ offsetof(njt_iwasm_conf_t, stack_size), ++ NULL }, ++ ++ { njt_string("iwasm_heap_size"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1, ++ njt_conf_set_size_slot, ++ 0, ++ offsetof(njt_iwasm_conf_t, heap_size), ++ NULL }, ++ ++ { njt_string("iwasm_global_heap_size"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1, ++ njt_conf_set_size_slot, ++ 0, ++ offsetof(njt_iwasm_conf_t, global_heap_size), ++ NULL }, ++ ++ njt_null_command ++}; ++ ++static njt_wasm_core_module_t njt_iwasm_module_ctx = { ++ &iwasm_name, ++ njt_iwasm_create_conf, /* create configuration */ ++ njt_iwasm_init_conf, /* init configuration */ ++ ++ { ++ njt_iwasm_create_runtime, ++ njt_iwasm_delete_runtime, ++ njt_iwasm_create_module, ++ njt_iwasm_delete_module, ++ njt_iwasm_create_instance, ++ njt_iwasm_delete_instance, ++ njt_iwasm_enter, ++ njt_iwasm_translate, ++ 1, ++ } ++}; ++ ++ ++njt_module_t njt_iwasm_module = { ++ NJT_MODULE_V1, ++ &njt_iwasm_module_ctx, /* module context */ ++ njt_iwasm_commands, /* module directives */ ++ NJT_WASM_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++#define njt_wasi_prefix "njt:wasi/syscall" ++ ++static NativeSymbol njt_iwasm_host_functions[] = ++{ ++ { "open", njt_iwasm_open, "(iii)i", NULL }, ++ { "close", njt_iwasm_close, "(i)i", NULL }, ++ { "read", njt_iwasm_read, "(iii)i", NULL }, ++ { "write", njt_iwasm_write, "(iii)i", NULL }, ++ { "get", njt_iwasm_get, "(iiii)i", NULL }, ++ { "set", njt_iwasm_set, "(iiii)i", NULL }, ++}; ++ ++ ++static void * ++njt_iwasm_create_conf(njt_cycle_t *cycle) ++{ ++ njt_iwasm_conf_t *iwcf; ++ ++ iwcf = njt_pcalloc(cycle->pool, sizeof(njt_iwasm_conf_t)); ++ if (iwcf == NULL) { ++ return NULL; ++ } ++ ++ iwcf->stack_size = NJT_CONF_UNSET_SIZE; ++ iwcf->heap_size = NJT_CONF_UNSET_SIZE; ++ iwcf->global_heap_size = NJT_CONF_UNSET_SIZE; ++ ++ return iwcf; ++} ++ ++ ++static char * ++njt_iwasm_init_conf(njt_cycle_t *cycle, void *conf) ++{ ++ njt_iwasm_conf_t *iwcf = conf; ++ ++ njt_conf_init_size_value(iwcf->stack_size, 8092); ++ njt_conf_init_size_value(iwcf->heap_size, 8092); ++ njt_conf_init_size_value(iwcf->global_heap_size, (1024 * 1024)); ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static njt_int_t ++njt_iwasm_create_runtime(njt_cycle_t *cycle) ++{ ++ u_char *heap; ++ RuntimeInitArgs init_args; ++ njt_iwasm_conf_t *iwcf; ++ ++ iwcf = (njt_iwasm_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_iwasm_module); ++ ++ heap = njt_pnalloc(cycle->pool, iwcf->global_heap_size); ++ if (heap == NULL) { ++ return NJT_ERROR; ++ } ++ ++ njt_memzero(&init_args, sizeof(RuntimeInitArgs)); ++ ++ init_args.mem_alloc_type = Alloc_With_Pool; ++ init_args.mem_alloc_option.pool.heap_buf = heap; ++ init_args.mem_alloc_option.pool.heap_size = iwcf->global_heap_size; ++ ++ init_args.n_native_symbols = sizeof(njt_iwasm_host_functions) ++ / sizeof(NativeSymbol); ++ ++ init_args.native_module_name = njt_wasi_prefix; ++ init_args.native_symbols = njt_iwasm_host_functions; ++ ++ if (!wasm_runtime_full_init(&init_args)) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, ++ "iwasm: wasm_runtime_init() failed"); ++ return NJT_ERROR; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_iwasm_delete_runtime(njt_cycle_t *cycle) ++{ ++ wasm_runtime_destroy(); ++} ++ ++ ++static njt_int_t ++njt_iwasm_create_module(njt_cycle_t *cycle, njt_wasm_module_t *wm) ++{ ++ uint8_t *p; ++ wasm_module_t mod; ++ njt_wasm_conf_t *wcf; ++ ++ char err[NJT_MAX_ERROR_STR]; ++ ++ wcf = (njt_wasm_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_wasm_core_module); ++ ++ /* iwasm modifies buffer on load, so duplicate to allow subsequent calls */ ++ p = njt_palloc(cycle->pool, wm->src.len); ++ if (p == NULL) { ++ return NJT_ERROR; ++ } ++ ++ memcpy(p, wm->src.data, wm->src.len); ++ ++ mod = wasm_runtime_load(p, wm->src.len, err, sizeof(err)); ++ if (mod == NULL) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, ++ "iwasm: wasm_runtime_load() failed: %*s", ++ njt_iwasm_err(err)); ++ return NJT_ERROR; ++ } ++ ++ wm->data = mod; ++ wm->ctx = njt_wasm_get_conf(cycle->conf_ctx, njt_iwasm_module); ++ wm->wcf = wcf; ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_iwasm_delete_module(njt_wasm_module_t *wm) ++{ ++ wasm_runtime_unload(wm->data); ++} ++ ++ ++static njt_wasm_instance_t * ++njt_iwasm_create_instance(njt_wasm_module_t *wm, njt_pool_t *pool, ++ njt_log_t *log) ++{ ++ njt_iwasm_conf_t *iwcf; ++ wasm_module_inst_t wmi; ++ njt_wasm_instance_t *wi; ++ njt_iwasm_instance_t *iwi; ++ ++ char error_buf[NJT_MAX_ERROR_STR]; ++ ++ iwcf = (njt_iwasm_conf_t *) wm->ctx; ++ ++ wi = njt_pcalloc(pool, sizeof(njt_wasm_instance_t)); ++ if (wi == NULL) { ++ return NULL; ++ } ++ ++ iwi = njt_pcalloc(pool, sizeof(njt_iwasm_instance_t)); ++ if (iwi == NULL) { ++ return NULL; ++ } ++ ++ wi->pool = pool; ++ wi->log = log; ++ wi->mod = wm; ++ ++ wmi = wasm_runtime_instantiate(wm->data, iwcf->stack_size, iwcf->heap_size, ++ error_buf, sizeof(error_buf)); ++ if (wmi == NULL) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "iwasm: wasm_runtime_instantiate() failed: %*s", ++ njt_iwasm_err(error_buf)); ++ return NULL; ++ } ++ ++ iwi->exec_env = wasm_runtime_create_exec_env(wmi, iwcf->stack_size); ++ if (iwi->exec_env == NULL) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "iwasm: wasm_runtime_create_exec_env() failed"); ++ goto failed; ++ } ++ ++ iwi->instance = wmi; ++ ++ wi->data = iwi; ++ ++ ++ return wi; ++ ++failed: ++ ++ if (iwi->exec_env) { ++ wasm_runtime_destroy_exec_env(iwi->exec_env); ++ } ++ ++ wasm_runtime_deinstantiate(wmi); ++ ++ return NULL; ++} ++ ++ ++static njt_int_t ++njt_iwasm_enter(njt_wasm_instance_t *wi, njt_wasm_call_t *call) ++{ ++ njt_iwasm_instance_t *iwi = wi->data; ++ ++ njt_uint_t i; ++ wasm_val_t *fargs, res; ++ wasm_function_inst_t func; ++ ++ func = wasm_runtime_lookup_function(iwi->instance, ++ (char *) call->name.data, NULL); ++ if (func == NULL) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "iwasm: wasm_runtime_lookup_function(%V) failed", ++ &call->name); ++ return NJT_ERROR; ++ } ++ ++ wasm_runtime_set_user_data(iwi->exec_env, call->host); ++ ++ switch (call->rc.kind) { ++ case NJT_WT_I32: ++ res.kind = WASM_I32; ++ res.of.i32 = 0; ++ break; ++ case NJT_WT_I64: ++ res.kind = WASM_I64; ++ res.of.i64 = 0; ++ break; ++ ++ default: ++ /* TODO: other types */ ++ return NJT_ERROR; ++ } ++ ++ if (call->nargs) { ++ ++ fargs = njt_pcalloc(call->host->pool, ++ sizeof(wasm_val_t) * call->nargs); ++ if (fargs == NULL) { ++ return NJT_ERROR; ++ } ++ ++ for (i = 0; i < call->nargs; i++) { ++ switch (call->args[i].kind) { ++ case NJT_WT_I32: ++ fargs[i].kind = WASM_I32; ++ fargs[i].of.i32 = call->args[i].of.i32; ++ break; ++ ++ case NJT_WT_I64: ++ fargs[i].kind = WASM_I64; ++ fargs[i].of.i64 = call->args[i].of.i64; ++ break; ++ ++ case NJT_WT_F32: ++ fargs[i].kind = WASM_F32; ++ fargs[i].of.f32 = call->args[i].of.f32; ++ break; ++ ++ case NJT_WT_F64: ++ fargs[i].kind = WASM_F64; ++ fargs[i].of.f64 = call->args[i].of.f64; ++ break; ++ ++ default: ++ return NJT_ERROR; ++ } ++ } ++ ++ } else { ++ fargs = NULL; ++ } ++ ++ njt_log_debug3(NJT_LOG_DEBUG_CORE, wi->log, 0, ++ "iwasm: calling %V.%V(%ui args)", &wi->mod->ns, ++ &call->name, call->nargs); ++ ++ if (!wasm_runtime_call_wasm_a(iwi->exec_env, func, 1, &res, ++ call->nargs, fargs)) ++ { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "iwasm: wasm_runtime_call_wasm(%V) failed: %s", ++ &call->name, wasm_runtime_get_exception(iwi->instance)); ++ ++ return NJT_ERROR; ++ } ++ ++ switch (res.kind) { ++ case WASM_I32: ++ call->rc.of.i32 = res.of.i32; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_CORE, wi->log, 0, ++ "iwasm: call \"%V\" rc:%D", ++ &call->name, call->rc.of.i32); ++ break; ++ ++ case WASM_I64: ++ call->rc.of.i64 = res.of.i64; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_CORE, wi->log, 0, ++ "iwasm: call \"%V\" rc:%L", ++ &call->name, call->rc.of.i64); ++ break; ++ ++ default: ++ /* TODO: other types */ ++ return NJT_ERROR; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++void * ++njt_iwasm_translate(njt_wasm_instance_t *wi, uint32_t addr, size_t len) ++{ ++ njt_iwasm_instance_t *iwi = wi->data; ++ ++ if (!wasm_runtime_validate_app_addr(iwi->instance, addr, len)) { ++ return NULL; ++ } ++ ++ return wasm_runtime_addr_app_to_native(iwi->instance, addr); ++} ++ ++ ++static void ++njt_iwasm_delete_instance(njt_wasm_instance_t *wi) ++{ ++ njt_iwasm_instance_t *iwi = wi->data; ++ ++ wasm_runtime_destroy_exec_env(iwi->exec_env); ++ wasm_runtime_deinstantiate(iwi->instance); ++} ++ ++ ++static int32_t ++njt_iwasm_open(wasm_exec_env_t exec_env, uint32_t namebuf, uint32_t len, ++ uint32_t parent) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ uint8_t *buf; ++ ++ buf = njt_wasm_translate(host->wi, namebuf, len); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_iwasm_read bad address"); ++ return NJT_ERROR; ++ } ++ ++ return host->ops->open(host, buf, len, parent); ++} ++ ++ ++static int32_t ++njt_iwasm_close(wasm_exec_env_t exec_env, uint32_t handle) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ return host->ops->close(host, handle); ++} ++ ++ ++static int32_t ++njt_iwasm_read(wasm_exec_env_t exec_env, uint32_t handle, uint32_t b, ++ uint32_t len) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ uint8_t *buf; ++ ++ buf = njt_wasm_translate(host->wi, b, len); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_iwasm_read bad address"); ++ return NJT_ERROR; ++ } ++ ++ return host->ops->read(host, handle, buf, len); ++} ++ ++ ++static int32_t ++njt_iwasm_write(wasm_exec_env_t exec_env, uint32_t handle, uint32_t b, ++ uint32_t len) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ uint8_t *buf; ++ ++ buf = njt_wasm_translate(host->wi, b, len); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_iwasm_write bad address"); ++ return NJT_ERROR; ++ } ++ ++ return host->ops->write(host, handle, buf, len); ++} ++ ++ ++static int32_t ++njt_iwasm_get(wasm_exec_env_t exec_env, uint32_t handle, uint32_t propid, ++ uint32_t b, uint32_t len) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ uint8_t *buf; ++ ++ buf = njt_wasm_translate(host->wi, b, len); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_iwasm_get bad address"); ++ return NJT_ERROR; ++ } ++ ++ return host->ops->get(host, handle, propid, buf, len); ++} ++ ++ ++static int32_t ++njt_iwasm_set(wasm_exec_env_t exec_env, uint32_t handle, uint32_t propid, ++ uint32_t b, uint32_t len) ++{ ++ njt_wasm_host_t *host = wasm_runtime_get_user_data(exec_env); ++ ++ uint8_t *buf; ++ ++ buf = njt_wasm_translate(host->wi, b, len); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_iwasm_set bad address"); ++ return NJT_ERROR; ++ } ++ ++ return host->ops->set(host, handle, propid, buf, len); ++} +diff -urN njet/src/core/njt_wasi_core.h njet-patch/src/core/njt_wasi_core.h +--- njet/src/core/njt_wasi_core.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasi_core.h 2024-11-12 14:38:17.221719629 +0800 +@@ -0,0 +1,27 @@ ++// Generated by `wit-bindgen` 0.26.0. DO NOT EDIT! ++#ifndef __BINDINGS_NJT_WASI_CORE_H ++#define __BINDINGS_NJT_WASI_CORE_H ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include ++#include ++ ++// log level: matches NJT_LOG_ defines in src/core/njt_log.h ++typedef uint8_t njt_wasi_host_ll_t; ++ ++#define NJT_WASI_HOST_LL_STDERR 0 ++#define NJT_WASI_HOST_LL_EMERG 1 ++#define NJT_WASI_HOST_LL_ALERT 2 ++#define NJT_WASI_HOST_LL_CRIT 3 ++#define NJT_WASI_HOST_LL_ERR 4 ++#define NJT_WASI_HOST_LL_WARN 5 ++#define NJT_WASI_HOST_LL_NOTICE 6 ++#define NJT_WASI_HOST_LL_INFO 7 ++#define NJT_WASI_HOST_LL_DEBUG 8 ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +diff -urN njet/src/core/njt_wasm_call_env.c njet-patch/src/core/njt_wasm_call_env.c +--- njet/src/core/njt_wasm_call_env.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_call_env.c 2024-11-15 16:20:33.201309211 +0800 +@@ -0,0 +1,269 @@ ++ ++#include ++#include ++#include ++ ++ ++typedef struct { ++ njt_uint_t curr_item; ++ njt_uint_t state; ++ njt_uint_t nread; ++ off_t off; ++ njt_wasm_call_env_t *env; ++} njt_wasm_call_env_ctx_t; ++ ++ ++uintptr_t ++njt_wasm_encode_varlen_int(uint8_t *p, uint64_t value) ++{ ++ if (value <= 63) { ++ if (p == NULL) { ++ return 1; ++ } ++ ++ *p++ = value; ++ return (uintptr_t) p; ++ } ++ ++ if (value <= 16383) { ++ if (p == NULL) { ++ return 2; ++ } ++ ++ *p++ = 0x40 | (value >> 8); ++ *p++ = value; ++ return (uintptr_t) p; ++ } ++ ++ if (value <= 1073741823) { ++ if (p == NULL) { ++ return 4; ++ } ++ ++ *p++ = 0x80 | (value >> 24); ++ *p++ = (value >> 16); ++ *p++ = (value >> 8); ++ *p++ = value; ++ return (uintptr_t) p; ++ } ++ ++ if (p == NULL) { ++ return 8; ++ } ++ ++ *p++ = 0xc0 | (value >> 56); ++ *p++ = (value >> 48); ++ *p++ = (value >> 40); ++ *p++ = (value >> 32); ++ *p++ = (value >> 24); ++ *p++ = (value >> 16); ++ *p++ = (value >> 8); ++ *p++ = value; ++ return (uintptr_t) p; ++} ++ ++ ++static int32_t njt_wasm_host_open_env(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_host_read_env(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len); ++static int32_t njt_wasm_host_env_property_get(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++ ++ ++njt_wasm_handle_ops_t njt_wasm_call_env_ops[] = { ++ ++ { .type = njt_string("njt::call_env"), ++ .tag = NJT_WASM_HOST_CALL_ENV_TAG, ++ .open = njt_wasm_host_open_env, ++ .read = njt_wasm_host_read_env, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_wasm_host_env_property_get, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_host_close_stub, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++ ++static int32_t ++njt_wasm_host_open_env(njt_wasm_handle_t *self, njt_wasm_handle_t *parent) ++{ ++ njt_wasm_call_env_ctx_t *ctx; ++ ++ if (parent == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "%V: call env context is missing", &self->host->name); ++ return NJT_ERROR; ++ } ++ ++ if (parent->tag != NJT_WASM_HOST_CALL_ENV_TAG) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "%V: unexpected call env context tag:%ui", ++ &self->host->name, parent->tag); ++ return NJT_ERROR; ++ } ++ ++ ctx = njt_pcalloc(self->host->pool, sizeof(njt_wasm_call_env_ctx_t)); ++ if (ctx == NULL) { ++ return NJT_ERROR; ++ } ++ ++ ctx->env = parent->data; ++ ++ if (ctx->env->keys.nelts != ctx->env->values.nelts) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "%V: number of keys does not match number of items", ++ &self->host->name); ++ return NJT_ERROR; ++ } ++ ++ self->data = ctx; ++ ++ return NJT_OK; ++} ++ ++ ++// TODO: test parsers on both sides, this is just quick'n'dirty version, untested ++static int32_t ++njt_wasm_host_read_env(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_call_env_ctx_t *ce = self->data; ++ ++ enum { ++ st_key_len, ++ st_key, ++ st_data_len, ++ st_data ++ } state; ++ ++ size_t size; ++ uint8_t *p; ++ njt_str_t *keys, *values; ++ njt_uint_t i, left; ++ ++ ++ if (ce->nread >= ce->env->keys.nelts) { ++ return 0; ++ } ++ ++ left = len; ++ ++ state = ce->state; ++ keys = ce->env->keys.elts; ++ values = ce->env->values.elts; ++ ++ p = buf; ++ ++ for (i = ce->curr_item; i < ce->env->keys.nelts; i++) { ++ ++ switch (state) { ++ ++ case st_key_len: ++ size = njt_wasm_encode_varlen_int(NULL, keys[i].len); ++ if (left < size) { ++ goto done; ++ } ++ ++ p = (uint8_t *) njt_wasm_encode_varlen_int(p, keys[i].len); ++ state = st_key; ++ left -= size; ++ ++ /* fall through */ ++ ++ case st_key: ++ ++ size = keys[i].len - ce->off; ++ ++ if (left < size) { ++ size = left; ++ } ++ ++ p = njt_cpymem(p, keys[i].data + ce->off, size); ++ ce->off += size; ++ left -= size; ++ ++ if ((size_t) ce->off != keys[i].len) { ++ goto done; ++ } ++ ++ state = st_data_len; ++ ce->off = 0; ++ ++ /* fall through */ ++ ++ case st_data_len: ++ ++ size = njt_wasm_encode_varlen_int(NULL, values[i].len); ++ if (left < size) { ++ goto done; ++ } ++ ++ p = (uint8_t *) njt_wasm_encode_varlen_int(p, values[i].len); ++ state = st_data; ++ left -= size; ++ ++ /* fall through */ ++ ++ case st_data: ++ size = values[i].len - ce->off; ++ ++ if (left < size) { ++ size = left; ++ } ++ ++ p = njt_cpymem(p, values[i].data + ce->off, size); ++ ce->off += size; ++ left -= size; ++ ++ if ((size_t) ce->off != values[i].len) { ++ goto done; ++ } ++ ++ state = st_key_len; ++ ce->off = 0; ++ ce->nread++; ++ } ++ } ++ ++done: ++ ++ ce->state = state; ++ ++ return p - buf; ++} ++ ++ ++static int32_t ++njt_wasm_host_env_property_get(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_call_env_ctx_t *ce = self->data; ++ ++ uint32_t sizes[3]; ++ njt_str_t *keys, *values; ++ njt_uint_t i; ++ ++ keys = ce->env->keys.elts; ++ values = ce->env->values.elts; ++ ++ ++ sizes[0] = ce->env->keys.nelts; ++ sizes[1] = 0; ++ sizes[2] = 0; ++ ++ for (i = 0; i < ce->env->keys.nelts; i++) { ++ sizes[1] += keys[i].len; ++ sizes[2] += values[i].len; ++ } ++ ++ if (len < sizeof(sizes)) { ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(buf, sizes, sizeof(sizes)); ++ ++ return sizeof(sizes); ++} ++ +diff -urN njet/src/core/njt_wasm_call_env.h njet-patch/src/core/njt_wasm_call_env.h +--- njet/src/core/njt_wasm_call_env.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_call_env.h 2024-11-15 16:19:59.305526105 +0800 +@@ -0,0 +1,21 @@ ++ ++ ++#ifndef _NJT_WASM_CALL_ENV_H_INCLUDED_ ++#define _NJT_WASM_CALL_ENV_H_INCLUDED_ ++ ++ ++#include ++#include ++ ++#define NJT_WASM_HOST_CALL_ENV_TAG 0x43454E56 /* CENV */ ++ ++ ++extern njt_wasm_handle_ops_t njt_wasm_call_env_ops[]; ++ ++typedef struct { ++ njt_array_t keys; ++ njt_array_t values; ++} njt_wasm_call_env_t; ++ ++ ++#endif /* _NJT_WASM_CALL_ENV_H_INCLUDED_ */ +diff -urN njet/src/core/njt_wasm_filter_ops.c njet-patch/src/core/njt_wasm_filter_ops.c +--- njet/src/core/njt_wasm_filter_ops.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_filter_ops.c 2024-11-15 16:22:27.544592419 +0800 +@@ -0,0 +1,305 @@ ++ ++#include ++#include ++#include ++#include ++ ++ ++#define NJT_WASM_FILTER_BUFFER_SIZE 4096 ++ ++ ++/* filter state */ ++typedef struct { ++ njt_pool_t *pool; ++ njt_chain_t *in; ++ njt_chain_t *end; ++ njt_chain_t **last; ++ njt_chain_t **freep; ++ off_t off; ++ njt_buf_tag_t tag; ++} njt_wasm_filter_chain_ctx_t; ++ ++ ++static int32_t njt_wasm_filter_open(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_filter_close(njt_wasm_handle_t *self); ++ ++static int32_t njt_wasm_filter_read(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len); ++static int32_t njt_wasm_filter_write(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len); ++ ++static size_t njt_chain_to_buffer(njt_chain_t *in, off_t off, uint8_t *buf, ++ size_t size); ++ ++ ++njt_wasm_handle_ops_t njt_wasm_filter_ops[] = { ++ { .type = njt_string("njt::filter"), ++ .tag = NJT_WASM_HOST_FILTER_OPS_TAG, ++ .open = njt_wasm_filter_open, ++ .read = njt_wasm_filter_read, ++ .write = njt_wasm_filter_write, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_filter_close, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++ ++static int32_t ++njt_wasm_filter_open(njt_wasm_handle_t *self, njt_wasm_handle_t *fenv) ++{ ++ njt_pool_t *pool; ++ njt_wasm_filter_env_t *env; ++ njt_wasm_filter_chain_ctx_t *cc; ++ ++ pool = self->host->pool; ++ ++ cc = njt_pcalloc(pool, sizeof(njt_wasm_filter_chain_ctx_t)); ++ if (cc == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (fenv == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "%V: filter context is missing", &self->host->name); ++ return NJT_ERROR; ++ } ++ ++ if (fenv->tag != NJT_WASM_HOST_FILTER_OPS_TAG) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "%V: unexpected filter context tag:%ui", ++ &self->host->name, fenv->tag); ++ ++ return NJT_ERROR; ++ } ++ ++ env = fenv->data; ++ ++ cc->pool = pool; ++ cc->in = env->in; ++ cc->last = env->outp; ++ cc->freep = env->freep; ++ cc->tag = env->tag; ++ /* ++ * set by njt_pcalloc(): ++ * ++ * cc->off = 0; ++ * cc->out = NULL; ++ * cc->end = NULL; ++ */ ++ ++ self->data = cc; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_filter_close(njt_wasm_handle_t *self) ++{ ++ njt_wasm_filter_chain_ctx_t *cc = self->data; ++ ++ njt_chain_t *cl; ++ ++ cl = cc->end; ++ if (cl) { ++ cl->buf->last_buf = 1; ++ cl->next = NULL; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_filter_read(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_filter_chain_ctx_t *cc = self->data; ++ ++ size_t n; ++ ++ n = njt_chain_to_buffer(cc->in, cc->off, buf, len); ++ ++ cc->off += n; ++ ++ return n; ++} ++ ++ ++static int32_t ++njt_wasm_filter_write(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_filter_chain_ctx_t *cc = self->data; ++ ++ size_t bsize; ++ uint32_t left; ++ njt_buf_t *b; ++ njt_chain_t *tl, **ll; ++ ++ if (len == 0) { ++ return 0; ++ } ++ ++ left = len; ++ ll = cc->last; ++ tl = cc->end; ++ ++ /* fill the last buffer */ ++ if (cc->end && cc->end->buf && cc->end->buf->start) { ++ b = cc->end->buf; ++ ++ bsize = b->end - b->last; ++ ++ if (bsize == 0) { ++ goto next_buf; ++ } ++ ++ if (bsize >= len) { ++ njt_memcpy(b->last, buf, len); ++ b->last += len; ++ return len; ++ } else { ++ ++ njt_memcpy(b->last, buf, bsize); ++ b->last += bsize; ++ buf += bsize; ++ left -= bsize; ++ } ++ } ++ ++next_buf: ++ ++ /* add more buffers to chain */ ++ while (left) { ++ ++ tl = njt_chain_get_free_buf(cc->pool, cc->freep); ++ if (tl == NULL) { ++ return NJT_ERROR; ++ } ++ ++ b = tl->buf; ++ b->tag = cc->tag; ++ b->memory = 1; ++ ++ if (b->start == NULL) { ++ ++ bsize = njt_max(len, NJT_WASM_FILTER_BUFFER_SIZE); ++ ++ b->start = njt_pcalloc(cc->pool, bsize); ++ if (b->start == NULL) { ++ return NJT_ERROR; ++ } ++ b->end = b->start + bsize; ++ b->pos = b->last = b->start; ++ ++ } else { ++ bsize = b->end - b->start; ++ b->pos = b->last = b->start; ++ } ++ ++ *ll = tl; ++ ll = &tl->next; ++ ++ if (left <= bsize) { ++ ++ njt_memcpy(b->pos, buf, left); ++ b->last += left; ++ ++ break; ++ } ++ ++ njt_memcpy(b->pos, buf, bsize); ++ b->last += bsize; ++ ++ buf += bsize; ++ left -= bsize; ++ } ++ ++ cc->last = ll; ++ cc->end = tl; ++ ++ return len; ++} ++ ++ ++static size_t ++njt_chain_to_buffer(njt_chain_t *in, off_t off, uint8_t *buf, size_t size) ++{ ++ size_t n, left, len; ++ uint8_t *pos, *rpos,skip; ++ njt_buf_t *b; ++ njt_chain_t *cl; ++ ++ n = 0; ++ pos = buf; ++ ++ if (off) { ++ skip = 1; ++ left = off; ++ ++ } else { ++ skip = 0; ++ left = size; ++ } ++ ++ for (cl = in; cl; cl = cl->next) { ++ ++ b = cl->buf; ++ ++ if (njt_buf_special(b)) { ++ continue; ++ } ++ ++ len = njt_buf_size(b); ++ ++ if (len < left) { ++ ++ left -= len; ++ ++ if (!skip) { ++ pos = njt_cpymem(pos, b->pos, len); ++ n += len; ++ } ++ ++ continue; ++ } ++ ++ /* len >= left */ ++ ++ if (skip) { ++ skip = 0; ++ len -= left; ++ rpos = b->pos +left; ++ ++ left = size; ++ ++ if (len < left) { ++ left -= len; ++ ++ njt_memcpy(pos, rpos, len); ++ n += len; ++ ++ continue; ++ ++ } else { ++ ++ njt_memcpy(pos, rpos, left); ++ n += left; ++ ++ break; ++ } ++ ++ } else { ++ ++ njt_memcpy(pos, b->pos, left); ++ n += left; ++ ++ break; ++ } ++ } ++ ++ return n; ++} +diff -urN njet/src/core/njt_wasm_filter_ops.h njet-patch/src/core/njt_wasm_filter_ops.h +--- njet/src/core/njt_wasm_filter_ops.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_filter_ops.h 2024-11-15 16:16:13.251038751 +0800 +@@ -0,0 +1,24 @@ ++ ++#ifndef _NJT_WASM_FILTER_OPS_H_INCLUDED_ ++#define _NJT_WASM_FILTER_OPS_H_INCLUDED_ ++ ++ ++#include ++#include ++ ++#define NJT_WASM_HOST_FILTER_OPS_TAG 0x464C5452 /* FLTR */ ++ ++ ++/* all that filter needs to know */ ++typedef struct { ++ njt_chain_t *in; ++ njt_chain_t **freep; ++ njt_chain_t **outp; ++ njt_buf_tag_t tag; ++} njt_wasm_filter_env_t; ++ ++ ++extern njt_wasm_handle_ops_t njt_wasm_filter_ops[]; ++ ++ ++#endif /* _NJT_WASM_FILTER_OPS_H_INCLUDED_ */ +diff -urN njet/src/core/njt_wasm.h njet-patch/src/core/njt_wasm.h +--- njet/src/core/njt_wasm.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm.h 2024-11-15 16:16:44.142824176 +0800 +@@ -0,0 +1,147 @@ ++#ifndef __NJT_WASM_H_INCLUDED__ ++#define __NJT_WASM_H_INCLUDED__ ++ ++#include ++#include ++ ++ ++#define njt_wasm_create_runtime njt_wasm_actions.create_runtime ++#define njt_wasm_delete_runtime njt_wasm_actions.delete_runtime ++#define njt_wasm_create_module njt_wasm_actions.create_module ++#define njt_wasm_delete_module njt_wasm_actions.delete_module ++#define njt_wasm_create_instance njt_wasm_actions.create_instance ++#define njt_wasm_delete_instance njt_wasm_actions.delete_instance ++#define njt_wasm_enter njt_wasm_actions.enter ++#define njt_wasm_translate njt_wasm_actions.translate ++ ++ ++#define NJT_WASM_MODULE 0x4D634157 /* "MSAW" */ ++#define NJT_WASM_CONF 0x02000000 ++ ++#define njt_wasm_get_conf(conf_ctx, module) \ ++ njt_get_conf(conf_ctx, njt_wasm_module) \ ++ ? (*(njt_get_conf(conf_ctx, njt_wasm_module))) [module.ctx_index] \ ++ : NULL ++ ++ ++typedef struct njt_wasm_instance_s njt_wasm_instance_t; ++ ++ ++/* configuration of the 'wasm_modules' block */ ++typedef struct { ++ njt_uint_t use; /* configured runtime */ ++ u_char *name; /* name of configured runtime */ ++ njt_array_t modules; /* of njt_wasm_module_t */ ++} njt_wasm_conf_t; ++ ++ ++/* loadable WASM module */ ++typedef struct { ++ njt_str_t ns; /* namespace for exported functions */ ++ njt_str_t file; /* file name is in config */ ++ njt_str_t src; /* file contents */ ++ njt_wasm_conf_t *wcf; ++ void *data; /* loaded module */ ++ void *ctx; /* loaded module runtime config */ ++ njt_wasm_instance_t *reactor; /* persistent module instance */ ++ njt_uint_t is_reactor; /* unsigned is_reactor:1; */ ++} njt_wasm_module_t; ++ ++ ++#include ++ ++/* wasm call arguments */ ++typedef enum { ++ NJT_WT_I32, ++ NJT_WT_I64, ++ NJT_WT_F32, ++ NJT_WT_F64, ++ /* TODO: refs */ ++} njt_wasm_val_kind_t; ++ ++ ++typedef struct { ++ union { ++ int32_t i32; ++ int64_t i64; ++ float f32; ++ double f64; ++ } of; ++ njt_wasm_val_kind_t kind; ++} njt_wasm_val_t; ++ ++ ++/* WASM function's arguments and environment */ ++typedef struct { ++ njt_wasm_host_t *host; /* pointer to host */ ++ njt_str_t name; /* function to call: wasi:bar */ ++ uint32_t nargs; /* arguments count */ ++ njt_wasm_val_t *args; /* arguments */ ++ njt_wasm_val_t rc; /* return value */ ++} njt_wasm_call_t; ++ ++ ++/* WASM module's instance */ ++struct njt_wasm_instance_s { ++ njt_pool_t *pool; /* pool to use for instance alloc */ ++ njt_log_t *log; /* instance log */ ++ njt_wasm_module_t *mod; /* instance origin */ ++ void *data; /* instance (native to runtime) */ ++ void *ctx; /* context for instance's owner */ ++}; ++ ++ ++/* separate module that provides host functions environment */ ++ ++/* methods/properties of WASM runtimes */ ++typedef struct { ++ njt_int_t (*create_runtime)(njt_cycle_t *cycle); ++ void (*delete_runtime)(njt_cycle_t *cycle); ++ ++ njt_int_t (*create_module)(njt_cycle_t *cycle, njt_wasm_module_t *wm); ++ void (*delete_module)(njt_wasm_module_t *wm); ++ ++ ++ njt_wasm_instance_t *(*create_instance)(njt_wasm_module_t *wm, ++ njt_pool_t *pool, njt_log_t *log); ++ void (*delete_instance)(njt_wasm_instance_t *wi); ++ ++ njt_int_t (*enter)(njt_wasm_instance_t *wi, ++ njt_wasm_call_t *call); ++ ++ void *(*translate)(njt_wasm_instance_t *wi, uint32_t addr, size_t len); ++ ++ njt_uint_t validate_on_start; ++} njt_wasm_actions_t; ++ ++ ++/* module implementing WASM runtime */ ++typedef struct { ++ njt_str_t *name; ++ ++ void *(*create_conf)(njt_cycle_t *cycle); ++ char *(*init_conf)(njt_cycle_t *cycle, void *conf); ++ ++ njt_wasm_actions_t actions; ++} njt_wasm_core_module_t; ++ ++ ++/* obtain module by name */ ++njt_wasm_module_t *njt_wasm_get_module(njt_conf_t *cf, njt_str_t *ns); ++ ++/* for use with directives */ ++typedef struct { ++ njt_wasm_module_t *wm; /* wasm module reference */ ++ njt_str_t func; /* wasm function name */ ++} njt_wasm_func_conf_t; ++ ++char *njt_conf_set_wasm_ref_slot(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++ ++ ++extern njt_module_t njt_wasm_module; ++extern njt_module_t njt_wasm_core_module; ++extern njt_wasm_actions_t njt_wasm_actions; ++ ++ ++#endif /* __NJT_WASM_H_INCLUDED__ */ +diff -urN njet/src/core/njt_wasm_handle.c njet-patch/src/core/njt_wasm_handle.c +--- njet/src/core/njt_wasm_handle.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_handle.c 2024-11-15 16:22:28.620585774 +0800 +@@ -0,0 +1,162 @@ ++ ++ ++#include ++#include ++#include ++#include ++ ++ ++/* rbtree of open handles with assigned descriptors */ ++struct njt_wasm_handles_s { ++ njt_rbtree_t rbtree; ++ njt_rbtree_node_t sentinel; ++ ++ njt_pool_t *pool; ++ ++ njt_queue_t free; /* closed handles */ ++ njt_uint_t num; /* descriptor counter */ ++}; ++ ++ ++ ++static void ++njt_wasm_handle_rbtree_insert(njt_rbtree_node_t *temp, njt_rbtree_node_t *node, ++ njt_rbtree_node_t *sentinel) ++{ ++ njt_rbtree_node_t **p; ++ njt_wasm_handle_t *n, *nt; ++ ++ for ( ;; ) { ++ ++ if (node->key < temp->key) { ++ ++ p = &temp->left; ++ ++ } else if (node->key > temp->key) { ++ ++ p = &temp->right; ++ ++ } else { /* node->key == temp->key */ ++ ++ n = (njt_wasm_handle_t *) node; ++ nt = (njt_wasm_handle_t *) temp; ++ ++ p = (n->fd < nt->fd) ? &temp->left : &temp->right; ++ } ++ ++ if (*p == sentinel) { ++ break; ++ } ++ ++ temp = *p; ++ } ++ ++ *p = node; ++ node->parent = temp; ++ node->left = sentinel; ++ node->right = sentinel; ++ njt_rbt_red(node); ++} ++ ++ ++njt_wasm_handles_t * ++njt_wasm_handles_create(njt_pool_t *pool) ++{ ++ njt_wasm_handles_t *ht; ++ ++ ht = njt_pcalloc(pool, sizeof(njt_wasm_handles_t)); ++ if (ht == NULL) { ++ return NULL; ++ } ++ ++ njt_queue_init(&ht->free); ++ ++ njt_rbtree_init(&ht->rbtree, &ht->sentinel, njt_wasm_handle_rbtree_insert); ++ ++ ht->pool = pool; ++ ++ return ht; ++} ++ ++ ++njt_wasm_handle_t * ++njt_wasm_create_handle(njt_wasm_handles_t *handles) ++{ ++ njt_queue_t *q; ++ njt_wasm_handle_t *handle; ++ njt_rbtree_node_t *node; ++ ++ if (njt_queue_empty(&handles->free)) { ++ handle = njt_palloc(handles->pool, sizeof(njt_wasm_handle_t)); ++ if (handle == NULL) { ++ return NULL; ++ } ++ ++ node = &handle->node; ++ ++ node->key = handles->num++; ++ handle->fd = node->key; ++ ++ njt_rbtree_insert(&handles->rbtree, node); ++ ++ } else { ++ q = njt_queue_head(&handles->free); ++ handle = njt_queue_data(q, njt_wasm_handle_t, queue); ++ njt_queue_remove(q); ++ ++ /* key is reset when node was removed from tree */ ++ handle->node.key = handle->fd; ++ njt_rbtree_insert(&handles->rbtree, &handle->node); ++ } ++ ++ return handle; ++} ++ ++ ++njt_wasm_handle_t * ++njt_wasm_find_handle(njt_wasm_handles_t *handles, int32_t fd) ++{ ++ njt_wasm_handle_t *n; ++ njt_rbtree_node_t *node, *sentinel; ++ ++ node = handles->rbtree.root; ++ sentinel = handles->rbtree.sentinel; ++ ++ if (fd < 0) { ++ return NULL; ++ } ++ ++ while (node != sentinel) { ++ ++ n = (njt_wasm_handle_t *) node; ++ ++ if ((uint32_t) fd < n->fd) { ++ node = node->left; ++ continue; ++ } ++ ++ if ((uint32_t) fd > n->fd) { ++ node = node->right; ++ continue; ++ } ++ ++ /* fd == n->fd */ ++ return n; ++ } ++ ++ return NULL; ++} ++ ++ ++void ++njt_wasm_delete_handle(njt_wasm_handles_t *handles, njt_wasm_handle_t *handle) ++{ ++ njt_rbtree_node_t *node; ++ ++ node = &handle->node; ++ ++ njt_rbtree_delete(&handles->rbtree, node); ++ ++ njt_queue_insert_head(&handles->free, &handle->queue); ++} ++ +diff -urN njet/src/core/njt_wasm_handle.h njet-patch/src/core/njt_wasm_handle.h +--- njet/src/core/njt_wasm_handle.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_handle.h 2024-11-15 16:19:20.057780094 +0800 +@@ -0,0 +1,46 @@ ++ ++#ifndef _NGX_WASM_HANDLE_H_INCLUDED_ ++#define _NGX_WASM_HANDLE_H_INCLUDED_ ++ ++ ++#include ++#include ++ ++ ++/* internal object handle with state identified by descriptor */ ++struct njt_wasm_handle_s { ++ njt_rbtree_node_t node; ++ njt_queue_t queue; /* in free list */ ++ uint32_t fd; /* assigned descriptor number */ ++ njt_wasm_host_t *host; /* host env of this handle */ ++ njt_wasm_handle_ops_t *ops; /* type-specific operations */ ++ njt_uint_t tag; /* set by host object or by open */ ++ njt_log_t *log; ++ void *data; /* internal state, created by open() */ ++}; ++ ++ ++/* actual operations on host's objects */ ++struct njt_wasm_handle_ops_s { ++ njt_str_t type; /* object name */ ++ njt_uint_t tag; ++ int32_t (*open)(njt_wasm_handle_t *self, njt_wasm_handle_t *ctx); ++ int32_t (*close)(njt_wasm_handle_t *self); ++ int32_t (*read)(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len); ++ int32_t (*write)(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len); ++ int32_t (*get)(njt_wasm_handle_t *self, uint32_t propid, uint8_t *buf, ++ uint32_t len); ++ int32_t (*set)(njt_wasm_handle_t *self, uint32_t propid, uint8_t *buf, ++ uint32_t len); ++}; ++ ++ ++njt_wasm_handles_t *njt_wasm_handles_create(njt_pool_t *pool); ++njt_wasm_handle_t *njt_wasm_find_handle(njt_wasm_handles_t *handles, ++ int32_t fd); ++njt_wasm_handle_t *njt_wasm_create_handle(njt_wasm_handles_t *handles); ++void njt_wasm_delete_handle(njt_wasm_handles_t *handles, ++ njt_wasm_handle_t *handle); ++ ++ ++#endif /* _NGX_WASM_HANDLE_H_INCLUDED_ */ +diff -urN njet/src/core/njt_wasm_host.c njet-patch/src/core/njt_wasm_host.c +--- njet/src/core/njt_wasm_host.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_host.c 2024-11-15 16:22:29.280581698 +0800 +@@ -0,0 +1,362 @@ ++ ++#include ++#include ++ ++/* exported interfaces */ ++#include ++ ++ ++static int32_t njt_wasm_host_open(njt_wasm_host_t *host, uint8_t *namebuf, ++ uint32_t len, int32_t ctx); ++static int32_t njt_wasm_host_close(njt_wasm_host_t *host, int32_t fd); ++static int32_t njt_wasm_host_read(njt_wasm_host_t *host, int32_t fd, ++ uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_host_write(njt_wasm_host_t *host, int32_t fd, ++ uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_host_get(njt_wasm_host_t *host, int32_t fd, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_host_set(njt_wasm_host_t *host, int32_t fd, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++ ++ ++static njt_wasm_host_ops_t njt_wasm_dispatch_ops = { ++ njt_wasm_host_open, ++ njt_wasm_host_close, ++ njt_wasm_host_read, ++ njt_wasm_host_write, ++ njt_wasm_host_get, ++ njt_wasm_host_set, ++}; ++ ++ ++static njt_wasm_handle_ops_t njt_wasm_host_stub_ops[] = { ++ { .type = njt_string("host_object"), ++ .tag = (njt_uint_t) -1, ++ .open = njt_wasm_host_open_stub, ++ .read = njt_wasm_host_io_stub, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_host_close_stub, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++ ++njt_wasm_host_t * ++njt_wasm_host_create(njt_wasm_instance_t *wi, njt_pool_t *pool, size_t size, ++ njt_log_t *log, const char *name, njt_wasm_handle_ops_t **apis) ++{ ++ njt_pool_t *tmp_pool; ++ njt_hash_init_t hash; ++ njt_wasm_host_t *wh; ++ njt_wasm_handle_ops_t *ops, **api; ++ njt_hash_keys_arrays_t *hk; ++ ++ wh = njt_pcalloc(pool, size); ++ if (wh == NULL) { ++ return NULL; ++ } ++ ++ wh->wi = wi; ++ wh->pool = pool; ++ wh->log = log; ++ wh->ops = &njt_wasm_dispatch_ops; ++ ++ wh->name.len = njt_strlen(name); ++ wh->name.data = njt_pnalloc(pool, wh->name.len); ++ if (wh->name.data == NULL) { ++ return NULL; ++ } ++ njt_memcpy(wh->name.data, name, wh->name.len); ++ ++ wh->handles = njt_wasm_handles_create(pool); ++ if (wh->handles == NULL) { ++ return NULL; ++ } ++ ++ tmp_pool = njt_create_pool(NJT_DEFAULT_POOL_SIZE, pool->log); ++ if (tmp_pool == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ hash.hash = &wh->handle_ops; ++ hash.key = njt_hash_key; ++ hash.max_size = 512; ++ hash.bucket_size = njt_align(64, njt_cacheline_size); ++ hash.name = "wasm ops hash"; ++ hash.pool = pool; ++ hash.temp_pool = tmp_pool; ++ ++ hk = &wh->handle_ops_keys; ++ ++ hk->pool = pool; ++ hk->temp_pool = tmp_pool; ++ ++ njt_hash_keys_array_init(hk, NJT_HASH_SMALL); ++ ++ for (api = apis; *api; api++) { ++ for (ops = *api; ops && ops->type.len; ops++) { ++ njt_hash_add_key(hk, &ops->type, ops, NJT_HASH_READONLY_KEY); ++ } ++ } ++ ++ njt_hash_init(&hash, hk->keys.elts, hk->keys.nelts); ++ ++ njt_destroy_pool(tmp_pool); ++ ++ return wh; ++} ++ ++ ++int32_t ++njt_wasm_host_create_object(njt_wasm_host_t *host, njt_uint_t tag, void *data) ++{ ++ njt_wasm_handle_t *handle; ++ ++ handle = njt_wasm_create_handle(host->handles); ++ if (handle == NULL) { ++ return NJT_ERROR; ++ } ++ ++ handle->tag = tag; ++ handle->ops = njt_wasm_host_stub_ops; ++ handle->host = host; ++ handle->data = data; ++ handle->log = host->log; ++ ++ return handle->fd; ++} ++ ++ ++njt_int_t ++njt_wasm_host_delete_object(njt_wasm_host_t *host, int32_t fd) ++{ ++ njt_wasm_handle_t *handle; ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to delete object", ++ &host->name, fd); ++ return NJT_ERROR; ++ } ++ ++ njt_wasm_delete_handle(host->handles, handle); ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_host_open(njt_wasm_host_t *host, uint8_t *namebuf, uint32_t len, ++ int32_t ctx) ++{ ++ njt_str_t name; ++ njt_uint_t key; ++ njt_wasm_handle_t *handle, *other; ++ njt_wasm_handle_ops_t *ops; ++ ++ name.data = namebuf; ++ name.len = len; ++ ++ njt_log_debug3(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: open(\"%V\", fd:%D)", &host->name, &name, ctx); ++ ++ if (ctx != -1) { ++ other = njt_wasm_find_handle(host->handles, ctx); ++ ++ if (other == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: incorrect fd %D passed to open(\"%V\")", ++ &host->name, ctx, &name); ++ return NJT_ERROR; ++ } ++ ++ } else { ++ other = NULL; ++ } ++ ++ key = njt_hash_key(name.data, name.len); ++ ++ ops = njt_hash_find(&host->handle_ops, key, name.data, name.len); ++ if (ops == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: open unknown type \"%V\"", ++ &host->name, &name); ++ return NJT_ERROR; ++ } ++ ++ handle = njt_wasm_create_handle(host->handles); ++ if (handle == NULL) { ++ return NJT_ERROR; ++ } ++ ++ handle->tag = ops->tag; ++ handle->ops = ops; ++ handle->host = host; ++ handle->log = host->log; ++ ++ if (ops->open(handle, other) != NJT_OK) { ++ njt_wasm_delete_handle(host->handles, handle); ++ return NJT_ERROR; ++ } ++ ++ njt_log_debug4(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: open(\"%V\",fd:%D) = #%D", ++ &host->name, &name, ctx, handle->fd); ++ ++ return handle->fd; ++} ++ ++ ++static int32_t ++njt_wasm_host_close(njt_wasm_host_t *host, int32_t fd) ++{ ++ int32_t rc; ++ njt_wasm_handle_t *handle; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: close(fd:%D)", &host->name, fd); ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to close", ++ &host->name, fd); ++ return NJT_ERROR; ++ } ++ ++ rc = handle->ops->close(handle); ++ ++ if (rc == NJT_OK) { ++ njt_wasm_delete_handle(host->handles, handle); ++ } ++ ++ return rc; ++} ++ ++ ++static int32_t ++njt_wasm_host_read(njt_wasm_host_t *host, int32_t fd, uint8_t *buf, ++ uint32_t len) ++{ ++ njt_wasm_handle_t *handle; ++ ++ njt_log_debug3(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: read(fd:%D, len:%uD)", &host->name, fd, len); ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to read", ++ &host->name, fd); ++ return NJT_ERROR; ++ } ++ ++ return handle->ops->read(handle, buf, len); ++} ++ ++ ++static int32_t ++njt_wasm_host_write(njt_wasm_host_t *host, int32_t fd, uint8_t *buf, ++ uint32_t len) ++{ ++ njt_wasm_handle_t *handle; ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to write", ++ &host->name, fd); ++ ++ return NJT_ERROR; ++ } ++ ++#if (NJT_DEBUG) ++ /* avoid debug for logging itself */ ++ if (handle->ops->tag != NJT_WASM_HOST_LOG_TAG) { ++ njt_log_debug3(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: write(fd:%D, len:%D)", ++ &host->name, fd, len); ++ } ++#endif ++ ++ return handle->ops->write(handle, buf, len); ++} ++ ++ ++static int32_t ++njt_wasm_host_get(njt_wasm_host_t *host, int32_t fd, uint32_t propid, ++ uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_handle_t *handle; ++ ++ njt_log_debug4(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: get(fd:%D, id:%D, len:%D)", ++ &host->name, fd, propid, len); ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to get", ++ &host->name, fd); ++ ++ return NJT_ERROR; ++ } ++ ++ return handle->ops->get(handle, propid, buf, len); ++} ++ ++ ++static int32_t ++njt_wasm_host_set(njt_wasm_host_t *host, int32_t fd, uint32_t propid, ++ uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_handle_t *handle; ++ ++ njt_log_debug4(NJT_LOG_DEBUG_CORE, host->log, 0, ++ "%V host: set(fd:%D, id:%D, len:%D)", ++ &host->name, fd, propid, len); ++ ++ handle = njt_wasm_find_handle(host->handles, fd); ++ if (handle == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->log, 0, ++ "%V: invalid handle %D passed to set", ++ &host->name, fd); ++ return NJT_ERROR; ++ } ++ ++ return handle->ops->set(handle, propid, buf, len); ++} ++ ++ ++int32_t ++njt_wasm_host_open_stub(njt_wasm_handle_t *self, njt_wasm_handle_t *parent) ++{ ++ return NJT_ERROR; ++} ++ ++ ++int32_t ++njt_wasm_host_close_stub(njt_wasm_handle_t *self) ++{ ++ return NJT_OK; ++} ++ ++ ++int32_t ++njt_wasm_host_io_stub(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len) ++{ ++ return NJT_ERROR; ++} ++ ++ ++int32_t ++njt_wasm_host_property_stub(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len) ++{ ++ return NJT_ERROR; ++} +diff -urN njet/src/core/njt_wasm_host.h njet-patch/src/core/njt_wasm_host.h +--- njet/src/core/njt_wasm_host.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_host.h 2024-11-15 16:18:47.089995965 +0800 +@@ -0,0 +1,66 @@ ++ ++#ifndef _NJT_WASM_HOST_H_INCLUDED_ ++#define _NJT_WASM_HOST_H_INCLUDED_ ++ ++ ++#include ++#include ++ ++#define njt_wasm_host_null_ops \ ++ { njt_null_string, 0, NULL, NULL, NULL, NULL, NULL, NULL } ++ ++ ++typedef struct njt_wasm_host_s njt_wasm_host_t; ++typedef struct njt_wasm_handle_s njt_wasm_handle_t; ++typedef struct njt_wasm_handles_s njt_wasm_handles_t; ++typedef struct njt_wasm_handle_ops_s njt_wasm_handle_ops_t; ++ ++#include ++ ++ ++typedef struct { ++ int32_t (*open)(njt_wasm_host_t *host, uint8_t *namebuf, uint32_t len, ++ int32_t ctx); ++ int32_t (*close)(njt_wasm_host_t *host, int32_t handle); ++ int32_t (*read)(njt_wasm_host_t *host, int32_t handle, uint8_t *buf, ++ uint32_t len); ++ int32_t (*write)(njt_wasm_host_t *host, int32_t handle, uint8_t *buf, ++ uint32_t len); ++ int32_t (*get)(njt_wasm_host_t *host, int32_t handle, uint32_t propid, ++ uint8_t *buf, uint32_t len); ++ int32_t (*set)(njt_wasm_host_t *host, int32_t handle, uint32_t propid, ++ uint8_t *buf, uint32_t len); ++} njt_wasm_host_ops_t; ++ ++ ++/* the outermost context for wasm calls */ ++struct njt_wasm_host_s { ++ njt_wasm_instance_t *wi; ++ njt_pool_t *pool; ++ njt_log_t *log; ++ njt_str_t name; /* host name for logs */ ++ njt_wasm_host_ops_t *ops; /* wasm engine entries */ ++ njt_wasm_handles_t *handles; /* open descriptors */ ++ njt_hash_t handle_ops; /* per-object operations */ ++ njt_hash_keys_arrays_t handle_ops_keys; ++ /* extended by specific host data on creation */ ++}; ++ ++ ++njt_wasm_host_t *njt_wasm_host_create(njt_wasm_instance_t *wi, njt_pool_t *pool, ++ size_t size, njt_log_t *log, const char *name, njt_wasm_handle_ops_t **ops); ++ ++int32_t njt_wasm_host_create_object(njt_wasm_host_t *host, njt_uint_t tag, ++ void *data); ++njt_int_t njt_wasm_host_delete_object(njt_wasm_host_t *host, int32_t fd); ++ ++int32_t njt_wasm_host_open_stub(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++int32_t njt_wasm_host_io_stub(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len); ++int32_t njt_wasm_host_property_stub(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++int32_t njt_wasm_host_close_stub(njt_wasm_handle_t *self); ++ ++ ++#endif /* _NJT_WASM_HOST_H_INCLUDED_ */ +diff -urN njet/src/core/njt_wasm_log.c njet-patch/src/core/njt_wasm_log.c +--- njet/src/core/njt_wasm_log.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_log.c 2024-11-15 16:20:45.593230452 +0800 +@@ -0,0 +1,74 @@ ++ ++ ++#include ++#include ++#include ++ ++ ++static int32_t njt_wasm_host_open_log(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_host_write_log(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len); ++ ++njt_wasm_handle_ops_t njt_wasm_log_ops[] = { ++ { .type = njt_string("njt::core::log"), ++ .tag = NJT_WASM_HOST_LOG_TAG, ++ .open = njt_wasm_host_open_log, ++ .read = njt_wasm_host_io_stub, ++ .write = njt_wasm_host_write_log, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_host_close_stub, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++ ++static int32_t ++njt_wasm_host_open_log(njt_wasm_handle_t *self, njt_wasm_handle_t *parent) ++{ ++ self->data = self->host->log; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_host_write_log(njt_wasm_handle_t *self, uint8_t *buf, uint32_t len) ++{ ++ njt_log_t *log = self->data; ++ ++ njt_str_t msg; ++ njt_uint_t level; ++ njt_log_handler_pt handler; ++ ++ if (len <= 1) { ++ return 0; ++ } ++ ++ level = *buf++; ++ ++ if (level > NJT_LOG_DEBUG) { ++ level = NJT_LOG_DEBUG; ++ } ++ ++ msg.data = (u_char *) buf; ++ msg.len = len - 1; ++ ++ /* avoid details, if any */ ++ handler = log->handler; ++ log->handler = NULL; ++ ++ if (level == NJT_LOG_DEBUG) { ++ njt_log_debug2(NJT_LOG_DEBUG_HTTP, log, 0, ++ "%V target: %V", &self->host->name, &msg); ++ ++ } else { ++ njt_log_error(level, log, 0, "%V target: %V", &self->host->name, &msg); ++ } ++ ++ log->handler = handler; ++ ++ return len; ++} +diff -urN njet/src/core/njt_wasm_log.h njet-patch/src/core/njt_wasm_log.h +--- njet/src/core/njt_wasm_log.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_log.h 2024-11-15 16:16:27.714937930 +0800 +@@ -0,0 +1,15 @@ ++ ++#ifndef _NJT_WASM_LOG_H_INCLUDED_ ++#define _NJT_WASM_LOG_H_INCLUDED_ ++ ++ ++#include ++#include ++ ++#define NJT_WASM_HOST_LOG_TAG 0x43767971 /* CLOG */ ++ ++ ++extern njt_wasm_handle_ops_t njt_wasm_log_ops[]; ++ ++ ++#endif /* _NJT_WASM_LOG_H_INCLUDED_ */ +diff -urN njet/src/core/njt_wasm_module.c njet-patch/src/core/njt_wasm_module.c +--- njet/src/core/njt_wasm_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasm_module.c 2024-11-15 16:19:01.409901903 +0800 +@@ -0,0 +1,719 @@ ++ ++#include ++#include ++#include ++ ++ ++/* ++ * Implementation of generic WASM module type. ++ * The njt_event.c was used as a model. Refer to it if in doubt. ++ */ ++ ++ ++static char *njt_wasm_plugins_block(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++static njt_int_t njt_wasm_verify_modules(njt_cycle_t *cycle); ++ ++static char *njt_wasm_core_use(njt_conf_t *cf, njt_command_t *cmd, void *conf); ++static char *njt_wasm_core_load_module(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++ ++static void *njt_wasm_core_create_conf(njt_cycle_t *cycle); ++static char *njt_wasm_core_init_conf(njt_cycle_t *cycle, void *conf); ++ ++static njt_int_t njt_wasm_core_module_init(njt_cycle_t *cycle); ++static njt_int_t njt_wasm_core_process_init(njt_cycle_t *cycle); ++static void njt_wasm_core_process_exit(njt_cycle_t *cycle); ++ ++ ++static njt_command_t njt_wasm_commands[] = { ++ ++ /* NB: The 'wasm' name is already taken by kong module */ ++ { njt_string("wasm_modules"), ++ NJT_MAIN_CONF|NJT_CONF_BLOCK|NJT_CONF_NOARGS, ++ njt_wasm_plugins_block, ++ 0, ++ 0, ++ NULL }, ++ ++ ++ njt_null_command ++}; ++ ++ ++static njt_command_t njt_wasm_core_commands[] = { ++ ++ { njt_string("use"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1, ++ njt_wasm_core_use, ++ 0, ++ 0, ++ NULL }, ++ ++ { njt_string("load"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1|NJT_CONF_TAKE123, ++ njt_wasm_core_load_module, ++ 0, ++ 0, ++ NULL }, ++ ++ njt_null_command ++}; ++ ++ ++static njt_core_module_t njt_wasm_module_ctx = { ++ njt_string("WASM"), ++ NULL, ++ NULL ++}; ++ ++static njt_str_t njt_wasm_core_module_name = njt_string("wasm_core"); ++ ++static njt_wasm_core_module_t njt_wasm_core_module_ctx = { ++ &njt_wasm_core_module_name, ++ njt_wasm_core_create_conf, ++ njt_wasm_core_init_conf, ++ ++ { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 } ++}; ++ ++ ++njt_module_t njt_wasm_module = { ++ NJT_MODULE_V1, ++ &njt_wasm_module_ctx, /* module context */ ++ njt_wasm_commands, /* module directives */ ++ NJT_CORE_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++njt_module_t njt_wasm_core_module = { ++ NJT_MODULE_V1, ++ &njt_wasm_core_module_ctx, /* module context */ ++ njt_wasm_core_commands, /* module directives */ ++ NJT_WASM_MODULE, /* module type */ ++ NULL, /* init master */ ++ njt_wasm_core_module_init, /* init module */ ++ njt_wasm_core_process_init, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ njt_wasm_core_process_exit, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++njt_wasm_actions_t njt_wasm_actions; ++static njt_uint_t njt_wasm_max_module; ++ ++ ++static char * ++njt_wasm_plugins_block(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ char *rv; ++ void ***ctx; ++ njt_uint_t i; ++ njt_conf_t pcf; ++ njt_wasm_core_module_t *m; ++ ++ if (*(void **) conf) { ++ return "is duplicate"; ++ } ++ ++ /* count the number of the wasm modules and set up their indices */ ++ ++ njt_wasm_max_module = njt_count_modules(cf->cycle, NJT_WASM_MODULE); ++ ++ ctx = njt_pcalloc(cf->pool, sizeof(void *)); ++ if (ctx == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ *ctx = njt_pcalloc(cf->pool, njt_wasm_max_module * sizeof(void *)); ++ if (*ctx == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ *(void **) conf = ctx; ++ ++ for (i = 0; cf->cycle->modules[i]; i++) { ++ if (cf->cycle->modules[i]->type != NJT_WASM_MODULE) { ++ continue; ++ } ++ ++ m = cf->cycle->modules[i]->ctx; ++ ++ if (m->create_conf) { ++ (*ctx)[cf->cycle->modules[i]->ctx_index] = ++ m->create_conf(cf->cycle); ++ if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ } ++ } ++ ++ pcf = *cf; ++ cf->ctx = ctx; ++ cf->module_type = NJT_WASM_MODULE; ++ cf->cmd_type = NJT_WASM_CONF; ++ ++ rv = njt_conf_parse(cf, NULL); ++ ++ *cf = pcf; ++ ++ if (rv != NJT_CONF_OK) { ++ return rv; ++ } ++ ++ for (i = 0; cf->cycle->modules[i]; i++) { ++ if (cf->cycle->modules[i]->type != NJT_WASM_MODULE) { ++ continue; ++ } ++ ++ m = cf->cycle->modules[i]->ctx; ++ ++ if (m->init_conf) { ++ rv = m->init_conf(cf->cycle, ++ (*ctx)[cf->cycle->modules[i]->ctx_index]); ++ if (rv != NJT_CONF_OK) { ++ return rv; ++ } ++ } ++ } ++ ++ if (njt_wasm_verify_modules(cf->cycle) != NJT_OK) { ++ return NJT_CONF_ERROR; ++ } ++ ++ return NJT_CONF_OK; ++} ++ ++ ++/* ++ * creates temporary runtime at configuration stage in order ++ * to verify modules to be loaded: detect files in bad format, ++ * missing functions, etc). ++ */ ++static njt_int_t ++njt_wasm_verify_modules(njt_cycle_t *cycle) ++{ ++ njt_uint_t i; ++ njt_wasm_conf_t *wcf; ++ njt_wasm_module_t *wm; ++ njt_wasm_instance_t *wi; ++ ++ /* some runtimes cannot be stopped, thus avoid them */ ++ if (!njt_wasm_actions.validate_on_start) { ++ return NJT_OK; ++ } ++ ++ wcf = njt_wasm_get_conf(cycle->conf_ctx, njt_wasm_core_module); ++ ++ /* nothing to check */ ++ if (wcf->modules.nelts == 0) { ++ return NJT_OK; ++ } ++ ++ if (njt_wasm_create_runtime(cycle) != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ wm = wcf->modules.elts; ++ ++ for (i = 0; i < wcf->modules.nelts; i++) { ++ ++ if (njt_wasm_create_module(cycle, &wm[i]) != NJT_OK) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, ++ "failed to verify module \"%V\"", ++ &wm[i].file); ++ ++ return NJT_ERROR; ++ } ++ ++ /* ++ * NB: we are probably running as root here, and module ++ * instantiation with WASI enabled may call __initialize__() ++ */ ++ wi = njt_wasm_create_instance(&wm[i], cycle->pool, cycle->log); ++ if (wi == NULL) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, ++ "failed to verify module \"%V\"", ++ &wm[i].file); ++ ++ return NJT_ERROR; ++ } ++ ++ njt_log_debug1(NJT_LOG_DEBUG_CORE, cycle->log, 0, ++ "module \"%V\" validated", &wm[i].file); ++ ++ njt_wasm_delete_instance(wi); ++ njt_wasm_delete_module(&wm[i]); ++ } ++ ++ njt_wasm_delete_runtime(cycle); ++ ++ return NJT_OK; ++} ++ ++ ++njt_wasm_module_t * ++njt_wasm_get_module(njt_conf_t *cf, njt_str_t *ns) ++{ ++ njt_uint_t i; ++ njt_wasm_conf_t *wcf; ++ njt_wasm_module_t *wm; ++ ++ wcf = (njt_wasm_conf_t *) njt_wasm_get_conf(cf->cycle->conf_ctx, ++ njt_wasm_core_module); ++ ++ wm = wcf->modules.elts; ++ ++ for (i = 0; i < wcf->modules.nelts; i++) { ++ if (wm[i].ns.len != ns->len) { ++ continue; ++ } ++ ++ if (ns->len == 0) { ++ return &wm[i]; ++ } ++ ++ if (njt_strncmp(wm[i].ns.data, ns->data, ns->len) != 0) { ++ continue; ++ } ++ ++ return &wm[i]; ++ } ++ ++ return NULL; ++} ++ ++ ++static char * ++njt_wasm_core_use(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ njt_wasm_conf_t *wcf = conf; ++ ++ njt_int_t m; ++ njt_str_t *value; ++ njt_wasm_conf_t *old_wcf; ++ njt_wasm_core_module_t *module; ++ ++ if (wcf->use != NJT_CONF_UNSET_UINT) { ++ return "is duplicate"; ++ } ++ ++ value = cf->args->elts; ++ ++ if (cf->cycle->old_cycle->conf_ctx) { ++ old_wcf = njt_wasm_get_conf(cf->cycle->old_cycle->conf_ctx, ++ njt_wasm_core_module); ++ } else { ++ old_wcf = NULL; ++ } ++ ++ ++ for (m = 0; cf->cycle->modules[m]; m++) { ++ if (cf->cycle->modules[m]->type != NJT_WASM_MODULE) { ++ continue; ++ } ++ ++ module = cf->cycle->modules[m]->ctx; ++ if (module->name->len == value[1].len) { ++ if (njt_strcmp(module->name->data, value[1].data) == 0) { ++ wcf->use = cf->cycle->modules[m]->ctx_index; ++ wcf->name = module->name->data; ++ ++ if (njt_process == NJT_PROCESS_SINGLE ++ && old_wcf ++ && old_wcf->use != wcf->use) ++ { ++ njt_conf_log_error(NJT_LOG_EMERG, cf, 0, ++ "when the server runs without a master process " ++ "the \"%V\" wasm type must be the same as " ++ "in previous configuration - \"%s\" " ++ "and it cannot be changed on the fly, " ++ "to change it you need to stop server " ++ "and start it again", ++ &value[1], old_wcf->name); ++ ++ return NJT_CONF_ERROR; ++ } ++ ++ return NJT_CONF_OK; ++ } ++ } ++ } ++ ++ njt_conf_log_error(NJT_LOG_EMERG, cf, 0, ++ "invalid wasm type \"%V\"", &value[1]); ++ ++ return NJT_CONF_ERROR; ++} ++ ++ ++ ++static char * ++njt_wasm_core_load_module(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ njt_wasm_conf_t *wcf = conf; ++ ++ u_char *buf; ++ size_t size; ++ ssize_t n; ++ njt_str_t *value; ++ njt_uint_t i; ++ njt_file_t file; ++ njt_file_info_t fi; ++ njt_wasm_module_t *wm; ++ ++ buf = NULL; ++#if (NJT_SUPPRESS_WARN) ++ size = 0; ++#endif ++ ++ value = cf->args->elts; ++ ++ wm = njt_array_push(&wcf->modules); ++ if (wm == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ njt_memzero(wm, sizeof(njt_wasm_module_t)); ++ ++ wm->file = value[1]; ++ ++ if (njt_conf_full_name(cf->cycle, &value[1], 1) != NJT_OK) { ++ return NJT_CONF_ERROR; ++ } ++ ++ for (i = 2; i < cf->args->nelts; i++) { ++ // TODO: REQUIRED FIRST ARG ++ if (njt_strncmp(value[i].data, "id=", 3) == 0) { ++ value[i].data += 3; ++ value[i].len -= 3; ++ ++ if (value[i].len == 0) { ++ return "empty module id"; ++ } ++ ++ wm->ns = value[i]; ++ continue; ++ } ++ ++ if (njt_strncmp(value[i].data, "type=", 5) == 0) { ++ value[i].data += 5; ++ value[i].len -= 5; ++ ++ if (value[i].len == 0) { ++ return "empty module type"; ++ } ++ ++ if (value[i].len == 7 ++ && njt_strncmp(value[i].data, "reactor", 7) == 0) ++ { ++ wm->is_reactor = 1; ++ continue; ++ } ++ ++ if (value[i].len == 7 ++ && njt_strncmp(value[i].data, "command", 7) == 0) ++ { ++ wm->is_reactor = 0; ++ continue; ++ } ++ ++ return "unknown module type"; ++ } ++ } ++ ++ njt_memzero(&file, sizeof(njt_file_t)); ++ file.name = value[1]; ++ file.log = cf->log; ++ ++ file.fd = njt_open_file(file.name.data, NJT_FILE_RDONLY, NJT_FILE_OPEN, 0); ++ ++ if (file.fd == NJT_INVALID_FILE) { ++ njt_conf_log_error(NJT_LOG_EMERG, cf, njt_errno, ++ njt_open_file_n " \"%V\" failed", &file.name); ++ return NJT_CONF_ERROR; ++ } ++ ++ if (njt_fd_info(file.fd, &fi) == NJT_FILE_ERROR) { ++ njt_conf_log_error(NJT_LOG_CRIT, cf, njt_errno, ++ njt_fd_info_n " \"%V\" failed", &file.name); ++ goto failed; ++ } ++ ++ size = njt_file_size(&fi); ++ ++ if (size == 0) { ++ njt_conf_log_error(NJT_LOG_EMERG, cf, 0, ++ "\"%V\" zero file size", &file.name); ++ goto failed; ++ } ++ ++ buf = njt_pnalloc(cf->pool, size); ++ if (buf == NULL) { ++ goto failed; ++ } ++ ++ n = njt_read_file(&file, buf, size, 0); ++ ++ if (n == NJT_ERROR) { ++ njt_conf_log_error(NJT_LOG_CRIT, cf, njt_errno, ++ njt_read_file_n " \"%V\" failed", &file.name); ++ goto failed; ++ } ++ ++ if ((size_t) n != size) { ++ njt_conf_log_error(NJT_LOG_CRIT, cf, 0, ++ njt_read_file_n " \"%V\" returned only " ++ "%z bytes instead of %uz", &file.name, n, size); ++ goto failed; ++ } ++ ++ wm->src.data = buf; ++ wm->src.len = n; ++ ++ if (njt_close_file(file.fd) == NJT_FILE_ERROR) { ++ njt_log_error(NJT_LOG_ALERT, cf->log, njt_errno, ++ njt_close_file_n " \"%V\" failed", &file.name); ++ } ++ ++ return NJT_CONF_OK; ++ ++failed: ++ ++ if (njt_close_file(file.fd) == NJT_FILE_ERROR) { ++ njt_log_error(NJT_LOG_ALERT, cf->log, njt_errno, ++ njt_close_file_n " \"%V\" failed", &file.name); ++ } ++ ++ return NJT_CONF_ERROR; ++} ++ ++ ++static void * ++njt_wasm_core_create_conf(njt_cycle_t *cycle) ++{ ++ njt_wasm_conf_t *wcf; ++ ++ wcf = njt_palloc(cycle->pool, sizeof(njt_wasm_conf_t)); ++ if (wcf == NULL) { ++ return NULL; ++ } ++ ++ wcf->use = NJT_CONF_UNSET_UINT; ++ wcf->name = (void *) NJT_CONF_UNSET; ++ ++ if (njt_array_init(&wcf->modules, cycle->pool, 4, sizeof(njt_wasm_module_t)) ++ != NJT_OK) ++ { ++ return NJT_CONF_ERROR; ++ } ++ ++ return wcf; ++} ++ ++ ++static char * ++njt_wasm_core_init_conf(njt_cycle_t *cycle, void *conf) ++{ ++ njt_wasm_conf_t *wcf = conf; ++ ++ njt_uint_t i; ++ njt_module_t *module; ++ njt_wasm_core_module_t *wcm; ++ ++ module = NULL; ++ ++ for (i = 0; cycle->modules[i]; i++) { ++ ++ if (cycle->modules[i]->type != NJT_WASM_MODULE) { ++ continue; ++ } ++ ++ wcm = cycle->modules[i]->ctx; ++ ++ if (njt_strcmp(wcm->name->data, njt_wasm_core_module_name.data) == 0) { ++ continue; ++ } ++ ++ /* stop search if we found configured module */ ++ if (cycle->modules[i]->ctx_index == wcf->use) { ++ goto found; ++ } ++ ++ /* remember first suitable module as default */ ++ if (module != NULL) { ++ continue; ++ } ++ ++ module = cycle->modules[i]; ++ } ++ ++ if (module == NULL) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, "no wasm runtime found"); ++ return NJT_CONF_ERROR; ++ } ++ ++ /* init default module */ ++ njt_conf_init_uint_value(wcf->use, module->ctx_index); ++ ++ wcm = module->ctx; ++ njt_conf_init_ptr_value(wcf->name, wcm->name->data); ++ ++found: ++ ++ njt_wasm_actions = wcm->actions; ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static njt_int_t ++njt_wasm_core_module_init(njt_cycle_t *cycle) ++{ ++ void ***cf; ++ njt_wasm_conf_t *wcf; ++ ++ cf = njt_get_conf(cycle->conf_ctx, njt_wasm_module); ++ if (cf == NULL) { ++ return NJT_OK; ++ } ++ ++ wcf = (*cf)[njt_wasm_core_module.ctx_index]; ++ ++ if (!njt_test_config && njt_process <= NJT_PROCESS_MASTER) { ++ njt_log_error(NJT_LOG_NOTICE, cycle->log, 0, ++ "using the \"%s\" wasm runtime", wcf->name); ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_wasm_core_process_init(njt_cycle_t *cycle) ++{ ++ njt_uint_t i; ++ njt_wasm_conf_t *wcf; ++ njt_wasm_module_t *wm; ++ ++ wcf = njt_wasm_get_conf(cycle->conf_ctx, njt_wasm_core_module); ++ ++ if (wcf == NULL) { ++ return NJT_OK; ++ } ++ ++ if (wcf->modules.nelts == 0) { ++ return NJT_OK; ++ } ++ ++ if (njt_wasm_create_runtime(cycle) != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ wm = wcf->modules.elts; ++ ++ for (i = 0; i < wcf->modules.nelts; i++) { ++ ++ if (njt_wasm_create_module(cycle, &wm[i]) != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ if (wm[i].is_reactor) { ++ wm[i].reactor = njt_wasm_create_instance(&wm[i], cycle->pool, ++ cycle->log); ++ if (wm[i].reactor == NULL) { ++ return NJT_ERROR; ++ } ++ } ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_wasm_core_process_exit(njt_cycle_t *cycle) ++{ ++ njt_uint_t i; ++ njt_wasm_conf_t *wcf; ++ njt_wasm_module_t *wm; ++ ++ wcf = njt_wasm_get_conf(cycle->conf_ctx, njt_wasm_core_module); ++ ++ if (wcf == NULL) { ++ return; ++ } ++ ++ if (wcf->modules.nelts == 0) { ++ return; ++ } ++ ++ wm = wcf->modules.elts; ++ ++ for (i = 0; i < wcf->modules.nelts; i++) { ++ if (wm[i].is_reactor && wm[i].reactor) { ++ njt_wasm_delete_instance(wm[i].reactor); ++ } ++ njt_wasm_delete_module(&wm[i]); ++ } ++ ++ njt_wasm_delete_runtime(cycle); ++} ++ ++ ++char *njt_conf_set_wasm_ref_slot(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf) ++{ ++ char *p = conf; ++ ++ njt_str_t *value; ++ njt_conf_post_t *post; ++ njt_wasm_func_conf_t *fc; ++ ++ fc = (njt_wasm_func_conf_t *) (p + cmd->offset); ++ ++ if (fc->func.len) { ++ return "is duplicate"; ++ } ++ ++ value = cf->args->elts; ++ ++ fc->wm = njt_wasm_get_module(cf, &value[1]); ++ if (fc->wm == NULL) { ++ njt_conf_log_error(NJT_LOG_EMERG, cf, 0, ++ "module \"%V\" not found", &value[1]); ++ return NJT_CONF_ERROR; ++ } ++ ++ fc->func.data = njt_pnalloc(cf->pool, value[2].len + 1); ++ if (fc->func.data == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ njt_memcpy(fc->func.data, value[2].data, value[2].len); ++ fc->func.len = value[2].len; ++ ++ /* zero-terminate function name for convenience */ ++ fc->func.data[fc->func.len] = 0; ++ ++ ++ if (cmd->post) { ++ post = cmd->post; ++ return post->post_handler(cf, post, fc); ++ } ++ ++ return NJT_CONF_OK; ++ ++} ++ +diff -urN njet/src/core/njt_wasmtime_module.c njet-patch/src/core/njt_wasmtime_module.c +--- njet/src/core/njt_wasmtime_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/core/njt_wasmtime_module.c 2024-11-15 16:20:15.817420173 +0800 +@@ -0,0 +1,773 @@ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define njt_wasmtime_trap(msg) wasmtime_trap_new(msg, njt_strlen(msg)) ++ ++#define njt_wasmtime_call_data(cl) \ ++ wasmtime_context_get_data( \ ++ (wasmtime_context_t *) wasmtime_caller_context(cl)) ++ ++ ++/* Host API modules require access to this to define own functions */ ++typedef struct { ++ wasm_config_t *config; ++ wasm_engine_t *engine; ++ wasmtime_linker_t *linker; ++ njt_uint_t timedout; ++ size_t stack_size; ++ njt_flag_t enable_wasi; ++} njt_wasmtime_conf_t; ++ ++ ++typedef struct { ++ wasmtime_instance_t instance; ++ ++ wasmtime_store_t *store; ++ wasmtime_context_t *context; ++ wasi_config_t *wasi_config; ++ ++ wasmtime_memory_t memory; ++} njt_wasmtime_instance_t; ++ ++ ++typedef wasm_trap_t *(*njt_wasmtime_host_handler_pt)(void *env, ++ wasmtime_caller_t *caller, const wasmtime_val_t *args, size_t nargs, ++ wasmtime_val_t *rc, size_t nres); ++ ++ ++/* exported host function description */ ++typedef struct { ++ njt_str_t export; ++ njt_wasmtime_host_handler_pt handler; ++ njt_uint_t nargs; ++} njt_wasmtime_host_handler_t; ++ ++ ++static void njt_wasmtime_log_error(njt_uint_t level, njt_log_t *log, ++ wasmtime_error_t *err, wasm_trap_t *trap, char *fmt, ...); ++static njt_int_t njt_wasmtime_lookup_func(njt_wasm_instance_t *wi, ++ njt_str_t *name, wasmtime_func_t *func); ++ ++static void *njt_wasmtime_create_conf(njt_cycle_t *cycle); ++static char *njt_wasmtime_init_conf(njt_cycle_t *cycle, void *conf); ++static njt_int_t njt_wasmtime_create_runtime(njt_cycle_t *cycle); ++static void njt_wasmtime_delete_runtime(njt_cycle_t *cycle); ++ ++static njt_int_t njt_wasmtime_create_module(njt_cycle_t *cycle, ++ njt_wasm_module_t *wm); ++static void njt_wasmtime_delete_module(njt_wasm_module_t *wm); ++ ++static njt_wasm_instance_t *njt_wasmtime_create_instance( ++ njt_wasm_module_t *wm, njt_pool_t *pool, njt_log_t *log); ++ ++static void njt_wasmtime_delete_instance(njt_wasm_instance_t *wi); ++ ++static njt_int_t njt_wasmtime_enter(njt_wasm_instance_t *wi, ++ njt_wasm_call_t *call); ++ ++void *njt_wasmtime_translate(njt_wasm_instance_t *wi, uint32_t addr, ++ size_t len); ++ ++static njt_int_t njt_wasmtime_init_host_interface(njt_wasmtime_conf_t *wtcf, ++ njt_str_t *ns, njt_wasmtime_host_handler_t *item, njt_log_t *log); ++ ++static wasm_trap_t *njt_wasmtime_open(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++static wasm_trap_t *njt_wasmtime_close(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++static wasm_trap_t *njt_wasmtime_read(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++static wasm_trap_t *njt_wasmtime_write(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++static wasm_trap_t *njt_wasmtime_get(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++static wasm_trap_t *njt_wasmtime_set(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres); ++ ++ ++static njt_command_t njt_wasmtime_commands[] = { ++ ++ { njt_string("wasmtime_stack_size"), ++ NJT_WASM_CONF|NJT_CONF_TAKE1, ++ njt_conf_set_size_slot, ++ 0, ++ offsetof(njt_wasmtime_conf_t, stack_size), ++ NULL }, ++ ++ { njt_string("wasmtime_enable_wasi"), ++ NJT_WASM_CONF|NJT_CONF_FLAG, ++ njt_conf_set_flag_slot, ++ 0, ++ offsetof(njt_wasmtime_conf_t, enable_wasi), ++ NULL }, ++ ++ njt_null_command ++}; ++ ++static njt_str_t wasmtime_name = njt_string("wasmtime"); ++ ++static njt_wasm_core_module_t njt_wasmtime_module_ctx = { ++ &wasmtime_name, ++ njt_wasmtime_create_conf, /* create configuration */ ++ njt_wasmtime_init_conf, /* init configuration */ ++ ++ { ++ njt_wasmtime_create_runtime, ++ njt_wasmtime_delete_runtime, ++ njt_wasmtime_create_module, ++ njt_wasmtime_delete_module, ++ njt_wasmtime_create_instance, ++ njt_wasmtime_delete_instance, ++ njt_wasmtime_enter, ++ njt_wasmtime_translate, ++ /* ++ * wasmtime starts threads - this leads to problems after fork(), ++ * thus on-start module validation is disabled ++ */ ++ 0 ++ } ++}; ++ ++ ++njt_module_t njt_wasmtime_module = { ++ NJT_MODULE_V1, ++ &njt_wasmtime_module_ctx, /* module context */ ++ njt_wasmtime_commands, /* module directives */ ++ NJT_WASM_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++static njt_str_t njt_wasi_prefix = njt_string("njt:wasi/syscall"); ++ ++static njt_wasmtime_host_handler_t njt_wasmtime_host_handlers[] = { ++ { njt_string("open"), njt_wasmtime_open, 3 }, ++ { njt_string("close"), njt_wasmtime_close, 1 }, ++ { njt_string("read"), njt_wasmtime_read, 3 }, ++ { njt_string("write"), njt_wasmtime_write, 3 }, ++ { njt_string("get"), njt_wasmtime_get, 4 }, ++ { njt_string("set"), njt_wasmtime_set, 4 }, ++}; ++ ++ ++static void ++njt_wasmtime_log_error(njt_uint_t level, njt_log_t *log, wasmtime_error_t *err, ++ wasm_trap_t *trap, char *fmt, ...) ++{ ++ va_list args; ++ u_char *p, *last; ++ u_char errstr[NJT_MAX_CONF_ERRSTR]; ++ wasm_byte_vec_t msg; ++ ++ last = errstr + NJT_MAX_CONF_ERRSTR; ++ ++ va_start(args, fmt); ++ p = njt_vslprintf(errstr, last - 1, fmt, args); ++ va_end(args); ++ ++ if (err != NULL) { ++ wasmtime_error_message(err, &msg); ++ ++ } else { ++ wasm_trap_message(trap, &msg); ++ } ++ ++ if (msg.size == 0) { ++ goto done; ++ } ++ ++ p = njt_slprintf(p, last, " (wasmtime %s: ", ++ err != NULL ? "error" : "trap"); ++ ++ if (p + msg.size > last) { ++ msg.size = last - p; ++ } ++ ++ p = njt_cpystrn(p, (u_char *) msg.data, msg.size); ++ ++ if (p < last) { ++ *p++ = ')'; ++ } ++ ++done: ++ ++ njt_log_error(level, log, 0, "%*s", p - errstr, errstr); ++ ++ if (err != NULL) { ++ wasmtime_error_delete(err); ++ ++ } else { ++ wasm_trap_delete(trap); ++ } ++} ++ ++ ++static void * ++njt_wasmtime_create_conf(njt_cycle_t *cycle) ++{ ++ njt_wasmtime_conf_t *wtcf; ++ ++ wtcf = njt_pcalloc(cycle->pool, sizeof(njt_wasmtime_conf_t)); ++ if (wtcf == NULL) { ++ return NULL; ++ } ++ ++ wtcf->stack_size = NJT_CONF_UNSET_SIZE; ++ wtcf->enable_wasi = NJT_CONF_UNSET; ++ ++ return wtcf; ++} ++ ++ ++static char * ++njt_wasmtime_init_conf(njt_cycle_t *cycle, void *conf) ++{ ++ njt_wasmtime_conf_t *wtcf = conf; ++ ++ njt_conf_init_size_value(wtcf->stack_size, 8092); ++ njt_conf_init_value(wtcf->enable_wasi, 1); ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static njt_int_t ++njt_wasmtime_create_runtime(njt_cycle_t *cycle) ++{ ++ njt_uint_t i, nhandlers; ++ wasmtime_error_t *error; ++ njt_wasmtime_conf_t *wtcf; ++ ++ wtcf = (njt_wasmtime_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_wasmtime_module); ++ ++ wtcf->config = wasm_config_new(); ++ if (wtcf->config == NULL) { ++ return NJT_ERROR; ++ } ++ ++ wasmtime_config_max_wasm_stack_set(wtcf->config, wtcf->stack_size); ++ ++ wtcf->engine = wasm_engine_new_with_config(wtcf->config); ++ if (wtcf->engine == NULL) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, "wasm_engine_new"); ++ return NJT_ERROR; ++ } ++ ++ wtcf->linker = wasmtime_linker_new(wtcf->engine); ++ if (wtcf->linker == NULL) { ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, "wasm_linker_new"); ++ return NJT_ERROR; ++ } ++ ++ if (wtcf->enable_wasi) { ++ error = wasmtime_linker_define_wasi(wtcf->linker); ++ if (error != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, cycle->log, error, NULL, ++ "failed to link wasi"); ++ return NJT_ERROR; ++ } ++ } ++ ++ nhandlers = sizeof(njt_wasmtime_host_handlers) ++ / sizeof(njt_wasmtime_host_handlers[0]); ++ ++ for (i = 0; i < nhandlers; i++) { ++ if (njt_wasmtime_init_host_interface(wtcf, &njt_wasi_prefix, ++ &njt_wasmtime_host_handlers[i], ++ cycle->log) ++ != NJT_OK) ++ { ++ return NJT_ERROR; ++ } ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_wasmtime_init_host_interface(njt_wasmtime_conf_t *wtcf, njt_str_t *ns, ++ njt_wasmtime_host_handler_t *item, njt_log_t *log) ++{ ++ njt_uint_t nargs, i; ++ wasm_valtype_t *arg_types[4], *rtype[1]; ++ wasm_functype_t *wft; ++ wasmtime_error_t *error; ++ wasm_valtype_vec_t func_params, results; ++ ++ if (item->nargs > 4) { ++ return NJT_ERROR; ++ } ++ ++ nargs = item->nargs; ++ ++ for (i = 0; i < nargs; i++) { ++ arg_types[i] = wasm_valtype_new_i32(); ++ } ++ ++ wasm_valtype_vec_new(&func_params, nargs, arg_types); ++ ++ rtype[0] = wasm_valtype_new_i32(); ++ wasm_valtype_vec_new(&results, 1, rtype); ++ ++ ++ wft = wasm_functype_new(&func_params, &results); ++ ++ error = wasmtime_linker_define_func(wtcf->linker, ++ (char *) ns->data, ns->len, ++ (char *) item->export.data, ++ item->export.len, ++ wft, item->handler, NULL, NULL); ++ if (error != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, log, error, NULL, ++ "failed to export host function \"%V\"", ++ &item->export); ++ return NJT_ERROR; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_wasmtime_enter(njt_wasm_instance_t *wi, njt_wasm_call_t *call) ++{ ++ njt_uint_t i; ++ wasm_trap_t *trap; ++ wasmtime_val_t res; ++ wasmtime_val_t *fargs; ++ wasmtime_func_t entry; ++ wasmtime_error_t *error; ++ njt_wasmtime_instance_t *wti; ++ ++ if (njt_wasmtime_lookup_func(wi, &call->name, &entry) ++ != NJT_OK) ++ { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "njt_wasmtime_enter failed to lookup function \"%V\"", ++ &call->name); ++ ++ return NJT_ERROR; ++ } ++ ++ wti = wi->data; ++ ++ wasmtime_context_set_data(wti->context, call->host); ++ ++ njt_memzero(&res, sizeof(wasmtime_val_t)); ++ ++ if (call->nargs) { ++ fargs = njt_palloc(call->host->pool, ++ sizeof(wasmtime_val_t) * call->nargs); ++ if (fargs == NULL) { ++ return NJT_ERROR; ++ } ++ ++ for (i = 0; i < call->nargs; i++) { ++ ++ switch (call->args[i].kind) { ++ case NJT_WT_I32: ++ fargs[i].kind = WASMTIME_I32; ++ fargs[i].of.i32 = call->args[i].of.i32; ++ break; ++ ++ case NJT_WT_I64: ++ fargs[i].kind = WASMTIME_I64; ++ fargs[i].of.i64 = call->args[i].of.i64; ++ break; ++ ++ case NJT_WT_F32: ++ fargs[i].kind = WASMTIME_F32; ++ fargs[i].of.f32 = call->args[i].of.f32; ++ break; ++ ++ case NJT_WT_F64: ++ fargs[i].kind = WASMTIME_F64; ++ fargs[i].of.f64 = call->args[i].of.f64; ++ break; ++ ++ default: ++ return NJT_ERROR; ++ } ++ } ++ ++ } else { ++ fargs = NULL; ++ } ++ ++ trap = NULL; ++ ++ error = wasmtime_func_call(wti->context, &entry, fargs, call->nargs, ++ &res, 1, &trap); ++ ++ if (error != NULL || trap != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, wi->log, error, trap, ++ "failed to call function \"%V\"", ++ &call->name); ++ return NJT_ERROR; ++ } ++ ++ switch (res.kind) { ++ case WASMTIME_I32: ++ call->rc.of.i32 = res.of.i32; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_CORE, wi->log, 0, ++ "wasmtime: call \"%V\" rc:%D", ++ &call->name, call->rc.of.i32); ++ break; ++ ++ case WASMTIME_I64: ++ call->rc.of.i64 = res.of.i64; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_CORE, wi->log, 0, ++ "wasmtime: call \"%V\" rc:%L", ++ &call->name, call->rc.of.i64); ++ break; ++ ++ default: ++ /* TODO: other types */ ++ return NJT_ERROR; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_wasmtime_delete_runtime(njt_cycle_t *cycle) ++{ ++ njt_wasmtime_conf_t *wtcf; ++ ++ wtcf = (njt_wasmtime_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_wasmtime_module); ++ wasm_engine_delete(wtcf->engine); ++ wtcf->engine = NULL; ++ ++ wasmtime_linker_delete(wtcf->linker); ++ wtcf->linker = NULL; ++ ++ wtcf->config = NULL; ++} ++ ++ ++static njt_int_t ++njt_wasmtime_create_module(njt_cycle_t *cycle, njt_wasm_module_t *wm) ++{ ++ njt_wasm_conf_t *wcf; ++ wasmtime_error_t *error; ++ wasmtime_module_t *mod; ++ njt_wasmtime_conf_t *wtcf; ++ ++ wcf = (njt_wasm_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_wasm_core_module); ++ ++ wtcf = (njt_wasmtime_conf_t *) njt_wasm_get_conf(cycle->conf_ctx, ++ njt_wasmtime_module); ++ ++ error = wasmtime_module_new(wtcf->engine, (uint8_t *) wm->src.data, ++ wm->src.len, &mod); ++ if (error != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, cycle->log, error, NULL, ++ "failed to load module"); ++ ++ njt_log_error(NJT_LOG_EMERG, cycle->log, 0, ++ "wasmtime: failed to verify module \"%V\"", ++ &wm->file); ++ ++ return NJT_ERROR; ++ } ++ ++ wm->data = mod; ++ wm->ctx = wtcf; ++ wm->wcf = wcf; ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_wasmtime_delete_module(njt_wasm_module_t *wm) ++{ ++ wasmtime_module_delete(wm->data); ++ wm->data = NULL; ++} ++ ++ ++static njt_wasm_instance_t * ++njt_wasmtime_create_instance(njt_wasm_module_t *wm, njt_pool_t *pool, ++ njt_log_t *log) ++{ ++ wasm_trap_t *trap; ++ ++ wasmtime_error_t *error; ++ wasmtime_extern_t item; ++ ++ njt_wasm_instance_t *wi; ++ njt_wasmtime_conf_t *wtcf; ++ njt_wasmtime_instance_t *wti; ++ ++ wtcf = (njt_wasmtime_conf_t *) wm->ctx; ++ ++ wi = njt_pcalloc(pool, sizeof(njt_wasm_instance_t)); ++ if (wi == NULL) { ++ return NULL; ++ } ++ ++ wi->pool = pool; ++ wi->log = log; ++ ++ wti = njt_pcalloc(pool, sizeof(njt_wasmtime_instance_t)); ++ if (wti == NULL) { ++ return NULL; ++ } ++ ++ wti->store = wasmtime_store_new(wtcf->engine, wtcf, NULL); ++ if (wti->store == NULL) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, "wasm_store_new"); ++ return NULL; ++ } ++ ++ wti->context = wasmtime_store_context(wti->store); ++ ++ wti->wasi_config = wasi_config_new(); ++ if (wti->wasi_config == NULL) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, "wasi_config"); ++ return NULL; ++ } ++ ++ wasi_config_inherit_stdout(wti->wasi_config); ++ wasi_config_inherit_stderr(wti->wasi_config); ++ ++ error = wasmtime_context_set_wasi(wti->context, wti->wasi_config); ++ if (error != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, wi->log, error, NULL, ++ "failed to instantiate WASI"); ++ return NULL; ++ } ++ ++ trap = NULL; ++ ++ error = wasmtime_linker_instantiate(wtcf->linker, wti->context, wm->data, ++ &wti->instance, &trap); ++ ++ if (error != NULL || trap != NULL) { ++ njt_wasmtime_log_error(NJT_LOG_EMERG, log, error, trap, ++ "linker failed to create instance"); ++ return NULL; ++ } ++ ++ wi->mod = wm; ++ wi->data = wti; ++ ++ ++ if (!wasmtime_instance_export_get(wti->context, &wti->instance, "memory", ++ 6, &item)) ++ { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "failed to access instance memory"); ++ return NULL; ++ } ++ ++ wti->memory = item.of.memory; ++ ++ return wi; ++} ++ ++ ++static njt_int_t ++njt_wasmtime_lookup_func(njt_wasm_instance_t *wi, njt_str_t *name, ++ wasmtime_func_t *func) ++{ ++ njt_wasmtime_instance_t *wti = wi->data; ++ ++ wasmtime_extern_t item; ++ ++ if (!wasmtime_instance_export_get(wti->context, &wti->instance, ++ (char *) name->data, name->len, &item)) ++ { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "wasmtime: failed to lookup \"%V\" function", name); ++ return NJT_ERROR; ++ } ++ ++ if (item.kind != WASMTIME_EXTERN_FUNC) { ++ njt_log_error(NJT_LOG_EMERG, wi->log, 0, ++ "wasmtime: \"%V\" is not a function", name); ++ return NJT_ERROR; ++ } ++ ++ *func = item.of.func; ++ ++ return NJT_OK; ++} ++ ++ ++static void ++njt_wasmtime_delete_instance(njt_wasm_instance_t *wi) ++{ ++ njt_wasmtime_instance_t *wti = wi->data; ++ wasmtime_store_delete(wti->store); ++} ++ ++ ++void * ++njt_wasmtime_translate(njt_wasm_instance_t *wi, uint32_t addr, size_t len) ++{ ++ size_t lmem_len; ++ uint8_t *lmem; ++ njt_wasmtime_instance_t *wti; ++ ++ wti = wi->data; ++ ++ lmem = wasmtime_memory_data(wti->context, &wti->memory); ++ lmem_len = wasmtime_memory_data_size(wti->context, &wti->memory); ++ ++ if (addr > (lmem_len - len)) { ++ return NULL; ++ } ++ ++ return &lmem[addr]; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_open(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ uint8_t *buf; ++ njt_wasm_host_t *host; ++ ++ host = njt_wasmtime_call_data(caller); ++ ++ buf = njt_wasm_translate(host->wi, args[0].of.i32, args[1].of.i32); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_wasmtime_open bad address"); ++ rc->of.i32 = NJT_ERROR; ++ return NULL; ++ } ++ ++ rc->of.i32 = host->ops->open(host, buf, args[1].of.i32, args[2].of.i32); ++ ++ return NULL; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_close(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ njt_wasm_host_t *host = njt_wasmtime_call_data(caller); ++ ++ rc->of.i32 = host->ops->close(host, args[0].of.i32); ++ ++ return NULL; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_read(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ uint8_t *buf; ++ njt_wasm_host_t *host; ++ ++ host = njt_wasmtime_call_data(caller); ++ ++ buf = njt_wasm_translate(host->wi, args[1].of.i32, args[2].of.i32); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_wasmtime_read bad address"); ++ rc->of.i32 = NJT_ERROR; ++ return NULL; ++ } ++ ++ rc->of.i32 = host->ops->read(host, args[0].of.i32, buf, args[2].of.i32); ++ ++ return NULL; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_write(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ uint8_t *buf; ++ njt_wasm_host_t *host; ++ ++ host = njt_wasmtime_call_data(caller); ++ ++ buf = njt_wasm_translate(host->wi, args[1].of.i32, args[2].of.i32); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_wasmtime_write bad address"); ++ rc->of.i32 = NJT_ERROR; ++ return NULL; ++ } ++ ++ rc->of.i32 = host->ops->write(host, args[0].of.i32, buf, args[2].of.i32); ++ ++ return NULL; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_get(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ uint8_t *buf; ++ njt_wasm_host_t *host; ++ ++ host = njt_wasmtime_call_data(caller); ++ ++ buf = njt_wasm_translate(host->wi, args[2].of.i32, args[3].of.i32); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_wasmtime_get bad address"); ++ ++ rc->of.i32 = NJT_ERROR; ++ return NULL; ++ } ++ ++ rc->of.i32 = host->ops->get(host, args[0].of.i32, args[1].of.i32, buf, ++ args[3].of.i32); ++ ++ return NULL; ++} ++ ++ ++static wasm_trap_t * ++njt_wasmtime_set(void *env, wasmtime_caller_t *caller, ++ const wasmtime_val_t *args, size_t nargs, wasmtime_val_t *rc, size_t nres) ++{ ++ uint8_t *buf; ++ njt_wasm_host_t *host; ++ ++ host = njt_wasmtime_call_data(caller); ++ ++ buf = njt_wasm_translate(host->wi, args[2].of.i32, args[3].of.i32); ++ if (buf == NULL) { ++ njt_log_error(NJT_LOG_ERR, host->wi->log, 0, ++ "njt_wasmtime_set bad address"); ++ rc->of.i32 = NJT_ERROR; ++ return NULL; ++ } ++ ++ rc->of.i32 = host->ops->set(host, args[0].of.i32, args[1].of.i32, buf, ++ args[3].of.i32); ++ ++ return NULL; ++} +diff -urN njet/src/http/modules/njt_http_wasm_content_module.c njet-patch/src/http/modules/njt_http_wasm_content_module.c +--- njet/src/http/modules/njt_http_wasm_content_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/modules/njt_http_wasm_content_module.c 2024-11-15 16:23:20.696266077 +0800 +@@ -0,0 +1,380 @@ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++typedef struct { ++ njt_wasm_func_conf_t fc; ++} njt_http_wasm_content_loc_conf_t; ++ ++ ++typedef struct { ++ njt_wasm_host_t wh; /* must be first */ ++ njt_wasm_http_ctx_t state; ++ int32_t rfd; ++} njt_http_wasm_content_host_t; ++ ++ ++typedef struct { ++ njt_wasm_instance_t *wi; ++ njt_http_wasm_content_host_t *host; ++ njt_str_t func; ++} njt_http_wasm_content_ctx_t; ++ ++ ++static void *njt_http_wasm_content_create_loc_conf(njt_conf_t *cf); ++static char *njt_http_wasm_content_merge_loc_conf(njt_conf_t *cf, void *parent, ++ void *child); ++static char *njt_http_wasm_content(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++ ++static njt_int_t njt_http_wasm_content_handler(njt_http_request_t *r); ++static njt_int_t njt_http_wasm_content_init_instance(njt_http_request_t *r, ++ njt_http_wasm_content_ctx_t *ctx); ++static njt_int_t njt_http_wasm_content_reject_request(njt_http_request_t *r, ++ njt_str_t *reject_msg); ++ ++static void njt_http_wasm_content_body_handler(njt_http_request_t *r); ++ ++ ++static njt_command_t njt_http_wasm_content_commands[] = { ++ ++ { njt_string("wasm_content"), ++ NJT_HTTP_LOC_CONF|NJT_CONF_NOARGS|NJT_CONF_TAKE2, ++ njt_http_wasm_content, ++ NJT_HTTP_LOC_CONF_OFFSET, ++ offsetof(njt_http_wasm_content_loc_conf_t, fc), ++ NULL }, ++ ++ njt_null_command ++}; ++ ++ ++static njt_http_module_t njt_http_wasm_content_module_ctx = { ++ NULL, /* preconfiguration */ ++ NULL, /* postconfiguration */ ++ ++ NULL, /* create main configuration */ ++ NULL, /* init main configuration */ ++ ++ NULL, /* create server configuration */ ++ NULL, /* merge server configuration */ ++ ++ njt_http_wasm_content_create_loc_conf, /* create location configuration */ ++ njt_http_wasm_content_merge_loc_conf /* merge location configuration */ ++}; ++ ++ ++njt_module_t njt_http_wasm_content_module = { ++ NJT_MODULE_V1, ++ &njt_http_wasm_content_module_ctx, /* module context */ ++ njt_http_wasm_content_commands, /* module directives */ ++ NJT_HTTP_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++static njt_wasm_handle_ops_t *njt_http_wasm_content_host_apis[] = { ++ njt_wasm_log_ops, ++ njt_http_wasm_request_ops, ++ njt_http_wasm_request_headers_ops, ++ njt_http_wasm_request_body_ops, ++ njt_http_wasm_response_headers_ops, ++ njt_http_wasm_response_body_ops, ++ NULL ++}; ++ ++ ++static void * ++njt_http_wasm_content_create_loc_conf(njt_conf_t *cf) ++{ ++ njt_http_wasm_content_loc_conf_t *conf; ++ ++ conf = njt_pcalloc(cf->pool, sizeof(njt_http_wasm_content_loc_conf_t)); ++ if (conf == NULL) { ++ return NULL; ++ } ++ ++ conf->fc.wm = NJT_CONF_UNSET_PTR; ++ ++ /* ++ * set by njt_pcalloc(): ++ * ++ * conf->fc.func = { 0, NULL }; ++ */ ++ ++ return conf; ++} ++ ++ ++static char * ++njt_http_wasm_content_merge_loc_conf(njt_conf_t *cf, void *parent, void *child) ++{ ++ njt_http_wasm_content_loc_conf_t *prev = parent; ++ njt_http_wasm_content_loc_conf_t *conf = child; ++ ++ njt_conf_merge_ptr_value(conf->fc.wm, prev->fc.wm, NULL); ++ njt_conf_merge_str_value(conf->fc.func, prev->fc.func, ""); ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static char * ++njt_http_wasm_content(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ char *rv; ++ njt_http_core_loc_conf_t *clcf; ++ ++ rv = njt_conf_set_wasm_ref_slot(cf, cmd, conf); ++ ++ if (rv != NJT_CONF_OK) { ++ return rv; ++ } ++ ++ clcf = njt_http_conf_get_module_loc_conf(cf, njt_http_core_module); ++ ++ // TODO: just use phase handler? ++ clcf->handler = njt_http_wasm_content_handler; ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_content_handler(njt_http_request_t *r) ++{ ++ njt_int_t rc; ++ njt_wasm_val_t args[1]; ++ njt_wasm_call_t call; ++ njt_http_wasm_content_ctx_t *ctx; ++ njt_http_wasm_content_host_t *host; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "http wasm content handler"); ++ ++ ctx = (njt_http_wasm_content_ctx_t *) njt_http_get_module_ctx(r, ++ njt_http_wasm_content_module); ++ if (ctx == NULL) { ++ ++ ctx = njt_pcalloc(r->pool, sizeof(njt_http_wasm_content_ctx_t)); ++ if (ctx == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (njt_http_wasm_content_init_instance(r, ctx) != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ njt_http_set_ctx(r, ctx, njt_http_wasm_content_module); ++ } ++ ++ host = ctx->host; ++ ++ njt_memzero(&call, sizeof(njt_wasm_call_t)); ++ ++ call.host = &host->wh; ++ call.name = ctx->func; ++ call.nargs = 1; ++ call.args = args; ++ ++ call.rc.kind = NJT_WT_I32; ++ ++ args[0].kind = NJT_WT_I32; ++ args[0].of.i32 = host->rfd; ++ ++ rc = njt_wasm_enter(ctx->wi, &call); ++ if (rc != NJT_OK) { ++ /* some error during wasm execution */ ++ goto failed; ++ } ++ ++ /* call.rc contains return code from wasm request handler */ ++ ++ rc = call.rc.of.i32; ++ ++ njt_log_debug1(NJT_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "http wasm content handler complete rc:%D", call.rc.of.i32); ++ ++ switch (rc) { ++ ++ case NJT_ERROR: ++ njt_log_error(NJT_LOG_NOTICE, r->connection->log, 0, ++ "http wasm content handler failed"); ++ goto failed; ++ ++ /* the request was reject with special response */ ++ case NJT_DECLINED: ++ njt_wasm_delete_instance(ctx->wi); ++ return njt_http_wasm_content_reject_request(r, &host->state.reject_msg); ++ ++ case NJT_DONE: ++ case NJT_AGAIN: ++ /* suspend phase handling until some future event */ ++ return rc; ++ ++ /* NJT_OK or HTTP response code */ ++ default: ++ njt_wasm_delete_instance(ctx->wi); ++ ++ if (r->discard_body) { ++ njt_http_finalize_request(r, rc); ++ } ++ ++ return rc; ++ } ++ ++failed: ++ ++ njt_wasm_delete_instance(ctx->wi); ++ ++ return NJT_ERROR; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_content_init_instance(njt_http_request_t *r, ++ njt_http_wasm_content_ctx_t *ctx) ++{ ++ int32_t fd; ++ njt_wasm_host_t *wh; ++ njt_http_wasm_content_loc_conf_t *wlcf; ++ ++ wlcf = njt_http_get_module_loc_conf(r, njt_http_wasm_content_module); ++ ++ ctx->wi = njt_wasm_create_instance(wlcf->fc.wm, r->pool, ++ r->connection->log); ++ if (ctx->wi == NULL) { ++ return NJT_ERROR; ++ } ++ ++ ctx->func = wlcf->fc.func; ++ ++ wh = njt_wasm_host_create(ctx->wi, r->pool, ++ sizeof(njt_http_wasm_content_host_t), ++ r->connection->log, "http wasm content", ++ njt_http_wasm_content_host_apis); ++ if (wh == NULL) { ++ njt_wasm_delete_instance(ctx->wi); ++ return NJT_ERROR; ++ } ++ ++ ctx->host = (njt_http_wasm_content_host_t *) wh; ++ ++ ctx->host->state.request = r; ++ ctx->host->state.body_handler = njt_http_wasm_content_body_handler; ++ ++ fd = njt_wasm_host_create_object(wh, NJT_WASM_HTTP_HOST_TAG, ++ &ctx->host->state); ++ if (fd == -1) { ++ njt_wasm_delete_instance(ctx->wi); ++ return NJT_ERROR; ++ } ++ ++ ctx->host->rfd = fd; ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_content_reject_request(njt_http_request_t *r, ++ njt_str_t *reject_msg) ++{ ++ njt_int_t rc; ++ njt_chain_t out; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "http wasm content request rejected"); ++ ++ if (r->header_sent) { ++ njt_log_error(NJT_LOG_ERR, r->connection->log, 0, ++ "http wasm content failed to reject request: " ++ "headers already sent"); ++ return NJT_ERROR; ++ } ++ ++ if (reject_msg->len) { ++ out.buf = njt_calloc_buf(r->pool); ++ if (out.buf == NULL) { ++ return NJT_ERROR; ++ } ++ ++ out.buf->start = reject_msg->data; ++ out.buf->last = out.buf->start + reject_msg->len; ++ out.buf->end = out.buf->last; ++ out.buf->pos = out.buf->start; ++ out.buf->memory = 1; ++ ++ out.buf->last_buf = (r == r->main) ? 1 : 0; ++ out.buf->last_in_chain = 1; ++ ++ r->headers_out.content_length_n = out.buf->last - out.buf->pos; ++ ++ } else { ++ r->headers_out.content_length_n = 0; ++ } ++ ++ rc = njt_http_send_header(r); ++ ++ if (rc == NJT_ERROR || rc > NJT_OK || r->header_only) { ++ return rc; ++ } ++ ++ out.next = NULL; ++ ++ if (reject_msg->len) { ++ return njt_http_output_filter(r, &out); ++ ++ } else { ++ return njt_http_output_filter(r, NULL); ++ } ++} ++ ++ ++static void ++njt_http_wasm_content_body_handler(njt_http_request_t *r) ++{ ++ njt_int_t rc; ++ njt_http_wasm_content_ctx_t *ctx; ++ njt_http_wasm_content_host_t *host; ++ ++ ctx = (njt_http_wasm_content_ctx_t *) njt_http_get_module_ctx(r, ++ njt_http_wasm_content_module); ++ host = ctx->host; ++ ++ njt_log_debug1(NJT_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "http wasm content body handler isc:%i", ++ host->state.in_syscall); ++ ++ host->state.post_body_called = 1; ++ ++ if (r->request_body == NULL) { ++ njt_log_error(NJT_LOG_ERR, r->connection->log, 0, ++ "http wasm content body handler: " ++ "called with empty body"); ++ njt_http_finalize_request(r, NJT_HTTP_INTERNAL_SERVER_ERROR); ++ return; ++ } ++ ++ if (!host->state.in_syscall) { ++ /* called from event loop after the body was finally read */ ++ rc = njt_http_wasm_content_handler(r); ++ ++ } else { ++ rc = NJT_OK; ++ } ++ ++ njt_http_finalize_request(r, rc); ++} +diff -urN njet/src/http/modules/njt_http_wasm_filter_module.c njet-patch/src/http/modules/njt_http_wasm_filter_module.c +--- njet/src/http/modules/njt_http_wasm_filter_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/modules/njt_http_wasm_filter_module.c 2024-11-15 16:23:24.124245163 +0800 +@@ -0,0 +1,396 @@ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++typedef struct { ++ njt_wasm_func_conf_t fc; ++ njt_array_t *env_params; ++ /* of njt_http_wasm_filter_param_t */ ++} njt_http_wasm_filter_loc_conf_t; ++ ++ ++typedef struct { ++ njt_str_t key; ++ njt_http_complex_value_t cv; ++} njt_http_wasm_filter_param_t; ++ ++ ++typedef struct { ++ njt_wasm_host_t wh; ++ ++ njt_chain_t *free; ++ njt_chain_t *busy; ++ njt_chain_t *out; ++} njt_http_wasm_filter_host_t; ++ ++ ++typedef struct { ++ njt_wasm_instance_t *wi; ++ njt_http_wasm_filter_host_t *host; ++ njt_str_t func; ++ njt_wasm_call_env_t *ce; ++} njt_http_wasm_filter_ctx_t; ++ ++ ++static void *njt_http_wasm_filter_create_loc_conf(njt_conf_t *cf); ++static char *njt_http_wasm_filter_merge_loc_conf(njt_conf_t *cf, void *parent, ++ void *child); ++static char *njt_http_wasm_filter(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++static char *njt_http_wasm_filter_param(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++ ++static njt_int_t njt_http_wasm_filter_init_instance(njt_http_request_t *r, ++ njt_http_wasm_filter_loc_conf_t *wfcf, njt_http_wasm_filter_ctx_t *ctx); ++static njt_int_t njt_http_wasm_body_filter(njt_http_request_t *r, ++ njt_chain_t *in); ++static njt_int_t njt_http_wasm_filter_init(njt_conf_t *cf); ++ ++ ++static njt_command_t njt_http_wasm_filter_commands[] = { ++ ++ { njt_string("wasm_filter"), ++ NJT_HTTP_MAIN_CONF|NJT_HTTP_SRV_CONF|NJT_HTTP_LOC_CONF|NJT_CONF_TAKE2, ++ njt_http_wasm_filter, ++ NJT_HTTP_LOC_CONF_OFFSET, ++ offsetof(njt_http_wasm_filter_loc_conf_t, fc), ++ NULL }, ++ ++ { njt_string("wasm_filter_param"), ++ NJT_HTTP_MAIN_CONF|NJT_HTTP_SRV_CONF|NJT_HTTP_LOC_CONF|NJT_CONF_TAKE2, ++ njt_http_wasm_filter_param, ++ NJT_HTTP_LOC_CONF_OFFSET, ++ 0, ++ NULL }, ++ ++ njt_null_command ++}; ++ ++ ++static njt_http_module_t njt_http_wasm_filter_module_ctx = { ++ NULL, /* preconfiguration */ ++ njt_http_wasm_filter_init, /* postconfiguration */ ++ ++ NULL, /* create main configuration */ ++ NULL, /* init main configuration */ ++ ++ NULL, /* create server configuration */ ++ NULL, /* merge server configuration */ ++ ++ njt_http_wasm_filter_create_loc_conf, /* create location configuration */ ++ njt_http_wasm_filter_merge_loc_conf, /* merge location configuration */ ++}; ++ ++ ++njt_module_t njt_http_wasm_filter_module = { ++ NJT_MODULE_V1, ++ &njt_http_wasm_filter_module_ctx, /* module context */ ++ njt_http_wasm_filter_commands, /* module directives */ ++ NJT_HTTP_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++static njt_http_output_body_filter_pt njt_http_next_body_filter; ++ ++ ++static njt_wasm_handle_ops_t *njt_wasm_filter_host_apis[] = { ++ njt_wasm_log_ops, ++ njt_wasm_filter_ops, ++ njt_wasm_call_env_ops, ++ NULL ++}; ++ ++ ++static void * ++njt_http_wasm_filter_create_loc_conf(njt_conf_t *cf) ++{ ++ njt_http_wasm_filter_loc_conf_t *conf; ++ ++ conf = njt_pcalloc(cf->pool, sizeof(njt_http_wasm_filter_loc_conf_t)); ++ if (conf == NULL) { ++ return NULL; ++ } ++ ++ conf->fc.wm = NJT_CONF_UNSET_PTR; ++ conf->env_params = NJT_CONF_UNSET_PTR; ++ ++ /* ++ * set by njt_pcalloc(): ++ * ++ * conf->fc.func = { 0, NULL }; ++ */ ++ ++ return conf; ++} ++ ++ ++static char * ++njt_http_wasm_filter_merge_loc_conf(njt_conf_t *cf, void *parent, void *child) ++{ ++ njt_http_wasm_filter_loc_conf_t *prev = parent; ++ njt_http_wasm_filter_loc_conf_t *conf = child; ++ ++ njt_conf_merge_ptr_value(conf->fc.wm, prev->fc.wm, NULL); ++ njt_conf_merge_str_value(conf->fc.func, prev->fc.func, ""); ++ ++ njt_conf_merge_ptr_value(conf->env_params, prev->env_params, NULL); ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static char * ++njt_http_wasm_filter(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ return njt_conf_set_wasm_ref_slot(cf, cmd, conf); ++} ++ ++ ++static char * ++njt_http_wasm_filter_param(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ njt_http_wasm_filter_loc_conf_t *wfcf = conf; ++ ++ njt_str_t *value; ++ njt_http_wasm_filter_param_t *param; ++ njt_http_compile_complex_value_t ccv; ++ ++ if (wfcf->env_params == NJT_CONF_UNSET_PTR) { ++ ++ wfcf->env_params = njt_array_create(cf->pool, 4, ++ sizeof(njt_http_wasm_filter_param_t)); ++ if (wfcf->env_params == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ } ++ ++ value = cf->args->elts; ++ ++ param = njt_array_push(wfcf->env_params); ++ if (param == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ param->key = value[1]; ++ ++ njt_memzero(&ccv, sizeof(njt_http_compile_complex_value_t)); ++ ++ ccv.cf = cf; ++ ccv.value = &value[2]; ++ ccv.complex_value = ¶m->cv; ++ ++ if (njt_http_compile_complex_value(&ccv) != NJT_OK) { ++ return NJT_CONF_ERROR; ++ } ++ ++ return NJT_CONF_OK; ++} ++ ++ ++ ++static njt_int_t ++njt_http_wasm_body_filter(njt_http_request_t *r, njt_chain_t *in) ++{ ++ int32_t obj_fd, env_fd; ++ njt_int_t rc; ++ njt_wasm_val_t args[2]; ++ njt_wasm_call_t call; ++ njt_wasm_filter_env_t fenv; ++ njt_http_wasm_filter_ctx_t *ctx; ++ njt_http_wasm_filter_host_t *host; ++ njt_http_wasm_filter_loc_conf_t *wfcf; ++ ++ if (in == NULL || r->header_only) { ++ return njt_http_next_body_filter(r, in); ++ } ++ ++ wfcf = njt_http_get_module_loc_conf(r, njt_http_wasm_filter_module); ++ ++ if (wfcf->fc.wm == NULL) { ++ return njt_http_next_body_filter(r, in); ++ } ++ ++ ctx = njt_http_get_module_ctx(r, njt_http_wasm_filter_module); ++ ++ if (ctx == NULL) { ++ ++ ctx = njt_pcalloc(r->pool, sizeof(njt_http_wasm_filter_ctx_t)); ++ if (ctx == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (njt_http_wasm_filter_init_instance(r, wfcf, ctx) != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ njt_http_set_ctx(r, ctx, njt_http_wasm_filter_module); ++ } ++ ++ host = ctx->host; ++ ++ fenv.in = in; ++ fenv.freep = &host->free; ++ fenv.outp = &host->out; ++ fenv.tag = (njt_buf_tag_t) &njt_http_wasm_filter_module; ++ ++ obj_fd = njt_wasm_host_create_object(&host->wh, ++ NJT_WASM_HOST_FILTER_OPS_TAG, &fenv); ++ if (obj_fd == -1) { ++ goto failed; ++ } ++ ++ if (ctx->ce) { ++ env_fd = njt_wasm_host_create_object(&host->wh, ++ NJT_WASM_HOST_CALL_ENV_TAG, ++ ctx->ce); ++ if (env_fd == -1) { ++ goto failed; ++ } ++ ++ } else { ++ env_fd = -1; /* no wasm environment in configuration */ ++ } ++ ++ njt_memzero(&call, sizeof(njt_wasm_call_t)); ++ ++ call.host = &host->wh; ++ call.name = ctx->func; ++ call.nargs = 2; // XXX: set to 1 and see an issue! ++ call.args = args; ++ ++ call.rc.kind = NJT_WT_I64; ++ ++ args[0].kind = NJT_WT_I32; ++ args[0].of.i32 = obj_fd; ++ ++ args[1].kind = NJT_WT_I32; ++ args[1].of.i32 = env_fd; ++ ++ rc = njt_wasm_enter(ctx->wi, &call); ++ if (rc != NJT_OK) { ++ goto failed; ++ } ++ ++ (void) njt_wasm_host_delete_object(&host->wh, obj_fd); ++ ++ rc = call.rc.of.i64; ++ if (rc < 0) { ++ njt_log_error(NJT_LOG_EMERG, r->connection->log, 0, ++ "wasm filter failed with %i", rc); ++ goto failed; ++ } ++ ++ rc = njt_http_next_body_filter(r, host->out); ++ ++ njt_chain_update_chains(r->pool, &host->free, &host->busy, &host->out, ++ (njt_buf_tag_t) &njt_http_wasm_filter_module); ++ ++ return rc; ++ ++failed: ++ ++ njt_wasm_delete_instance(ctx->wi); ++ ++ return NJT_ERROR; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_filter_init_instance(njt_http_request_t *r, ++ njt_http_wasm_filter_loc_conf_t *wfcf, ++ njt_http_wasm_filter_ctx_t *ctx) ++{ ++ njt_str_t *str; ++ njt_uint_t i; ++ njt_wasm_host_t *wh; ++ njt_wasm_call_env_t *ce; ++ njt_http_wasm_filter_param_t *params; ++ ++ ctx->func = wfcf->fc.func; ++ ++ ctx->wi = njt_wasm_create_instance(wfcf->fc.wm, r->pool, ++ r->connection->log); ++ if (ctx->wi == NULL) { ++ return NJT_ERROR; ++ } ++ ++ wh = njt_wasm_host_create(ctx->wi, r->pool, ++ sizeof(njt_http_wasm_filter_host_t), ++ r->connection->log, "http wasm filter", ++ njt_wasm_filter_host_apis); ++ if (wh == NULL) { ++ njt_wasm_delete_instance(ctx->wi); ++ return NJT_ERROR; ++ } ++ ++ ctx->host = (njt_http_wasm_filter_host_t *) wh; ++ ++ /* ++ * host->free etc are initialized by njt_pcalloc() ++ */ ++ ++ if (wfcf->env_params == NULL) { ++ return NJT_OK; ++ } ++ ++ ce = njt_pcalloc(r->pool, sizeof(njt_wasm_call_env_t)); ++ if (ce == NULL) { ++ njt_wasm_delete_instance(ctx->wi); ++ return NJT_ERROR; ++ } ++ ++ njt_array_init(&ce->keys, r->pool, wfcf->env_params->nelts, ++ sizeof(njt_str_t)); ++ ++ njt_array_init(&ce->values, r->pool, wfcf->env_params->nelts, ++ sizeof(njt_str_t)); ++ ++ params = wfcf->env_params->elts; ++ ++ for (i = 0; i < wfcf->env_params->nelts; i++) { ++ ++ str = njt_array_push(&ce->keys); ++ ++ *str = params[i].key; ++ ++ str = njt_array_push(&ce->values); ++ ++ if (njt_http_complex_value(r, ¶ms[i].cv, str) != NJT_OK) { ++ njt_wasm_delete_instance(ctx->wi); ++ return NJT_ERROR; ++ } ++ } ++ ++ ctx->ce = ce; ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_filter_init(njt_conf_t *cf) ++{ ++ // XXX TODO: avoid filtering of special responses, i.e. 502 ++ // ++ // set r->main_filter_need_in_memory ? ++ // ++ // property_set to set CL ? ++ ++ njt_http_next_body_filter = njt_http_top_body_filter; ++ njt_http_top_body_filter = njt_http_wasm_body_filter; ++ ++ return NJT_OK; ++} +diff -urN njet/src/http/modules/njt_http_wasm_var_module.c njet-patch/src/http/modules/njt_http_wasm_var_module.c +--- njet/src/http/modules/njt_http_wasm_var_module.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/modules/njt_http_wasm_var_module.c 2024-11-15 16:23:20.056269983 +0800 +@@ -0,0 +1,572 @@ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++typedef struct { ++ njt_wasm_func_conf_t fc; ++ njt_array_t arg_vars; /* of njt_int_t: var indexes */ ++ njt_array_t arg_values; /* of njt_str_t*: var values */ ++} njt_http_wasm_var_ctx_t; ++ ++ ++/* instance state */ ++typedef struct { ++ uint32_t list_mem; ++ uint32_t list_mem_size; ++ uint32_t result_mem; ++} njt_http_wasm_var_state_t; ++ ++ ++/* call environment */ ++typedef struct { ++ njt_wasm_host_t wh; ++ njt_http_request_t *r; ++ njt_http_wasm_var_ctx_t *ctx; ++ ++ int32_t args_fd; ++ int32_t log_fd; ++} njt_http_wasm_var_host_t; ++ ++ ++static char *njt_http_wasm_variable(njt_conf_t *cf, njt_command_t *cmd, ++ void *conf); ++static njt_int_t njt_http_wasm_variable_handler(njt_http_request_t *r, ++ njt_http_variable_value_t *v, uintptr_t data); ++ ++static njt_wasm_instance_t *njt_http_wasm_var_get_instance( ++ njt_http_request_t *r, njt_wasm_module_t *wm); ++ ++static njt_wasm_host_t *njt_http_wasm_var_host_create(njt_wasm_instance_t *wi, ++ njt_http_request_t *r, njt_http_wasm_var_ctx_t *ctx); ++ ++static int32_t njt_http_wasm_var_open_args(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *ctx); ++static int32_t njt_http_wasm_var_read_args(njt_wasm_handle_t *self, ++ uint8_t *buf, uint32_t len); ++ ++ ++static njt_command_t njt_http_wasm_var_commands[] = { ++ ++ { njt_string("wasm_var"), ++ NJT_HTTP_MAIN_CONF|NJT_CONF_ANY, ++ njt_http_wasm_variable, ++ NJT_HTTP_MAIN_CONF_OFFSET, ++ 0, NULL }, ++ ++ njt_null_command ++}; ++ ++ ++static njt_http_module_t njt_http_wasm_var_module_ctx = { ++ NULL, /* preconfiguration */ ++ NULL, /* postconfiguration */ ++ ++ NULL, /* create main configuration */ ++ NULL, /* init main configuration */ ++ ++ NULL, /* create server configuration */ ++ NULL, /* merge server configuration */ ++ ++ NULL, /* create location configuration */ ++ NULL /* merge location configuration */ ++}; ++ ++ ++njt_module_t njt_http_wasm_var_module = { ++ NJT_MODULE_V1, ++ &njt_http_wasm_var_module_ctx, /* module context */ ++ njt_http_wasm_var_commands, /* module directives */ ++ NJT_HTTP_MODULE, /* module type */ ++ NULL, /* init master */ ++ NULL, /* init module */ ++ NULL, /* init process */ ++ NULL, /* init thread */ ++ NULL, /* exit thread */ ++ NULL, /* exit process */ ++ NULL, /* exit master */ ++ NJT_MODULE_V1_PADDING ++}; ++ ++ ++#define NJT_HTTP_VARS_TAG_ARGS 0x41524753 /* ARGS */ ++ ++static njt_wasm_handle_ops_t njt_http_wasm_var_ops[] = { ++ { .type = njt_string("njt::http::vars::args"), ++ .tag = NJT_HTTP_VARS_TAG_ARGS, ++ .open = njt_http_wasm_var_open_args, ++ .read = njt_http_wasm_var_read_args, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_host_close_stub, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++static njt_wasm_handle_ops_t *njt_http_var_host_apis[] = { ++ njt_wasm_log_ops, ++ njt_http_wasm_var_ops, ++ NULL ++}; ++ ++ ++static njt_str_t njt_http_wasm_var_list_alloc_name = ++ njt_string("njt:wasi/utils#list-alloc"); ++ ++ ++static char * ++njt_http_wasm_variable(njt_conf_t *cf, njt_command_t *cmd, void *conf) ++{ ++ char *rv; ++ size_t n; ++ njt_int_t *vi; ++ njt_str_t name, *value, **arg_val; ++ njt_uint_t i; ++ njt_http_variable_t *var; ++ njt_http_wasm_var_ctx_t *ctx; ++ ++ value = cf->args->elts; ++ ++ if (cf->args->nelts < 4) { ++ return "invalid number of arguments"; ++ } ++ ++ ++ ctx = njt_pcalloc(cf->pool, sizeof(njt_http_wasm_var_ctx_t)); ++ if (ctx == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ rv = njt_conf_set_wasm_ref_slot(cf, cmd, &ctx->fc); ++ ++ if (rv != NJT_CONF_OK) { ++ return rv; ++ } ++ ++ name = value[3]; ++ ++ if (name.data[0] != '$') { ++ njt_conf_log_error(NJT_LOG_EMERG, cf, 0, ++ "invalid variable name \"%V\"", &name); ++ return NJT_CONF_ERROR; ++ } ++ ++ name.len--; ++ name.data++; ++ ++ var = njt_http_add_variable(cf, &name, NJT_HTTP_VAR_CHANGEABLE); ++ if (var == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ n = cf->args->nelts - 3; ++ ++ if (njt_array_init(&ctx->arg_vars, cf->pool, n, sizeof(njt_uint_t)) ++ != NJT_OK) ++ { ++ return NJT_CONF_ERROR; ++ } ++ ++ if (njt_array_init(&ctx->arg_values, cf->pool, n, sizeof(njt_str_t *)) ++ != NJT_OK) ++ { ++ return NJT_CONF_ERROR; ++ } ++ ++ for (i = 4; i < cf->args->nelts; i++) { ++ ++ vi = njt_array_push(&ctx->arg_vars); ++ if (vi == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ ++ name = value[i]; ++ name.len--; ++ name.data++; ++ ++ if (name.len == 0) { ++ return NJT_CONF_ERROR; ++ } ++ ++ *vi = njt_http_get_variable_index(cf, &name); ++ if (*vi == NJT_ERROR) { ++ return NJT_CONF_ERROR; ++ } ++ ++ arg_val = njt_array_push(&ctx->arg_values); ++ if (arg_val == NULL) { ++ return NJT_CONF_ERROR; ++ } ++ *arg_val = NULL; ++ } ++ ++ var->get_handler = njt_http_wasm_variable_handler; ++ var->data = (uintptr_t) ctx; ++ ++ return NJT_CONF_OK; ++} ++ ++ ++static njt_int_t ++njt_http_wasm_variable_handler(njt_http_request_t *r, ++ njt_http_variable_value_t *v, uintptr_t data) ++{ ++ njt_http_wasm_var_ctx_t *ctx = (njt_http_wasm_var_ctx_t *) data; ++ ++ size_t len; ++ uint32_t *retval; ++ njt_int_t *vars, rc; ++ njt_str_t **arg_vals, *str, result; ++ njt_uint_t i; ++ njt_wasm_val_t args[7]; ++ njt_wasm_call_t call; ++ njt_wasm_host_t *whost; ++ njt_wasm_instance_t *wi; ++ njt_http_wasm_var_host_t *host; ++ njt_http_wasm_var_state_t *is; ++ njt_http_variable_value_t *vv; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "wasm vars variable handler nvars:%ui nvals:%ui", ++ ctx->arg_vars.nelts, ctx->arg_values.nelts); ++ ++ vars = ctx->arg_vars.elts; ++ arg_vals = ctx->arg_values.elts; ++ ++ len = 0; ++ ++ for (i = 0; i < ctx->arg_vars.nelts; i++) { ++ ++ vv = njt_http_get_indexed_variable(r, vars[i]); ++ if (vv == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (vv->not_found) { ++ arg_vals[i] = NULL; ++ ++ } else { ++ str = njt_palloc(r->pool, sizeof(njt_str_t)); ++ if (str == NULL) { ++ return NJT_ERROR; ++ } ++ str->len = vv->len; ++ str->data = vv->data; ++ ++ arg_vals[i] = str; ++ ++ len += vv->len; ++ } ++ } ++ ++ wi = njt_http_wasm_var_get_instance(r, ctx->fc.wm); ++ if (wi == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (wi->ctx == NULL) { ++ /* new instance was created or initial call */ ++ ++ is = njt_pcalloc(wi->pool, sizeof(njt_http_wasm_var_state_t)); ++ if (is == NULL) { ++ return NJT_ERROR; ++ } ++ ++ wi->ctx = is; ++ } ++ ++ whost = njt_http_wasm_var_host_create(wi, r, ctx); ++ if (whost == NULL) { ++ return NJT_ERROR; ++ } ++ ++ host = (njt_http_wasm_var_host_t *) whost; ++ is = wi->ctx; ++ ++ /* ask target to allocate memory for arguments and read them from host */ ++ ++ njt_memzero(&call, sizeof(njt_wasm_call_t)); ++ ++ call.name = njt_http_wasm_var_list_alloc_name; ++ call.host = whost; ++ ++ call.args = args; ++ call.nargs = 7; ++ ++ call.rc.kind = NJT_WT_I32; ++ ++ args[0].kind = NJT_WT_I32; ++ args[0].of.i32 = host->args_fd; ++ ++ args[1].kind = NJT_WT_I32; ++ args[1].of.i32 = ctx->arg_values.nelts; ++ ++ args[2].kind = NJT_WT_I32; ++ args[2].of.i32 = len; ++ ++ args[3].kind = NJT_WT_I32; ++ args[3].of.i32 = is->list_mem; /* allocated previously mem, if any */ ++ ++ args[4].kind = NJT_WT_I32; ++ args[4].of.i32 = is->list_mem_size; /* size of allocated memory */ ++ ++ args[5].kind = NJT_WT_I32; ++ args[5].of.i32 = is->result_mem; /* previous result mem */ ++ ++ args[6].kind = NJT_WT_I32; ++ args[6].of.i32 = host->log_fd; ++ ++ rc = njt_wasm_enter(wi, &call); ++ ++ if (rc != NJT_OK) { ++ /* we failed the call */ ++ goto wasm_failed; ++ } ++ ++ if (call.rc.of.i32 < 0) { ++ /* function was called and returned an error */ ++ rc = NJT_ERROR; ++ goto wasm_failed; ++ } ++ ++ is->list_mem = call.rc.of.i32; /* arguments are here */ ++ is->list_mem_size = len; /* size of allocated memory */ ++ ++ /* call the function that computes the variable */ ++ ++ njt_memzero(&call, sizeof(njt_wasm_call_t)); ++ ++ call.host = whost; ++ call.name = ctx->fc.func; /* as specified in configuration file */ ++ ++ call.args = args; ++ call.nargs = 3; ++ ++ call.rc.kind = NJT_WT_I32; ++ ++ /* func(array, nitems); */ ++ args[0].kind = NJT_WT_I32; ++ args[0].of.i32 = is->list_mem; ++ ++ args[1].kind = NJT_WT_I32; ++ args[1].of.i32 = ctx->arg_values.nelts; ++ ++ args[2].kind = NJT_WT_I32; ++ args[2].of.i32 = host->log_fd; ++ ++ rc = njt_wasm_enter(wi, &call); ++ ++ if (rc != NJT_OK) { ++ goto wasm_failed; ++ } ++ ++ if (call.rc.of.i32 < 0) { ++ njt_log_error(NJT_LOG_NOTICE, r->connection->log, 0, ++ "wasm call failed with rc:%d", call.rc.of.i32); ++ goto nores; ++ } ++ ++ /* the function was succesfully called, obtain results */ ++ ++ /* result is [ptr][len] in linear memory, both u32 */ ++ ++ retval = njt_wasm_translate(wi, call.rc.of.i32, sizeof(uint32_t) * 2); ++ if (retval == NULL) { ++ goto failed; ++ } ++ ++ is->result_mem = retval[0]; ++ ++ result.len = retval[1]; ++ ++ result.data = njt_wasm_translate(wi, retval[0], retval[1]); ++ if (result.data == NULL) { ++ goto failed; ++ } ++ ++ v->len = result.len; ++ v->data = njt_pstrdup(r->pool, &result); ++ if (v->data == NULL) { ++ goto failed; ++ } ++ ++ /* cleanup */ ++ if (ctx->fc.wm->reactor == NULL) { ++ njt_wasm_delete_instance(wi); ++ } ++ ++ v->valid = 1; ++ v->no_cacheable = 0; ++ v->not_found = 0; ++ ++ return NJT_OK; ++ ++nores: ++ ++ v->not_found = 1; ++ ++ if (ctx->fc.wm->reactor == NULL) { ++ njt_wasm_delete_instance(wi); ++ } ++ ++ return NJT_OK; ++ ++wasm_failed: ++ ++ if (rc == NJT_ABORT) { ++ /* the wasm instance is heavily broken: trapped or killed by signal */ ++ if (ctx->fc.wm->reactor) { ++ njt_wasm_delete_instance(ctx->fc.wm->reactor); ++ ctx->fc.wm->reactor = NULL; ++ } ++ } ++ ++failed: ++ ++ if (ctx->fc.wm->reactor == NULL) { ++ njt_wasm_delete_instance(wi); ++ } ++ ++ return NJT_ERROR; ++} ++ ++ ++static njt_wasm_instance_t * ++njt_http_wasm_var_get_instance(njt_http_request_t *r, njt_wasm_module_t *wm) ++{ ++ njt_wasm_instance_t *wi; ++ ++ if (!wm->is_reactor) { ++ wi = njt_wasm_create_instance(wm, r->pool, r->connection->log); ++ if (wi == NULL) { ++ return NULL; ++ } ++ ++ return wi; ++ } ++ ++ if (wm->reactor) { ++ return wm->reactor; ++ } ++ ++ njt_log_error(NJT_LOG_NOTICE, r->connection->log, 0, ++ "wasm reactor recreating instance"); ++ ++ /* the instance was destroyed due to fatal error, re-create */ ++ wi = njt_wasm_create_instance(wm, njt_cycle->pool, njt_cycle->log); ++ if (wi == NULL) { ++ return NULL; ++ } ++ ++ wm->reactor = wi; ++ ++ return wi; ++} ++ ++ ++static njt_wasm_host_t * ++njt_http_wasm_var_host_create(njt_wasm_instance_t *wi, njt_http_request_t *r, ++ njt_http_wasm_var_ctx_t *ctx) ++{ ++ njt_str_t opname; ++ njt_wasm_host_t *wh; ++ njt_http_wasm_var_host_t *host; ++ ++ wh = njt_wasm_host_create(wi, r->pool, sizeof(njt_http_wasm_var_host_t), ++ r->connection->log, "wasm vars", ++ njt_http_var_host_apis); ++ if (wh == NULL) { ++ return NULL; ++ } ++ ++ host = (njt_http_wasm_var_host_t *) wh; ++ host->r = r; ++ host->ctx = ctx; ++ ++ njt_str_set(&opname, "njt::http::vars::args"); ++ ++ host->args_fd = wh->ops->open(wh, opname.data, opname.len, -1); ++ if (host->args_fd < 0) { ++ return NULL; ++ } ++ ++ njt_str_set(&opname, "njt::core::log"); ++ ++ host->log_fd = wh->ops->open(wh, opname.data, opname.len, -1); ++ if (host->log_fd < 0) { ++ return NULL; ++ } ++ ++ return wh; ++} ++ ++ ++static int32_t ++njt_http_wasm_var_open_args(njt_wasm_handle_t *self, njt_wasm_handle_t *ctx) ++{ ++ njt_http_wasm_var_host_t *host = (njt_http_wasm_var_host_t *) self->host; ++ ++ self->data = host->ctx; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_http_wasm_var_read_args(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len) ++{ ++ u_char *p; ++ size_t left, rec_size; ++ uint32_t n; ++ njt_str_t **values; ++ njt_uint_t i; ++ ++ njt_http_wasm_var_ctx_t *ctx; ++ njt_http_wasm_var_host_t *host; ++ ++ host = (njt_http_wasm_var_host_t *) self->host; ++ ctx = self->data; ++ ++ values = ctx->arg_values.elts; ++ ++ p = buf; ++ left = len; ++ n = 0; ++ ++ for (i = 0; i < ctx->arg_values.nelts; i++) { ++ ++ if (values[i] == NULL) { ++ /* non-existing variables: may skip or pass them */ // TODO ++ ++ *p++ = 0; ++ left--; ++ n++; ++ continue; ++ } ++ ++ rec_size = values[i]->len + 1; ++ ++ if (left < rec_size) { ++ if (left == len) { ++ njt_log_error(NJT_LOG_ERR, host->wh.log, 0, "buffer too small"); ++ return NJT_ERROR; ++ } ++ ++ break; ++ } ++ ++ p = njt_cpymem(p, values[i]->data, values[i]->len); ++ *p++ = 0; ++ ++ left -= rec_size; ++ n++; ++ } ++ ++ return n; ++} +diff -urN njet/src/http/njt_http_wasm_host.c njet-patch/src/http/njt_http_wasm_host.c +--- njet/src/http/njt_http_wasm_host.c 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/njt_http_wasm_host.c 2024-11-15 16:23:21.348262098 +0800 +@@ -0,0 +1,1087 @@ ++ ++#include ++#include ++#include ++ ++#include ++#include /* for properties definitions */ ++ ++ ++typedef struct { ++ njt_list_part_t *curr_part; ++ njt_uint_t curr_item; ++} njt_http_wc_headers_in_ctx_t; ++ ++ ++typedef struct { ++ njt_http_request_t *r; ++ njt_http_request_body_t *body; ++ off_t offset; ++ njt_uint_t read_started; ++ njt_wasm_http_ctx_t *host_ctx; ++} njt_http_wc_body_in_ctx_t; ++ ++ ++typedef struct { ++ njt_http_request_t *r; ++ ++ njt_chain_t *out_bufs; ++ njt_chain_t *free_bufs; ++} njt_http_wc_body_out_ctx_t; ++ ++ ++/* request */ ++static int32_t njt_wasm_http_request_open(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_http_request_property_get(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++static int32_t njt_http_request_property_var(njt_wasm_host_t *wh, ++ njt_http_request_t *r, uint8_t *buf, uint32_t len); ++static int32_t njt_http_request_property_set(njt_wasm_handle_t *self, ++ uint32_t propid, uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_http_request_close(njt_wasm_handle_t *self); ++ ++/* request headers */ ++static int32_t njt_wasm_http_open_request_headers(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_http_read_request_headers( ++ njt_wasm_handle_t *self, uint8_t *buf, uint32_t len); ++ ++/* request body */ ++static int32_t njt_wasm_http_open_request_body(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_http_read_request_body(njt_wasm_handle_t *self, ++ uint8_t *buf, uint32_t len); ++static njt_int_t njt_wasm_http_body_from_mem(njt_http_request_body_t *body, ++ off_t off, uint8_t *buf, size_t size, size_t *nread); ++static njt_int_t njt_wasm_http_body_from_file(njt_http_request_body_t *body, ++ off_t off, uint8_t *buf, size_t size, size_t *nread, njt_log_t *log); ++ ++/* response headers */ ++static int32_t njt_wasm_http_open_response_headers(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_http_write_response_headers(njt_wasm_handle_t *self, ++ uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_http_close_response_headers(njt_wasm_handle_t *self); ++ ++/* response body */ ++static int32_t njt_wasm_http_open_response_body(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *parent); ++static int32_t njt_wasm_http_write_response_body(njt_wasm_handle_t *self, ++ uint8_t *buf, uint32_t len); ++static int32_t njt_wasm_http_close_response_body(njt_wasm_handle_t *self); ++ ++/* misc */ ++static u_char *njt_wasm_http_get_stringz(u_char *p, u_char *end, ++ njt_str_t *res); ++static uint32_t njt_wasm_http_get_schema(njt_http_request_t *r); ++static njt_uint_t njt_http_wc_request_headers_count(njt_http_request_t *r); ++ ++ ++/* objects exported by this host module */ ++njt_wasm_handle_ops_t njt_http_wasm_request_ops[] = { ++ { .type = njt_string("njt::http::request"), ++ .tag = NJT_WASM_HTTP_TAG_REQUEST, ++ .open = njt_wasm_http_request_open, ++ .read = njt_wasm_host_io_stub, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_http_request_property_get, ++ .set = njt_http_request_property_set, ++ .close = njt_wasm_http_request_close, ++ }, ++ ++ njt_wasm_host_null_ops ++}; ++ ++njt_wasm_handle_ops_t njt_http_wasm_request_headers_ops[] = { ++ { .type = njt_string("njt::http::request::headers"), ++ .tag = NJT_WASM_HTTP_TAG_REQUEST_HEADERS, ++ .open = njt_wasm_http_open_request_headers, ++ .close = njt_wasm_host_close_stub, ++ .read = njt_wasm_http_read_request_headers, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ }, ++ njt_wasm_host_null_ops ++}; ++ ++njt_wasm_handle_ops_t njt_http_wasm_request_body_ops[] = { ++ { .type = njt_string("njt::http::request::body"), ++ .tag = NJT_WASM_HTTP_TAG_REQUEST_BODY, ++ .open = njt_wasm_http_open_request_body, ++ .close = njt_wasm_host_close_stub, ++ .read = njt_wasm_http_read_request_body, ++ .write = njt_wasm_host_io_stub, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ }, ++ njt_wasm_host_null_ops ++}; ++ ++njt_wasm_handle_ops_t njt_http_wasm_response_headers_ops[] = { ++ { .type = njt_string("njt::http::response::headers"), ++ .tag = NJT_WASM_HTTP_TAG_RESPONSE_HEADERS, ++ .open = njt_wasm_http_open_response_headers, ++ .read = njt_wasm_host_io_stub, ++ .write = njt_wasm_http_write_response_headers, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ .close = njt_wasm_http_close_response_headers ++ }, ++ njt_wasm_host_null_ops ++}; ++ ++njt_wasm_handle_ops_t njt_http_wasm_response_body_ops[] = { ++ { .type = njt_string("njt::http::response::body"), ++ .tag = NJT_WASM_HTTP_TAG_RESPONSE_BODY, ++ .open = njt_wasm_http_open_response_body, ++ .close = njt_wasm_http_close_response_body, ++ .read = njt_wasm_host_io_stub, ++ .write = njt_wasm_http_write_response_body, ++ .get = njt_wasm_host_property_stub, ++ .set = njt_wasm_host_property_stub, ++ }, ++ njt_wasm_host_null_ops ++}; ++ ++ ++static int32_t ++njt_wasm_http_request_open(njt_wasm_handle_t *self, njt_wasm_handle_t *ctx) ++{ ++ if (ctx == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (ctx->tag != NJT_WASM_HTTP_HOST_TAG) { ++ // XXX: ERROR ++ return NJT_ERROR; ++ } ++ ++ ++ self->data = ctx->data; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_http_request_property_get(njt_wasm_handle_t *self, uint32_t propid, ++ uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_http_ctx_t *host_ctx = self->data; ++ ++ njt_http_request_t *r = host_ctx->request; ++ ++ njt_log_t *log; ++ uint32_t meta[NJT_WASI_HTTP_HOST_REQUEST_META_LAST]; ++ ++ log = self->log; ++ ++ switch (propid) { ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_META: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content get request metadata"); ++ ++ /* ++ * TODO: for old clients, write only known fields, think of API version ++ */ ++ if (len < sizeof(meta)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "buffer is too small"); ++ return NJT_ERROR; ++ } ++ ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_CTX] = host_ctx->wasm_request; ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_METHOD] = r->method; ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_SCHEMA] = ++ njt_wasm_http_get_schema(r); ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_VERSION] = r->http_version; ++ ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_URI_LEN] = r->uri.len; ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_ADDR_LEN] = ++ r->connection->addr_text.len; ++ ++ meta[NJT_WASI_HTTP_HOST_REQUEST_META_HEADER_COUNT] = ++ njt_http_wc_request_headers_count(r); ++ ++ njt_memcpy(buf, meta, sizeof(meta)); ++ ++ return sizeof(meta); ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_URI: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content get request uri"); ++ ++ if (len < r->uri.len) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "buffer is too small"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(buf, r->uri.data, r->uri.len); ++ ++ return r->uri.len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_REMOTE_ADDR: ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content get request remote addr"); ++ ++ if (len < r->connection->addr_text.len) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "buffer is too small"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(buf, r->connection->addr_text.data, ++ r->connection->addr_text.len); ++ ++ return r->connection->addr_text.len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content get request variable"); ++ ++ return njt_http_request_property_var(self->host, r, buf, len); ++ ++ default: ++ ++ njt_log_error(NJT_LOG_ERR, log, 0, ++ "wasm content unknown request property %D", propid); ++ ++ return NJT_ERROR; ++ } ++ ++ return 0; ++} ++ ++ ++static int32_t ++njt_http_request_property_var(njt_wasm_host_t *wh, njt_http_request_t *r, ++ uint8_t *buf, uint32_t len) ++{ ++ uint32_t *in; ++ njt_uint_t hash; ++ njt_str_t key, val; ++ njt_http_variable_value_t *vv; ++ ++ /* ++ * input: array[4] of u32: [ key.len, key.ptr, val.len, val.ptr ] ++ * ++ * if val.len != 0 -> copy result, otherwise just return length ++ */ ++ ++ if (len != sizeof(uint32_t) * 4) { ++ return NJT_ERROR; ++ } ++ ++ in = (uint32_t *) buf; ++ ++ key.len = in[0]; ++ key.data = njt_wasm_translate(wh->wi, (uintptr_t) in[1], key.len); ++ ++ val.len = in[2]; ++#if (NJT_SUPPRESS_WARN) ++ val.data = NULL; ++#endif ++ ++ if (val.len) { ++ val.data = njt_wasm_translate(wh->wi, (uintptr_t) in[3], val.len); ++ if (val.data == NULL) { ++ njt_log_error(NJT_LOG_ERR, wh->log, 0, "bad address"); ++ return NJT_ERROR; ++ } ++ } ++ ++ hash = njt_hash_strlow(key.data, key.data, key.len); ++ ++ vv = njt_http_get_variable(r, &key, hash); ++ if (vv == NULL) { ++ return NJT_ERROR; ++ } ++ ++ if (vv->not_found) { ++ return 0; ++ } ++ ++ if (val.len == 0) { ++ return vv->len; ++ } ++ ++ if (vv->len > len) { ++ njt_log_error(NJT_LOG_ERR, wh->log, 0, "buffer too small"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(val.data, vv->data, vv->len); ++ ++ return vv->len; ++} ++ ++ ++static int32_t ++njt_http_request_property_set(njt_wasm_handle_t *self, uint32_t propid, ++ uint8_t *buf, uint32_t len) ++{ ++ njt_wasm_http_ctx_t *host_ctx = self->data; ++ ++ uint32_t num; ++ uint64_t num64; ++ njt_int_t rc; ++ njt_log_t *log; ++ njt_http_request_t *r; ++ ++ r = host_ctx->request; ++ ++ log = self->log; ++ ++ switch (propid) { ++ ++ /* saves wasm pointer to request in the host request context */ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_SELF: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request pointer"); ++ ++ if (len < sizeof(uint32_t)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(&host_ctx->wasm_request, buf, sizeof(uint32_t)); ++ ++ return len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_DISCARD_BODY: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request discard body"); ++ ++ if (len < sizeof(uint8_t)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ if (buf[0] != 1) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument value"); ++ return NJT_ERROR; ++ } ++ ++ rc = njt_http_discard_request_body(r); ++ if (rc != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ return len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_STATUS: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request response status"); ++ ++ if (len < sizeof(uint32_t)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(&num, buf, sizeof(uint32_t)); ++ ++ // TODO: check status for validity ++ ++ r->headers_out.status = num; ++ ++ return len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_REJECT_MSG: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request response reject message"); ++ ++ if (len > 2048) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ host_ctx->reject_msg.data = njt_pnalloc(r->pool, len); ++ if (host_ctx->reject_msg.data == NULL) { ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(host_ctx->reject_msg.data, buf, len); ++ host_ctx->reject_msg.len = len; ++ ++ return len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_CONTENT_LENGTH: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request content length"); ++ ++ if (len < sizeof(uint64_t)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ njt_memcpy(&num64, buf, sizeof(uint64_t)); ++ ++ if (num64 == (uint64_t) -1) { ++ /* chunked */ ++ r->headers_out.content_length_n = -1; ++ ++ } else { ++ r->headers_out.content_length_n = num64; ++ } ++ ++ return len; ++ ++ case NJT_WASI_HTTP_HOST_REQUEST_PROPS_HEADER_ONLY: ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content set request header only"); ++ ++ if (len < sizeof(uint8_t)) { ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument"); ++ return NJT_ERROR; ++ } ++ ++ if (buf[0] == 0) { ++ r->header_only = 0; ++ ++ } else if (buf[0] == 1) { ++ r->header_only = 1; ++ ++ } else{ ++ njt_log_error(NJT_LOG_ERR, log, 0, "invalid argument value"); ++ return NJT_ERROR; ++ } ++ ++ return len; ++ ++ default: ++ ++ njt_log_error(NJT_LOG_ERR, log, 0, ++ "wasm content set request unknown property id: %D", ++ propid); ++ ++ return NJT_ERROR; ++ } ++ ++ return 0; ++} ++ ++ ++static int32_t ++njt_wasm_http_request_close(njt_wasm_handle_t *self) ++{ ++ /* TODO: content handler finally done with request, do something? */ ++ return 0; ++} ++ ++ ++static int32_t ++njt_wasm_http_open_request_headers(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *ph) ++{ ++ njt_http_request_t *r; ++ njt_http_wc_headers_in_ctx_t *ch; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content open request headers"); ++ ++ if (ph == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, "missing parent handle"); ++ return NJT_ERROR; ++ } ++ ++ if (ph->ops->tag != NJT_WASM_HTTP_TAG_REQUEST) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid parent handle type"); ++ return NJT_ERROR; ++ } ++ ++ r = ((njt_wasm_http_ctx_t *) ph->data)->request; ++ ++ ch = njt_palloc(self->host->pool, sizeof(njt_http_wc_headers_in_ctx_t)); ++ if (ch == NULL) { ++ return NJT_ERROR; ++ } ++ ++ ch->curr_part = &r->headers_in.headers.part; ++ ch->curr_item = 0; ++ ++ self->data = ch; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_read_request_headers(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len) ++{ ++ u_char *p; ++ size_t left, rec_size; ++ njt_uint_t i; ++ njt_list_part_t *part; ++ njt_table_elt_t *header; ++ njt_http_wc_headers_in_ctx_t *hc; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content read request headers"); ++ ++ hc = self->data; ++ ++ part = hc->curr_part; ++ header = part->elts; ++ ++ p = buf; ++ left = len; ++ ++ for (i = hc->curr_item; /* void */; i++) { ++ ++ if (i >= part->nelts) { ++ if (part->next == NULL) { ++ break; ++ } ++ ++ part = part->next; ++ header = part->elts; ++ i = 0; ++ } ++ ++ rec_size = header[i].key.len + header[i].value.len + 2; ++ if (left < rec_size) { ++ ++ if (left == len) { ++ /* provided buffer cannot fit key/value tuple */ ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "buffer too small"); ++ return NJT_ERROR; ++ } ++ ++ break; ++ } ++ ++ p = njt_cpymem(p, header[i].key.data, header[i].key.len); ++ *p++ = 0; ++ p = njt_cpymem(p, header[i].value.data, header[i].value.len); ++ *p++ = 0; ++ ++ left -= rec_size; ++ } ++ ++ hc->curr_part = part; ++ hc->curr_item = i; ++ ++ return p - buf; ++} ++ ++ ++static int32_t ++njt_wasm_http_open_request_body(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *ph) ++{ ++ njt_http_request_t *r; ++ njt_http_wc_body_in_ctx_t *sc; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content open request body"); ++ ++ if (ph == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, "invalid parent handle"); ++ return NJT_ERROR; ++ } ++ ++ if (ph->ops->tag != NJT_WASM_HTTP_TAG_REQUEST) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid parent handle type"); ++ return NJT_ERROR; ++ } ++ ++ njt_wasm_http_ctx_t *host_ctx = (njt_wasm_http_ctx_t *) ph->data; ++ r = host_ctx->request; ++ ++ sc = njt_palloc(self->host->pool, sizeof(njt_http_wc_body_in_ctx_t)); ++ if (sc == NULL) { ++ return NJT_ERROR; ++ } ++ ++ sc->r = r; ++ sc->body = NULL; /* r->request_body is not set yet */ ++ sc->offset = 0; ++ sc->read_started = 0; ++ sc->host_ctx = host_ctx; ++ ++ self->data = sc; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_read_request_body(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t len) ++{ ++ njt_http_wc_body_in_ctx_t *sc = self->data; ++ ++ size_t n; ++ njt_int_t rc; ++ njt_log_t *log; ++ ++ // TODO: state flags ++ ++ log = self->log; ++ ++ njt_log_debug2(NJT_LOG_DEBUG_HTTP, log, 0, ++ "wasm content open read request body rs:%i isc:%d", ++ sc->read_started, sc->host_ctx->in_syscall); ++ ++ if (!sc->read_started) { ++ ++ sc->host_ctx->in_syscall = 1; ++ ++ rc = njt_http_read_client_request_body(sc->r, ++ sc->host_ctx->body_handler); ++ ++ sc->host_ctx->in_syscall = 0; ++ ++ if (rc >= NJT_HTTP_SPECIAL_RESPONSE) { ++ ++ njt_log_error(NJT_LOG_ERR, log, 0, ++ "wasm content internal server error: " ++ "special response %i", rc); ++ ++ return NJT_ERROR; ++ } ++ ++ sc->read_started = 1; ++ ++ if (!sc->host_ctx->post_body_called) { ++ /* the njt_http_wc_body_handler will invoke wasm handler later */ ++ return NJT_DONE; ++ } ++ ++ /* else: body can be read, proceed further */ ++ } ++ ++ if (sc->r->request_body == NULL) { ++ njt_log_error(NJT_LOG_ERR, log, 0, ++ "wasm content handler called with no body"); ++ return NJT_ERROR; ++ } ++ ++ sc->body = sc->r->request_body; ++ ++ /* wasm target expects body, but client did not send it */ ++ if (sc->body->bufs == NULL) { ++ njt_log_error(NJT_LOG_ERR, log, 0, ++ "wasm content handler called with empty body"); ++ return NJT_ERROR; ++ } ++ ++ n = 0; ++ ++ if (sc->body->temp_file) { ++ rc = njt_wasm_http_body_from_file(sc->body, sc->offset, buf, len, ++ &n, log); ++ ++ } else { ++ rc = njt_wasm_http_body_from_mem(sc->body, sc->offset, buf, len, &n); ++ } ++ ++ if (rc != NJT_OK) { ++ return NJT_ERROR; ++ } ++ ++ sc->offset += n; ++ ++ return n; ++} ++ ++ ++static njt_int_t ++njt_wasm_http_body_from_mem(njt_http_request_body_t *body, off_t off, ++ uint8_t *buf, size_t size, size_t *nread) ++{ ++ size_t n, left, len; ++ uint8_t *pos, *rpos,skip; ++ njt_buf_t *b; ++ njt_chain_t *cl; ++ ++ n = 0; ++ pos = buf; ++ ++ if (off) { ++ skip = 1; ++ left = off; ++ ++ } else { ++ skip = 0; ++ left = size; ++ } ++ ++ for (cl = body->bufs; cl; cl = cl->next) { ++ ++ b = cl->buf; ++ ++ if (njt_buf_special(b)) { ++ continue; ++ } ++ ++ len = njt_buf_size(b); ++ ++ if (len < left) { ++ ++ left -= len; ++ ++ if (!skip) { ++ pos = njt_cpymem(pos, b->pos, len); ++ n += len; ++ } ++ ++ continue; ++ } ++ ++ /* len >= left */ ++ ++ if (skip) { ++ skip = 0; ++ len -= left; ++ rpos = b->pos +left; ++ ++ left = size; ++ ++ if (len < left) { ++ left -= len; ++ ++ njt_memcpy(pos, rpos, len); ++ n += len; ++ ++ continue; ++ ++ } else { ++ ++ njt_memcpy(pos, rpos, left); ++ n += left; ++ ++ break; ++ } ++ ++ } else { ++ ++ njt_memcpy(pos, b->pos, left); ++ n += left; ++ ++ break; ++ } ++ } ++ ++ *nread = n; ++ ++ return NJT_OK; ++} ++ ++ ++static njt_int_t ++njt_wasm_http_body_from_file(njt_http_request_body_t *body, off_t off, ++ uint8_t *buf, size_t size, size_t *nread, njt_log_t *log) ++{ ++ int fd; ++ ssize_t n; ++ ++ fd = body->temp_file->file.fd; ++ ++ if (lseek(fd, off, SEEK_SET) == -1) { ++ njt_log_error(NJT_LOG_ERR, log, njt_errno, ++ "wasm content body from file lseek(%D, %O) failed", ++ fd, off); ++ return NJT_ERROR; ++ } ++ ++ n = njt_read_fd(fd, buf, size); ++ if (n == -1) { ++ njt_log_error(NJT_LOG_ERR, log, njt_errno, ++ "wasm content body from file read(%D, %z) failed", ++ fd, size); ++ return NJT_ERROR; ++ } ++ ++ *nread = (size_t) n; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_open_response_headers(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *ph) ++{ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content open response headers"); ++ ++ if (ph == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, "invalid parent handle"); ++ return NJT_ERROR; ++ } ++ ++ if (ph->ops->tag != NJT_WASM_HTTP_TAG_REQUEST) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid parent handle type"); ++ return NJT_ERROR; ++ } ++ ++ self->data = ((njt_wasm_http_ctx_t *) ph->data)->request; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_write_response_headers(njt_wasm_handle_t *self, ++ uint8_t *buf, uint32_t len) ++{ ++ njt_http_request_t *r = self->data; ++ ++ uint8_t *p, *end; ++ njt_str_t key, value; ++ njt_table_elt_t *h; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content write response headers"); ++ ++ end = buf + len; ++ p = buf; ++ ++ while (p < end) { ++ ++ p = njt_wasm_http_get_stringz(p, end, &key); ++ if (p == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid value format"); ++ return NJT_ERROR; ++ } ++ ++ p = njt_wasm_http_get_stringz(p, end, &value); ++ if (p == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid value format"); ++ return NJT_ERROR; ++ } ++ ++ h = njt_list_push(&r->headers_out.headers); ++ if (h == NULL) { ++ return NJT_ERROR; ++ } ++ ++ h->hash = 1; ++ h->key.len = key.len; ++ h->key.data = njt_pnalloc(self->host->pool, key.len); ++ if (h->key.data == NULL) { ++ return NJT_ERROR; ++ } ++ njt_memcpy(h->key.data, key.data, key.len); ++ ++ h->value.len = value.len; ++ h->value.data = njt_pnalloc(self->host->pool, value.len); ++ if (h->value.data == NULL) { ++ return NJT_ERROR; ++ } ++ njt_memcpy(h->value.data, value.data, value.len); ++ } ++ ++ return p - buf; ++} ++ ++ ++static int32_t ++njt_wasm_http_close_response_headers(njt_wasm_handle_t *self) ++{ ++ njt_http_request_t *r = self->data; ++ ++ njt_int_t rc; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content close response headers"); ++ ++ rc = njt_http_send_header(r); ++ ++ if (rc == NJT_ERROR || rc > NJT_OK || r->header_only) { ++ ++ if (rc > NJT_OK) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "njt_http_send_header() failed with %i", rc); ++ rc = NJT_ERROR; ++ } ++ ++ return rc; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_open_response_body(njt_wasm_handle_t *self, ++ njt_wasm_handle_t *ph) ++{ ++ njt_http_wc_body_out_ctx_t *rbctx; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content open response body"); ++ ++ if (ph == NULL) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, "invalid parent handle"); ++ return NJT_ERROR; ++ } ++ ++ if (ph->ops->tag != NJT_WASM_HTTP_TAG_REQUEST) { ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "invalid parent handle type"); ++ return NJT_ERROR; ++ } ++ ++ rbctx = njt_pcalloc(self->host->pool, sizeof(njt_http_wc_body_out_ctx_t)); ++ if (rbctx == NULL) { ++ return NJT_ERROR; ++ } ++ ++ rbctx->r = ((njt_wasm_http_ctx_t *) ph->data)->request; ++ ++ self->data = rbctx; ++ ++ return NJT_OK; ++} ++ ++ ++static int32_t ++njt_wasm_http_write_response_body(njt_wasm_handle_t *self, uint8_t *buf, ++ uint32_t bytes) ++{ ++ njt_buf_t *b; ++ njt_chain_t *cl, **ll; ++ ++ njt_http_wc_body_out_ctx_t *rbctx; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content write response body"); ++ ++ if (bytes == 0) { ++ return 0; ++ } ++ ++ rbctx = self->data; ++ ++ for (cl = rbctx->out_bufs, ll = &rbctx->out_bufs; cl; cl = cl->next) { ++ ll = &cl->next; ++ } ++ ++ cl = njt_chain_get_free_buf(self->host->pool, &rbctx->free_bufs); ++ if (cl == NULL) { ++ return NJT_ERROR; ++ } ++ ++ *ll = cl; ++ ++ b = cl->buf; ++ ++ b->pos = njt_palloc(self->host->pool, bytes + 2); ++ if (b->pos == NULL) { ++ return NJT_ERROR; ++ } ++ ++ b->flush = 1; ++ b->memory = 1; ++ njt_memcpy(b->pos, buf, bytes); ++ b->last = b->pos + bytes; ++ *b->last++ = CR; ++ *b->last++ = LF; ++ ++ return bytes; ++} ++ ++ ++static int32_t ++njt_wasm_http_close_response_body(njt_wasm_handle_t *self) ++{ ++ njt_int_t rc; ++ njt_buf_t *b; ++ njt_chain_t *cl, **ll; ++ njt_http_request_t *r; ++ njt_http_wc_body_out_ctx_t *rbctx; ++ ++ njt_log_debug0(NJT_LOG_DEBUG_HTTP, self->log, 0, ++ "wasm content close response body"); ++ ++ rbctx = self->data; ++ r = rbctx->r; ++ ++ for (cl = rbctx->out_bufs, ll = &rbctx->out_bufs; cl; cl = cl->next) { ++ ll = &cl->next; ++ } ++ ++ cl = njt_chain_get_free_buf(self->host->pool, &rbctx->free_bufs); ++ if (cl == NULL) { ++ return NJT_ERROR; ++ } ++ ++ *ll = cl; ++ ++ b = cl->buf; ++ ++ b->flush = 1; ++ b->last_in_chain = 1; ++ b->last_buf = (r == r->main) ? 1 : 0; ++ ++ rc = njt_http_output_filter(rbctx->r, rbctx->out_bufs); ++ ++ if (rc == NJT_ERROR || rc > NJT_OK) { ++ ++ njt_log_error(NJT_LOG_ERR, self->log, 0, ++ "njt_http_output_filter() failed with %i", rc); ++ ++ return NJT_ERROR; ++ } ++ ++ return NJT_OK; ++} ++ ++ ++static u_char * ++njt_wasm_http_get_stringz(u_char *p, u_char *end, njt_str_t *res) ++{ ++ res->data = p; ++ ++ while (p < end) { ++ if (*p == 0) { ++ res->len = p - res->data; ++ return ++p; ++ } ++ p++; ++ } ++ ++ return NULL; ++} ++ ++ ++static uint32_t ++njt_wasm_http_get_schema(njt_http_request_t *r) ++{ ++#if (NJT_HTTP_SSL) ++ if (r->connection->ssl) { ++ return 1; ++ } ++#endif ++ ++ return 0; ++} ++ ++ ++static njt_uint_t ++njt_http_wc_request_headers_count(njt_http_request_t *r) ++{ ++ njt_uint_t n; ++ njt_list_part_t *part; ++ ++ part = &r->headers_in.headers.part; ++ ++ n = 0; ++ while (part) { ++ n += part->nelts; ++ part = part->next; ++ } ++ ++ return n; ++} +diff -urN njet/src/http/njt_http_wasm_host.h njet-patch/src/http/njt_http_wasm_host.h +--- njet/src/http/njt_http_wasm_host.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/njt_http_wasm_host.h 2024-11-15 16:23:19.436273767 +0800 +@@ -0,0 +1,43 @@ ++ ++#ifndef _NJT_HTTP_WASM_HOST_H_INCLUDED_ ++#define _NJT_HTTP_WASM_HOST_H_INCLUDED_ ++ ++ ++#include ++#include ++#include ++ ++ ++enum njt_wasm_http_ops_tags_e { ++ NJT_WASM_HTTP_HOST_TAG = 0x57485448, /* WHTH */ ++ NJT_WASM_HTTP_TAG_REQUEST_LOG, ++ NJT_WASM_HTTP_TAG_REQUEST, ++ NJT_WASM_HTTP_TAG_REQUEST_HEADERS, ++ NJT_WASM_HTTP_TAG_REQUEST_BODY, ++ NJT_WASM_HTTP_TAG_RESPONSE_HEADERS, ++ NJT_WASM_HTTP_TAG_RESPONSE_BODY ++}; ++ ++ ++typedef struct { ++ njt_http_request_t *request; ++ njt_http_client_body_handler_pt body_handler; ++ njt_str_t reject_msg; ++ uint32_t wasm_request; ++ unsigned in_syscall:1; ++ unsigned post_body_called:1; ++} njt_wasm_http_ctx_t; ++ ++ ++typedef struct { ++ njt_http_request_t *request; ++} njt_wasm_http_vars_ctx_t; ++ ++ ++extern njt_wasm_handle_ops_t njt_http_wasm_request_ops[]; ++extern njt_wasm_handle_ops_t njt_http_wasm_request_headers_ops[]; ++extern njt_wasm_handle_ops_t njt_http_wasm_request_body_ops[]; ++extern njt_wasm_handle_ops_t njt_http_wasm_response_headers_ops[]; ++extern njt_wasm_handle_ops_t njt_http_wasm_response_body_ops[]; ++ ++#endif /* _NJT_HTTP_WASM_HOST_H_INCLUDED_ */ +diff -urN njet/src/http/njt_wasi_http.h njet-patch/src/http/njt_wasi_http.h +--- njet/src/http/njt_wasi_http.h 1970-01-01 08:00:00.000000000 +0800 ++++ njet-patch/src/http/njt_wasi_http.h 2024-11-13 15:13:19.873105120 +0800 +@@ -0,0 +1,51 @@ ++// Generated by `wit-bindgen` 0.26.0. DO NOT EDIT! ++#ifndef __BINDINGS_NJT_WASI_HTTP_H ++#define __BINDINGS_NJT_WASI_HTTP_H ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++#include ++#include ++ ++typedef uint8_t njt_wasi_http_host_objects_t; ++ ++#define NJT_WASI_HTTP_HOST_OBJECTS_REQUEST_LOG 0 ++#define NJT_WASI_HTTP_HOST_OBJECTS_REQUEST 1 ++#define NJT_WASI_HTTP_HOST_OBJECTS_REQUEST_HEADERS 2 ++#define NJT_WASI_HTTP_HOST_OBJECTS_REQUEST_BODY 3 ++#define NJT_WASI_HTTP_HOST_OBJECTS_RESPONSE_HEADERS 4 ++#define NJT_WASI_HTTP_HOST_OBJECTS_RESPONSE_BODY 5 ++ ++// indexes in u32 array; array len? ++typedef uint8_t njt_wasi_http_host_request_meta_t; ++ ++#define NJT_WASI_HTTP_HOST_REQUEST_META_CTX 0 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_METHOD 1 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_SCHEMA 2 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_VERSION 3 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_URI_LEN 4 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_ADDR_LEN 5 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_HEADER_COUNT 6 ++#define NJT_WASI_HTTP_HOST_REQUEST_META_LAST 7 ++ ++typedef uint8_t njt_wasi_http_host_request_props_t; ++ ++// input ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_META 0 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_SELF 1 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_URI 2 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_REMOTE_ADDR 3 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_DISCARD_BODY 4 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR 5 ++// output ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_STATUS 6 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_CONTENT_LENGTH 7 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_RANGES 8 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_HEADER_ONLY 9 ++#define NJT_WASI_HTTP_HOST_REQUEST_PROPS_REJECT_MSG 10 ++ ++#ifdef __cplusplus ++} ++#endif ++#endif diff --git a/njet-http-wasm-module/config b/njet-http-wasm-module/config deleted file mode 100644 index 9ccf10efbd25bfe4da8bf28b8d0430e821e120d5..0000000000000000000000000000000000000000 --- a/njet-http-wasm-module/config +++ /dev/null @@ -1,22 +0,0 @@ -njt_addon_name=njt_http_wasm_module -njt_module_type=HTTP -njt_module_name=$njt_addon_name -njt_module_incs=" \ -$njt_addon_dir/include \ -" -njt_module_srcs=" \ - $njt_addon_dir/src/njt_http_wasm_module.c \ -" - -njt_module_libs="" #-lpthread - -have=NJT_HTTP_WASM_MODULE . auto/have -njt_module_incs="$njt_addon_dir/../../auto/lib/wasmedge/build/include/" -njt_module_libs="-L$njt_addon_dir/../../auto/lib/wasmedge/build/lib/ -lwasmedge" - -NJT_HTTP_WASM="YES" -. auto/module - - -# CORE_INCS="$CORE_INCS /root/.wasmedge/include/" -# CORE_LIBS="$CORE_LIBS -L/root/.wasmedge/lib/ -lwasmedge" \ No newline at end of file diff --git a/njet-http-wasm-module/src/njt_http_wasm_module.c b/njet-http-wasm-module/src/njt_http_wasm_module.c deleted file mode 100644 index 12ec4381ab80fddd03d8eb7ea7c9e2e39abd0ee7..0000000000000000000000000000000000000000 --- a/njet-http-wasm-module/src/njt_http_wasm_module.c +++ /dev/null @@ -1,484 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "njt_http_api_register_module.h" -#include - -#include "njt_string.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -typedef struct njt_http_wasm_main_conf_s -{ - njt_http_request_t **reqs; - njt_int_t size; -} njt_http_wasm_main_conf_t; - -typedef struct -{ - njt_http_request_t *req; - njt_int_t index; - njt_http_wasm_main_conf_t *dlmcf; -} njt_http_wasm_rpc_ctx_t; - -typedef struct njt_http_wasm_loc_conf_s -{ - njt_flag_t wasm_enable; - njt_str_t func_name; - njt_str_t plugin_path; -} njt_http_wasm_loc_conf_t; - - -static WasmEdge_VMContext *vm; -static WasmEdge_MemoryInstanceContext *memory; -static void -njt_http_wasm_read_data(njt_http_request_t *r); - -static njt_int_t -njt_http_wasm_handler(njt_http_request_t *r); - -static njt_int_t -njt_http_wasm_init_worker(njt_cycle_t *cycle); - -static void * -njt_http_wasm_create_loc_conf(njt_conf_t *cf); - -static char *njt_http_wasm_merge_loc_conf(njt_conf_t *cf, - void *parent, void *child); - -static void * -njt_http_wasm_create_main_conf(njt_conf_t *cf); - -static void njt_http_wasm_exit(njt_cycle_t *cycle); - -static njt_int_t -njt_http_wasm_init(njt_conf_t *cf); -static njt_int_t -load_wasm_instance(njt_http_wasm_loc_conf_t *conf, const char *path); - -static char * -njt_http_wasm_plugin(njt_conf_t *cf, njt_command_t *cmd, void *conf); - -uint32_t ptr_offset = 10240; - -static njt_command_t njt_http_wasm_commands[] = { - {njt_string("wasm_plugin"), - NJT_HTTP_MAIN_CONF | NJT_HTTP_SRV_CONF | NJT_HTTP_LOC_CONF | NJT_CONF_ANY, - njt_http_wasm_plugin, - NJT_HTTP_LOC_CONF_OFFSET, - offsetof(njt_http_wasm_loc_conf_t, wasm_enable), - NULL}, - {njt_string("wasm_func_name"), - NJT_HTTP_MAIN_CONF | NJT_HTTP_SRV_CONF | NJT_HTTP_LOC_CONF | NJT_CONF_ANY, - njt_conf_set_str_slot, - NJT_HTTP_LOC_CONF_OFFSET, - offsetof(njt_http_wasm_loc_conf_t, func_name), - NULL}, - {njt_string("wasm_plugin_path"), - NJT_HTTP_MAIN_CONF | NJT_HTTP_SRV_CONF | NJT_HTTP_LOC_CONF | NJT_CONF_ANY, - njt_conf_set_str_slot, - NJT_HTTP_LOC_CONF_OFFSET, - offsetof(njt_http_wasm_loc_conf_t, plugin_path), - NULL}, - njt_null_command}; - -static njt_http_module_t njt_http_wasm_module_ctx = { - NULL, - njt_http_wasm_init, - njt_http_wasm_create_main_conf, - NULL, - NULL, - NULL, - njt_http_wasm_create_loc_conf, - njt_http_wasm_merge_loc_conf}; - -njt_module_t njt_http_wasm_module = { - NJT_MODULE_V1, - &njt_http_wasm_module_ctx, - njt_http_wasm_commands, - NJT_HTTP_MODULE, - NULL, - NULL, - njt_http_wasm_init_worker, - NULL, - NULL, - njt_http_wasm_exit, - NULL, - NJT_MODULE_V1_PADDING}; - -static char * -njt_http_wasm_plugin(njt_conf_t *cf, njt_command_t *cmd, void *conf) -{ - - njt_http_wasm_loc_conf_t *clcf = conf; - clcf->wasm_enable = 1; - - njt_http_core_loc_conf_t *core_conf; - core_conf = njt_http_conf_get_module_loc_conf(cf, njt_http_core_module); - core_conf->handler = njt_http_wasm_handler; - - return NJT_CONF_OK; -} - -static njt_int_t -njt_http_wasm_init(njt_conf_t *cf) -{ - return NJT_OK; -} - -static void * -njt_http_wasm_create_loc_conf(njt_conf_t *cf) -{ - njt_http_wasm_loc_conf_t *uclcf; - uclcf = njt_pcalloc(cf->pool, sizeof(njt_http_wasm_loc_conf_t)); - if (uclcf == NULL) - { - njt_log_error(NJT_LOG_ERR, cf->log, 0, "malloc uclcf eror"); - return NULL; - } - uclcf->wasm_enable = NJT_CONF_UNSET; - uclcf->func_name.len = 0; - uclcf->func_name.data = NULL; - uclcf->plugin_path.len = 0; - uclcf->plugin_path.data = NULL; - return uclcf; -} - -static void * -njt_http_wasm_create_main_conf(njt_conf_t *cf) -{ - njt_http_wasm_main_conf_t *uclcf; - - uclcf = njt_pcalloc(cf->pool, sizeof(njt_http_wasm_main_conf_t)); - if (uclcf == NULL) - { - njt_log_error(NJT_LOG_ERR, cf->log, 0, "malloc njt_http_wasm_main_conf_t eror"); - return NULL; - } - uclcf->size = NJT_CONF_UNSET; - return uclcf; -} - -static njt_int_t load_wasm_instance(njt_http_wasm_loc_conf_t *conf, const char *path) -{ - WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); - WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); - - vm = WasmEdge_VMCreate(ConfCxt, NULL); - WasmEdge_VMContext *VMCxt = vm; - WasmEdge_ConfigureDelete(ConfCxt); - - WasmEdge_ModuleInstanceContext *WasiCxt = - WasmEdge_VMGetImportModuleContext(VMCxt, WasmEdge_HostRegistration_Wasi); - WasmEdge_ModuleInstanceInitWASI(WasiCxt, NULL, 0, NULL, 3, NULL, 0); - - WasmEdge_Result Res; - - Res = WasmEdge_VMLoadWasmFromFile(VMCxt, path); - if (!WasmEdge_ResultOK(Res)) - { - njt_log_error(NJT_LOG_EMERG, njt_cycle->log, 0, "Load WASM failed. Error message: %s\n", - WasmEdge_ResultGetMessage(Res)); - return NJT_ERROR; - } - Res = WasmEdge_VMValidate(VMCxt); - - if (!WasmEdge_ResultOK(Res)) - { - njt_log_error(NJT_LOG_EMERG, njt_cycle->log, 0, "Validate WASM failed. Error message: %s\n", - WasmEdge_ResultGetMessage(Res)); - return NJT_ERROR; - } - Res = WasmEdge_VMInstantiate(VMCxt); - - if (!WasmEdge_ResultOK(Res)) - { - njt_log_error(NJT_LOG_EMERG, njt_cycle->log, 0, "Instantiate WASM failed. Error message: %s\n", - WasmEdge_ResultGetMessage(Res)); - return NJT_ERROR; - } - - const WasmEdge_ModuleInstanceContext *mod_inst = WasmEdge_VMGetActiveModule(VMCxt); - memory = WasmEdge_ModuleInstanceFindMemory(mod_inst, WasmEdge_StringCreateByCString("memory")); - if (!memory) - { - njt_log_error(NJT_LOG_EMERG, njt_cycle->log, 0, "Failed to find memory instance.", - WasmEdge_ResultGetMessage(Res)); - return NJT_ERROR; - } - return NJT_OK; -} - -static char *njt_http_wasm_merge_loc_conf(njt_conf_t *cf, - void *parent, void *child) -{ - njt_http_wasm_loc_conf_t *prev = parent; - njt_http_wasm_loc_conf_t *conf = child; - - njt_conf_merge_value(conf->wasm_enable, prev->wasm_enable, 0); - njt_conf_merge_str_value(conf->func_name, prev->func_name, ""); - njt_conf_merge_str_value(conf->plugin_path, prev->plugin_path, ""); - return NJT_CONF_OK; -} - -static njt_int_t -njt_http_wasm_handler(njt_http_request_t *r) -{ - njt_int_t rc = NJT_OK; - - njt_http_core_loc_conf_t *loc; - njt_http_wasm_loc_conf_t *wasm_clcf; - - loc = njt_http_get_module_loc_conf(r, njt_http_core_module); - wasm_clcf = njt_http_get_module_loc_conf(r, njt_http_wasm_module); - if (wasm_clcf && wasm_clcf->wasm_enable && loc) - { - } - else - { - return NJT_DECLINED; - } - - njt_log_debug0(NJT_LOG_DEBUG_ALLOC, r->pool->log, 0, "1 read_client_request_body start +++++++++++++++"); - rc = njt_http_read_client_request_body(r, njt_http_wasm_read_data); - if (rc >= NJT_HTTP_SPECIAL_RESPONSE) - { - return rc; - } - - return NJT_DONE; -} - -static njt_int_t -njt_http_wasm_init_worker(njt_cycle_t *cycle) -{ - - return NJT_OK; -} - -static int njt_http_wasm_request_output(njt_http_request_t *r, njt_int_t code, njt_str_t *msg) -{ - njt_int_t rc; - njt_buf_t *buf; - njt_chain_t out; - - if (code == NJT_OK) - { - if (msg == NULL || msg->len == 0) - { - r->headers_out.status = NJT_HTTP_NO_CONTENT; - } - else - { - r->headers_out.status = NJT_HTTP_OK; - } - } - else - { - r->headers_out.status = code; - } - r->headers_out.content_length_n = 0; - if (msg != NULL && msg->len > 0) - { - njt_str_t type = njt_string("text/plain"); - r->headers_out.content_type = type; - r->headers_out.content_length_n = msg->len; - } - if (r->headers_out.content_length) - { - r->headers_out.content_length->hash = 0; - r->headers_out.content_length = NULL; - } - rc = njt_http_send_header(r); - if (rc == NJT_ERROR || rc > NJT_OK || r->header_only || msg == NULL || msg->len < 1) - { - return rc; - } - buf = njt_create_temp_buf(r->pool, msg->len); - if (buf == NULL) - { - return NJT_ERROR; - } - njt_memcpy(buf->pos, msg->data, msg->len); - buf->last = buf->pos + msg->len; - buf->last_buf = 1; - out.buf = buf; - out.next = NULL; - return njt_http_output_filter(r, &out); -} - -static void add_obj_to_json(char *str, char *key, char *value) -{ - strcat(str, ",\""); - strcat(str, key); - strcat(str, "\":\""); - strcat(str, value); - strcat(str, "\""); -} - -static char *loop_headers(njt_http_request_t *r) -{ - char *res = njt_palloc(r->pool, 1000); - memset(res, 0, 1000); - strcat(res, "{\"headers\": { \"proxy-from\": \"wasm-module\""); - njt_list_part_t *part = &r->headers_in.headers.part; - njt_table_elt_t *data = part->elts; - njt_uint_t i = 0; - for (i = 0 ; /* void */ ; i++) { - if (i >= part->nelts) { - if (part->next == NULL) { - break; - } - - part = part->next; - data = part->elts; - i = 0; - } - add_obj_to_json(res, (char *) data[i].key.data, (char *) data[i].value.data); - } - strcat(res, "}"); - return res; -} - -static void -njt_http_wasm_read_data(njt_http_request_t *r) -{ - njt_int_t rc; - - njt_http_wasm_loc_conf_t *wasm_clcf = njt_http_get_module_loc_conf(r, njt_http_wasm_module); - if (vm == NULL) - { - njt_str_t path = wasm_clcf->plugin_path; - // check wasm plugin path config - if(path.len == 0) { - njt_str_t err = njt_string("no wasm plugin_path config!"); - rc = njt_http_wasm_request_output(r, NJT_HTTP_INTERNAL_SERVER_ERROR, &err); - njt_http_finalize_request(r, rc); - return; - } - - u_char *wasmPath = path.data; - if (path.data[path.len - 1] != '\0') - { - u_char *new_data = njt_palloc(r->pool, path.len + 1); - if (new_data == NULL) - { - return; - } - njt_memcpy(new_data, path.data, path.len); - new_data[path.len] = '\0'; - wasmPath = new_data; - } - njt_int_t load_result = load_wasm_instance(wasm_clcf, (const char *)wasmPath); - - if(load_result != NJT_OK) { - njt_str_t err = njt_string("load wasm plugin error!"); - rc = njt_http_wasm_request_output(r, NJT_HTTP_INTERNAL_SERVER_ERROR, &err); - njt_http_finalize_request(r, rc); - return; - } - } - - njt_str_t response_data = njt_string("wasm world!"); - njt_str_t no_json_body = njt_string("\"no body content\""); - njt_str_t json_body; - rc = njt_http_util_read_request_body(r, &json_body, 2, 5242880); - if (rc != NJT_OK) - { - json_body = no_json_body; - } - - char *request_str = loop_headers(r); - - strcat(request_str, ",\"body\": "); - strcat(request_str, (char *)(char *)json_body.data); - strcat(request_str, "}"); - - const char *input = request_str; - size_t input_len = strlen(input); - WasmEdge_Result Res; - - WasmEdge_MemoryInstanceSetData(memory, (const uint8_t *)input, ptr_offset, input_len); - - WasmEdge_Value Params[2] = {WasmEdge_ValueGenI32(ptr_offset), - WasmEdge_ValueGenI32(input_len)}; - ptr_offset += input_len; - - WasmEdge_Value Returns[1] = {}; - WasmEdge_String FuncName = WasmEdge_StringCreateByCString((char *)wasm_clcf->func_name.data); - Res = WasmEdge_VMExecute(vm, FuncName, Params, 2, Returns, 1); - if (!WasmEdge_ResultOK(Res)) - { - njt_str_t err = njt_string("wasm execute error!"); - rc = njt_http_wasm_request_output(r, NJT_HTTP_OK, &err); - njt_http_finalize_request(r, rc); - return; - } - - uint32_t ptr = WasmEdge_ValueGetI32(Returns[0]); - - uint32_t *data = (uint32_t *)WasmEdge_MemoryInstanceGetPointer(memory, ptr, 2 * sizeof(uint32_t)); - - uint32_t str_ptr = data[0]; - uint32_t str_len = data[1]; - - u_char *c_string = (u_char *)WasmEdge_MemoryInstanceGetPointer(memory, str_ptr, str_len); - - njt_int_t plugin_response_status = 200; - if (str_len > 3) - { - char tmp[4]; - njt_memcpy(tmp, c_string, 3); - tmp[3] = '\0'; - plugin_response_status = atoi(tmp); - if (plugin_response_status == 0) - { - c_string = (u_char *)"插件返回格式出错"; - str_len = 24; - - } - else - { - c_string = c_string + 3; - str_len = str_len - 3; - } - } - else - { - c_string = (u_char *)"插件返回格式出错"; - str_len = 24; - } - - njt_str_t tmp_str; - tmp_str.data = c_string; - tmp_str.len = str_len; - - response_data = tmp_str; - rc = njt_http_wasm_request_output(r, plugin_response_status, &response_data); - njt_http_finalize_request(r, rc); - return; -} - - -static void njt_http_wasm_exit(njt_cycle_t *cycle) -{ - WasmEdge_VMDelete(vm); - WasmEdge_MemoryInstanceDelete(memory); - return; -} \ No newline at end of file diff --git a/njet.conf b/njet.conf new file mode 100644 index 0000000000000000000000000000000000000000..301c03906b1bfb038b0fd779f8286c5cf9d0af54 --- /dev/null +++ b/njet.conf @@ -0,0 +1,45 @@ +worker_processes auto; + +cluster_name njet; +node_name node1; + +error_log logs/error.log error; + +helper broker /usr/local/njet/modules/njt_helper_broker_module.so; +load_module /usr/local/njet/modules/njt_http_location_module.so; + +load_module modules/njt_iwasm_module.so; +# load_module modules/njt_wasmtime_module.so; + +# user njet; + +events { + worker_connections 1024; +} + +wasm_modules { + load njt_http_handler.wasm id=handler; + load njt_http_vars.wasm id=vars type=reactor; +} + + +http { + include mime.types; + access_log off; + + wasm_var vars "njt:wasi/var-utils#sum" $rvar $arg_a $arg_b $arg_c $arg_d; + + server { + listen *:8080; + + access_log stderr; + + location / { + return 200 "sum('$arg_a','$arg_b','$arg_c','$arg_d')=$rvar\n"; + } + + location /wasm { + wasm_content handler "njt:wasi/http-handler#handle-request"; + } + } +} \ No newline at end of file diff --git a/wasm-baselib/libnjthost/module.mk b/wasm-baselib/libnjthost/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..9e54d74257ecb6e8aab4893984f36afd49673e87 --- /dev/null +++ b/wasm-baselib/libnjthost/module.mk @@ -0,0 +1,19 @@ + +DEPS = src/njt_wasi_common.h \ + bindings/njt_host_lib.h + +SRCS = src/njt_wasi_utils.c \ + src/njt_wasi_http_request.c + + +# produces header files used by nginx +$(eval $(call mkbind,njt-wasi-core)) +$(eval $(call mkbind,njt-wasi-http)) + +# build base library to link into wasm modules +$(eval $(call make-static-lib,$(module)/objs/libnjthost.a,$(SRCS),$(DEPS))) + +# build base library as component, just in case +$(eval $(call wasm-component,$(SRCS),$(DEPS),njt-host-lib)) + + diff --git a/wasm-baselib/libnjthost/src/njt_wasi_common.h b/wasm-baselib/libnjthost/src/njt_wasi_common.h new file mode 100644 index 0000000000000000000000000000000000000000..3300e2f13dc8339fcf650145eaed12708b2382f7 --- /dev/null +++ b/wasm-baselib/libnjthost/src/njt_wasi_common.h @@ -0,0 +1,105 @@ + +#ifndef _NJT_WASI_COMMON_INCLUDED_ +#define _NJT_WASI_COMMON_INCLUDED_ + + +#include +#include +#include + +//#include "bindings/njt.h" +#include "bindings/njt_host_lib.h" + +typedef njt_host_lib_string_t njt_string_t; +typedef njt_host_lib_list_string_t njt_list_string_t; + +/* for read/write syscalls */ +#define NJT_WASI_BUF_SIZE 4096 + +/* TBD */ +#define njt_host_alloc(size) cabi_realloc(NULL, 0, sizeof(uint32_t), size) +#define njt_host_nalloc(size) cabi_realloc(NULL, 0, 1, size) + +#define njt_host_declare_str(name, cstr) \ + njt_host_lib_string_t name; \ + name.ptr = (uint8_t *) cstr; \ + name.len = sizeof(cstr) - 1; \ + +#define njt_string_set(s) { (uint8_t *) (s), sizeof(s) -1 } + + +#define NJT_WASI_OK 0 +#define NJT_WASI_ERROR -1 +#define NJT_WASI_AGAIN -2 +#define NJT_WASI_BUSY -3 +#define NJT_WASI_DONE -4 +#define NJT_WASI_DECLINED -5 +#define NJT_WASI_ABORT -6 + +/* shorten auto-generated types */ +typedef exports_njt_wasi_http_request_method_t njt_http_req_method_t; +typedef exports_njt_wasi_http_request_schema_t njt_http_req_schema_t; +typedef exports_njt_wasi_http_request_version_t njt_http_req_version_t; + +/* TBD */ +void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size); + +/* varargs wrapper on syscall */ +void njt_wasi_log_error(int32_t fd, uint8_t level, uint32_t errnum, + char *fmt, ...); + +// TODO: use njet defs + +//int32_t njt_wasi_open_log(njt_log_t *log); + +/* to be implemented by component */ +int32_t njt_wasi_http_handler_init(uint32_t req); +int32_t njt_wasi_http_handler_process_request_body(uint32_t req); +int32_t njt_wasi_http_handler_setup_response(uint32_t req); +int32_t njt_wasi_http_handler_generate_response(uint32_t req); +int32_t njt_wasi_http_handler_finalize(uint32_t req); + + +static inline njt_string_t *njt_wasi_string_dup(njt_string_t *src); +static inline void njt_wasi_string_dup_content(njt_string_t *dst, + njt_string_t *src); + +static inline uint8_t * +njt_wasi_get_stringz(uint8_t *p, uint8_t *end, njt_string_t *res) +{ + res->ptr = p; + + while (p < end) { + if (*p == 0) { + res->len = p - res->ptr; + return ++p; + } + p++; + } + + return NULL; +} + + +static inline njt_string_t * +njt_wasi_string_dup(njt_string_t *src) +{ + njt_string_t *dst; + + dst = malloc(sizeof(njt_string_t)); + njt_wasi_string_dup_content(dst, src); + + return dst; +} + + +static inline void +njt_wasi_string_dup_content(njt_string_t *dst, njt_string_t *src) +{ + dst->ptr = malloc(src->len); + dst->len = src->len; + + memcpy(dst->ptr, src->ptr, src->len); +} + +#endif /* _NJT_WASI_COMMON_INCLUDED_ */ diff --git a/wasm-baselib/libnjthost/src/njt_wasi_http_request.c b/wasm-baselib/libnjthost/src/njt_wasi_http_request.c new file mode 100644 index 0000000000000000000000000000000000000000..4bbc5aa150144af079fb4210181618b8b4b695d3 --- /dev/null +++ b/wasm-baselib/libnjthost/src/njt_wasi_http_request.c @@ -0,0 +1,1243 @@ + +#include +#include + +#include "njt_wasi_common.h" + +#define E(foo) exports_##foo + +// Exported Functions from `njt:wasi/http-handler` +int32_t exports_njt_wasi_http_handler_init(uint32_t req); +int32_t exports_njt_wasi_http_handler_process_request_body(uint32_t req); +int32_t exports_njt_wasi_http_handler_setup_response(uint32_t req); +int32_t exports_njt_wasi_http_handler_generate_response(uint32_t req); +int32_t exports_njt_wasi_http_handler_finalize(uint32_t req); + + +typedef enum { + NJT_WASI_HTTP_REQUEST_STATE_INITIAL, + NJT_WASI_HTTP_REQUEST_STATE_READING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE, + NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS, + NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_FINALIZED, + NJT_WASI_HTTP_REQUEST_STATE_REJECTED +} njt_wasi_http_req_state_t; + + +typedef struct njt_http_header_s njt_http_header_t; + +struct njt_http_header_s { + njt_string_t key; + njt_string_t value; + njt_http_header_t *next; + njt_http_header_t *next_value; +}; + + +typedef struct { + /* handles for objects on host */ + int32_t handle; + int32_t log; + int32_t body_handle; + int32_t headers_out_handle; + int32_t response_body_handle; + + uint32_t user_ctx; /* attached user data */ + + njt_wasi_http_req_state_t state; /* processing phase */ + njt_string_t reject_msg; + + /* request properties */ + + uint32_t method; + uint32_t version; + njt_http_req_schema_t schema; + + njt_string_t uri; + njt_string_t remote_addr; + + uint32_t nheaders_in; + njt_http_header_t *headers_in; /* array[nheaders_in] */ + + /* response properties */ + + uint32_t status; + uint8_t has_response_body; + uint64_t content_length; + + uint32_t max_kv_len; + njt_http_header_t *headers_out; /* linked list */ + njt_http_header_t **last_header_out; + + off_t response_bytes_sent; + +} njt_http_request_t; + + +static int32_t njt_wasi_http_request_read_headers(njt_http_request_t *r); +static njt_http_header_t *njt_wasi_http_request_find_request_header( + njt_http_request_t *r, njt_string_t *key, size_t *count, size_t *rlen); +static njt_http_header_t *njt_wasi_http_request_find_response_header( + njt_http_request_t *r, njt_string_t *key); +static void njt_wasi_http_request_delete_response_header_values( + njt_http_header_t *header); +static int32_t njt_wasi_http_request_list_to_reponse_headers( + njt_http_header_t *head, njt_list_string_t *values); + +static int32_t njt_wasi_http_final_response_setup(njt_http_request_t *r); +static int32_t njt_wasi_http_request_send_headers(njt_http_request_t *r); +static int32_t njt_wasi_http_response_body_finalize(uint32_t req); + + +static njt_http_request_t * +njt_wasi_http_request_get(int32_t rhandle, int32_t log_fd) +{ + int32_t rc; + uint32_t meta[NJT_WASI_HTTP_HOST_REQUEST_META_LAST]; + njt_http_request_t *r; + + rc = njt_wasi_syscall_get(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_META, + (uintptr_t) meta, sizeof(meta)); + if (rc < 0) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request meta"); + return NULL; + } + + if (meta[NJT_WASI_HTTP_HOST_REQUEST_META_CTX] != 0) { + return (njt_http_request_t *) meta[NJT_WASI_HTTP_HOST_REQUEST_META_CTX]; + } + + r = malloc(sizeof(njt_http_request_t)); + + memset(r, 0, sizeof(njt_http_request_t)); + + r->log = log_fd; + r->handle = rhandle; + r->body_handle = -1; + r->headers_out_handle = -1; + r->content_length = (uint64_t) -1; + r->status = 200; + + r->state = NJT_WASI_HTTP_REQUEST_STATE_INITIAL; + + r->method = meta[NJT_WASI_HTTP_HOST_REQUEST_META_METHOD]; + r->schema = meta[NJT_WASI_HTTP_HOST_REQUEST_META_SCHEMA]; + r->version = meta[NJT_WASI_HTTP_HOST_REQUEST_META_VERSION]; + + r->nheaders_in = meta[NJT_WASI_HTTP_HOST_REQUEST_META_HEADER_COUNT]; + + r->uri.len = meta[NJT_WASI_HTTP_HOST_REQUEST_META_URI_LEN]; + r->remote_addr.len = meta[NJT_WASI_HTTP_HOST_REQUEST_META_ADDR_LEN]; + + r->uri.ptr = malloc(r->uri.len); + r->remote_addr.ptr = malloc(r->remote_addr.len); + + rc = njt_wasi_syscall_get(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_URI, + (uintptr_t) r->uri.ptr, r->uri.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request uri"); + return NULL; + } + + rc = njt_wasi_syscall_get(rhandle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_REMOTE_ADDR, + (uintptr_t) r->remote_addr.ptr, + r->remote_addr.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request remote_addr"); + return NULL; + } + + rc = njt_wasi_syscall_set(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_SELF, + (uintptr_t) &r, sizeof(uint32_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set request context"); + return NULL; + } + + if (njt_wasi_http_request_read_headers(r) != NJT_WASI_OK) { + return NULL; + } + + return r; +} + +int32_t +exports_njt_wasi_http_request_get_log(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->log; +} + + +njt_http_req_method_t +exports_njt_wasi_http_request_get_method(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + /* see njet/src/http/njt_http_request.h */ + switch (r->method) { + case 0x00000002: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_GET; + case 0x00000004: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_HEAD; + case 0x00000008: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_POST; + case 0x00000010: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PUT; + case 0x00000020: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_DELETE; + case 0x00000040: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_MKCOL; + case 0x00000080L: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_COPY; + case 0x00000100L: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_MOVE; + case 0x00000200: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_OPTIONS; + case 0x00000400: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PROPFIND; + case 0x00000800: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PROPPATCH; + case 0x00001000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_LOCK; + case 0x00002000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_UNLOCK; + case 0x00004000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PATCH; + case 0x00008000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_TRACE; + case 0x00010000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_CONNECT; + default: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_UNKNOWN; + } + + return r->method; +} + + +njt_http_req_schema_t +exports_njt_wasi_http_request_get_schema(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->schema; +} + + +njt_http_req_version_t +exports_njt_wasi_http_request_get_version(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + switch (r->version) { + case 9: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V09; + case 1000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V10; + case 1001: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V11; + case 2000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V20; + case 3000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V30; + default: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_VUNKNOWN; + } +} + + +void +exports_njt_wasi_http_request_get_uri(uint32_t req, njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + *ret = r->uri; +} + + +void +exports_njt_wasi_http_request_get_remote_addr(uint32_t req, + njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + *ret = r->remote_addr; +} + + +int32_t +exports_njt_wasi_http_request_handle_body(uint32_t req, uint8_t enabled) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc, fd; + uint8_t on; + + if (!enabled) { + + on = 1; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_DISCARD_BODY, + (uintptr_t) &on, sizeof(uint8_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to discard body"); + return NJT_WASI_ERROR; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE; + + return NJT_WASI_OK; + } + + fd = r->body_handle; + + if (fd < 0) { + + njt_host_declare_str(bname, "njt::http::request::body"); + + fd = njt_wasi_syscall_open(&bname, r->handle); + + if (fd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, fd, + "failed to open request body"); + return NJT_WASI_ERROR; + } + + r->body_handle = fd; + r->state = NJT_WASI_HTTP_REQUEST_STATE_READING_BODY; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_read_body(uint32_t req, uint32_t buf, + uint32_t len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + ssize_t n; + + if (r->body_handle < 0) { + return NJT_WASI_ERROR; + } + + n = njt_wasi_syscall_read(r->body_handle, (uintptr_t) buf, len); + + if (n < 0) { + return n; + } + + if (n == 0) { + r->state = NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE; + } + + return n; +} + + +void +exports_njt_wasi_http_request_variable(uint32_t req, njt_string_t *key, + njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t n; + + uint32_t args[4]; + + args[0] = key->len; + args[1] = (uintptr_t) key->ptr; + args[2] = 0; + args[3] = 0; + + n = njt_wasi_syscall_get(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR, + (uintptr_t) args, sizeof(args)); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, + "failed to get request variable length"); + goto failed; + } + + ret->len = n; + ret->ptr = malloc(n); + + args[2] = n; + args[3] = (uintptr_t) ret->ptr; + + n = njt_wasi_syscall_get(r->handle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR, + (uintptr_t) args, sizeof(args)); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, + "failed to get request variable"); + goto failed; + } + + return; + +failed: + + ret->ptr = NULL; + ret->len = 0; +} + + +void +exports_njt_wasi_http_request_get_header(uint32_t req, + njt_string_t *key, njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + size_t n, len; + uint8_t *p; + njt_http_header_t *h; + + h = njt_wasi_http_request_find_request_header(r, key, &n, &len); + + if (h == NULL) { + ret->ptr = NULL; + ret->len = 0; + return; + } + + if (h->next == NULL) { + ret->ptr = h->value.ptr; + ret->len = h->value.len; + return; + } + + p = malloc(len); + ret->ptr = p; + + for ( ;; ) { + + memcpy(p, h->value.ptr, h->value.len); + p += h->value.len; + + if (h->next == NULL) { + break; + } + + *p++ = ','; *p++ = ' '; + + h = h->next; + } + + ret->len = len; +} + + +void +exports_njt_wasi_http_request_get_header_values(uint32_t req, + njt_string_t *key, njt_list_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + size_t n, len; + uint32_t i; + njt_string_t *out; + njt_http_header_t *h; + + h = njt_wasi_http_request_find_request_header(r, key, &n, &len); + + if (h == NULL) { + ret->ptr = NULL; + ret->len = 0; + return; + } + + out = malloc(sizeof(njt_string_t) * n); + + ret->ptr = out; + ret->len = n; + + + for (i = 0; ; i++) { + + out[i].ptr = h->value.ptr; + out[i].len = h->value.len; + + if (h->next == NULL) { + break; + } + + h = h->next; + } +} + + +uint32_t +exports_njt_wasi_http_request_args_count(uint32_t req) +{ + // TBD + return 0; +} + +void +exports_njt_wasi_http_request_arg_by_index(uint32_t req, uint32_t index, + njt_string_t *ret) +{ + // TBD +} + + +void +exports_njt_wasi_http_request_arg_by_key(uint32_t req, njt_string_t *key, + njt_string_t *ret) +{ + // TBD +} + + +void +exports_njt_wasi_http_request_allow_ranges(uint32_t req) +{ + // TBD +} + +int32_t +exports_njt_wasi_http_request_set_header(uint32_t req, njt_string_t *key, + njt_string_t *value) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + njt_string_t dup; + njt_http_header_t *h; + + if (r->max_kv_len < (key->len + value->len)) { + r->max_kv_len = key->len + value->len; + } + + njt_wasi_string_dup_content(&dup, value); + + h = njt_wasi_http_request_find_response_header(r, key); + + if (h) { + njt_wasi_http_request_delete_response_header_values(h); + h->value = dup; + + return NJT_WASI_OK; + } + + h = malloc(sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->key, key); + h->value = dup; + h->next = NULL; + h->next_value = NULL; + + if (r->last_header_out) { + *r->last_header_out = h; + + } else { + r->headers_out = h; + } + + r->last_header_out = &h->next; + + return NJT_WASI_OK; +} + + +static void +njt_wasi_http_request_delete_response_header_values(njt_http_header_t *header) +{ + njt_http_header_t *h, *next; + + h = header->next_value; + + while (h) { + free(h->key.ptr); + free(h->value.ptr); + next = h->next_value; + free(h); + h = next; + } + + free(header->value.ptr); + header->next_value = NULL; +} + + +static int32_t +njt_wasi_http_request_list_to_reponse_headers(njt_http_header_t *head, + njt_list_string_t *values) +{ + uint32_t i; + njt_string_t *str_values; + njt_http_header_t *h; + + str_values = values->ptr; + + njt_wasi_string_dup_content(&head->value, &str_values[0]); + head->next_value = NULL; + + for (i = 1; i < values->len; i++) { + + h = malloc(sizeof(njt_http_header_t)); + memset(h, 0, sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->value, &str_values[i]); + + head->next_value = h; + head = h; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_set_header_values(uint32_t req, + njt_string_t *key, njt_list_string_t *values) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc, found; + uint32_t i; + njt_string_t *str_values; + njt_http_header_t *h; + + if (values->len == 0) { + return NJT_WASI_ERROR; + } + + found = 0; + + h = njt_wasi_http_request_find_response_header(r, key); + + if (h) { + njt_wasi_http_request_delete_response_header_values(h); + found = 1; + + } else { + + h = malloc(sizeof(njt_http_header_t)); + memset(h, 0, sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->key, key); + } + + rc = njt_wasi_http_request_list_to_reponse_headers(h, values); + if (rc != NJT_WASI_OK) { + return rc; + } + + str_values = values->ptr; + + for (i = 0; i < values->len; i++) { + if (r->max_kv_len < (key->len + str_values[i].len)) { + r->max_kv_len = key->len + str_values[i].len; + } + } + + if (found) { + return NJT_WASI_OK; + } + + if (r->last_header_out) { + *r->last_header_out = h; + + } else { + r->headers_out = h; + } + + r->last_header_out = &h->next; + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_set_status(uint32_t req, uint32_t status) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + if (status > 999) { + return NJT_WASI_ERROR; + } + + r->status = status; + + return NJT_WASI_OK; +} + + + +int32_t +exports_njt_wasi_http_request_setup_response(uint32_t req, uint8_t has_body, + uint64_t body_len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + uint8_t on; + int32_t rc; + + r->has_response_body = has_body; + + on = has_body ? 0 : 1; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_HEADER_ONLY, + (uintptr_t) &on, sizeof(uint8_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response header only state"); + return NJT_WASI_ERROR; + } + + njt_host_declare_str(bname, "njt::http::response::body"); + + rc = njt_wasi_syscall_open(&bname, r->handle); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to open response body"); + return NJT_WASI_ERROR; + } + + r->response_body_handle = rc; + + if (body_len == (uint64_t) -1) { + /* chunked encoding by default */ + return NJT_WASI_OK; + } + + r->content_length = body_len; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_CONTENT_LENGTH, + (uintptr_t) &body_len, sizeof(uint64_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response content length"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_write_body(uint32_t req, uint32_t buf, + uint32_t len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + ssize_t n; + + if (r->response_body_handle == -1) { + return NJT_WASI_ERROR; + } + + n = njt_wasi_syscall_write(r->response_body_handle, buf, len); + if (n < 0) { + return n; + } + + r->response_bytes_sent += n; + + return n; +} + + +int32_t +exports_njt_wasi_http_request_reject(uint32_t req, uint32_t status, + njt_string_t *msg) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + + if (status > 999) { + return NJT_WASI_ERROR; + } + + r->status = status; + + njt_wasi_string_dup_content(&r->reject_msg, msg); + + r->state = NJT_WASI_HTTP_REQUEST_STATE_REJECTED; + + return njt_wasi_http_final_response_setup(r); +} + + +int32_t +exports_njt_wasi_http_request_finalize(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc; + + if (r->state == NJT_WASI_HTTP_REQUEST_STATE_REJECTED) { + // special code to avoid syscall errors to ensure request will be rejected + return NJT_WASI_DECLINED; + } + + // good request finalization + + rc = njt_wasi_syscall_close(r->handle); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, "close request"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_final_response_setup(njt_http_request_t *r) +{ + int32_t rc; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_STATUS, + (uintptr_t) &r->status, sizeof(uint32_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response status"); + return NJT_WASI_ERROR; + } + + if (r->state == NJT_WASI_HTTP_REQUEST_STATE_REJECTED) { + + // XXX: r->reject_msg.len = 0 + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_REJECT_MSG, + (uintptr_t) r->reject_msg.ptr, + r->reject_msg.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set reject message"); + return NJT_WASI_ERROR; + } + } + + return NJT_WASI_OK; +} + +static int32_t +njt_wasi_http_request_write_header(njt_http_request_t *r, int32_t hd, + uint8_t *b, njt_string_t *k, njt_string_t *v) +{ + uint8_t *p; + int32_t rc; + size_t len; + + len = k->len + v->len + 2; + + p = b; + + memcpy(p, (char *) k->ptr, k->len); + p += k->len; + + *p++ = 0; + + memcpy(p, (char *) v->ptr, v->len); + p += v->len; + + *p++ = 0; + + rc = njt_wasi_syscall_write(hd, (uintptr_t) b, len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "write response headers"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_request_send_headers(njt_http_request_t *r) +{ + uint8_t *buf; + int32_t hd, rc; + njt_http_header_t *h, *mh; + + hd = r->headers_out_handle; + + if (hd == -1) { + + njt_host_declare_str(hname, "njt::http::response::headers"); + + hd = njt_wasi_syscall_open(&hname, r->handle); + if (hd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, hd, + "open response headers"); + return NJT_WASI_ERROR; + } + + buf = malloc(r->max_kv_len + 2); + + for (h = r->headers_out; h; h = h->next) { + + rc = njt_wasi_http_request_write_header(r, hd, buf, + &h->key, &h->value); + if (rc < 0) { + free(buf); + return NJT_WASI_ERROR; + } + + for (mh = h->next_value; mh; mh = mh->next_value) { + rc = njt_wasi_http_request_write_header(r, hd, buf, &h->key, + &mh->value); + if (rc < 0) { + free(buf); + return NJT_WASI_ERROR; + } + } + } + + free(buf); + + r->headers_out_handle = hd; + } + + /* + * closing response headers will trigger actual send by njet, + * so we can get AGAIN here + */ + rc = njt_wasi_syscall_close(hd); + if (rc < 0) { + return rc; + } + + /* got OK - headers sent */ + + if (r->has_response_body) { + r->state = NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY; + + } else { + r->state = NJT_WASI_HTTP_REQUEST_STATE_FINALIZED; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_response_body_finalize(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return njt_wasi_syscall_close(r->response_body_handle); +} + + +/* helper functions */ + +static int32_t +njt_wasi_http_request_read_headers(njt_http_request_t *r) +{ + ssize_t n; + uint8_t *p, *end; + int32_t hd; + uint32_t i; + uint8_t hbuf[NJT_WASI_BUF_SIZE]; + njt_string_t k, v; + + r->headers_in = malloc(sizeof(njt_http_header_t) * r->nheaders_in); + + njt_host_declare_str(hname, "njt::http::request::headers"); + + hd = njt_wasi_syscall_open(&hname, r->handle); + + if (hd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, hd, + "open request headers"); + return NJT_WASI_ERROR; + } + + i = 0; + + do { + n = njt_wasi_syscall_read(hd, (uintptr_t) hbuf, NJT_WASI_BUF_SIZE); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, "read headers"); + goto failed; + } + + p = hbuf; + end = hbuf + n; + + while (p < end) { + + p = njt_wasi_get_stringz(p, end, &k); + if (p == NULL) { + goto failed; + } + + p = njt_wasi_get_stringz(p, end, &v); + if (p == NULL) { + goto failed; + } + + if (i == r->nheaders_in) { + goto failed; + } + + njt_wasi_string_dup_content(&r->headers_in[i].key, &k); + njt_wasi_string_dup_content(&r->headers_in[i].value, &v); + + r->headers_in[i].next = NULL; + + i++; + } + + } while (n); + + (void) njt_wasi_syscall_close(hd); + + return NJT_WASI_OK; + +failed: + + (void) njt_wasi_syscall_close(hd); + return NJT_WASI_ERROR; +} + + +static inline uint32_t +njt_wasi_header_key_match(njt_string_t *key, njt_string_t *item) +{ + uint8_t ch; + uint32_t n; + + + if (item->len != key->len) { + return 0; + } + + for (n = 0; n < key->len; n++) { + ch = item->ptr[n]; + + if (ch >= 'A' && ch <= 'Z') { + ch |= 0x20; + + } else if (ch == '-') { +// ch = '_'; // XXX: WTF? // XXX + ch = '-'; + } + + if (key->ptr[n] != ch) { + return 0; + } + } + + if (n != key->len) { + return 0; + } + + return 1; +} + + +static njt_http_header_t * +njt_wasi_http_request_find_request_header(njt_http_request_t *r, + njt_string_t *key, size_t *rcount, size_t *rlen) +{ + size_t len, count; + uint32_t i; + njt_http_header_t *h, **ph; + + + count = 0; + len = 0; + ph = &h; + + for (i = 0; i < r->nheaders_in; i++) { + + if (!njt_wasi_header_key_match(key, &r->headers_in[i].key)) { + continue; + } + + len += r->headers_in[i].value.len + 2; + count++; + + *ph = &r->headers_in[i]; + ph = &r->headers_in[i].next; + } + + *ph = NULL; + + if (h == NULL) { + return NULL; + } + + len -= 2; + + *rlen = len; + *rcount = count; + + return h; +} + + +static njt_http_header_t * +njt_wasi_http_request_find_response_header(njt_http_request_t *r, + njt_string_t *key) +{ + njt_http_header_t *h; + + for (h = r->headers_out; h; h = h->next) { + + if (!njt_wasi_header_key_match(&h->key, key)) { + continue; + } + + return h; + } + + return NULL; +} + + +void +exports_njt_wasi_http_request_set_context(uint32_t req, uint32_t data) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + r->user_ctx = data; +} + + +uint32_t +exports_njt_wasi_http_request_get_context(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->user_ctx; +} + + +int32_t +exports_njt_wasi_http_handler_handle_request(int32_t fd) +{ + int32_t rc, log_fd, rfd; + uintptr_t req; + njt_http_request_t *r; + + njt_host_declare_str(rname, "njt::http::request"); + rfd = njt_wasi_syscall_open(&rname, fd); + if (rfd < 0) { + return NJT_WASI_ERROR; + } + + njt_host_declare_str(logname, "njt::core::log"); // host log + log_fd = njt_wasi_syscall_open(&logname, -1); + if (log_fd < 0) { + return NJT_WASI_ERROR; + } + + r = njt_wasi_http_request_get(rfd, log_fd); + if (r == NULL) { + return NJT_WASI_ERROR; + } + + req = (uintptr_t) r; + + for ( ;; ) { + + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_DEBUG, 0, + "wasm http state: %d", (uint32_t) r->state); + + switch (r->state) { + + case NJT_WASI_HTTP_REQUEST_STATE_INITIAL: + + if (E(njt_wasi_http_handler_init)(req) < 0) { + return NJT_WASI_ERROR; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_READING_BODY: + + rc = E(njt_wasi_http_handler_process_request_body)(req); + if (rc < 0) { + return rc; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE: + + rc = E(njt_wasi_http_handler_setup_response(req)); + if (rc < 0) { + return rc; + } + + rc = njt_wasi_http_final_response_setup(r); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS: + + rc = njt_wasi_http_request_send_headers(r); + if (rc < 0) { + return rc; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY: + + rc = E(njt_wasi_http_handler_generate_response)(req); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY: + + rc = njt_wasi_http_response_body_finalize(req); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_FINALIZED; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_REJECTED: + goto done; + + case NJT_WASI_HTTP_REQUEST_STATE_FINALIZED: + + rc = E(njt_wasi_http_handler_finalize)(req); + if (rc < 0) { + return rc; + } + + goto done; + } + } + +done: + + return exports_njt_wasi_http_request_finalize(req); +} diff --git a/wasm-baselib/libnjthost/src/njt_wasi_utils.c b/wasm-baselib/libnjthost/src/njt_wasi_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..d00ac8811b660a5f3e21c46f95e594cecd44de58 --- /dev/null +++ b/wasm-baselib/libnjthost/src/njt_wasi_utils.c @@ -0,0 +1,398 @@ + +#include +#include +#include + +#include "njt_wasi_common.h" + + +#define NJT_HOST_MAX_ERR 2048 + + +static char *njt_errmsg(int32_t err); + + +static char *njt_errors[] = { + "", + "internal error", + "again", + "busy", + "done", + "declined", + "abort", +}; + + +static char * +njt_errmsg(int32_t err) +{ + size_t len; + + len = sizeof(njt_errors) / sizeof(njt_errors[0]); + + if (err >= 0) { + return ""; + } + + err = -err; + + if (err > (len - 1)) { + return "Unknown error"; + } + + return njt_errors[err]; +} + + +uint8_t * +njt_wasi_parse_int(uint8_t *pos, uint8_t *end, uint64_t *out) +{ + uint8_t *p; + uint64_t value; + uint64_t len; + + if (pos >= end) { + return NULL; + } + + p = pos; + len = 1 << (*p >> 6); + + value = *p++ & 0x3f; + + if ((size_t)(end - p) < (len - 1)) { + return NULL; + } + + while (--len) { + value = (value << 8) + *p++; + } + + *out = value; + + return p; +} + + +void +njt_wasi_log_error(int32_t fd, uint8_t level, uint32_t errnum, char *fmt, ...) +{ + int n; + char *p; + size_t left; + va_list ap; + njt_string_t emsg; + + char buf[NJT_HOST_MAX_ERR]; + + p = buf; + left = NJT_HOST_MAX_ERR; + + /* pass log level in 1st byte of message */ + *p++ = level; + left--; + + va_start(ap, fmt); + n = vsnprintf(p, left, fmt, ap); + va_end(ap); + + if (n < 0) { + return; + } + + p += n; + left -= n; + + if (errnum) { + exports_njt_wasi_utils_strerror(errnum, &emsg); + + n = snprintf((char *) p, left, " (%.*s)", (int) emsg.len, emsg.ptr); + if (n < 0) { + abort(); + } + p += n; + left -= n; + } + + (void) njt_wasi_syscall_write(fd, (uintptr_t) buf, p - buf); +} + + +void +exports_njt_wasi_utils_strerror(int32_t errnum, njt_string_t *ret) +{ + char *e; + + e = njt_errmsg(errnum); + + ret->ptr = (uint8_t *) e; + ret->len = strlen(e); +} + + +int32_t +exports_njt_wasi_utils_list_alloc(int32_t fd, uint32_t nargs, + uint32_t size, uint32_t oldmem, uint32_t oldmem_size, uint32_t old_result, + int32_t log_fd) +{ + void *mem, *omem; + uint8_t *buf, *p, *end; + ssize_t n, len; + uint32_t i; + njt_string_t tmp, *items; + + len = sizeof(njt_string_t) * nargs + size + nargs; + + omem = (void *) oldmem; + + if (oldmem_size < len) { + free(omem); + omem = NULL; + } + + if (old_result) { + free((void *) old_result); + } + + if (omem) { + mem = omem; + + } else { + mem = njt_host_alloc(len); + } + + items = mem; + + buf = mem + sizeof(njt_string_t) * nargs; + + n = njt_wasi_syscall_read(fd, (uintptr_t) buf, size + nargs); + if (n < 0) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, n, "read vars"); + return -1; + } + + // XXX: what should read() return: actual bytes (including sep?) + if (n != nargs) { + // XXX: FREE ON ERR ? + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "read failed: got %d expected %d", n,nargs); + return -1; + } + + p = buf; + end = buf + size + nargs; + i = 0; + + while (p < end) { + + p = njt_wasi_get_stringz(p, end, &tmp); + if (p == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, n, + "read vars format error"); + abort(); + } + //printf("GOT STRING: %.*s\n", (int)tmp.len, tmp.ptr); + + if (i >= nargs) { + break; + } + + items[i++] = tmp; + } + + // XXX: handle NULL return on host + return (uintptr_t) mem; +} + + +void +exports_njt_wasi_utils_log_error(int32_t fd, uint8_t level, int32_t errnum, + njt_string_t *msg) +{ + njt_wasi_log_error(fd, level, errnum, "%.*s", (int) msg->len, msg->ptr); +} + + +bool +exports_njt_wasi_utils_get_env(int32_t env_fd, int32_t log_fd, + exports_njt_wasi_utils_list_keyval_t *ret, int32_t *err) +{ + exports_njt_wasi_utils_keyval_t *kvs; + + uint8_t *vp, *end, *kd, *vd, *kdp, *vdp, *kdp_end, *vdp_end; + int32_t fd, n, left, k; + uint32_t sizes[3]; + uint64_t varint, curr_len; + + uint8_t ebuf[4096]; + + enum { + st_key_len, + st_key, + st_data_len, + st_data + } state; + + njt_string_t opname = njt_string_set("njt::call_env"); + fd = njt_wasi_syscall_open(&opname, env_fd); + if (fd < 0) { + *err = fd; + return false; + } + + n = njt_wasi_syscall_get(fd, 0, (uint32_t) sizes, sizeof(sizes)); + if (n < 0 || n != sizeof(sizes)) { + *err = -1; + return false; + } + + kvs = njt_host_alloc(sizeof(exports_njt_wasi_utils_keyval_t) * sizes[0] + + sizes[1] + sizes[2]); + + kd = (uint8_t *) kvs + + sizeof(exports_njt_wasi_utils_keyval_t) * sizes[0]; + vd = kd + sizes[1]; + + + + ret->len = sizes[0]; + ret->ptr = kvs; + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "========================size0:%d len:%d", sizes[0], ret->len); + kdp = kd; kdp_end = kdp + sizes[1]; + vdp = vd; vdp_end = vdp + sizes[2]; + + curr_len = 0; + + state = 0; + k = 0; + + do { + n = njt_wasi_syscall_read(fd, (uint32_t)ebuf, sizeof(ebuf)); + if (n < 0) { + *err = n; + return false; + } + + if (n == 0) { + break; + } + + vp = ebuf; + end = ebuf + n; + + while (vp < end) { + + switch (state) { + case st_key_len: + vp = njt_wasi_parse_int(vp, end, &varint); + if (vp == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "truncated key len"); + *err = -1; + return false; + } + curr_len = varint; + + kvs[k].key.len = varint; + kvs[k].key.ptr = kdp; + + /* fall through */ + + case st_key: + + left = end - vp; + + if (left < curr_len) { + + if (kdp + left > kdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(kdp, vp, left); + kdp += left; + + vp += left; + curr_len -= left; + break; + + } else { + if (kdp + curr_len > kdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(kdp, vp, curr_len); + kdp += curr_len; + vp += curr_len; + } + + /* fall through */ + + case st_data_len: + + vp = njt_wasi_parse_int(vp, end, &varint); + if (vp == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "truncated key len"); + *err = -1; + return false; + } + curr_len = varint; + + kvs[k].value.len = varint; + kvs[k].value.ptr = vdp; + + /* fall through */ + + case st_data: + left = end - vp; + + if (left < curr_len) { + if (vdp + left > vdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(vdp, vp, left); + vdp += left; + vp += left; + curr_len -= left; + break; + + } else { + if (vdp + curr_len > vdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(vdp, vp, curr_len); + vdp += curr_len; + vp += curr_len; + } + + k++; + } + } + + } while (n > 0); + + if (k != sizes[0]) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "env count does not match: found %u expected %u", + sizes[0], k); + *err = -1; + return false; + } + + return true; +} diff --git a/wasm-baselib/make.conf b/wasm-baselib/make.conf new file mode 100644 index 0000000000000000000000000000000000000000..438c9319ebe7e787174357922af3c8d2dc82c78d --- /dev/null +++ b/wasm-baselib/make.conf @@ -0,0 +1,5 @@ +TOOLSDIR=./ +SDK=wasi-sdk-24.0-x86_64-linux +WASM_TOOLS=wasm-tools-1.217.0-x86_64-linux +WIT_BINDGEN=wit-bindgen-0.26.0-x86_64-linux +MODULES_DST=/njet/conf diff --git a/wasm-baselib/makefile b/wasm-baselib/makefile new file mode 100644 index 0000000000000000000000000000000000000000..6d3dbff0862c3248f2f20126968d6b64c9670c2b --- /dev/null +++ b/wasm-baselib/makefile @@ -0,0 +1,33 @@ +include make.conf +include rules.mk + +all: results + +parts = libnjthost + +modules := +targets := +clean-objs := + +$(foreach p,$(parts),$(shell mkdir -p $p/objs $p/bindings)) +$(foreach p,$(parts),$(eval include $p/module.mk)) +$(foreach p,$(parts),$(eval clean_objs += $p/objs $p/bindings)) + + +results: $(targets) + +install: results + @install -v $(modules) $(MODULES_DST) + +clean: + @rm -rf $(clean_objs) + + +PROGRESS= +PROGRESS=--progress=plain + +docker: + docker build $(PROGRESS) . -t wasm-examples + +.PHONY: install clean docker + diff --git a/wasm-baselib/rules.mk b/wasm-baselib/rules.mk new file mode 100644 index 0000000000000000000000000000000000000000..512674eb29815ab32aed6773edc7fe598503e245 --- /dev/null +++ b/wasm-baselib/rules.mk @@ -0,0 +1,107 @@ +# +# generic rules for building WASM +# + +CLANG=$(TOOLSDIR)/$(SDK)/bin/clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip1-clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip2-clang + +WLD=$(TOOLSDIR)/$(SDK)/bin/wasm-ld +AR=$(TOOLSDIR)/$(SDK)/bin/ar +RANLIB=$(TOOLSDIR)/$(SDK)/bin/ranlib +WTOOLS=$(TOOLSDIR)/$(WASM_TOOLS) +BG=$(TOOLSDIR)/$(WIT_BINDGEN) + +mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST))) +module = $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +WIT_OPTS=--out-dir=$(module)/bindings \ + --no-helpers \ + --no-object-file \ + --autodrop-borrows=yes + +WITDIR=wit + +OPTS=-Wall -Werror -O2 -I. -I$(module) + +LDOPTS=-Wl,--no-entry -Wl,--import-undefined -mexec-model=reactor + +HOSTLIB=libnjthost/objs/libnjthost.a + +WASI_PLUG=vendor/wasi_snapshot_preview1.proxy.wasm + +# for debug purposes: produce human-readable version of code +%.wasm.wat: %.wasm + $(WTOOLS)/wasm-tools print $^ > $@ + +src-to-obj = $(subst src/,objs/,$(subst .c,.wasm,$(filter %.c,$1))) + +world-to-fn = $(subst -,_,$1) +world-to-wit =$(WITDIR)/$(call world-to-fn,$1).wit + +# $(call wasm-component,1:srcs,2:deps,3:world) +define wasm-component + + $(eval id=$(call world-to-fn,$3)) + + targets += $(module)/objs/$(id).wasm.wat \ + $(module)/objs/$(id)-obj.wasm.wat \ + $(module)/objs/$(id)-component.wasm.wat \ + $(module)/bindings/$(id).c \ + $(module)/bindings/$(id).h + + modules += $(module)/objs/$(id).wasm + components += $(module)/objs/$(id)-component.wasm + + $(call mkbind,$3) + + # build module + $(module)/objs/$(id)-obj.wasm: $(addprefix $(module)/,$1) $(addprefix $(module)/,$2) $(module)/bindings/$(id).c $(module)/bindings/$(id).h $(HOSTLIB) + $(CLANG) $(OPTS) $(LDOPTS) -o $$@ $(addprefix $(module)/,$1) $(module)/bindings/$(id).c $(HOSTLIB) + + # embed WIT + $(module)/objs/$(id).wasm: $(module)/objs/$(id)-obj.wasm $(call world-to-wit,$3) + $(WTOOLS)/wasm-tools component embed $(WITDIR) $$< -o $$@ --world $3 + + $(module)/objs/$(id)-component.wasm: $(module)/objs/$(id).wasm + $(WTOOLS)/wasm-tools component new $$^ --adapt $(WASI_PLUG) -o $$@ + +endef + +# $(call mkbind,1:world) +define mkbind + + $(eval nm=$(call world-to-fn,$1)) + + targets += $(module)/bindings/$(nm).c \ + $(module)/bindings/$(nm).h + + $(module)/bindings/$(nm).c $(module)/bindings/$(nm).h: $(call world-to-wit,$1) + $(BG)/wit-bindgen c $(WIT_OPTS) $(WITDIR) --world $1 + +endef + + +# $(call compile-src,1:src,2:deps) +define compile-src + + targets += $(call src-to-obj,$1).wat + + $(call src-to-obj,$1): $1 $2 + $(CLANG) -c $(OPTS) -fPIC -o $$@ $$< + +endef + +# $(call make-static-lib,1:name,2:srcs,3:deps) +define make-static-lib + + $(foreach item,$(addprefix $(module)/,$2),$(call compile-src,$(item),$(addprefix $(module)/,$3))) + + targets += $1 + + $1: $(call src-to-obj,$(addprefix $(module)/,$2)) + $(AR) r $$@ $$^ + $(RANLIB) $$@ + +endef + diff --git a/wasm-baselib/vendor/wasi_snapshot_preview1.proxy.wasm b/wasm-baselib/vendor/wasi_snapshot_preview1.proxy.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7dd6ecd2a00124011a10e7fc1cd64fcb3d32e358 Binary files /dev/null and b/wasm-baselib/vendor/wasi_snapshot_preview1.proxy.wasm differ diff --git a/wasm-baselib/wasm-tools-1.217.0-x86_64-linux.tar.gz b/wasm-baselib/wasm-tools-1.217.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8dfce4f026b34aeb8f0ff9c30494611a4b5c2fdf Binary files /dev/null and b/wasm-baselib/wasm-tools-1.217.0-x86_64-linux.tar.gz differ diff --git a/wasm-baselib/wit-bindgen-0.26.0-x86_64-linux.tar.gz b/wasm-baselib/wit-bindgen-0.26.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c92d4c84c7eb86403e8f9494df28ecaa848831ee Binary files /dev/null and b/wasm-baselib/wit-bindgen-0.26.0-x86_64-linux.tar.gz differ diff --git a/wasm-baselib/wit/njt_host_lib.wit b/wasm-baselib/wit/njt_host_lib.wit new file mode 100644 index 0000000000000000000000000000000000000000..c51970128d8f0a1aeff05331a5fc6e5660535449 --- /dev/null +++ b/wasm-baselib/wit/njt_host_lib.wit @@ -0,0 +1,9 @@ + +world njt-host-lib { + import syscall; + import host; + import http-host; + export utils; + export http-request; +} + diff --git a/wasm-baselib/wit/njt_wasi.wit b/wasm-baselib/wit/njt_wasi.wit new file mode 100644 index 0000000000000000000000000000000000000000..9eab45c7706b6dec0bead021909ee807eccec926 --- /dev/null +++ b/wasm-baselib/wit/njt_wasi.wit @@ -0,0 +1,128 @@ +package njt:wasi; + +interface host { + + // log level: matches NGX_LOG_ defines in src/core/njt_log.h + enum ll { + STDERR, EMERG, ALERT, CRIT, ERR, WARN, NOTICE, INFO, DEBUG + } +} + +interface syscall { + + // all syscalls return: + // on success: NGX_OK (zero) or positive value + // otherwise: NGX_ERROR/AGAIN... standard nginx return codes (negative) + // negative codes are expected to be returned to host as is + + open: func(name:string, ctx:s32) -> s32; + + read: func(handle:s32, buf:u32, len:u32) -> s32; + write: func(handle:s32, buf:u32, len:u32) -> s32; + + get: func(handle:s32, propid:u32, buf:u32, len:u32) -> s32; + set: func(handle:s32, propid:u32, val:u32, len:u32) -> s32; + + close: func(handle:s32) -> s32; +} + +interface http-host { + + // indexes in u32 array; array len? + enum request-meta { + ctx, method, schema, version, uri-len, addr-len, + header-count, last + } + + enum request-props { + // input + meta, self, uri, remote-addr, discard-body, var, + // output + status, content-length, ranges, header-only, reject-msg + } +} + +interface utils { + + record keyval { + key: string, + value: string + } + + strerror: func(errnum: s32) -> string; + + log-error: func(fd: s32, level: u8, errnum:s32, msg:string); + + get-env: func(fd: s32, log-fd: s32) -> result,s32>; + + list-alloc: func(fd: s32, nargs:u32, size:u32, old:u32, oldsize:u32, oldres:u32, logfd:s32) -> s32; +} + +interface http-request { + + enum schema { HTTP, HTTPS } + + enum method { + UNKNOWN, GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, + OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH, TRACE, + CONNECT + } + + enum version { VUNKNOWN, V09, V10, V11, V20, V30 } + + set-context: func(req:u32, data:u32); + get-context: func(req:u32) -> u32; + + reject: func(req:u32, status:u32, msg: string) -> s32; + + get-log: func(req:u32) -> s32; + get-method: func(req:u32) -> method; + get-schema: func(req:u32) -> schema; + get-uri: func(req:u32) -> string; + get-version: func(req:u32) -> version; + get-remote-addr: func(req:u32) -> string; + + variable: func(req:u32, key:string) -> string; + + get-header: func(req:u32, key:string) -> string; + get-header-values: func(req:u32, key:string) -> list; + + set-header: func(req:u32, key: string, value:string) -> s32; + set-header-values: func(req:u32, key:string, value: list) -> s32; + + // NEED it? variables are enough? + args-count: func(req:u32) -> u32; + arg-by-index: func(req:u32, index:u32) -> string; + arg-by-key: func(req:u32, key:string) -> string; + + handle-body: func(req:u32, enabled:u8) -> s32; + + read-body: func(req:u32, buf:u32, len:u32) -> s32; + + + set-status: func(req:u32, status:u32) -> s32; + + setup-response: func(req:u32, has-body:u8, body-len: u64) -> s32; + + // NEED IT ? param in response setup? + allow-ranges: func(req:u32); + + write-body: func(req:u32, buf:u32, len:u32) -> s32; + + // NEED it ? auto on close? + finalize: func(req:u32) -> s32; +} + +interface http-filter { + process-stream: func(fd: s32, env-fd:s32) -> s64; +} + +interface http-handler { + handle-request: func(req: s32) -> s32; + + init: func(req:u32) -> s32; + process-request-body: func(req:u32) -> s32; + setup-response: func(req:u32) -> s32; + generate-response: func(req:u32) -> s32; + finalize: func(req:u32) -> s32; +} diff --git a/wasm-baselib/wit/njt_wasi_core.wit b/wasm-baselib/wit/njt_wasi_core.wit new file mode 100644 index 0000000000000000000000000000000000000000..09de697d82b51e11c2518caf503eed109f7f0d49 --- /dev/null +++ b/wasm-baselib/wit/njt_wasi_core.wit @@ -0,0 +1,6 @@ + +// source for src/core/njt_wasi_core.h +world njt-wasi-core { + import host; +} + diff --git a/wasm-baselib/wit/njt_wasi_http.wit b/wasm-baselib/wit/njt_wasi_http.wit new file mode 100644 index 0000000000000000000000000000000000000000..31b0ed7169f16f0816e00b998f2b9b7261f50ead --- /dev/null +++ b/wasm-baselib/wit/njt_wasi_http.wit @@ -0,0 +1,6 @@ + +// source for src/http/njt_wasi_http.h +world njt-wasi-http { + import http-host; +} + diff --git a/wasm-runtime/WAMR-1.3.2.tar.gz b/wasm-runtime/WAMR-1.3.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f1097ef6dae2b3dabdd597049e73e4dfce52f3a6 Binary files /dev/null and b/wasm-runtime/WAMR-1.3.2.tar.gz differ diff --git a/wasm-runtime/wasm-tools-1.217.0-x86_64-linux.tar.gz b/wasm-runtime/wasm-tools-1.217.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8dfce4f026b34aeb8f0ff9c30494611a4b5c2fdf Binary files /dev/null and b/wasm-runtime/wasm-tools-1.217.0-x86_64-linux.tar.gz differ diff --git a/wasm-runtime/wasmtime-v25.0.0-x86_64-linux-c-api.tar.xz b/wasm-runtime/wasmtime-v25.0.0-x86_64-linux-c-api.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..f44e7725801e88fb283223a80e2072fd0102867c Binary files /dev/null and b/wasm-runtime/wasmtime-v25.0.0-x86_64-linux-c-api.tar.xz differ diff --git a/wasm-runtime/wit-bindgen-0.26.0-x86_64-linux.tar.gz b/wasm-runtime/wit-bindgen-0.26.0-x86_64-linux.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c92d4c84c7eb86403e8f9494df28ecaa848831ee Binary files /dev/null and b/wasm-runtime/wit-bindgen-0.26.0-x86_64-linux.tar.gz differ diff --git a/wasm/Dockerfile b/wasm/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9c8a347549e2b2cf0174b2bbd1da9e0983fcd001 --- /dev/null +++ b/wasm/Dockerfile @@ -0,0 +1,47 @@ + +# minimal scenario to build just wasm modules; + +FROM ubuntu:22.04 as builder + +RUN apt-get update \ + && apt-get install wget build-essential -y + +WORKDIR /build + +ARG ARCH=x86_64-linux + +ARG SDK_VER_MAJOR=24 +ARG SDK_VER_MINOR=0 +ARG WTOOLS_VER=1.217.0 +ARG BG_VER=0.26.0 + +ARG SDK=wasi-sdk-${SDK_VER_MAJOR}.${SDK_VER_MINOR}-${ARCH} +ARG WTOOLS=wasm-tools-${WTOOLS_VER}-${ARCH} +ARG BG=wit-bindgen-${BG_VER}-${ARCH} + +RUN wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${SDK_VER_MAJOR}/${SDK}.tar.gz +RUN tar xvf ${SDK}.tar.gz + +RUN wget https://github.com/bytecodealliance/wasm-tools/releases/download/v${WTOOLS_VER}/${WTOOLS}.tar.gz +RUN tar xvf ${WTOOLS}.tar.gz + +RUN wget https://github.com/bytecodealliance/wit-bindgen/releases/download/v${BG_VER}/${BG}.tar.gz +RUN tar xvf ${BG}.tar.gz + +ADD / /build/ + +# rewrite local make.version with actually used +RUN echo "TOOLSDIR=/build" > /build/make.conf +RUN echo "MODULES_DST=/nginx/conf" >> /build/make.conf +RUN echo "SDK=${SDK}" >> /build/make.conf +RUN echo "WASM_TOOLS=${WTOOLS}" >> /build/make.conf +RUN echo "WIT_BINDGEN=${BG}\n" >> /build/make.conf + +RUN make all + +FROM scratch AS result + +COPY --from=builder /build/libnjthost/objs/libnjthost.a / +COPY --from=builder /build/njt-http-vars/objs/njt_http_vars.wasm / +COPY --from=builder /build/njt-http-filter/objs/njt_http_filter.wasm / +COPY --from=builder /build/njt-http-handler/objs/njt_http_handler.wasm / diff --git a/wasm/libnjthost/module.mk b/wasm/libnjthost/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..9e54d74257ecb6e8aab4893984f36afd49673e87 --- /dev/null +++ b/wasm/libnjthost/module.mk @@ -0,0 +1,19 @@ + +DEPS = src/njt_wasi_common.h \ + bindings/njt_host_lib.h + +SRCS = src/njt_wasi_utils.c \ + src/njt_wasi_http_request.c + + +# produces header files used by nginx +$(eval $(call mkbind,njt-wasi-core)) +$(eval $(call mkbind,njt-wasi-http)) + +# build base library to link into wasm modules +$(eval $(call make-static-lib,$(module)/objs/libnjthost.a,$(SRCS),$(DEPS))) + +# build base library as component, just in case +$(eval $(call wasm-component,$(SRCS),$(DEPS),njt-host-lib)) + + diff --git a/wasm/libnjthost/src/njt_wasi_common.h b/wasm/libnjthost/src/njt_wasi_common.h new file mode 100644 index 0000000000000000000000000000000000000000..3300e2f13dc8339fcf650145eaed12708b2382f7 --- /dev/null +++ b/wasm/libnjthost/src/njt_wasi_common.h @@ -0,0 +1,105 @@ + +#ifndef _NJT_WASI_COMMON_INCLUDED_ +#define _NJT_WASI_COMMON_INCLUDED_ + + +#include +#include +#include + +//#include "bindings/njt.h" +#include "bindings/njt_host_lib.h" + +typedef njt_host_lib_string_t njt_string_t; +typedef njt_host_lib_list_string_t njt_list_string_t; + +/* for read/write syscalls */ +#define NJT_WASI_BUF_SIZE 4096 + +/* TBD */ +#define njt_host_alloc(size) cabi_realloc(NULL, 0, sizeof(uint32_t), size) +#define njt_host_nalloc(size) cabi_realloc(NULL, 0, 1, size) + +#define njt_host_declare_str(name, cstr) \ + njt_host_lib_string_t name; \ + name.ptr = (uint8_t *) cstr; \ + name.len = sizeof(cstr) - 1; \ + +#define njt_string_set(s) { (uint8_t *) (s), sizeof(s) -1 } + + +#define NJT_WASI_OK 0 +#define NJT_WASI_ERROR -1 +#define NJT_WASI_AGAIN -2 +#define NJT_WASI_BUSY -3 +#define NJT_WASI_DONE -4 +#define NJT_WASI_DECLINED -5 +#define NJT_WASI_ABORT -6 + +/* shorten auto-generated types */ +typedef exports_njt_wasi_http_request_method_t njt_http_req_method_t; +typedef exports_njt_wasi_http_request_schema_t njt_http_req_schema_t; +typedef exports_njt_wasi_http_request_version_t njt_http_req_version_t; + +/* TBD */ +void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size); + +/* varargs wrapper on syscall */ +void njt_wasi_log_error(int32_t fd, uint8_t level, uint32_t errnum, + char *fmt, ...); + +// TODO: use njet defs + +//int32_t njt_wasi_open_log(njt_log_t *log); + +/* to be implemented by component */ +int32_t njt_wasi_http_handler_init(uint32_t req); +int32_t njt_wasi_http_handler_process_request_body(uint32_t req); +int32_t njt_wasi_http_handler_setup_response(uint32_t req); +int32_t njt_wasi_http_handler_generate_response(uint32_t req); +int32_t njt_wasi_http_handler_finalize(uint32_t req); + + +static inline njt_string_t *njt_wasi_string_dup(njt_string_t *src); +static inline void njt_wasi_string_dup_content(njt_string_t *dst, + njt_string_t *src); + +static inline uint8_t * +njt_wasi_get_stringz(uint8_t *p, uint8_t *end, njt_string_t *res) +{ + res->ptr = p; + + while (p < end) { + if (*p == 0) { + res->len = p - res->ptr; + return ++p; + } + p++; + } + + return NULL; +} + + +static inline njt_string_t * +njt_wasi_string_dup(njt_string_t *src) +{ + njt_string_t *dst; + + dst = malloc(sizeof(njt_string_t)); + njt_wasi_string_dup_content(dst, src); + + return dst; +} + + +static inline void +njt_wasi_string_dup_content(njt_string_t *dst, njt_string_t *src) +{ + dst->ptr = malloc(src->len); + dst->len = src->len; + + memcpy(dst->ptr, src->ptr, src->len); +} + +#endif /* _NJT_WASI_COMMON_INCLUDED_ */ diff --git a/wasm/libnjthost/src/njt_wasi_http_request.c b/wasm/libnjthost/src/njt_wasi_http_request.c new file mode 100644 index 0000000000000000000000000000000000000000..4bbc5aa150144af079fb4210181618b8b4b695d3 --- /dev/null +++ b/wasm/libnjthost/src/njt_wasi_http_request.c @@ -0,0 +1,1243 @@ + +#include +#include + +#include "njt_wasi_common.h" + +#define E(foo) exports_##foo + +// Exported Functions from `njt:wasi/http-handler` +int32_t exports_njt_wasi_http_handler_init(uint32_t req); +int32_t exports_njt_wasi_http_handler_process_request_body(uint32_t req); +int32_t exports_njt_wasi_http_handler_setup_response(uint32_t req); +int32_t exports_njt_wasi_http_handler_generate_response(uint32_t req); +int32_t exports_njt_wasi_http_handler_finalize(uint32_t req); + + +typedef enum { + NJT_WASI_HTTP_REQUEST_STATE_INITIAL, + NJT_WASI_HTTP_REQUEST_STATE_READING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE, + NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS, + NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY, + NJT_WASI_HTTP_REQUEST_STATE_FINALIZED, + NJT_WASI_HTTP_REQUEST_STATE_REJECTED +} njt_wasi_http_req_state_t; + + +typedef struct njt_http_header_s njt_http_header_t; + +struct njt_http_header_s { + njt_string_t key; + njt_string_t value; + njt_http_header_t *next; + njt_http_header_t *next_value; +}; + + +typedef struct { + /* handles for objects on host */ + int32_t handle; + int32_t log; + int32_t body_handle; + int32_t headers_out_handle; + int32_t response_body_handle; + + uint32_t user_ctx; /* attached user data */ + + njt_wasi_http_req_state_t state; /* processing phase */ + njt_string_t reject_msg; + + /* request properties */ + + uint32_t method; + uint32_t version; + njt_http_req_schema_t schema; + + njt_string_t uri; + njt_string_t remote_addr; + + uint32_t nheaders_in; + njt_http_header_t *headers_in; /* array[nheaders_in] */ + + /* response properties */ + + uint32_t status; + uint8_t has_response_body; + uint64_t content_length; + + uint32_t max_kv_len; + njt_http_header_t *headers_out; /* linked list */ + njt_http_header_t **last_header_out; + + off_t response_bytes_sent; + +} njt_http_request_t; + + +static int32_t njt_wasi_http_request_read_headers(njt_http_request_t *r); +static njt_http_header_t *njt_wasi_http_request_find_request_header( + njt_http_request_t *r, njt_string_t *key, size_t *count, size_t *rlen); +static njt_http_header_t *njt_wasi_http_request_find_response_header( + njt_http_request_t *r, njt_string_t *key); +static void njt_wasi_http_request_delete_response_header_values( + njt_http_header_t *header); +static int32_t njt_wasi_http_request_list_to_reponse_headers( + njt_http_header_t *head, njt_list_string_t *values); + +static int32_t njt_wasi_http_final_response_setup(njt_http_request_t *r); +static int32_t njt_wasi_http_request_send_headers(njt_http_request_t *r); +static int32_t njt_wasi_http_response_body_finalize(uint32_t req); + + +static njt_http_request_t * +njt_wasi_http_request_get(int32_t rhandle, int32_t log_fd) +{ + int32_t rc; + uint32_t meta[NJT_WASI_HTTP_HOST_REQUEST_META_LAST]; + njt_http_request_t *r; + + rc = njt_wasi_syscall_get(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_META, + (uintptr_t) meta, sizeof(meta)); + if (rc < 0) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request meta"); + return NULL; + } + + if (meta[NJT_WASI_HTTP_HOST_REQUEST_META_CTX] != 0) { + return (njt_http_request_t *) meta[NJT_WASI_HTTP_HOST_REQUEST_META_CTX]; + } + + r = malloc(sizeof(njt_http_request_t)); + + memset(r, 0, sizeof(njt_http_request_t)); + + r->log = log_fd; + r->handle = rhandle; + r->body_handle = -1; + r->headers_out_handle = -1; + r->content_length = (uint64_t) -1; + r->status = 200; + + r->state = NJT_WASI_HTTP_REQUEST_STATE_INITIAL; + + r->method = meta[NJT_WASI_HTTP_HOST_REQUEST_META_METHOD]; + r->schema = meta[NJT_WASI_HTTP_HOST_REQUEST_META_SCHEMA]; + r->version = meta[NJT_WASI_HTTP_HOST_REQUEST_META_VERSION]; + + r->nheaders_in = meta[NJT_WASI_HTTP_HOST_REQUEST_META_HEADER_COUNT]; + + r->uri.len = meta[NJT_WASI_HTTP_HOST_REQUEST_META_URI_LEN]; + r->remote_addr.len = meta[NJT_WASI_HTTP_HOST_REQUEST_META_ADDR_LEN]; + + r->uri.ptr = malloc(r->uri.len); + r->remote_addr.ptr = malloc(r->remote_addr.len); + + rc = njt_wasi_syscall_get(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_URI, + (uintptr_t) r->uri.ptr, r->uri.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request uri"); + return NULL; + } + + rc = njt_wasi_syscall_get(rhandle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_REMOTE_ADDR, + (uintptr_t) r->remote_addr.ptr, + r->remote_addr.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to get request remote_addr"); + return NULL; + } + + rc = njt_wasi_syscall_set(rhandle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_SELF, + (uintptr_t) &r, sizeof(uint32_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set request context"); + return NULL; + } + + if (njt_wasi_http_request_read_headers(r) != NJT_WASI_OK) { + return NULL; + } + + return r; +} + +int32_t +exports_njt_wasi_http_request_get_log(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->log; +} + + +njt_http_req_method_t +exports_njt_wasi_http_request_get_method(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + /* see njet/src/http/njt_http_request.h */ + switch (r->method) { + case 0x00000002: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_GET; + case 0x00000004: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_HEAD; + case 0x00000008: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_POST; + case 0x00000010: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PUT; + case 0x00000020: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_DELETE; + case 0x00000040: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_MKCOL; + case 0x00000080L: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_COPY; + case 0x00000100L: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_MOVE; + case 0x00000200: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_OPTIONS; + case 0x00000400: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PROPFIND; + case 0x00000800: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PROPPATCH; + case 0x00001000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_LOCK; + case 0x00002000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_UNLOCK; + case 0x00004000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_PATCH; + case 0x00008000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_TRACE; + case 0x00010000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_CONNECT; + default: + return EXPORTS_NJT_WASI_HTTP_REQUEST_METHOD_UNKNOWN; + } + + return r->method; +} + + +njt_http_req_schema_t +exports_njt_wasi_http_request_get_schema(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->schema; +} + + +njt_http_req_version_t +exports_njt_wasi_http_request_get_version(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + switch (r->version) { + case 9: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V09; + case 1000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V10; + case 1001: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V11; + case 2000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V20; + case 3000: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_V30; + default: + return EXPORTS_NJT_WASI_HTTP_REQUEST_VERSION_VUNKNOWN; + } +} + + +void +exports_njt_wasi_http_request_get_uri(uint32_t req, njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + *ret = r->uri; +} + + +void +exports_njt_wasi_http_request_get_remote_addr(uint32_t req, + njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + *ret = r->remote_addr; +} + + +int32_t +exports_njt_wasi_http_request_handle_body(uint32_t req, uint8_t enabled) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc, fd; + uint8_t on; + + if (!enabled) { + + on = 1; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_DISCARD_BODY, + (uintptr_t) &on, sizeof(uint8_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to discard body"); + return NJT_WASI_ERROR; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE; + + return NJT_WASI_OK; + } + + fd = r->body_handle; + + if (fd < 0) { + + njt_host_declare_str(bname, "njt::http::request::body"); + + fd = njt_wasi_syscall_open(&bname, r->handle); + + if (fd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, fd, + "failed to open request body"); + return NJT_WASI_ERROR; + } + + r->body_handle = fd; + r->state = NJT_WASI_HTTP_REQUEST_STATE_READING_BODY; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_read_body(uint32_t req, uint32_t buf, + uint32_t len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + ssize_t n; + + if (r->body_handle < 0) { + return NJT_WASI_ERROR; + } + + n = njt_wasi_syscall_read(r->body_handle, (uintptr_t) buf, len); + + if (n < 0) { + return n; + } + + if (n == 0) { + r->state = NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE; + } + + return n; +} + + +void +exports_njt_wasi_http_request_variable(uint32_t req, njt_string_t *key, + njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t n; + + uint32_t args[4]; + + args[0] = key->len; + args[1] = (uintptr_t) key->ptr; + args[2] = 0; + args[3] = 0; + + n = njt_wasi_syscall_get(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR, + (uintptr_t) args, sizeof(args)); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, + "failed to get request variable length"); + goto failed; + } + + ret->len = n; + ret->ptr = malloc(n); + + args[2] = n; + args[3] = (uintptr_t) ret->ptr; + + n = njt_wasi_syscall_get(r->handle, NJT_WASI_HTTP_HOST_REQUEST_PROPS_VAR, + (uintptr_t) args, sizeof(args)); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, + "failed to get request variable"); + goto failed; + } + + return; + +failed: + + ret->ptr = NULL; + ret->len = 0; +} + + +void +exports_njt_wasi_http_request_get_header(uint32_t req, + njt_string_t *key, njt_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + size_t n, len; + uint8_t *p; + njt_http_header_t *h; + + h = njt_wasi_http_request_find_request_header(r, key, &n, &len); + + if (h == NULL) { + ret->ptr = NULL; + ret->len = 0; + return; + } + + if (h->next == NULL) { + ret->ptr = h->value.ptr; + ret->len = h->value.len; + return; + } + + p = malloc(len); + ret->ptr = p; + + for ( ;; ) { + + memcpy(p, h->value.ptr, h->value.len); + p += h->value.len; + + if (h->next == NULL) { + break; + } + + *p++ = ','; *p++ = ' '; + + h = h->next; + } + + ret->len = len; +} + + +void +exports_njt_wasi_http_request_get_header_values(uint32_t req, + njt_string_t *key, njt_list_string_t *ret) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + size_t n, len; + uint32_t i; + njt_string_t *out; + njt_http_header_t *h; + + h = njt_wasi_http_request_find_request_header(r, key, &n, &len); + + if (h == NULL) { + ret->ptr = NULL; + ret->len = 0; + return; + } + + out = malloc(sizeof(njt_string_t) * n); + + ret->ptr = out; + ret->len = n; + + + for (i = 0; ; i++) { + + out[i].ptr = h->value.ptr; + out[i].len = h->value.len; + + if (h->next == NULL) { + break; + } + + h = h->next; + } +} + + +uint32_t +exports_njt_wasi_http_request_args_count(uint32_t req) +{ + // TBD + return 0; +} + +void +exports_njt_wasi_http_request_arg_by_index(uint32_t req, uint32_t index, + njt_string_t *ret) +{ + // TBD +} + + +void +exports_njt_wasi_http_request_arg_by_key(uint32_t req, njt_string_t *key, + njt_string_t *ret) +{ + // TBD +} + + +void +exports_njt_wasi_http_request_allow_ranges(uint32_t req) +{ + // TBD +} + +int32_t +exports_njt_wasi_http_request_set_header(uint32_t req, njt_string_t *key, + njt_string_t *value) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + njt_string_t dup; + njt_http_header_t *h; + + if (r->max_kv_len < (key->len + value->len)) { + r->max_kv_len = key->len + value->len; + } + + njt_wasi_string_dup_content(&dup, value); + + h = njt_wasi_http_request_find_response_header(r, key); + + if (h) { + njt_wasi_http_request_delete_response_header_values(h); + h->value = dup; + + return NJT_WASI_OK; + } + + h = malloc(sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->key, key); + h->value = dup; + h->next = NULL; + h->next_value = NULL; + + if (r->last_header_out) { + *r->last_header_out = h; + + } else { + r->headers_out = h; + } + + r->last_header_out = &h->next; + + return NJT_WASI_OK; +} + + +static void +njt_wasi_http_request_delete_response_header_values(njt_http_header_t *header) +{ + njt_http_header_t *h, *next; + + h = header->next_value; + + while (h) { + free(h->key.ptr); + free(h->value.ptr); + next = h->next_value; + free(h); + h = next; + } + + free(header->value.ptr); + header->next_value = NULL; +} + + +static int32_t +njt_wasi_http_request_list_to_reponse_headers(njt_http_header_t *head, + njt_list_string_t *values) +{ + uint32_t i; + njt_string_t *str_values; + njt_http_header_t *h; + + str_values = values->ptr; + + njt_wasi_string_dup_content(&head->value, &str_values[0]); + head->next_value = NULL; + + for (i = 1; i < values->len; i++) { + + h = malloc(sizeof(njt_http_header_t)); + memset(h, 0, sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->value, &str_values[i]); + + head->next_value = h; + head = h; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_set_header_values(uint32_t req, + njt_string_t *key, njt_list_string_t *values) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc, found; + uint32_t i; + njt_string_t *str_values; + njt_http_header_t *h; + + if (values->len == 0) { + return NJT_WASI_ERROR; + } + + found = 0; + + h = njt_wasi_http_request_find_response_header(r, key); + + if (h) { + njt_wasi_http_request_delete_response_header_values(h); + found = 1; + + } else { + + h = malloc(sizeof(njt_http_header_t)); + memset(h, 0, sizeof(njt_http_header_t)); + + njt_wasi_string_dup_content(&h->key, key); + } + + rc = njt_wasi_http_request_list_to_reponse_headers(h, values); + if (rc != NJT_WASI_OK) { + return rc; + } + + str_values = values->ptr; + + for (i = 0; i < values->len; i++) { + if (r->max_kv_len < (key->len + str_values[i].len)) { + r->max_kv_len = key->len + str_values[i].len; + } + } + + if (found) { + return NJT_WASI_OK; + } + + if (r->last_header_out) { + *r->last_header_out = h; + + } else { + r->headers_out = h; + } + + r->last_header_out = &h->next; + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_set_status(uint32_t req, uint32_t status) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + if (status > 999) { + return NJT_WASI_ERROR; + } + + r->status = status; + + return NJT_WASI_OK; +} + + + +int32_t +exports_njt_wasi_http_request_setup_response(uint32_t req, uint8_t has_body, + uint64_t body_len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + uint8_t on; + int32_t rc; + + r->has_response_body = has_body; + + on = has_body ? 0 : 1; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_HEADER_ONLY, + (uintptr_t) &on, sizeof(uint8_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response header only state"); + return NJT_WASI_ERROR; + } + + njt_host_declare_str(bname, "njt::http::response::body"); + + rc = njt_wasi_syscall_open(&bname, r->handle); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to open response body"); + return NJT_WASI_ERROR; + } + + r->response_body_handle = rc; + + if (body_len == (uint64_t) -1) { + /* chunked encoding by default */ + return NJT_WASI_OK; + } + + r->content_length = body_len; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_CONTENT_LENGTH, + (uintptr_t) &body_len, sizeof(uint64_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response content length"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +int32_t +exports_njt_wasi_http_request_write_body(uint32_t req, uint32_t buf, + uint32_t len) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + ssize_t n; + + if (r->response_body_handle == -1) { + return NJT_WASI_ERROR; + } + + n = njt_wasi_syscall_write(r->response_body_handle, buf, len); + if (n < 0) { + return n; + } + + r->response_bytes_sent += n; + + return n; +} + + +int32_t +exports_njt_wasi_http_request_reject(uint32_t req, uint32_t status, + njt_string_t *msg) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + + if (status > 999) { + return NJT_WASI_ERROR; + } + + r->status = status; + + njt_wasi_string_dup_content(&r->reject_msg, msg); + + r->state = NJT_WASI_HTTP_REQUEST_STATE_REJECTED; + + return njt_wasi_http_final_response_setup(r); +} + + +int32_t +exports_njt_wasi_http_request_finalize(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + int32_t rc; + + if (r->state == NJT_WASI_HTTP_REQUEST_STATE_REJECTED) { + // special code to avoid syscall errors to ensure request will be rejected + return NJT_WASI_DECLINED; + } + + // good request finalization + + rc = njt_wasi_syscall_close(r->handle); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, "close request"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_final_response_setup(njt_http_request_t *r) +{ + int32_t rc; + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_STATUS, + (uintptr_t) &r->status, sizeof(uint32_t)); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set response status"); + return NJT_WASI_ERROR; + } + + if (r->state == NJT_WASI_HTTP_REQUEST_STATE_REJECTED) { + + // XXX: r->reject_msg.len = 0 + + rc = njt_wasi_syscall_set(r->handle, + NJT_WASI_HTTP_HOST_REQUEST_PROPS_REJECT_MSG, + (uintptr_t) r->reject_msg.ptr, + r->reject_msg.len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "failed to set reject message"); + return NJT_WASI_ERROR; + } + } + + return NJT_WASI_OK; +} + +static int32_t +njt_wasi_http_request_write_header(njt_http_request_t *r, int32_t hd, + uint8_t *b, njt_string_t *k, njt_string_t *v) +{ + uint8_t *p; + int32_t rc; + size_t len; + + len = k->len + v->len + 2; + + p = b; + + memcpy(p, (char *) k->ptr, k->len); + p += k->len; + + *p++ = 0; + + memcpy(p, (char *) v->ptr, v->len); + p += v->len; + + *p++ = 0; + + rc = njt_wasi_syscall_write(hd, (uintptr_t) b, len); + if (rc < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, rc, + "write response headers"); + return NJT_WASI_ERROR; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_request_send_headers(njt_http_request_t *r) +{ + uint8_t *buf; + int32_t hd, rc; + njt_http_header_t *h, *mh; + + hd = r->headers_out_handle; + + if (hd == -1) { + + njt_host_declare_str(hname, "njt::http::response::headers"); + + hd = njt_wasi_syscall_open(&hname, r->handle); + if (hd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, hd, + "open response headers"); + return NJT_WASI_ERROR; + } + + buf = malloc(r->max_kv_len + 2); + + for (h = r->headers_out; h; h = h->next) { + + rc = njt_wasi_http_request_write_header(r, hd, buf, + &h->key, &h->value); + if (rc < 0) { + free(buf); + return NJT_WASI_ERROR; + } + + for (mh = h->next_value; mh; mh = mh->next_value) { + rc = njt_wasi_http_request_write_header(r, hd, buf, &h->key, + &mh->value); + if (rc < 0) { + free(buf); + return NJT_WASI_ERROR; + } + } + } + + free(buf); + + r->headers_out_handle = hd; + } + + /* + * closing response headers will trigger actual send by njet, + * so we can get AGAIN here + */ + rc = njt_wasi_syscall_close(hd); + if (rc < 0) { + return rc; + } + + /* got OK - headers sent */ + + if (r->has_response_body) { + r->state = NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY; + + } else { + r->state = NJT_WASI_HTTP_REQUEST_STATE_FINALIZED; + } + + return NJT_WASI_OK; +} + + +static int32_t +njt_wasi_http_response_body_finalize(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return njt_wasi_syscall_close(r->response_body_handle); +} + + +/* helper functions */ + +static int32_t +njt_wasi_http_request_read_headers(njt_http_request_t *r) +{ + ssize_t n; + uint8_t *p, *end; + int32_t hd; + uint32_t i; + uint8_t hbuf[NJT_WASI_BUF_SIZE]; + njt_string_t k, v; + + r->headers_in = malloc(sizeof(njt_http_header_t) * r->nheaders_in); + + njt_host_declare_str(hname, "njt::http::request::headers"); + + hd = njt_wasi_syscall_open(&hname, r->handle); + + if (hd < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, hd, + "open request headers"); + return NJT_WASI_ERROR; + } + + i = 0; + + do { + n = njt_wasi_syscall_read(hd, (uintptr_t) hbuf, NJT_WASI_BUF_SIZE); + if (n < 0) { + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_ERR, n, "read headers"); + goto failed; + } + + p = hbuf; + end = hbuf + n; + + while (p < end) { + + p = njt_wasi_get_stringz(p, end, &k); + if (p == NULL) { + goto failed; + } + + p = njt_wasi_get_stringz(p, end, &v); + if (p == NULL) { + goto failed; + } + + if (i == r->nheaders_in) { + goto failed; + } + + njt_wasi_string_dup_content(&r->headers_in[i].key, &k); + njt_wasi_string_dup_content(&r->headers_in[i].value, &v); + + r->headers_in[i].next = NULL; + + i++; + } + + } while (n); + + (void) njt_wasi_syscall_close(hd); + + return NJT_WASI_OK; + +failed: + + (void) njt_wasi_syscall_close(hd); + return NJT_WASI_ERROR; +} + + +static inline uint32_t +njt_wasi_header_key_match(njt_string_t *key, njt_string_t *item) +{ + uint8_t ch; + uint32_t n; + + + if (item->len != key->len) { + return 0; + } + + for (n = 0; n < key->len; n++) { + ch = item->ptr[n]; + + if (ch >= 'A' && ch <= 'Z') { + ch |= 0x20; + + } else if (ch == '-') { +// ch = '_'; // XXX: WTF? // XXX + ch = '-'; + } + + if (key->ptr[n] != ch) { + return 0; + } + } + + if (n != key->len) { + return 0; + } + + return 1; +} + + +static njt_http_header_t * +njt_wasi_http_request_find_request_header(njt_http_request_t *r, + njt_string_t *key, size_t *rcount, size_t *rlen) +{ + size_t len, count; + uint32_t i; + njt_http_header_t *h, **ph; + + + count = 0; + len = 0; + ph = &h; + + for (i = 0; i < r->nheaders_in; i++) { + + if (!njt_wasi_header_key_match(key, &r->headers_in[i].key)) { + continue; + } + + len += r->headers_in[i].value.len + 2; + count++; + + *ph = &r->headers_in[i]; + ph = &r->headers_in[i].next; + } + + *ph = NULL; + + if (h == NULL) { + return NULL; + } + + len -= 2; + + *rlen = len; + *rcount = count; + + return h; +} + + +static njt_http_header_t * +njt_wasi_http_request_find_response_header(njt_http_request_t *r, + njt_string_t *key) +{ + njt_http_header_t *h; + + for (h = r->headers_out; h; h = h->next) { + + if (!njt_wasi_header_key_match(&h->key, key)) { + continue; + } + + return h; + } + + return NULL; +} + + +void +exports_njt_wasi_http_request_set_context(uint32_t req, uint32_t data) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + r->user_ctx = data; +} + + +uint32_t +exports_njt_wasi_http_request_get_context(uint32_t req) +{ + njt_http_request_t *r = (njt_http_request_t *) req; + + return r->user_ctx; +} + + +int32_t +exports_njt_wasi_http_handler_handle_request(int32_t fd) +{ + int32_t rc, log_fd, rfd; + uintptr_t req; + njt_http_request_t *r; + + njt_host_declare_str(rname, "njt::http::request"); + rfd = njt_wasi_syscall_open(&rname, fd); + if (rfd < 0) { + return NJT_WASI_ERROR; + } + + njt_host_declare_str(logname, "njt::core::log"); // host log + log_fd = njt_wasi_syscall_open(&logname, -1); + if (log_fd < 0) { + return NJT_WASI_ERROR; + } + + r = njt_wasi_http_request_get(rfd, log_fd); + if (r == NULL) { + return NJT_WASI_ERROR; + } + + req = (uintptr_t) r; + + for ( ;; ) { + + njt_wasi_log_error(r->log, NJT_WASI_HOST_LL_DEBUG, 0, + "wasm http state: %d", (uint32_t) r->state); + + switch (r->state) { + + case NJT_WASI_HTTP_REQUEST_STATE_INITIAL: + + if (E(njt_wasi_http_handler_init)(req) < 0) { + return NJT_WASI_ERROR; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_READING_BODY: + + rc = E(njt_wasi_http_handler_process_request_body)(req); + if (rc < 0) { + return rc; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SETUP_RESPONSE: + + rc = E(njt_wasi_http_handler_setup_response(req)); + if (rc < 0) { + return rc; + } + + rc = njt_wasi_http_final_response_setup(r); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SENDING_HEADERS: + + rc = njt_wasi_http_request_send_headers(r); + if (rc < 0) { + return rc; + } + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_GENERATING_BODY: + + rc = E(njt_wasi_http_handler_generate_response)(req); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_SENDING_BODY: + + rc = njt_wasi_http_response_body_finalize(req); + if (rc < 0) { + return rc; + } + + r->state = NJT_WASI_HTTP_REQUEST_STATE_FINALIZED; + + continue; + + case NJT_WASI_HTTP_REQUEST_STATE_REJECTED: + goto done; + + case NJT_WASI_HTTP_REQUEST_STATE_FINALIZED: + + rc = E(njt_wasi_http_handler_finalize)(req); + if (rc < 0) { + return rc; + } + + goto done; + } + } + +done: + + return exports_njt_wasi_http_request_finalize(req); +} diff --git a/wasm/libnjthost/src/njt_wasi_utils.c b/wasm/libnjthost/src/njt_wasi_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..d00ac8811b660a5f3e21c46f95e594cecd44de58 --- /dev/null +++ b/wasm/libnjthost/src/njt_wasi_utils.c @@ -0,0 +1,398 @@ + +#include +#include +#include + +#include "njt_wasi_common.h" + + +#define NJT_HOST_MAX_ERR 2048 + + +static char *njt_errmsg(int32_t err); + + +static char *njt_errors[] = { + "", + "internal error", + "again", + "busy", + "done", + "declined", + "abort", +}; + + +static char * +njt_errmsg(int32_t err) +{ + size_t len; + + len = sizeof(njt_errors) / sizeof(njt_errors[0]); + + if (err >= 0) { + return ""; + } + + err = -err; + + if (err > (len - 1)) { + return "Unknown error"; + } + + return njt_errors[err]; +} + + +uint8_t * +njt_wasi_parse_int(uint8_t *pos, uint8_t *end, uint64_t *out) +{ + uint8_t *p; + uint64_t value; + uint64_t len; + + if (pos >= end) { + return NULL; + } + + p = pos; + len = 1 << (*p >> 6); + + value = *p++ & 0x3f; + + if ((size_t)(end - p) < (len - 1)) { + return NULL; + } + + while (--len) { + value = (value << 8) + *p++; + } + + *out = value; + + return p; +} + + +void +njt_wasi_log_error(int32_t fd, uint8_t level, uint32_t errnum, char *fmt, ...) +{ + int n; + char *p; + size_t left; + va_list ap; + njt_string_t emsg; + + char buf[NJT_HOST_MAX_ERR]; + + p = buf; + left = NJT_HOST_MAX_ERR; + + /* pass log level in 1st byte of message */ + *p++ = level; + left--; + + va_start(ap, fmt); + n = vsnprintf(p, left, fmt, ap); + va_end(ap); + + if (n < 0) { + return; + } + + p += n; + left -= n; + + if (errnum) { + exports_njt_wasi_utils_strerror(errnum, &emsg); + + n = snprintf((char *) p, left, " (%.*s)", (int) emsg.len, emsg.ptr); + if (n < 0) { + abort(); + } + p += n; + left -= n; + } + + (void) njt_wasi_syscall_write(fd, (uintptr_t) buf, p - buf); +} + + +void +exports_njt_wasi_utils_strerror(int32_t errnum, njt_string_t *ret) +{ + char *e; + + e = njt_errmsg(errnum); + + ret->ptr = (uint8_t *) e; + ret->len = strlen(e); +} + + +int32_t +exports_njt_wasi_utils_list_alloc(int32_t fd, uint32_t nargs, + uint32_t size, uint32_t oldmem, uint32_t oldmem_size, uint32_t old_result, + int32_t log_fd) +{ + void *mem, *omem; + uint8_t *buf, *p, *end; + ssize_t n, len; + uint32_t i; + njt_string_t tmp, *items; + + len = sizeof(njt_string_t) * nargs + size + nargs; + + omem = (void *) oldmem; + + if (oldmem_size < len) { + free(omem); + omem = NULL; + } + + if (old_result) { + free((void *) old_result); + } + + if (omem) { + mem = omem; + + } else { + mem = njt_host_alloc(len); + } + + items = mem; + + buf = mem + sizeof(njt_string_t) * nargs; + + n = njt_wasi_syscall_read(fd, (uintptr_t) buf, size + nargs); + if (n < 0) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, n, "read vars"); + return -1; + } + + // XXX: what should read() return: actual bytes (including sep?) + if (n != nargs) { + // XXX: FREE ON ERR ? + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "read failed: got %d expected %d", n,nargs); + return -1; + } + + p = buf; + end = buf + size + nargs; + i = 0; + + while (p < end) { + + p = njt_wasi_get_stringz(p, end, &tmp); + if (p == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, n, + "read vars format error"); + abort(); + } + //printf("GOT STRING: %.*s\n", (int)tmp.len, tmp.ptr); + + if (i >= nargs) { + break; + } + + items[i++] = tmp; + } + + // XXX: handle NULL return on host + return (uintptr_t) mem; +} + + +void +exports_njt_wasi_utils_log_error(int32_t fd, uint8_t level, int32_t errnum, + njt_string_t *msg) +{ + njt_wasi_log_error(fd, level, errnum, "%.*s", (int) msg->len, msg->ptr); +} + + +bool +exports_njt_wasi_utils_get_env(int32_t env_fd, int32_t log_fd, + exports_njt_wasi_utils_list_keyval_t *ret, int32_t *err) +{ + exports_njt_wasi_utils_keyval_t *kvs; + + uint8_t *vp, *end, *kd, *vd, *kdp, *vdp, *kdp_end, *vdp_end; + int32_t fd, n, left, k; + uint32_t sizes[3]; + uint64_t varint, curr_len; + + uint8_t ebuf[4096]; + + enum { + st_key_len, + st_key, + st_data_len, + st_data + } state; + + njt_string_t opname = njt_string_set("njt::call_env"); + fd = njt_wasi_syscall_open(&opname, env_fd); + if (fd < 0) { + *err = fd; + return false; + } + + n = njt_wasi_syscall_get(fd, 0, (uint32_t) sizes, sizeof(sizes)); + if (n < 0 || n != sizeof(sizes)) { + *err = -1; + return false; + } + + kvs = njt_host_alloc(sizeof(exports_njt_wasi_utils_keyval_t) * sizes[0] + + sizes[1] + sizes[2]); + + kd = (uint8_t *) kvs + + sizeof(exports_njt_wasi_utils_keyval_t) * sizes[0]; + vd = kd + sizes[1]; + + + + ret->len = sizes[0]; + ret->ptr = kvs; + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "========================size0:%d len:%d", sizes[0], ret->len); + kdp = kd; kdp_end = kdp + sizes[1]; + vdp = vd; vdp_end = vdp + sizes[2]; + + curr_len = 0; + + state = 0; + k = 0; + + do { + n = njt_wasi_syscall_read(fd, (uint32_t)ebuf, sizeof(ebuf)); + if (n < 0) { + *err = n; + return false; + } + + if (n == 0) { + break; + } + + vp = ebuf; + end = ebuf + n; + + while (vp < end) { + + switch (state) { + case st_key_len: + vp = njt_wasi_parse_int(vp, end, &varint); + if (vp == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "truncated key len"); + *err = -1; + return false; + } + curr_len = varint; + + kvs[k].key.len = varint; + kvs[k].key.ptr = kdp; + + /* fall through */ + + case st_key: + + left = end - vp; + + if (left < curr_len) { + + if (kdp + left > kdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(kdp, vp, left); + kdp += left; + + vp += left; + curr_len -= left; + break; + + } else { + if (kdp + curr_len > kdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(kdp, vp, curr_len); + kdp += curr_len; + vp += curr_len; + } + + /* fall through */ + + case st_data_len: + + vp = njt_wasi_parse_int(vp, end, &varint); + if (vp == NULL) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "truncated key len"); + *err = -1; + return false; + } + curr_len = varint; + + kvs[k].value.len = varint; + kvs[k].value.ptr = vdp; + + /* fall through */ + + case st_data: + left = end - vp; + + if (left < curr_len) { + if (vdp + left > vdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(vdp, vp, left); + vdp += left; + vp += left; + curr_len -= left; + break; + + } else { + if (vdp + curr_len > vdp_end) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "buffer size does not match"); + *err = -1; + return false; + } + + memcpy(vdp, vp, curr_len); + vdp += curr_len; + vp += curr_len; + } + + k++; + } + } + + } while (n > 0); + + if (k != sizes[0]) { + njt_wasi_log_error(log_fd, NJT_WASI_HOST_LL_ERR, 0, + "env count does not match: found %u expected %u", + sizes[0], k); + *err = -1; + return false; + } + + return true; +} diff --git a/wasm/make.conf b/wasm/make.conf new file mode 100644 index 0000000000000000000000000000000000000000..6c6f85c223fc88d596e42cb348a168ee9aa0711d --- /dev/null +++ b/wasm/make.conf @@ -0,0 +1,5 @@ +TOOLSDIR=../ +SDK=wasi-sdk-24.0-x86_64-linux +WASM_TOOLS=wasm-tools-1.217.0-x86_64-linux +WIT_BINDGEN=wit-bindgen-0.26.0-x86_64-linux +MODULES_DST=/njet/conf diff --git a/wasm/makefile b/wasm/makefile new file mode 100644 index 0000000000000000000000000000000000000000..494bfc08b4771267166d951fa976153e2f76fabf --- /dev/null +++ b/wasm/makefile @@ -0,0 +1,35 @@ +include make.conf +include rules.mk + +all: results + +parts = libnjthost \ + njt-http-vars \ + njt-http-filter \ + njt-http-handler + +modules := +targets := +clean-objs := + +$(foreach p,$(parts),$(shell mkdir -p $p/objs $p/bindings)) +$(foreach p,$(parts),$(eval include $p/module.mk)) +$(foreach p,$(parts),$(eval clean_objs += $p/objs $p/bindings)) + + +results: $(targets) + +install: results + @install -v $(modules) $(MODULES_DST) + +clean: + @rm -rf $(clean_objs) + + +PROGRESS= +PROGRESS=--progress=plain + +docker: + docker build $(PROGRESS) . -t wasm-examples + +.PHONY: install clean docker diff --git a/wasm/njt-http-filter/module.mk b/wasm/njt-http-filter/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..a15b4822a16cf72c69931063b0181911130503a1 --- /dev/null +++ b/wasm/njt-http-filter/module.mk @@ -0,0 +1,5 @@ + +SRCS=src/main.c +DEPS= + +$(eval $(call wasm-component,$(SRCS),$(DEPS),njt-http-filter)) diff --git a/wasm/njt-http-filter/src/main.c b/wasm/njt-http-filter/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..8b1fedab69dbfa16911879cef71d1c0736613bb3 --- /dev/null +++ b/wasm/njt-http-filter/src/main.c @@ -0,0 +1,123 @@ + +/* EXAMPLE HTTP HANDLER */ + +#include +#include +#include +#include + +#include "bindings/njt_http_filter.h" /* auto-generated from WIT */ + + +#define njt_string_set(s) { (uint8_t *) (s), sizeof(s) -1 } + + +/* each world produces own string type; just typedef them for convenience */ +typedef njt_http_filter_string_t njt_string_t; +typedef exports_njt_wasi_utils_keyval_t njt_wasi_utils_keyval_t; +typedef exports_njt_wasi_utils_list_keyval_t njt_wasi_utils_list_keyval_t; + +int64_t +exports_njt_wasi_http_filter_process_stream(int32_t ctx_fd, int32_t env_fd) +{ + int32_t n, left, fd, err; + uint32_t i; + int64_t rc, total; + uint8_t buf[4096], *p, find, replace; + + if (env_fd == -1) { + printf("must have params\n"); + return -1; + } + + njt_wasi_utils_keyval_t *kvs; + njt_wasi_utils_list_keyval_t env; + + if (!exports_njt_wasi_utils_get_env(env_fd, -1, &env, &err)) { + printf("get env err:%d\n", err); + return err; + } + + kvs = env.ptr; + + if (env.len < 2) { + printf("need args\n"); + return -1; + } + + if (kvs[0].value.len < 1) { + printf("bad flen\n"); + return -1; + } + + if (kvs[1].value.len < 1) { + printf("bad rlen\n"); + return -1; + } + + find = kvs[0].value.ptr[0]; + replace = kvs[1].value.ptr[0]; + + for (i = 0; i < env.len; i++) { + printf("%.*s = %.*s\n", (int) kvs[i].key.len, kvs[i].key.ptr, + (int) kvs[i].value.len, kvs[i].value.ptr); + } + + total = 0; + + njt_string_t opname = njt_string_set("njt::filter"); + fd = njt_wasi_syscall_open(&opname, ctx_fd); + if (fd < 0) { + printf("bad filter fd\n"); + return fd; + } + + for (;;) { + + n = njt_wasi_syscall_read(fd, (uint32_t) buf, sizeof(buf)); + if (n < 0) { + rc = n; + goto done; + } + + if (n == 0) { + break; + } + printf("===n:%d find:%c replace:%c fd:%d\n", n, find,replace, fd); + + /* filter payload: charachter replace */ + for (i = 0; i < n; i++) { + printf("=================buf[i]:%c \n", buf[i]); + if (buf[i] == find) { + buf[i] = replace; + + printf("=================place \n"); + } + } + + left = n; + total += n; + p = buf; + + while (left > 0) { +printf("=================left:%d \n", left); + n = njt_wasi_syscall_write(fd, (uint32_t) p, left); +printf("=================left:%d n:%d\n", left, n); + if (n < 0) { + rc = n; + goto done; + } + + p += (uint32_t) n; + left -= n; + } + } + + rc = total; + +done: + + (void) njt_wasi_syscall_close(fd); + + return rc; +} diff --git a/wasm/njt-http-handler/module.mk b/wasm/njt-http-handler/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..c41e4241abeaa757f3b5d580664c8a3a6740e349 --- /dev/null +++ b/wasm/njt-http-handler/module.mk @@ -0,0 +1,5 @@ + +SRCS=src/main.c +DEPS= + +$(eval $(call wasm-component,$(SRCS),$(DEPS),njt-http-handler)) diff --git a/wasm/njt-http-handler/src/main.c b/wasm/njt-http-handler/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..9fb5624d37a65cdc7a32e4498b07a0080216c01a --- /dev/null +++ b/wasm/njt-http-handler/src/main.c @@ -0,0 +1,435 @@ + +/* EXAMPLE HTTP HANDLER */ + +#include +#include +#include +#include + +#include "bindings/njt_http_handler.h" /* auto-generated from WIT */ + +/* + * macros to wrap exported/imported WIT symbols; to be removed at the end; + * this is useful when WIT files organisation change and lead to different + * prefixes of C functions; macros allows to avoid massive renames in such case + */ +#define E(foo) exports_##foo +#define EE(foo) EXPORTS_##foo + +#define njt_string_set(s) { (uint8_t *) (s), sizeof(s) -1 } + + +/* buffer size to use for read/write */ +#define RWBUF 4096 + + +/* each world produces own string type; just typedef them for convenience */ +typedef njt_http_handler_string_t njt_string_t; +typedef njt_http_handler_list_string_t njt_list_string_t; + + +/* state of our request handler */ +typedef struct { + char *buf; + char *last; + char *pos; + uint32_t recv_body; + uint32_t send_body; + uint32_t chunked; +} test_ctx_t; + + +static void +out_json_int(test_ctx_t *ctx, const char *name, int value, int comma) +{ + ctx->last += sprintf(ctx->last, "\"%s\": %d%s", name, value, + comma ? "," : ""); +} + + +static void +out_json_text(test_ctx_t *ctx, size_t len, char *s) +{ + /* this not a real json escape: just enough for tests */ + + uint32_t i; + + for (i = 0; i < len; i++) { + switch (s[i]) { + case '"': + ctx->last += sprintf(ctx->last, "%s", "\\\""); + break; + case '\\': + ctx->last += sprintf(ctx->last, "%s", "\\\\"); + break; + case '\b': + ctx->last += sprintf(ctx->last, "%s", "\\b"); + break; + case '\t': + ctx->last += sprintf(ctx->last, "%s", "\\t"); + break; + case '\n': + ctx->last += sprintf(ctx->last, "%s", "\\n"); + break; + case '\f': + ctx->last += sprintf(ctx->last, "%s", "\\f"); + break; + case '\r': + ctx->last += sprintf(ctx->last, "%s", "\\r"); + break; + default: + *(ctx->last) = s[i]; + ctx->last++; + } + } +} + + +static void +out_json_str(test_ctx_t *ctx, const char *name, njt_string_t *s, int comma) +{ + ctx->last += sprintf(ctx->last, "\"%s\": \"", name); + + out_json_text(ctx, s->len, (char *) s->ptr); + + ctx->last += sprintf(ctx->last, "\"%s", comma ? "," : ""); +} + + +static njt_string_t * +get_http_var(uint32_t r, const char *name) +{ + njt_string_t key, *value; + + key.len = strlen(name); + key.ptr = (uint8_t *) name; + + value = malloc(sizeof(njt_string_t)); + + E(njt_wasi_http_request_variable)(r, &key, value); + + return value; +} + +static int +reject(uint32_t r, uint32_t code, const char *reason) +{ + njt_string_t rmsg; + rmsg.len = strlen(reason); + rmsg.ptr = (uint8_t *) reason; + + return E(njt_wasi_http_request_reject)(r, code, &rmsg); +} + + +int32_t +exports_njt_wasi_http_handler_init(uint32_t r) +{ + int32_t rc, log_fd; + uint32_t method; + + test_ctx_t *ctx; + + log_fd = exports_njt_wasi_http_request_get_log(r); + + njt_string_t notice = njt_string_set("wasm content handler test start"); + E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_NOTICE, 0, ¬ice); + + njt_string_t llte = njt_string_set("log-level-test-error"); + njt_string_t llti = njt_string_set("log-level-test-info"); + E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_ERR, 0, &llte); + E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_INFO, 0, &llti); + + /* allocate and initialize the user context */ + ctx = malloc(sizeof(test_ctx_t)); + + ctx->buf = malloc(8 * 1024 * 1024); /* enough for everyone */ + ctx->chunked = 0; + ctx->last = ctx->buf; + ctx->pos = NULL; + + ctx->recv_body = 0; + ctx->send_body = 0; + + njt_string_t *ch = get_http_var(r, "arg_chunked"); + if (ch->len == 1) { + ctx->chunked = (ch->ptr[0] == '1'); + } + + njt_string_t *mode = get_http_var(r, "arg_body"); + + if (mode->len == 1) { + if (mode->ptr[0] == 'r') { + ctx->recv_body = 1; + + } else if (mode->ptr[0] == 'w') { + ctx->send_body = 1; + } + + } else if (mode->len == 2) { + if (mode->ptr[0] == 'r' && mode->ptr[1] == 'w') { + ctx->recv_body = 1; + ctx->send_body = 1; + } + } + + method = E(njt_wasi_http_request_get_method)(r); + + switch (method) { + + case EE(NJT_WASI_HTTP_REQUEST_METHOD_PUT): + break; + + case EE(NJT_WASI_HTTP_REQUEST_METHOD_GET): + if (ctx->recv_body) { + return reject(r, 400, "cannot recv body with GET\n"); + } + break; + + case EE(NJT_WASI_HTTP_REQUEST_METHOD_HEAD): + if (ctx->send_body) { + /* error msg will not be sent by njet , since its HEAD */ + return reject(r, 401, "cannot send body with HEAD\n"); + } + break; + + default: + return reject(r, 400, "unsupported method\n"); + } + + + ctx->last += sprintf(ctx->last, "%s", "{"); + + /* attach user-defined data to request */ + E(njt_wasi_http_request_set_context)(r, (uintptr_t) ctx); + + out_json_int(ctx, "version", E(njt_wasi_http_request_get_version)(r), 1); + + /* access request URI */ + njt_string_t uri; + E(njt_wasi_http_request_get_uri)(r, &uri); + out_json_str(ctx, "uri", &uri, 1); + + /* access remote addr */ + njt_string_t ra; + E(njt_wasi_http_request_get_remote_addr)(r, &ra); + out_json_str(ctx, "remote_addr", &ra, 1); + + /* access request variables, for example, arguments */ + njt_string_t vk = njt_string_set("arg_foo"); + njt_string_t vv; + E(njt_wasi_http_request_variable)(r, &vk, &vv); + out_json_str(ctx, "arg_foo", &vv, 1); + + /* access header value (single value) */ + njt_string_t hkey = njt_string_set("host"); + njt_string_t sh; + E(njt_wasi_http_request_get_header)(r, &hkey, &sh); + out_json_str(ctx, "header_host", &sh, 1); + + /* acess header value (as an array) */ + njt_string_t h; + njt_string_t *elts; + njt_list_string_t hvals; + + njt_string_t mkey = njt_string_set("foo"); + + /* multi-header as a string */ + E(njt_wasi_http_request_get_header)(r, &mkey, &h); + out_json_str(ctx, "header_foo_as_string", &h, 1); + + /* multi-header as an array */ + E(njt_wasi_http_request_get_header_values)(r, &mkey, &hvals); + + elts = hvals.ptr; + + ctx->last += sprintf(ctx->last, "%s", "\"header_foo_as_array\":["); + + if (hvals.len) { + for (uint32_t i = 0; i < hvals.len; i++) { + ctx->last += sprintf(ctx->last, "\"%.*s\"", + (int)elts[i].len, elts[i].ptr); + if (i != hvals.len - 1) { + ctx->last += sprintf(ctx->last, "%s", ","); + } + } + } + + ctx->last += sprintf(ctx->last, "%s", "]"); + + ctx->last += sprintf(ctx->last, "%s", ctx->recv_body ? "," : ""); + + if (ctx->recv_body) { + ctx->last += sprintf(ctx->last, "%s", "\"body\":\""); + } + + /* say what to do with body: discard or read */ + rc = E(njt_wasi_http_request_handle_body)(r, ctx->recv_body); + if (rc < 0) { + return rc; + } + + /* next phase: read body or setup response */ + return 0; +} + + +/* + * called if request has body + * request is received on host, then this function is called + */ +int32_t +exports_njt_wasi_http_handler_process_request_body(uint32_t r) +{ + ssize_t n; + uint8_t buf[RWBUF]; + test_ctx_t *ctx; + int32_t log_fd; + + log_fd = exports_njt_wasi_http_request_get_log(r); + ctx = (test_ctx_t *) E(njt_wasi_http_request_get_context)(r); + njt_string_t llte = njt_string_set("=================read body before"); + njt_string_t llte2 = njt_string_set("=================read body after"); + + /* + * read till EOF or error, + * all negative return codes are returned to host; + * it will call function again when needed or handle error + */ + do { + + E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_ERR, 0, &llte); + n = E(njt_wasi_http_request_read_body)(r, (uintptr_t) buf, RWBUF); + if (n < 0) { + /* either an error or again - host will call us when needed */ + return n; + } +E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_ERR, 0, &llte2); + out_json_text(ctx, n, (char *) buf); + + } while (n > 0); + + return 0; +} + + +int32_t +exports_njt_wasi_http_handler_setup_response(uint32_t r) +{ + int32_t rc; + uint64_t cl; + test_ctx_t *ctx; + + ctx = (test_ctx_t *) E(njt_wasi_http_request_get_context)(r); + + if (ctx->recv_body) { + ctx->last += sprintf(ctx->last, "%s", "\""); + } + + ctx->last += sprintf(ctx->last, "%s", "}"); + + if (ctx->chunked) { + cl = (uint64_t) -1; + + } else { + cl = ctx->last - ctx->buf; + } + + /* default status is 200 */ + if (ctx->recv_body) { + /* set 201 for PUT requests to tests setting return code */ + rc = E(njt_wasi_http_request_set_status)(r, 201); + if (rc < 0) { + return rc; + } + } + + /* set if we have body or not, and size or chunked */ + rc = E(njt_wasi_http_request_setup_response)(r, ctx->send_body, cl); + if (rc < 0) { + return rc; + } + + /* set output header */ + njt_string_t key = njt_string_set("hello"); + njt_string_t val = njt_string_set("wasm"); + + E(njt_wasi_http_request_set_header)(r, &key, &val); + + /* set multi-value header */ + njt_string_t values[3] = { + njt_string_set("one"), + njt_string_set("two"), + njt_string_set("three") + }; + + njt_list_string_t lv; + lv.ptr = values; + lv.len = 3; + + njt_string_t mkey = njt_string_set("x-foo"); + + rc = E(njt_wasi_http_request_set_header_values)(r, &mkey, &lv); + if (rc < 0) { + return rc; + } + + /* reset multivalue header */ + njt_string_t xvalues[2] = { + njt_string_set("aa"), + njt_string_set("bb"), + }; + + lv.ptr = xvalues; + lv.len = 2; + + rc = E(njt_wasi_http_request_set_header_values)(r, &mkey, &lv); + if (rc < 0) { + return rc; + } + + /* headers will be sent after return */ + return 0; +} + + +int32_t +exports_njt_wasi_http_handler_generate_response(uint32_t r) +{ + int32_t rc; + test_ctx_t *ctx; + + ctx = (test_ctx_t *) E(njt_wasi_http_request_get_context)(r); + + if (ctx->pos == NULL) { + ctx->pos = ctx->buf; + } + + while (ctx->pos < ctx->last) { + + rc = E(njt_wasi_http_request_write_body)(r, (uintptr_t) ctx->pos, + ctx->last - ctx->pos); + if (rc < 0) { + /* erorr or again: host will call us if needed */ + return rc; + } + + ctx->pos += rc; + } + + return 0; +} + + +int32_t +exports_njt_wasi_http_handler_finalize(uint32_t r) +{ + int32_t log_fd; + log_fd = exports_njt_wasi_http_request_get_log(r); + + njt_string_t notice = njt_string_set("wasm content handler test done"); + E(njt_wasi_utils_log_error)(log_fd, NJT_WASI_HOST_LL_NOTICE, 0, ¬ice); + + return 0; +} + diff --git a/wasm/njt-http-vars/module.mk b/wasm/njt-http-vars/module.mk new file mode 100644 index 0000000000000000000000000000000000000000..0c9c1e68ed48f38149af1f795f479087bb11de91 --- /dev/null +++ b/wasm/njt-http-vars/module.mk @@ -0,0 +1,8 @@ +# +# Copyright (C) 2024 Web Server LLC +# + +SRCS=src/main.c +DEPS= + +$(eval $(call wasm-component,$(SRCS),$(DEPS),njt-http-vars)) diff --git a/wasm/njt-http-vars/src/main.c b/wasm/njt-http-vars/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..8b6ecdef0bcd44da8f8a1e0fe346560c11393755 --- /dev/null +++ b/wasm/njt-http-vars/src/main.c @@ -0,0 +1,66 @@ + +#include +#include +#include +#include +#include + +#include "bindings/njt_http_vars.h" + +typedef njt_http_vars_string_t njt_wasi_str_t; +typedef njt_http_vars_list_string_t njt_wasi_str_list_t; + +void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size); + +void +exports_njt_wasi_var_utils_sum(njt_wasi_str_list_t *in, int32_t log_fd, + njt_wasi_str_t *ret) +{ + char *p; + size_t n; + uint32_t i, sum; + static char buf[64], msgbuf[2048]; + njt_wasi_str_t msg; + + njt_wasi_str_t *items; + + n = snprintf(msgbuf, 2048, "reduce called input: %p", in); + + msg.ptr = (uint8_t *) msgbuf; + msg.len = n; + + exports_njt_wasi_utils_log_error(log_fd, NJT_WASI_HOST_LL_NOTICE, 0, &msg); + + items = (njt_wasi_str_t *) in->ptr; + + if (in->len == 0) { + ret->ptr = NULL; + return; + } + + p = cabi_realloc(NULL, 0, 1, 32); + if (p == NULL) { + ret->ptr = NULL; + return; + } + + ret->ptr = (uint8_t *) p; + + sum = 0; + + for (i = 0; i < in->len; i++) { + + if (items[i].len > 64) { + /* too big ;-) */ + continue; + } + + memcpy(buf, items[i].ptr, items[i].len); + buf[items[i].len] = 0; + + sum += atoi(buf); + } + + ret->len = snprintf(p, 32, "%d", sum); +} + diff --git a/wasm/rules.mk b/wasm/rules.mk new file mode 100644 index 0000000000000000000000000000000000000000..512674eb29815ab32aed6773edc7fe598503e245 --- /dev/null +++ b/wasm/rules.mk @@ -0,0 +1,107 @@ +# +# generic rules for building WASM +# + +CLANG=$(TOOLSDIR)/$(SDK)/bin/clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip1-clang +#CLANG=$(TOOLSDIR)/$(SDK)/bin/wasm32-wasip2-clang + +WLD=$(TOOLSDIR)/$(SDK)/bin/wasm-ld +AR=$(TOOLSDIR)/$(SDK)/bin/ar +RANLIB=$(TOOLSDIR)/$(SDK)/bin/ranlib +WTOOLS=$(TOOLSDIR)/$(WASM_TOOLS) +BG=$(TOOLSDIR)/$(WIT_BINDGEN) + +mkfile_path = $(abspath $(lastword $(MAKEFILE_LIST))) +module = $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +WIT_OPTS=--out-dir=$(module)/bindings \ + --no-helpers \ + --no-object-file \ + --autodrop-borrows=yes + +WITDIR=wit + +OPTS=-Wall -Werror -O2 -I. -I$(module) + +LDOPTS=-Wl,--no-entry -Wl,--import-undefined -mexec-model=reactor + +HOSTLIB=libnjthost/objs/libnjthost.a + +WASI_PLUG=vendor/wasi_snapshot_preview1.proxy.wasm + +# for debug purposes: produce human-readable version of code +%.wasm.wat: %.wasm + $(WTOOLS)/wasm-tools print $^ > $@ + +src-to-obj = $(subst src/,objs/,$(subst .c,.wasm,$(filter %.c,$1))) + +world-to-fn = $(subst -,_,$1) +world-to-wit =$(WITDIR)/$(call world-to-fn,$1).wit + +# $(call wasm-component,1:srcs,2:deps,3:world) +define wasm-component + + $(eval id=$(call world-to-fn,$3)) + + targets += $(module)/objs/$(id).wasm.wat \ + $(module)/objs/$(id)-obj.wasm.wat \ + $(module)/objs/$(id)-component.wasm.wat \ + $(module)/bindings/$(id).c \ + $(module)/bindings/$(id).h + + modules += $(module)/objs/$(id).wasm + components += $(module)/objs/$(id)-component.wasm + + $(call mkbind,$3) + + # build module + $(module)/objs/$(id)-obj.wasm: $(addprefix $(module)/,$1) $(addprefix $(module)/,$2) $(module)/bindings/$(id).c $(module)/bindings/$(id).h $(HOSTLIB) + $(CLANG) $(OPTS) $(LDOPTS) -o $$@ $(addprefix $(module)/,$1) $(module)/bindings/$(id).c $(HOSTLIB) + + # embed WIT + $(module)/objs/$(id).wasm: $(module)/objs/$(id)-obj.wasm $(call world-to-wit,$3) + $(WTOOLS)/wasm-tools component embed $(WITDIR) $$< -o $$@ --world $3 + + $(module)/objs/$(id)-component.wasm: $(module)/objs/$(id).wasm + $(WTOOLS)/wasm-tools component new $$^ --adapt $(WASI_PLUG) -o $$@ + +endef + +# $(call mkbind,1:world) +define mkbind + + $(eval nm=$(call world-to-fn,$1)) + + targets += $(module)/bindings/$(nm).c \ + $(module)/bindings/$(nm).h + + $(module)/bindings/$(nm).c $(module)/bindings/$(nm).h: $(call world-to-wit,$1) + $(BG)/wit-bindgen c $(WIT_OPTS) $(WITDIR) --world $1 + +endef + + +# $(call compile-src,1:src,2:deps) +define compile-src + + targets += $(call src-to-obj,$1).wat + + $(call src-to-obj,$1): $1 $2 + $(CLANG) -c $(OPTS) -fPIC -o $$@ $$< + +endef + +# $(call make-static-lib,1:name,2:srcs,3:deps) +define make-static-lib + + $(foreach item,$(addprefix $(module)/,$2),$(call compile-src,$(item),$(addprefix $(module)/,$3))) + + targets += $1 + + $1: $(call src-to-obj,$(addprefix $(module)/,$2)) + $(AR) r $$@ $$^ + $(RANLIB) $$@ + +endef + diff --git a/wasm/vendor/wasi_snapshot_preview1.proxy.wasm b/wasm/vendor/wasi_snapshot_preview1.proxy.wasm new file mode 100644 index 0000000000000000000000000000000000000000..7dd6ecd2a00124011a10e7fc1cd64fcb3d32e358 Binary files /dev/null and b/wasm/vendor/wasi_snapshot_preview1.proxy.wasm differ diff --git a/wasm/wit/njt_host_lib.wit b/wasm/wit/njt_host_lib.wit new file mode 100644 index 0000000000000000000000000000000000000000..c51970128d8f0a1aeff05331a5fc6e5660535449 --- /dev/null +++ b/wasm/wit/njt_host_lib.wit @@ -0,0 +1,9 @@ + +world njt-host-lib { + import syscall; + import host; + import http-host; + export utils; + export http-request; +} + diff --git a/wasm/wit/njt_http_filter.wit b/wasm/wit/njt_http_filter.wit new file mode 100644 index 0000000000000000000000000000000000000000..1d92034fff0853191056d0297c6a5a3955b4fb7b --- /dev/null +++ b/wasm/wit/njt_http_filter.wit @@ -0,0 +1,10 @@ + +world njt-http-filter { + import host; + import http-host; + import syscall; + export utils; + //import utils; + export http-filter; +} + diff --git a/wasm/wit/njt_http_handler.wit b/wasm/wit/njt_http_handler.wit new file mode 100644 index 0000000000000000000000000000000000000000..98be7918020395dfc9df8786d1cf07a138e763a0 --- /dev/null +++ b/wasm/wit/njt_http_handler.wit @@ -0,0 +1,10 @@ + +world njt-http-handler { + import host; + import http-host; + import syscall; + export utils; + export http-request; + export http-handler; + +} diff --git a/wasm/wit/njt_http_vars.wit b/wasm/wit/njt_http_vars.wit new file mode 100644 index 0000000000000000000000000000000000000000..e1c959eff4a937245362426d58a73e1acf5e0118 --- /dev/null +++ b/wasm/wit/njt_http_vars.wit @@ -0,0 +1,11 @@ + +interface var-utils { + sum: func(in: list, log-fd:s32) -> string; +} + +world njt-http-vars { + import host; + import syscall; + export utils; + export var-utils; +} diff --git a/wasm/wit/njt_wasi.wit b/wasm/wit/njt_wasi.wit new file mode 100644 index 0000000000000000000000000000000000000000..9eab45c7706b6dec0bead021909ee807eccec926 --- /dev/null +++ b/wasm/wit/njt_wasi.wit @@ -0,0 +1,128 @@ +package njt:wasi; + +interface host { + + // log level: matches NGX_LOG_ defines in src/core/njt_log.h + enum ll { + STDERR, EMERG, ALERT, CRIT, ERR, WARN, NOTICE, INFO, DEBUG + } +} + +interface syscall { + + // all syscalls return: + // on success: NGX_OK (zero) or positive value + // otherwise: NGX_ERROR/AGAIN... standard nginx return codes (negative) + // negative codes are expected to be returned to host as is + + open: func(name:string, ctx:s32) -> s32; + + read: func(handle:s32, buf:u32, len:u32) -> s32; + write: func(handle:s32, buf:u32, len:u32) -> s32; + + get: func(handle:s32, propid:u32, buf:u32, len:u32) -> s32; + set: func(handle:s32, propid:u32, val:u32, len:u32) -> s32; + + close: func(handle:s32) -> s32; +} + +interface http-host { + + // indexes in u32 array; array len? + enum request-meta { + ctx, method, schema, version, uri-len, addr-len, + header-count, last + } + + enum request-props { + // input + meta, self, uri, remote-addr, discard-body, var, + // output + status, content-length, ranges, header-only, reject-msg + } +} + +interface utils { + + record keyval { + key: string, + value: string + } + + strerror: func(errnum: s32) -> string; + + log-error: func(fd: s32, level: u8, errnum:s32, msg:string); + + get-env: func(fd: s32, log-fd: s32) -> result,s32>; + + list-alloc: func(fd: s32, nargs:u32, size:u32, old:u32, oldsize:u32, oldres:u32, logfd:s32) -> s32; +} + +interface http-request { + + enum schema { HTTP, HTTPS } + + enum method { + UNKNOWN, GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, + OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH, TRACE, + CONNECT + } + + enum version { VUNKNOWN, V09, V10, V11, V20, V30 } + + set-context: func(req:u32, data:u32); + get-context: func(req:u32) -> u32; + + reject: func(req:u32, status:u32, msg: string) -> s32; + + get-log: func(req:u32) -> s32; + get-method: func(req:u32) -> method; + get-schema: func(req:u32) -> schema; + get-uri: func(req:u32) -> string; + get-version: func(req:u32) -> version; + get-remote-addr: func(req:u32) -> string; + + variable: func(req:u32, key:string) -> string; + + get-header: func(req:u32, key:string) -> string; + get-header-values: func(req:u32, key:string) -> list; + + set-header: func(req:u32, key: string, value:string) -> s32; + set-header-values: func(req:u32, key:string, value: list) -> s32; + + // NEED it? variables are enough? + args-count: func(req:u32) -> u32; + arg-by-index: func(req:u32, index:u32) -> string; + arg-by-key: func(req:u32, key:string) -> string; + + handle-body: func(req:u32, enabled:u8) -> s32; + + read-body: func(req:u32, buf:u32, len:u32) -> s32; + + + set-status: func(req:u32, status:u32) -> s32; + + setup-response: func(req:u32, has-body:u8, body-len: u64) -> s32; + + // NEED IT ? param in response setup? + allow-ranges: func(req:u32); + + write-body: func(req:u32, buf:u32, len:u32) -> s32; + + // NEED it ? auto on close? + finalize: func(req:u32) -> s32; +} + +interface http-filter { + process-stream: func(fd: s32, env-fd:s32) -> s64; +} + +interface http-handler { + handle-request: func(req: s32) -> s32; + + init: func(req:u32) -> s32; + process-request-body: func(req:u32) -> s32; + setup-response: func(req:u32) -> s32; + generate-response: func(req:u32) -> s32; + finalize: func(req:u32) -> s32; +} diff --git a/wasm/wit/njt_wasi_core.wit b/wasm/wit/njt_wasi_core.wit new file mode 100644 index 0000000000000000000000000000000000000000..09de697d82b51e11c2518caf503eed109f7f0d49 --- /dev/null +++ b/wasm/wit/njt_wasi_core.wit @@ -0,0 +1,6 @@ + +// source for src/core/njt_wasi_core.h +world njt-wasi-core { + import host; +} + diff --git a/wasm/wit/njt_wasi_http.wit b/wasm/wit/njt_wasi_http.wit new file mode 100644 index 0000000000000000000000000000000000000000..31b0ed7169f16f0816e00b998f2b9b7261f50ead --- /dev/null +++ b/wasm/wit/njt_wasi_http.wit @@ -0,0 +1,6 @@ + +// source for src/http/njt_wasi_http.h +world njt-wasi-http { + import http-host; +} + diff --git a/wasmedge/conf b/wasmedge/conf deleted file mode 100644 index 81d592439406eeb382333226ad4eefac873a1787..0000000000000000000000000000000000000000 --- a/wasmedge/conf +++ /dev/null @@ -1,31 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. -# Copyright (C) TMLake, Inc. - -WASMEDGE="auto/lib/wasmedge" -wasm_arch=$(uname -m) -wasm_os_type=$(uname -s) - -case "$CC" in - *) - if [ "$wasm_arch" != "x86_64" ] && [ "$wasm_arch" != "aarch64" ]; then - cat << END - $0: error: not allow build use with system architecture $wasm_arch. -END - exit 1 - fi - - if [ "$wasm_os_type" != Linux ]; then - cat << END - $0: error: not allow build use with operating system $wasm_os_type. -END - exit 1 - fi - - CORE_DEPS="$CORE_DEPS $WASMEDGE/build/include/wasmedge/wasmedge.h" - ;; -esac - - - diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum.inc b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum.inc deleted file mode 100644 index bf1c8f7c78cadc318de23d5319956d6bc6ce427d..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum.inc +++ /dev/null @@ -1,1201 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum.inc - Enumerations ---------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains all enumerations of WasmEdge. -/// -//===----------------------------------------------------------------------===// - -#ifndef Line -#error "this header file must not be included directly" -#endif - -// enum_ast.hpp - -#ifdef UseASTNodeAttr -#define A Line - -A(Component, "component") -A(Sec_CoreMod, "component core:module section") -A(Sec_CoreInstance, "component core:instance section") -A(Sec_Alias, "component alias section") -A(Sec_Comp, "nested component section") -A(Sec_Instance, "component instance section") -A(Sec_CompType, "component type section") -A(Sec_Canon, "component canonical section") -A(Sec_CompStart, "component start section") -A(Sec_CompImport, "component import section") -A(Sec_CompExport, "component export section") -A(ImportExportName, "import/export name") -A(Import, "import") -A(Export, "export") -A(Canonical, "canonical") -A(Alias, "alias") -A(DefType, "component defined type") -A(InstanceDecl, "instance decl") -A(ExternDesc, "extern desc") -A(Name, "import/export name") -A(AliasTarget, "alias target") -A(Sort, "sort") -A(Instance, "instance expr") -A(CoreInstance, "core:instance expr") -A(Module, "module") -A(Sec_Custom, "custom section") -A(Sec_Type, "type section") -A(Sec_Import, "import section") -A(Sec_Function, "function section") -A(Sec_Table, "table section") -A(Sec_Memory, "memory section") -A(Sec_Global, "global section") -A(Sec_Export, "export section") -A(Sec_Start, "start section") -A(Sec_Element, "element section") -A(Sec_Code, "code section") -A(Sec_Data, "data section") -A(Sec_DataCount, "data count section") -A(Sec_Tag, "tag section") -A(Desc_Import, "import description") -A(Desc_Export, "export description") -A(Seg_Table, "table segment") -A(Seg_Global, "global segment") -A(Seg_Element, "element segment") -A(Seg_Code, "code segment") -A(Seg_Data, "data segment") -A(Type_Module, "module type") -A(Type_Rec, "recursive type") -A(Type_Sub, "sub type") -A(Type_Limit, "limit") -A(Type_Function, "function type") -A(Type_Memory, "memory type") -A(Type_Table, "table type") -A(Type_Global, "global type") -A(Type_Instance, "instance type") -A(Type_Component, "component type") -A(Expression, "expression") -A(Instruction, "instruction") -A(Sec_AOT, "aot section") - -#undef A -#endif // UseASTNodeAttr - -#ifdef UseOpCode -#define O Line -#define OFB Line_FB -#define OFC Line_FC -#define OFD Line_FD -#define OFE Line_FE - -// OpCode: -// NAME | STRING | CODE [ | EXTEND ] - -// Control instructions (part 1) -O(Unreachable, "unreachable", 0x00) -O(Nop, "nop", 0x01) -O(Block, "block", 0x02) -O(Loop, "loop", 0x03) -O(If, "if", 0x04) -O(Else, "else", 0x05) -O(Try, "try", 0x06) // For legacy EH proposal -O(Catch, "catch", 0x07) // For legacy EH proposal -O(Throw, "throw", 0x08) -O(Rethrow, "rethrow", 0x09) // For legacy EH proposal -O(Throw_ref, "throw_ref", 0x0A) -O(End, "end", 0x0B) -O(Br, "br", 0x0C) -O(Br_if, "br_if", 0x0D) -O(Br_table, "br_table", 0x0E) -O(Return, "return", 0x0F) -O(Call, "call", 0x10) -O(Call_indirect, "call_indirect", 0x11) -O(Return_call, "return_call", 0x12) -O(Return_call_indirect, "return_call_indirect", 0x13) -O(Call_ref, "call_ref", 0x14) -O(Return_call_ref, "return_call_ref", 0x15) -// 0x16: Reserved -// 0x17: Reserved -O(Delegate, "delegate", 0x18) // For legacy EH proposal -O(Catch_all, "catch_all", 0x19) // For legacy EH proposal - -// Parametric Instructions -O(Drop, "drop", 0x1A) -O(Select, "select", 0x1B) -O(Select_t, "select", 0x1C) -// 0x1D: Reserved -// 0x1E: Reserved - -// Control instructions (part 2) -O(Try_table, "try_table", 0x1F) - -// Variable Instructions -O(Local__get, "local.get", 0x20) -O(Local__set, "local.set", 0x21) -O(Local__tee, "local.tee", 0x22) -O(Global__get, "global.get", 0x23) -O(Global__set, "global.set", 0x24) - -// Table Instructions (part 1) -O(Table__get, "table.get", 0x25) -O(Table__set, "table.set", 0x26) -// 0x27: Reserved - -// Memory Instructions (part 1) -O(I32__load, "i32.load", 0x28) -O(I64__load, "i64.load", 0x29) -O(F32__load, "f32.load", 0x2A) -O(F64__load, "f64.load", 0x2B) -O(I32__load8_s, "i32.load8_s", 0x2C) -O(I32__load8_u, "i32.load8_u", 0x2D) -O(I32__load16_s, "i32.load16_s", 0x2E) -O(I32__load16_u, "i32.load16_u", 0x2F) -O(I64__load8_s, "i64.load8_s", 0x30) -O(I64__load8_u, "i64.load8_u", 0x31) -O(I64__load16_s, "i64.load16_s", 0x32) -O(I64__load16_u, "i64.load16_u", 0x33) -O(I64__load32_s, "i64.load32_s", 0x34) -O(I64__load32_u, "i64.load32_u", 0x35) -O(I32__store, "i32.store", 0x36) -O(I64__store, "i64.store", 0x37) -O(F32__store, "f32.store", 0x38) -O(F64__store, "f64.store", 0x39) -O(I32__store8, "i32.store8", 0x3A) -O(I32__store16, "i32.store16", 0x3B) -O(I64__store8, "i64.store8", 0x3C) -O(I64__store16, "i64.store16", 0x3D) -O(I64__store32, "i64.store32", 0x3E) -O(Memory__size, "memory.size", 0x3F) -O(Memory__grow, "memory.grow", 0x40) - -// Const numeric instructions -O(I32__const, "i32.const", 0x41) -O(I64__const, "i64.const", 0x42) -O(F32__const, "f32.const", 0x43) -O(F64__const, "f64.const", 0x44) - -// Numeric instructions -O(I32__eqz, "i32.eqz", 0x45) -O(I32__eq, "i32.eq", 0x46) -O(I32__ne, "i32.ne", 0x47) -O(I32__lt_s, "i32.lt_s", 0x48) -O(I32__lt_u, "i32.lt_u", 0x49) -O(I32__gt_s, "i32.gt_s", 0x4A) -O(I32__gt_u, "i32.gt_u", 0x4B) -O(I32__le_s, "i32.le_s", 0x4C) -O(I32__le_u, "i32.le_u", 0x4D) -O(I32__ge_s, "i32.ge_s", 0x4E) -O(I32__ge_u, "i32.ge_u", 0x4F) -O(I64__eqz, "i64.eqz", 0x50) -O(I64__eq, "i64.eq", 0x51) -O(I64__ne, "i64.ne", 0x52) -O(I64__lt_s, "i64.lt_s", 0x53) -O(I64__lt_u, "i64.lt_u", 0x54) -O(I64__gt_s, "i64.gt_s", 0x55) -O(I64__gt_u, "i64.gt_u", 0x56) -O(I64__le_s, "i64.le_s", 0x57) -O(I64__le_u, "i64.le_u", 0x58) -O(I64__ge_s, "i64.ge_s", 0x59) -O(I64__ge_u, "i64.ge_u", 0x5A) -O(F32__eq, "f32.eq", 0x5B) -O(F32__ne, "f32.ne", 0x5C) -O(F32__lt, "f32.lt", 0x5D) -O(F32__gt, "f32.gt", 0x5E) -O(F32__le, "f32.le", 0x5F) -O(F32__ge, "f32.ge", 0x60) -O(F64__eq, "f64.eq", 0x61) -O(F64__ne, "f64.ne", 0x62) -O(F64__lt, "f64.lt", 0x63) -O(F64__gt, "f64.gt", 0x64) -O(F64__le, "f64.le", 0x65) -O(F64__ge, "f64.ge", 0x66) -O(I32__clz, "i32.clz", 0x67) -O(I32__ctz, "i32.ctz", 0x68) -O(I32__popcnt, "i32.popcnt", 0x69) -O(I32__add, "i32.add", 0x6A) -O(I32__sub, "i32.sub", 0x6B) -O(I32__mul, "i32.mul", 0x6C) -O(I32__div_s, "i32.div_s", 0x6D) -O(I32__div_u, "i32.div_u", 0x6E) -O(I32__rem_s, "i32.rem_s", 0x6F) -O(I32__rem_u, "i32.rem_u", 0x70) -O(I32__and, "i32.and", 0x71) -O(I32__or, "i32.or", 0x72) -O(I32__xor, "i32.xor", 0x73) -O(I32__shl, "i32.shl", 0x74) -O(I32__shr_s, "i32.shr_s", 0x75) -O(I32__shr_u, "i32.shr_u", 0x76) -O(I32__rotl, "i32.rotl", 0x77) -O(I32__rotr, "i32.rotr", 0x78) -O(I64__clz, "i64.clz", 0x79) -O(I64__ctz, "i64.ctz", 0x7A) -O(I64__popcnt, "i64.popcnt", 0x7B) -O(I64__add, "i64.add", 0x7C) -O(I64__sub, "i64.sub", 0x7D) -O(I64__mul, "i64.mul", 0x7E) -O(I64__div_s, "i64.div_s", 0x7F) -O(I64__div_u, "i64.div_u", 0x80) -O(I64__rem_s, "i64.rem_s", 0x81) -O(I64__rem_u, "i64.rem_u", 0x82) -O(I64__and, "i64.and", 0x83) -O(I64__or, "i64.or", 0x84) -O(I64__xor, "i64.xor", 0x85) -O(I64__shl, "i64.shl", 0x86) -O(I64__shr_s, "i64.shr_s", 0x87) -O(I64__shr_u, "i64.shr_u", 0x88) -O(I64__rotl, "i64.rotl", 0x89) -O(I64__rotr, "i64.rotr", 0x8A) -O(F32__abs, "f32.abs", 0x8B) -O(F32__neg, "f32.neg", 0x8C) -O(F32__ceil, "f32.ceil", 0x8D) -O(F32__floor, "f32.floor", 0x8E) -O(F32__trunc, "f32.trunc", 0x8F) -O(F32__nearest, "f32.nearest", 0x90) -O(F32__sqrt, "f32.sqrt", 0x91) -O(F32__add, "f32.add", 0x92) -O(F32__sub, "f32.sub", 0x93) -O(F32__mul, "f32.mul", 0x94) -O(F32__div, "f32.div", 0x95) -O(F32__min, "f32.min", 0x96) -O(F32__max, "f32.max", 0x97) -O(F32__copysign, "f32.copysign", 0x98) -O(F64__abs, "f64.abs", 0x99) -O(F64__neg, "f64.neg", 0x9A) -O(F64__ceil, "f64.ceil", 0x9B) -O(F64__floor, "f64.floor", 0x9C) -O(F64__trunc, "f64.trunc", 0x9D) -O(F64__nearest, "f64.nearest", 0x9E) -O(F64__sqrt, "f64.sqrt", 0x9F) -O(F64__add, "f64.add", 0xA0) -O(F64__sub, "f64.sub", 0xA1) -O(F64__mul, "f64.mul", 0xA2) -O(F64__div, "f64.div", 0xA3) -O(F64__min, "f64.min", 0xA4) -O(F64__max, "f64.max", 0xA5) -O(F64__copysign, "f64.copysign", 0xA6) -O(I32__wrap_i64, "i32.wrap_i64", 0xA7) -O(I32__trunc_f32_s, "i32.trunc_f32_s", 0xA8) -O(I32__trunc_f32_u, "i32.trunc_f32_u", 0xA9) -O(I32__trunc_f64_s, "i32.trunc_f64_s", 0xAA) -O(I32__trunc_f64_u, "i32.trunc_f64_u", 0xAB) -O(I64__extend_i32_s, "i64.extend_i32_s", 0xAC) -O(I64__extend_i32_u, "i64.extend_i32_u", 0xAD) -O(I64__trunc_f32_s, "i64.trunc_f32_s", 0xAE) -O(I64__trunc_f32_u, "i64.trunc_f32_u", 0xAF) -O(I64__trunc_f64_s, "i64.trunc_f64_s", 0xB0) -O(I64__trunc_f64_u, "i64.trunc_f64_u", 0xB1) -O(F32__convert_i32_s, "f32.convert_i32_s", 0xB2) -O(F32__convert_i32_u, "f32.convert_i32_u", 0xB3) -O(F32__convert_i64_s, "f32.convert_i64_s", 0xB4) -O(F32__convert_i64_u, "f32.convert_i64_u", 0xB5) -O(F32__demote_f64, "f32.demote_f64", 0xB6) -O(F64__convert_i32_s, "f64.convert_i32_s", 0xB7) -O(F64__convert_i32_u, "f64.convert_i32_u", 0xB8) -O(F64__convert_i64_s, "f64.convert_i64_s", 0xB9) -O(F64__convert_i64_u, "f64.convert_i64_u", 0xBA) -O(F64__promote_f32, "f64.promote_f32", 0xBB) -O(I32__reinterpret_f32, "i32.reinterpret_f32", 0xBC) -O(I64__reinterpret_f64, "i64.reinterpret_f64", 0xBD) -O(F32__reinterpret_i32, "f32.reinterpret_i32", 0xBE) -O(F64__reinterpret_i64, "f64.reinterpret_i64", 0xBF) -O(I32__extend8_s, "i32.extend8_s", 0xC0) -O(I32__extend16_s, "i32.extend16_s", 0xC1) -O(I64__extend8_s, "i64.extend8_s", 0xC2) -O(I64__extend16_s, "i64.extend16_s", 0xC3) -O(I64__extend32_s, "i64.extend32_s", 0xC4) -// 0xC5 ~ 0xCF: Reserved - -// Reference Instructions -O(Ref__null, "ref.null", 0xD0) -O(Ref__is_null, "ref.is_null", 0xD1) -O(Ref__func, "ref.func", 0xD2) -O(Ref__eq, "ref.eq", 0xD3) -O(Ref__as_non_null, "ref.as_non_null", 0xD4) - -// Control Instructions (part 3) -O(Br_on_null, "br_on_null", 0xD5) -O(Br_on_non_null, "br_on_non_null", 0xD6) -// 0xD7 ~ 0xFA: Reserved - -// 0xFB prefix - GC Instructions -OFB(Struct__new, "struct.new", 0xFB, 0) -OFB(Struct__new_default, "struct.new_default", 0xFB, 1) -OFB(Struct__get, "struct.get", 0xFB, 2) -OFB(Struct__get_s, "struct.get_s", 0xFB, 3) -OFB(Struct__get_u, "struct.get_u", 0xFB, 4) -OFB(Struct__set, "struct.set", 0xFB, 5) -OFB(Array__new, "array.new", 0xFB, 6) -OFB(Array__new_default, "array.new_default", 0xFB, 7) -OFB(Array__new_fixed, "array.new_fixed", 0xFB, 8) -OFB(Array__new_data, "array.new_data", 0xFB, 9) -OFB(Array__new_elem, "array.new_elem", 0xFB, 10) -OFB(Array__get, "array.get", 0xFB, 11) -OFB(Array__get_s, "array.get_s", 0xFB, 12) -OFB(Array__get_u, "array.get_u", 0xFB, 13) -OFB(Array__set, "array.set", 0xFB, 14) -OFB(Array__len, "array.len", 0xFB, 15) -OFB(Array__fill, "array.fill", 0xFB, 16) -OFB(Array__copy, "array.copy", 0xFB, 17) -OFB(Array__init_data, "array.init_data", 0xFB, 18) -OFB(Array__init_elem, "array.init_elem", 0xFB, 19) -OFB(Ref__test, "ref.test (ref)", 0xFB, 20) -OFB(Ref__test_null, "ref.test (ref.null)", 0xFB, 21) -OFB(Ref__cast, "ref.cast (ref)", 0xFB, 22) -OFB(Ref__cast_null, "ref.cast (ref.null)", 0xFB, 23) -OFB(Br_on_cast, "br_on_cast", 0xFB, 24) -OFB(Br_on_cast_fail, "br_on_cast_fail", 0xFB, 25) -OFB(Any__convert_extern, "any.convert_extern", 0xFB, 26) -OFB(Extern__convert_any, "extern.convert_any", 0xFB, 27) -OFB(Ref__i31, "ref.i31", 0xFB, 28) -OFB(I31__get_s, "i31.get_s", 0xFB, 29) -OFB(I31__get_u, "i31.get_u", 0xFB, 30) - -// 0xFC prefix - Saturating Truncation Instructions -OFC(I32__trunc_sat_f32_s, "i32.trunc_sat_f32_s", 0xFC, 0) -OFC(I32__trunc_sat_f32_u, "i32.trunc_sat_f32_u", 0xFC, 1) -OFC(I32__trunc_sat_f64_s, "i32.trunc_sat_f64_s", 0xFC, 2) -OFC(I32__trunc_sat_f64_u, "i32.trunc_sat_f64_u", 0xFC, 3) -OFC(I64__trunc_sat_f32_s, "i64.trunc_sat_f32_s", 0xFC, 4) -OFC(I64__trunc_sat_f32_u, "i64.trunc_sat_f32_u", 0xFC, 5) -OFC(I64__trunc_sat_f64_s, "i64.trunc_sat_f64_s", 0xFC, 6) -OFC(I64__trunc_sat_f64_u, "i64.trunc_sat_f64_u", 0xFC, 7) - -// 0xFC prefix - Memory Instructions (part 2) -OFC(Memory__init, "memory.init", 0xFC, 8) -OFC(Data__drop, "data.drop", 0xFC, 9) -OFC(Memory__copy, "memory.copy", 0xFC, 10) -OFC(Memory__fill, "memory.fill", 0xFC, 11) - -// 0xFC prefix - Table Instructions (part 2) -OFC(Table__init, "table.init", 0xFC, 12) -OFC(Elem__drop, "elem.drop", 0xFC, 13) -OFC(Table__copy, "table.copy", 0xFC, 14) -OFC(Table__grow, "table.grow", 0xFC, 15) -OFC(Table__size, "table.size", 0xFC, 16) -OFC(Table__fill, "table.fill", 0xFC, 17) - -// 0xFD prefix - Vector Memory Instructions (part 1) -OFD(V128__load, "v128.load", 0xFD, 0) -OFD(V128__load8x8_s, "v128.load8x8_s", 0xFD, 1) -OFD(V128__load8x8_u, "v128.load8x8_u", 0xFD, 2) -OFD(V128__load16x4_s, "v128.load16x4_s", 0xFD, 3) -OFD(V128__load16x4_u, "v128.load16x4_u", 0xFD, 4) -OFD(V128__load32x2_s, "v128.load32x2_s", 0xFD, 5) -OFD(V128__load32x2_u, "v128.load32x2_u", 0xFD, 6) -OFD(V128__load8_splat, "v128.load8_splat", 0xFD, 7) -OFD(V128__load16_splat, "v128.load16_splat", 0xFD, 8) -OFD(V128__load32_splat, "v128.load32_splat", 0xFD, 9) -OFD(V128__load64_splat, "v128.load64_splat", 0xFD, 10) -OFD(V128__store, "v128.store", 0xFD, 11) - -// 0xFD prefix - Vector Numeric Instructions (part 1) -OFD(V128__const, "v128.const", 0xFD, 12) -OFD(I8x16__shuffle, "i8x16.shuffle", 0xFD, 13) -OFD(I8x16__swizzle, "i8x16.swizzle", 0xFD, 14) -OFD(I8x16__splat, "i8x16.splat", 0xFD, 15) -OFD(I16x8__splat, "i16x8.splat", 0xFD, 16) -OFD(I32x4__splat, "i32x4.splat", 0xFD, 17) -OFD(I64x2__splat, "i64x2.splat", 0xFD, 18) -OFD(F32x4__splat, "f32x4.splat", 0xFD, 19) -OFD(F64x2__splat, "f64x2.splat", 0xFD, 20) - -// 0xFD prefix - Vector Lane Instructions -OFD(I8x16__extract_lane_s, "i8x16.extract_lane_s", 0xFD, 21) -OFD(I8x16__extract_lane_u, "i8x16.extract_lane_u", 0xFD, 22) -OFD(I8x16__replace_lane, "i8x16.replace_lane", 0xFD, 23) -OFD(I16x8__extract_lane_s, "i16x8.extract_lane_s", 0xFD, 24) -OFD(I16x8__extract_lane_u, "i16x8.extract_lane_u", 0xFD, 25) -OFD(I16x8__replace_lane, "i16x8.replace_lane", 0xFD, 26) -OFD(I32x4__extract_lane, "i32x4.extract_lane", 0xFD, 27) -OFD(I32x4__replace_lane, "i32x4.replace_lane", 0xFD, 28) -OFD(I64x2__extract_lane, "i64x2.extract_lane", 0xFD, 29) -OFD(I64x2__replace_lane, "i64x2.replace_lane", 0xFD, 30) -OFD(F32x4__extract_lane, "f32x4.extract_lane", 0xFD, 31) -OFD(F32x4__replace_lane, "f32x4.replace_lane", 0xFD, 32) -OFD(F64x2__extract_lane, "f64x2.extract_lane", 0xFD, 33) -OFD(F64x2__replace_lane, "f64x2.replace_lane", 0xFD, 34) - -// 0xFD prefix - Vector Numeric Instructions (part 2) -OFD(I8x16__eq, "i8x16.eq", 0xFD, 35) -OFD(I8x16__ne, "i8x16.ne", 0xFD, 36) -OFD(I8x16__lt_s, "i8x16.lt_s", 0xFD, 37) -OFD(I8x16__lt_u, "i8x16.lt_u", 0xFD, 38) -OFD(I8x16__gt_s, "i8x16.gt_s", 0xFD, 39) -OFD(I8x16__gt_u, "i8x16.gt_u", 0xFD, 40) -OFD(I8x16__le_s, "i8x16.le_s", 0xFD, 41) -OFD(I8x16__le_u, "i8x16.le_u", 0xFD, 42) -OFD(I8x16__ge_s, "i8x16.ge_s", 0xFD, 43) -OFD(I8x16__ge_u, "i8x16.ge_u", 0xFD, 44) -OFD(I16x8__eq, "i16x8.eq", 0xFD, 45) -OFD(I16x8__ne, "i16x8.ne", 0xFD, 46) -OFD(I16x8__lt_s, "i16x8.lt_s", 0xFD, 47) -OFD(I16x8__lt_u, "i16x8.lt_u", 0xFD, 48) -OFD(I16x8__gt_s, "i16x8.gt_s", 0xFD, 49) -OFD(I16x8__gt_u, "i16x8.gt_u", 0xFD, 50) -OFD(I16x8__le_s, "i16x8.le_s", 0xFD, 51) -OFD(I16x8__le_u, "i16x8.le_u", 0xFD, 52) -OFD(I16x8__ge_s, "i16x8.ge_s", 0xFD, 53) -OFD(I16x8__ge_u, "i16x8.ge_u", 0xFD, 54) -OFD(I32x4__eq, "i32x4.eq", 0xFD, 55) -OFD(I32x4__ne, "i32x4.ne", 0xFD, 56) -OFD(I32x4__lt_s, "i32x4.lt_s", 0xFD, 57) -OFD(I32x4__lt_u, "i32x4.lt_u", 0xFD, 58) -OFD(I32x4__gt_s, "i32x4.gt_s", 0xFD, 59) -OFD(I32x4__gt_u, "i32x4.gt_u", 0xFD, 60) -OFD(I32x4__le_s, "i32x4.le_s", 0xFD, 61) -OFD(I32x4__le_u, "i32x4.le_u", 0xFD, 62) -OFD(I32x4__ge_s, "i32x4.ge_s", 0xFD, 63) -OFD(I32x4__ge_u, "i32x4.ge_u", 0xFD, 64) -OFD(F32x4__eq, "f32x4.eq", 0xFD, 65) -OFD(F32x4__ne, "f32x4.ne", 0xFD, 66) -OFD(F32x4__lt, "f32x4.lt", 0xFD, 67) -OFD(F32x4__gt, "f32x4.gt", 0xFD, 68) -OFD(F32x4__le, "f32x4.le", 0xFD, 69) -OFD(F32x4__ge, "f32x4.ge", 0xFD, 70) -OFD(F64x2__eq, "f64x2.eq", 0xFD, 71) -OFD(F64x2__ne, "f64x2.ne", 0xFD, 72) -OFD(F64x2__lt, "f64x2.lt", 0xFD, 73) -OFD(F64x2__gt, "f64x2.gt", 0xFD, 74) -OFD(F64x2__le, "f64x2.le", 0xFD, 75) -OFD(F64x2__ge, "f64x2.ge", 0xFD, 76) -OFD(V128__not, "v128.not", 0xFD, 77) -OFD(V128__and, "v128.and", 0xFD, 78) -OFD(V128__andnot, "v128.andnot", 0xFD, 79) -OFD(V128__or, "v128.or", 0xFD, 80) -OFD(V128__xor, "v128.xor", 0xFD, 81) -OFD(V128__bitselect, "v128.bitselect", 0xFD, 82) -OFD(V128__any_true, "v128.any_true", 0xFD, 83) - -// 0xFD prefix - Vector Memory Instructions (part 2) -OFD(V128__load8_lane, "v128.load8_lane", 0xFD, 84) -OFD(V128__load16_lane, "v128.load16_lane", 0xFD, 85) -OFD(V128__load32_lane, "v128.load32_lane", 0xFD, 86) -OFD(V128__load64_lane, "v128.load64_lane", 0xFD, 87) -OFD(V128__store8_lane, "v128.store8_lane", 0xFD, 88) -OFD(V128__store16_lane, "v128.store16_lane", 0xFD, 89) -OFD(V128__store32_lane, "v128.store32_lane", 0xFD, 90) -OFD(V128__store64_lane, "v128.store64_lane", 0xFD, 91) -OFD(V128__load32_zero, "v128.load32_zero", 0xFD, 92) -OFD(V128__load64_zero, "v128.load64_zero", 0xFD, 93) - -// 0xFD prefix - Vector Numeric Instructions (part 3) -OFD(F32x4__demote_f64x2_zero, "f32x4.demote_f64x2_zero", 0xFD, 94) -OFD(F64x2__promote_low_f32x4, "f64x2.promote_low_f32x4", 0xFD, 95) -OFD(I8x16__abs, "i8x16.abs", 0xFD, 96) -OFD(I8x16__neg, "i8x16.neg", 0xFD, 97) -OFD(I8x16__popcnt, "i8x16.popcnt", 0xFD, 98) -OFD(I8x16__all_true, "i8x16.all_true", 0xFD, 99) -OFD(I8x16__bitmask, "i8x16.bitmask", 0xFD, 100) -OFD(I8x16__narrow_i16x8_s, "i8x16.narrow_i16x8_s", 0xFD, 101) -OFD(I8x16__narrow_i16x8_u, "i8x16.narrow_i16x8_u", 0xFD, 102) -OFD(F32x4__ceil, "f32x4.ceil", 0xFD, 103) -OFD(F32x4__floor, "f32x4.floor", 0xFD, 104) -OFD(F32x4__trunc, "f32x4.trunc", 0xFD, 105) -OFD(F32x4__nearest, "f32x4.nearest", 0xFD, 106) -OFD(I8x16__shl, "i8x16.shl", 0xFD, 107) -OFD(I8x16__shr_s, "i8x16.shr_s", 0xFD, 108) -OFD(I8x16__shr_u, "i8x16.shr_u", 0xFD, 109) -OFD(I8x16__add, "i8x16.add", 0xFD, 110) -OFD(I8x16__add_sat_s, "i8x16.add_sat_s", 0xFD, 111) -OFD(I8x16__add_sat_u, "i8x16.add_sat_u", 0xFD, 112) -OFD(I8x16__sub, "i8x16.sub", 0xFD, 113) -OFD(I8x16__sub_sat_s, "i8x16.sub_sat_s", 0xFD, 114) -OFD(I8x16__sub_sat_u, "i8x16.sub_sat_u", 0xFD, 115) -OFD(F64x2__ceil, "f64x2.ceil", 0xFD, 116) -OFD(F64x2__floor, "f64x2.floor", 0xFD, 117) -OFD(I8x16__min_s, "i8x16.min_s", 0xFD, 118) -OFD(I8x16__min_u, "i8x16.min_u", 0xFD, 119) -OFD(I8x16__max_s, "i8x16.max_s", 0xFD, 120) -OFD(I8x16__max_u, "i8x16.max_u", 0xFD, 121) -OFD(F64x2__trunc, "f64x2.trunc", 0xFD, 122) -OFD(I8x16__avgr_u, "i8x16.avgr_u", 0xFD, 123) -OFD(I16x8__extadd_pairwise_i8x16_s, "i16x8.extadd_pairwise_i8x16_s", 0xFD, 124) -OFD(I16x8__extadd_pairwise_i8x16_u, "i16x8.extadd_pairwise_i8x16_u", 0xFD, 125) -OFD(I32x4__extadd_pairwise_i16x8_s, "i32x4.extadd_pairwise_i16x8_s", 0xFD, 126) -OFD(I32x4__extadd_pairwise_i16x8_u, "i32x4.extadd_pairwise_i16x8_u", 0xFD, 127) -OFD(I16x8__abs, "i16x8.abs", 0xFD, 128) -OFD(I16x8__neg, "i16x8.neg", 0xFD, 129) -OFD(I16x8__q15mulr_sat_s, "i16x8.q15mulr_sat_s", 0xFD, 130) -OFD(I16x8__all_true, "i16x8.all_true", 0xFD, 131) -OFD(I16x8__bitmask, "i16x8.bitmask", 0xFD, 132) -OFD(I16x8__narrow_i32x4_s, "i16x8.narrow_i32x4_s", 0xFD, 133) -OFD(I16x8__narrow_i32x4_u, "i16x8.narrow_i32x4_u", 0xFD, 134) -OFD(I16x8__extend_low_i8x16_s, "i16x8.extend_low_i8x16_s", 0xFD, 135) -OFD(I16x8__extend_high_i8x16_s, "i16x8.extend_high_i8x16_s", 0xFD, 136) -OFD(I16x8__extend_low_i8x16_u, "i16x8.extend_low_i8x16_u", 0xFD, 137) -OFD(I16x8__extend_high_i8x16_u, "i16x8.extend_high_i8x16_u", 0xFD, 138) -OFD(I16x8__shl, "i16x8.shl", 0xFD, 139) -OFD(I16x8__shr_s, "i16x8.shr_s", 0xFD, 140) -OFD(I16x8__shr_u, "i16x8.shr_u", 0xFD, 141) -OFD(I16x8__add, "i16x8.add", 0xFD, 142) -OFD(I16x8__add_sat_s, "i16x8.add_sat_s", 0xFD, 143) -OFD(I16x8__add_sat_u, "i16x8.add_sat_u", 0xFD, 144) -OFD(I16x8__sub, "i16x8.sub", 0xFD, 145) -OFD(I16x8__sub_sat_s, "i16x8.sub_sat_s", 0xFD, 146) -OFD(I16x8__sub_sat_u, "i16x8.sub_sat_u", 0xFD, 147) -OFD(F64x2__nearest, "f64x2.nearest", 0xFD, 148) -OFD(I16x8__mul, "i16x8.mul", 0xFD, 149) -OFD(I16x8__min_s, "i16x8.min_s", 0xFD, 150) -OFD(I16x8__min_u, "i16x8.min_u", 0xFD, 151) -OFD(I16x8__max_s, "i16x8.max_s", 0xFD, 152) -OFD(I16x8__max_u, "i16x8.max_u", 0xFD, 153) -// 0xFD 154: Reserved -OFD(I16x8__avgr_u, "i16x8.avgr_u", 0xFD, 155) -OFD(I16x8__extmul_low_i8x16_s, "i16x8.extmul_low_i8x16_s", 0xFD, 156) -OFD(I16x8__extmul_high_i8x16_s, "i16x8.extmul_high_i8x16_s", 0xFD, 157) -OFD(I16x8__extmul_low_i8x16_u, "i16x8.extmul_low_i8x16_u", 0xFD, 158) -OFD(I16x8__extmul_high_i8x16_u, "i16x8.extmul_high_i8x16_u", 0xFD, 159) -OFD(I32x4__abs, "i32x4.abs", 0xFD, 160) -OFD(I32x4__neg, "i32x4.neg", 0xFD, 161) -// 0xFD 162: Reserved -OFD(I32x4__all_true, "i32x4.all_true", 0xFD, 163) -OFD(I32x4__bitmask, "i32x4.bitmask", 0xFD, 164) -// 0xFD 165: Reserved -// 0xFD 166: Reserved -OFD(I32x4__extend_low_i16x8_s, "i32x4.extend_low_i16x8_s", 0xFD, 167) -OFD(I32x4__extend_high_i16x8_s, "i32x4.extend_high_i16x8_s", 0xFD, 168) -OFD(I32x4__extend_low_i16x8_u, "i32x4.extend_low_i16x8_u", 0xFD, 169) -OFD(I32x4__extend_high_i16x8_u, "i32x4.extend_high_i16x8_u", 0xFD, 170) -OFD(I32x4__shl, "i32x4.shl", 0xFD, 171) -OFD(I32x4__shr_s, "i32x4.shr_s", 0xFD, 172) -OFD(I32x4__shr_u, "i32x4.shr_u", 0xFD, 173) -OFD(I32x4__add, "i32x4.add", 0xFD, 174) -// 0xFD 175: Reserved -// 0xFD 176: Reserved -OFD(I32x4__sub, "i32x4.sub", 0xFD, 177) -// 0xFD 178: Reserved -// 0xFD 179: Reserved -// 0xFD 180: Reserved -OFD(I32x4__mul, "i32x4.mul", 0xFD, 181) -OFD(I32x4__min_s, "i32x4.min_s", 0xFD, 182) -OFD(I32x4__min_u, "i32x4.min_u", 0xFD, 183) -OFD(I32x4__max_s, "i32x4.max_s", 0xFD, 184) -OFD(I32x4__max_u, "i32x4.max_u", 0xFD, 185) -OFD(I32x4__dot_i16x8_s, "i32x4.dot_i16x8_s", 0xFD, 186) -// 0xFD 187: Reserved -OFD(I32x4__extmul_low_i16x8_s, "i32x4.extmul_low_i16x8_s", 0xFD, 188) -OFD(I32x4__extmul_high_i16x8_s, "i32x4.extmul_high_i16x8_s", 0xFD, 189) -OFD(I32x4__extmul_low_i16x8_u, "i32x4.extmul_low_i16x8_u", 0xFD, 190) -OFD(I32x4__extmul_high_i16x8_u, "i32x4.extmul_high_i16x8_u", 0xFD, 191) -OFD(I64x2__abs, "i64x2.abs", 0xFD, 192) -OFD(I64x2__neg, "i64x2.neg", 0xFD, 193) -// 0xFD 194: Reserved -OFD(I64x2__all_true, "i64x2.all_true", 0xFD, 195) -OFD(I64x2__bitmask, "i64x2.bitmask", 0xFD, 196) -// 0xFD 197: Reserved -// 0xFD 198: Reserved -OFD(I64x2__extend_low_i32x4_s, "i64x2.extend_low_i32x4_s", 0xFD, 199) -OFD(I64x2__extend_high_i32x4_s, "i64x2.extend_high_i32x4_s", 0xFD, 200) -OFD(I64x2__extend_low_i32x4_u, "i64x2.extend_low_i32x4_u", 0xFD, 201) -OFD(I64x2__extend_high_i32x4_u, "i64x2.extend_high_i32x4_u", 0xFD, 202) -OFD(I64x2__shl, "i64x2.shl", 0xFD, 203) -OFD(I64x2__shr_s, "i64x2.shr_s", 0xFD, 204) -OFD(I64x2__shr_u, "i64x2.shr_u", 0xFD, 205) -OFD(I64x2__add, "i64x2.add", 0xFD, 206) -// 0xFD 207: Reserved -// 0xFD 208: Reserved -OFD(I64x2__sub, "i64x2.sub", 0xFD, 209) -// 0xFD 210: Reserved -// 0xFD 211: Reserved -// 0xFD 212: Reserved -OFD(I64x2__mul, "i64x2.mul", 0xFD, 213) -OFD(I64x2__eq, "i64x2.eq", 0xFD, 214) -OFD(I64x2__ne, "i64x2.ne", 0xFD, 215) -OFD(I64x2__lt_s, "i64x2.lt_s", 0xFD, 216) -OFD(I64x2__gt_s, "i64x2.gt_s", 0xFD, 217) -OFD(I64x2__le_s, "i64x2.le_s", 0xFD, 218) -OFD(I64x2__ge_s, "i64x2.ge_s", 0xFD, 219) -OFD(I64x2__extmul_low_i32x4_s, "i64x2.extmul_low_i32x4_s", 0xFD, 220) -OFD(I64x2__extmul_high_i32x4_s, "i64x2.extmul_high_i32x4_s", 0xFD, 221) -OFD(I64x2__extmul_low_i32x4_u, "i64x2.extmul_low_i32x4_u", 0xFD, 222) -OFD(I64x2__extmul_high_i32x4_u, "i64x2.extmul_high_i32x4_u", 0xFD, 223) -OFD(F32x4__abs, "f32x4.abs", 0xFD, 224) -OFD(F32x4__neg, "f32x4.neg", 0xFD, 225) -// 0xFD 226: Reserved -OFD(F32x4__sqrt, "f32x4.sqrt", 0xFD, 227) -OFD(F32x4__add, "f32x4.add", 0xFD, 228) -OFD(F32x4__sub, "f32x4.sub", 0xFD, 229) -OFD(F32x4__mul, "f32x4.mul", 0xFD, 230) -OFD(F32x4__div, "f32x4.div", 0xFD, 231) -OFD(F32x4__min, "f32x4.min", 0xFD, 232) -OFD(F32x4__max, "f32x4.max", 0xFD, 233) -OFD(F32x4__pmin, "f32x4.pmin", 0xFD, 234) -OFD(F32x4__pmax, "f32x4.pmax", 0xFD, 235) -OFD(F64x2__abs, "f64x2.abs", 0xFD, 236) -OFD(F64x2__neg, "f64x2.neg", 0xFD, 237) -OFD(F64x2__sqrt, "f64x2.sqrt", 0xFD, 239) -OFD(F64x2__add, "f64x2.add", 0xFD, 240) -OFD(F64x2__sub, "f64x2.sub", 0xFD, 241) -OFD(F64x2__mul, "f64x2.mul", 0xFD, 242) -OFD(F64x2__div, "f64x2.div", 0xFD, 243) -OFD(F64x2__min, "f64x2.min", 0xFD, 244) -OFD(F64x2__max, "f64x2.max", 0xFD, 245) -OFD(F64x2__pmin, "f64x2.pmin", 0xFD, 246) -OFD(F64x2__pmax, "f64x2.pmax", 0xFD, 247) -OFD(I32x4__trunc_sat_f32x4_s, "i32x4.trunc_sat_f32x4_s", 0xFD, 248) -OFD(I32x4__trunc_sat_f32x4_u, "i32x4.trunc_sat_f32x4_u", 0xFD, 249) -OFD(F32x4__convert_i32x4_s, "f32x4.convert_i32x4_s", 0xFD, 250) -OFD(F32x4__convert_i32x4_u, "f32x4.convert_i32x4_u", 0xFD, 251) -OFD(I32x4__trunc_sat_f64x2_s_zero, "i32x4.trunc_sat_f64x2_s_zero", 0xFD, 252) -OFD(I32x4__trunc_sat_f64x2_u_zero, "i32x4.trunc_sat_f64x2_u_zero", 0xFD, 253) -OFD(F64x2__convert_low_i32x4_s, "f64x2.convert_low_i32x4_s", 0xFD, 254) -OFD(F64x2__convert_low_i32x4_u, "f64x2.convert_low_i32x4_u", 0xFD, 255) - -// 0xFE prefix - Relaxed SIMD Instructions (part 4) -OFD(I8x16__relaxed_swizzle, "i8x16.relaxed_swizzle", 0xFD, 256) -OFD(I32x4__relaxed_trunc_f32x4_s, "i32x4.relaxed_trunc_f32x4_s", 0xFD, 257) -OFD(I32x4__relaxed_trunc_f32x4_u, "i32x4.relaxed_trunc_f32x4_u", 0xFD, 258) -OFD(I32x4__relaxed_trunc_f64x2_s_zero, "i32x4.relaxed_trunc_f64x2_s_zero", 0xFD, - 259) -OFD(I32x4__relaxed_trunc_f64x2_u_zero, "i32x4.relaxed_trunc_f64x2_u_zero", 0xFD, - 260) -OFD(F32x4__relaxed_madd, "f32x4.relaxed_madd", 0xFD, 261) -OFD(F32x4__relaxed_nmadd, "f32x4.relaxed_nmadd", 0xFD, 262) -OFD(F64x2__relaxed_madd, "f32x4.relaxed_madd", 0xFD, 263) -OFD(F64x2__relaxed_nmadd, "f32x4.relaxed_nmadd", 0xFD, 264) -OFD(I8x16__relaxed_laneselect, "i8x16.relaxed_laneselect", 0xFD, 265) -OFD(I16x8__relaxed_laneselect, "i16x8.relaxed_laneselect", 0xFD, 266) -OFD(I32x4__relaxed_laneselect, "i32x4.relaxed_laneselect", 0xFD, 267) -OFD(I64x2__relaxed_laneselect, "i64x2.relaxed_laneselect", 0xFD, 268) -OFD(F32x4__relaxed_min, "f32x4.relaxed_min", 0xFD, 269) -OFD(F32x4__relaxed_max, "f32x4.relaxed_max", 0xFD, 270) -OFD(F64x2__relaxed_min, "f64x2.relaxed_min", 0xFD, 271) -OFD(F64x2__relaxed_max, "f64x2.relaxed_max", 0xFD, 272) -OFD(I16x8__relaxed_q15mulr_s, "i16x8.relaxed_q15mulr_s", 0xFD, 273) -OFD(I16x8__relaxed_dot_i8x16_i7x16_s, "i16x8.relaxed_dot_i8x16_i7x16_s", 0xFD, - 274) -OFD(I32x4__relaxed_dot_i8x16_i7x16_add_s, "i32x4.relaxed_dot_i8x16_i7x16_add_s", - 0xFD, 275) -// 0xFD 276 ~ 303: Reserved - -// 0xFE prefix - Atomic instructions -OFE(Memory__atomic__notify, "memory.atomic.notify", 0xFE, 0) -OFE(Memory__atomic__wait32, "memory.atomic.wait32", 0xFE, 1) -OFE(Memory__atomic__wait64, "memory.atomic.wait64", 0xFE, 2) -OFE(Atomic__fence, "atomic.fence", 0xFE, 3) -// 0xFE 4 ~ 15: Reserved -OFE(I32__atomic__load, "i32.atomic.load", 0xFE, 16) -OFE(I64__atomic__load, "i64.atomic.load", 0xFE, 17) -OFE(I32__atomic__load8_u, "i32.atomic.load8_u", 0xFE, 18) -OFE(I32__atomic__load16_u, "i32.atomic.load16_u", 0xFE, 19) -OFE(I64__atomic__load8_u, "i64.atomic.load8_u", 0xFE, 20) -OFE(I64__atomic__load16_u, "i64.atomic.load16_u", 0xFE, 21) -OFE(I64__atomic__load32_u, "i64.atomic.load32_u", 0xFE, 22) -OFE(I32__atomic__store, "i32.atomic.store", 0xFE, 23) -OFE(I64__atomic__store, "i64.atomic.store", 0xFE, 24) -OFE(I32__atomic__store8, "i32.atomic.store8", 0xFE, 25) -OFE(I32__atomic__store16, "i32.atomic.store16", 0xFE, 26) -OFE(I64__atomic__store8, "i64.atomic.store8", 0xFE, 27) -OFE(I64__atomic__store16, "i64.atomic.store16", 0xFE, 28) -OFE(I64__atomic__store32, "i64.atomic.store32", 0xFE, 29) -OFE(I32__atomic__rmw__add, "i32.atomic.rmw.add", 0xFE, 30) -OFE(I64__atomic__rmw__add, "i64.atomic.rmw.add", 0xFE, 31) -OFE(I32__atomic__rmw8__add_u, "i32.atomic.rmw8.add_u", 0xFE, 32) -OFE(I32__atomic__rmw16__add_u, "i32.atomic.rmw16.add_u", 0xFE, 33) -OFE(I64__atomic__rmw8__add_u, "i64.atomic.rmw8.add_u", 0xFE, 34) -OFE(I64__atomic__rmw16__add_u, "i64.atomic.rmw16.add_u", 0xFE, 35) -OFE(I64__atomic__rmw32__add_u, "i64.atomic.rmw32.add_u", 0xFE, 36) -OFE(I32__atomic__rmw__sub, "i32.atomic.rmw.sub", 0xFE, 37) -OFE(I64__atomic__rmw__sub, "i64.atomic.rmw.sub", 0xFE, 38) -OFE(I32__atomic__rmw8__sub_u, "i32.atomic.rmw8.sub_u", 0xFE, 39) -OFE(I32__atomic__rmw16__sub_u, "i32.atomic.rmw16.sub_u", 0xFE, 40) -OFE(I64__atomic__rmw8__sub_u, "i64.atomic.rmw8.sub_u", 0xFE, 41) -OFE(I64__atomic__rmw16__sub_u, "i64.atomic.rmw16.sub_u", 0xFE, 42) -OFE(I64__atomic__rmw32__sub_u, "i64.atomic.rmw32.sub_u", 0xFE, 43) -OFE(I32__atomic__rmw__and, "i32.atomic.rmw.and", 0xFE, 44) -OFE(I64__atomic__rmw__and, "i64.atomic.rmw.and", 0xFE, 45) -OFE(I32__atomic__rmw8__and_u, "i32.atomic.rmw8.and_u", 0xFE, 46) -OFE(I32__atomic__rmw16__and_u, "i32.atomic.rmw16.and_u", 0xFE, 47) -OFE(I64__atomic__rmw8__and_u, "i64.atomic.rmw8.and_u", 0xFE, 48) -OFE(I64__atomic__rmw16__and_u, "i64.atomic.rmw16.and_u", 0xFE, 49) -OFE(I64__atomic__rmw32__and_u, "i64.atomic.rmw32.and_u", 0xFE, 50) -OFE(I32__atomic__rmw__or, "i32.atomic.rmw.or", 0xFE, 51) -OFE(I64__atomic__rmw__or, "i64.atomic.rmw.or", 0xFE, 52) -OFE(I32__atomic__rmw8__or_u, "i32.atomic.rmw8.or_u", 0xFE, 53) -OFE(I32__atomic__rmw16__or_u, "i32.atomic.rmw16.or_u", 0xFE, 54) -OFE(I64__atomic__rmw8__or_u, "i64.atomic.rmw8.or_u", 0xFE, 55) -OFE(I64__atomic__rmw16__or_u, "i64.atomic.rmw16.or_u", 0xFE, 56) -OFE(I64__atomic__rmw32__or_u, "i64.atomic.rmw32.or_u", 0xFE, 57) -OFE(I32__atomic__rmw__xor, "i32.atomic.rmw.xor", 0xFE, 58) -OFE(I64__atomic__rmw__xor, "i64.atomic.rmw.xor", 0xFE, 59) -OFE(I32__atomic__rmw8__xor_u, "i32.atomic.rmw8.xor_u", 0xFE, 60) -OFE(I32__atomic__rmw16__xor_u, "i32.atomic.rmw16.xor_u", 0xFE, 61) -OFE(I64__atomic__rmw8__xor_u, "i64.atomic.rmw8.xor_u", 0xFE, 62) -OFE(I64__atomic__rmw16__xor_u, "i64.atomic.rmw16.xor_u", 0xFE, 63) -OFE(I64__atomic__rmw32__xor_u, "i64.atomic.rmw32.xor_u", 0xFE, 64) -OFE(I32__atomic__rmw__xchg, "i32.atomic.rmw.xchg", 0xFE, 65) -OFE(I64__atomic__rmw__xchg, "i64.atomic.rmw.xchg", 0xFE, 66) -OFE(I32__atomic__rmw8__xchg_u, "i32.atomic.rmw8.xchg_u", 0xFE, 67) -OFE(I32__atomic__rmw16__xchg_u, "i32.atomic.rmw16.xchg_u", 0xFE, 68) -OFE(I64__atomic__rmw8__xchg_u, "i64.atomic.rmw8.xchg_u", 0xFE, 69) -OFE(I64__atomic__rmw16__xchg_u, "i64.atomic.rmw16.xchg_u", 0xFE, 70) -OFE(I64__atomic__rmw32__xchg_u, "i64.atomic.rmw32.xchg_u", 0xFE, 71) -OFE(I32__atomic__rmw__cmpxchg, "i32.atomic.rmw.cmpxchg", 0xFE, 72) -OFE(I64__atomic__rmw__cmpxchg, "i64.atomic.rmw.cmpxchg", 0xFE, 73) -OFE(I32__atomic__rmw8__cmpxchg_u, "i32.atomic.rmw8.cmpxchg_u", 0xFE, 74) -OFE(I32__atomic__rmw16__cmpxchg_u, "i32.atomic.rmw16.cmpxchg_u", 0xFE, 75) -OFE(I64__atomic__rmw8__cmpxchg_u, "i64.atomic.rmw8.cmpxchg_u", 0xFE, 76) -OFE(I64__atomic__rmw16__cmpxchg_u, "i64.atomic.rmw16.cmpxchg_u", 0xFE, 77) -OFE(I64__atomic__rmw32__cmpxchg_u, "i64.atomic.rmw32.cmpxchg_u", 0xFE, 78) - -#undef O -#undef OFB -#undef OFC -#undef OFD -#undef OFE -#endif // UseOpCode - -// enum_configure.h - -#ifdef UseProposal -#define P Line -// Finished and standardized proposals -P(ImportExportMutGlobals, "Import/Export of Mutable Globals") -P(NonTrapFloatToIntConversions, "Non-trapping float-to-int Conversions") -P(SignExtensionOperators, "Sign-extension Operators") -P(MultiValue, "Multi-value") -P(BulkMemoryOperations, "Bulk Memory Operations") -P(ReferenceTypes, "Reference Types") -P(SIMD, "Fixed-width SIMD") -// Phase 4 proposals -P(TailCall, "Tail Call") -P(ExtendedConst, "Extended Const Expressions") -P(FunctionReferences, "Typed Function References") -P(GC, "Garbage Collection") -P(MultiMemories, "Multiple Memories") -P(Threads, "Threads") -P(RelaxSIMD, "Relaxed SIMD") -// Phase 3 proposals -P(Annotations, "Custom Annotation Syntax in the Text Format") -P(Memory64, "Memory64") -P(ExceptionHandling, "Exception Handling") -// Phase 1 proposals -P(Component, "Component Model") -#undef P -#endif // UseProposal - -#ifdef UseHostRegistration -#define H Line -H(Wasi) -#undef H -#endif // UseHostRegistration - -// enum_errcode.h - -#ifdef UseErrCategory -#define C Line - -C(WASM, 0x00) -C(UserLevelError, 0x01) - -#undef C -#endif // UseErrCategory - -#ifdef UseErrCode -#define E Line - -E(Success, 0x0000, "success") -// Exit and return success. -E(Terminated, 0x0001, "terminated") -// Generic runtime error. -E(RuntimeError, 0x0002, "generic runtime error") -// Exceeded cost limit (out of gas). -E(CostLimitExceeded, 0x0003, "cost limit exceeded") -// Wrong VM's workflow -E(WrongVMWorkflow, 0x0004, "wrong VM workflow") -// Wasm function not found -E(FuncNotFound, 0x0005, "wasm function not found") -// AOT runtime is disabled -E(AOTDisabled, 0x0006, "AOT runtime is disabled in this build") -// Execution interrupted -E(Interrupted, 0x0007, "execution interrupted") -// Not validated module -E(NotValidated, 0x0008, "wasm module hasn't passed validation yet") -// Non-Null value is required -E(NonNullRequired, 0x0009, "set null value into non-nullable value type") -// Unable to set value due to const -E(SetValueToConst, 0x000A, "set value into const") -// Set value failed due to mismatch value type -E(SetValueErrorType, 0x000B, "set value type mismatch") -// User defined error -E(UserDefError, 0x000C, "user defined error code") - -// Load phase -// @{ -// File not found -E(IllegalPath, 0x0100, "invalid path") -// Error when reading -E(ReadError, 0x0101, "read error") -// Reach end of file when reading -E(UnexpectedEnd, 0x0102, "unexpected end") -// Not detected magic header -E(MalformedMagic, 0x0103, "magic header not detected") -// Unsupported version -E(MalformedVersion, 0x0104, "unknown binary version") -// Malformed section ID -E(MalformedSection, 0x0105, "malformed section id") -// Section size mismatched -E(SectionSizeMismatch, 0x0106, "section size mismatch") -// Length out of bounds -E(LengthOutOfBounds, 0x0107, "length out of bounds") -// Junk sections -E(JunkSection, 0x0108, "unexpected content after last section") -// Incompatible function and code section -E(IncompatibleFuncCode, 0x0109, - "function and code section have inconsistent lengths") -// Incompatible data and datacount section -E(IncompatibleDataCount, 0x010A, - "data count and data section have inconsistent lengths") -// Datacount section required -E(DataCountRequired, 0x010B, "data count section required") -// Malformed import kind -E(MalformedImportKind, 0x010C, "malformed import kind") -// Malformed export kind -E(MalformedExportKind, 0x010D, "malformed export kind") -// Not loaded an expected zero byte -E(ExpectedZeroByte, 0x010E, "zero byte expected") -// Malformed mutability -E(InvalidMut, 0x010F, "malformed mutability") -// Local size too large -E(TooManyLocals, 0x0110, "too many locals") -// Malformed value type -E(MalformedValType, 0x0111, "malformed value type") -// Malformed element type (Bulk-mem proposal) -E(MalformedElemType, 0x0112, "malformed element type") -// Malformed reference type (Ref-types proposal) -E(MalformedRefType, 0x0113, "malformed reference type") -// Invalid utf-8 encoding -E(MalformedUTF8, 0x0114, "malformed UTF-8 encoding") -// Invalid too large integer -E(IntegerTooLarge, 0x0115, "integer too large") -// Invalid presentation too long integer -E(IntegerTooLong, 0x0116, "integer representation too long") -// Illegal OpCode -E(IllegalOpCode, 0x0117, "illegal opcode") -// END OpCode expected -E(ENDCodeExpected, 0x0118, "END opcode expected") -// Parsing error -E(IllegalGrammar, 0x0119, "invalid wasm grammar") -// Shared memory must have max -E(SharedMemoryNoMax, 0x011A, "shared memory must have maximum") -// Intrinsics table not found -E(IntrinsicsTableNotFound, 0x011B, "intrinsics table not found") -// Malformed table (Ref-types proposal) -E(MalformedTable, 0x011C, "malformed table") -// Alignment must < 64 without and < 128 with multi-memory proposal. -E(InvalidStoreAlignment, 0x011D, "invalid store alignment") -// @} - -// Validation phase -// @{ -// Alignment > natural -E(InvalidAlignment, 0x0200, "alignment must not be larger than natural") -// Got unexpected type when checking -E(TypeCheckFailed, 0x0201, "type mismatch") -// Branch to unknown label index -E(InvalidLabelIdx, 0x0202, "unknown label") -// Access unknown local index -E(InvalidLocalIdx, 0x0203, "unknown local") -// Access unknown field index -E(InvalidFieldIdx, 0x0204, "unknown field") -// Type index not defined -E(InvalidFuncTypeIdx, 0x0205, "unknown type") -// Function index not defined -E(InvalidFuncIdx, 0x0206, "unknown function") -// Table index not defined -E(InvalidTableIdx, 0x0207, "unknown table") -// Memory index not defined -E(InvalidMemoryIdx, 0x0208, "unknown memory") -// Global index not defined -E(InvalidGlobalIdx, 0x0209, "unknown global") -// Tag index not defined -E(InvalidTagIdx, 0x020A, "unknown tag") -// Element segment index not defined -E(InvalidElemIdx, 0x020B, "unknown elem segment") -// Data segment index not defined -E(InvalidDataIdx, 0x020C, "unknown data segment") -// Undeclared reference -E(InvalidRefIdx, 0x020D, "undeclared function reference") -// Should be constant expression -E(ConstExprRequired, 0x020E, "constant expression required") -// Export name conflicted -E(DupExportName, 0x020F, "duplicate export name") -// Tried to store to const global value -E(ImmutableGlobal, 0x0210, "global is immutable") -// Tried to store to const field of structure -E(ImmutableField, 0x0211, "field is immutable") -// Tried to store to const array -E(ImmutableArray, 0x0212, "array is immutable") -// Invalid result arity in select t* instruction -E(InvalidResultArity, 0x0213, "invalid result arity") -// #Tables > 1 (without Ref-types proposal) -E(MultiTables, 0x0214, "multiple tables") -// #Memories > 1 -E(MultiMemories, 0x0215, "multiple memories") -// Invalid Limit grammar -E(InvalidLimit, 0x0216, "size minimum must not be greater than maximum") -// Memory pages > 65536 -E(InvalidMemPages, 0x0217, "memory size must be at most 65536 pages (4GiB)") -// Invalid start function signature -E(InvalidStartFunc, 0x0218, "start function") -// Invalid lane index -E(InvalidLaneIdx, 0x0219, "invalid lane index") -// Invalid uninitialized local -E(InvalidUninitLocal, 0x021A, "uninitialized local") -// Defaultable field type required -E(InvalidNotDefaultableField, 0x021B, "field type is not defaultable") -// Defaultable array type required -E(InvalidNotDefaultableArray, 0x021C, "array type is not defaultable") -// Unpacked field type required, but got packed one -E(InvalidPackedField, 0x021D, "field is packed") -// Unpacked array type required, but got packed one -E(InvalidPackedArray, 0x021E, "array is packed") -// Packed field type required, but got unpacked one -E(InvalidUnpackedField, 0x021F, "field is unpacked") -// Packed array type required, but got unpacked one -E(InvalidUnpackedArray, 0x0220, "array is unpacked") -// Invalid Br ref type -E(InvalidBrRefType, 0x0221, "invalid br ref type") -// 2 array types not matched -E(ArrayTypesMismatch, 0x0222, "array types do not match") -// Should be numeric type in array type -E(ArrayTypesNumtypeRequired, 0x0223, "array type is not numeric or vector") -// Sub type matching or validation failed -E(InvalidSubType, 0x0224, "sub type") -// Invalid Tag type -E(InvalidTagResultType, 0x0225, "non-empty tag result type") -// @} - -// Instantiation phase -// @{ -// Module name conflicted when importing. -E(ModuleNameConflict, 0x0300, "module name conflict") -// Import matching failed -E(IncompatibleImportType, 0x0301, "incompatible import type") -// Unknown import instances -E(UnknownImport, 0x0302, "unknown import") -// Init failed when instantiating data segment -E(DataSegDoesNotFit, 0x0303, "data segment does not fit") -// Init failed when instantiating element segment -E(ElemSegDoesNotFit, 0x0304, "elements segment does not fit") -// Invalid core sort for component export -E(InvalidCoreSort, 0x0305, "invalid core sort") -E(InvalidCanonOption, 0x0306, "invalid canonical option") -// @} - -// Execution phase -// @{ -// Wrong access of instances addresses -E(WrongInstanceAddress, 0x0400, "wrong instance address") -// Wrong access of instances indices -E(WrongInstanceIndex, 0x0401, "wrong instance index") -// Instruction type not match -E(InstrTypeMismatch, 0x0402, "instruction type mismatch") -// Function signature not match when invoking -E(FuncSigMismatch, 0x0403, "function signature mismatch") -// Divide by zero -E(DivideByZero, 0x0404, "integer divide by zero") -// Integer overflow -E(IntegerOverflow, 0x0405, "integer overflow") -// Cannot do convert to integer -E(InvalidConvToInt, 0x0406, "invalid conversion to integer") -// Out of bounds table access -E(TableOutOfBounds, 0x0407, "out of bounds table access") -// Out of bounds memory access -E(MemoryOutOfBounds, 0x0408, "out of bounds memory access") -// Out of bounds array access -E(ArrayOutOfBounds, 0x0409, "out of bounds array access") -// Meet an unreachable instruction -E(Unreachable, 0x040A, "unreachable") -// Uninitialized element in table instance -E(UninitializedElement, 0x040B, "uninitialized element") -// Access undefined element in table instances -E(UndefinedElement, 0x040C, "undefined element") -// Func type mismatch in call_indirect -E(IndirectCallTypeMismatch, 0x040D, "indirect call type mismatch") -// Host function execution failed -E(HostFuncError, 0x040E, "host function failed") -// Reference type not match -E(RefTypeMismatch, 0x040F, "reference type mismatch") -// Unaligned atomic memory access -E(UnalignedAtomicAccess, 0x0410, "unaligned atomic") -// wait32/wait64 on unshared memory -E(ExpectSharedMemory, 0x0411, "expected shared memory") -// Cast null pointer to non null -E(CastNullToNonNull, 0x0412, "null reference") -// Access to null function reference -E(AccessNullFunc, 0x0413, "null function reference") -// Access to null structure reference -E(AccessNullStruct, 0x0414, "null structure reference") -// Access to null array reference -E(AccessNullArray, 0x0415, "null array reference") -// Access to null i31 reference -E(AccessNullI31, 0x0416, "null i31 reference") -// Access to null exception reference -E(AccessNullException, 0x0417, "null exception reference") -// Fail to cast reference -E(CastFailed, 0x0418, "cast failure") -// Uncaught Exception -E(UncaughtException, 0x0419, "uncaught exception") -// @} - -// Component model load phase -// @{ -// Malformed sort -E(MalformedSort, 0x0500, "malformed sort") -// Malformed alias target -E(MalformedAliasTarget, 0x0501, "malformed alias target") -// Malformed core instance -E(MalformedCoreInstance, 0x0502, "malformed core instance") -// Malformed instance -E(MalformedInstance, 0x0503, "malformed instance") -// Malformed defType -E(MalformedDefType, 0x0504, "malformed defined type") -// Malformed record type -E(MalformedRecordType, 0x0505, "malformed record type") -// Malformed variant type -E(MalformedVariantType, 0x0506, "malformed variant type") -// Malformed tuple type -E(MalformedTupleType, 0x0507, "malformed tuple type") -// Malformed flags type -E(MalformedFlagsType, 0x0508, "malformed flags type") -// Malformed canonical -E(MalformedCanonical, 0x0509, "malformed canonical") -// Unknown canonical option -E(UnknownCanonicalOption, 0x050A, "unknown canonical option") -// Malformed name -E(MalformedName, 0x050B, "malformed name") -// @} - -// Component model instantiation phase -// @{ -E(CoreInvalidExport, 0x0600, "invalid export in core module") -// @} - -#undef E -#endif // UseErrCode - -#ifdef UseWasmPhase -#define P Line - -P(WasmEdge, 0x00, "wasmedge runtime") -P(Loading, 0x01, "loading") -P(Validation, 0x02, "validation") -P(Instantiation, 0x03, "instantiation") -P(Execution, 0x04, "execution") -P(UserDefined, 0x05, "user defined") - -#undef P -#endif // UseWasmPhase - -// enum_errinfo.hpp - -#ifdef UsePtrType -#define P Line - -P(Index, "index") // Index of instances -P(Address, "address") // Absolute address - -#undef P -#endif // UsePtrType - -#ifdef UseMismatchCategory -#define M Line - -M(Alignment, "memory alignment") // Alignment in memory instructions -M(ValueType, "value type") // Value type -M(ValueTypes, "value types") // Value type list -M(Mutation, "mutation") // Const or Var -M(ExternalType, "external type") // External typing -M(FunctionType, "function type") // Function type -M(Table, "table") // Table instance -M(Memory, "memory") // Memory instance -M(Global, "global") // Global instance -M(Version, "version") // Versions - -#undef M -#endif // UseMismatchCategory - -#ifdef UseIndexCategory -#define I Line - -I(Label, "label") -I(Local, "local") -I(DefinedType, "defined type") -I(FunctionType, "function type") -I(Function, "function") -I(Table, "table") -I(Memory, "memory") -I(Global, "global") -I(Element, "element") -I(Data, "data") -I(Lane, "lane") -I(Field, "field") -I(TagType, "tag type") -I(Tag, "tag") - -#undef I -#endif // UseIndexCategory - -// enum_types.h - -#ifdef UseTypeCode -#define T Line - -T(TypeIndex, 0x00, "type_index") // 0x00 reserved for type index case -T(I32, 0x7F, "i32") // -0x01 for number type -T(I64, 0x7E, "i64") // -0x02 for number type -T(F32, 0x7D, "f32") // -0x03 for number type -T(F64, 0x7C, "f64") // -0x04 for number type -T(V128, 0x7B, "v128") // -0x05 for vector type -T(I8, 0x78, "i8") // -0x08 for packed type -T(I16, 0x77, "i16") // -0x09 for packed type -T(NullFuncRef, 0x73, "nofunc") // -0x0D for heap type -T(NullExternRef, 0x72, "noextern") // -0x0E for heap type -T(NullRef, 0x71, "none") // -0x0F for heap type -T(FuncRef, 0x70, "func") // -0x10 for heap type -T(ExternRef, 0x6F, "extern") // -0x11 for heap type -T(AnyRef, 0x6E, "any") // -0x12 for heap type -T(EqRef, 0x6D, "eq") // -0x13 for heap type -T(I31Ref, 0x6C, "i31") // -0x14 for heap type -T(StructRef, 0x6B, "struct") // -0x15 for heap type -T(ArrayRef, 0x6A, "array") // -0x16 for heap type -T(ExnRef, 0x69, "exn") // -0x17 for reference type -T(Ref, 0x64, "ref") // -0x1C for reference type -T(RefNull, 0x63, "ref_null") // -0x1D for reference type -T(Func, 0x60, "func") // -0x20 for composite type -T(Struct, 0x5F, "struct") // -0x21 for composite type -T(Array, 0x5E, "array") // -0x22 for composite type -T(Sub, 0x50, "sub") // -0x30 for sub type -T(SubFinal, 0x4F, "sub_final") // -0x31 for sub type -T(Rec, 0x4E, "rec") // -0x32 for recursive type -T(Epsilon, 0x40, "-") // -0x40 for result type -// component model types -T(String, 0x80, "string") // string type - -#undef T -#endif // UseTypeCode - -#ifdef UseValMut -#define M Line - -M(Const, 0x00, "const") -M(Var, 0x01, "var") - -#undef M -#endif // UseValMut - -#ifdef UseExternalType -#define E Line - -E(Function, 0x00U, "function") -E(Table, 0x01U, "table") -E(Memory, 0x02U, "memory") -E(Global, 0x03U, "global") -E(Tag, 0x04U, "tag") - -#undef E -#endif // UseExternalType diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_configure.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_configure.h deleted file mode 100644 index eb40f76c94c9bf0f1e1ea1751c1fa5e473f70824..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_configure.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_configure.h - Configure related enumerations -===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definitions of configure related enumerations. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_CONFIGURE_H -#define WASMEDGE_C_API_ENUM_CONFIGURE_H - -/// WASM Proposal C enumeration. -enum WasmEdge_Proposal { -#define UseProposal -#define Line(NAME, STRING) WasmEdge_Proposal_##NAME, -#include "enum.inc" -#undef Line -#undef UseProposal -}; - -/// Host Module Registration C enumeration. -enum WasmEdge_HostRegistration { -#define UseHostRegistration -#define Line(NAME) WasmEdge_HostRegistration_##NAME, -#include "enum.inc" -#undef Line -#undef UseHostRegistration -}; - -/// AOT compiler optimization level C enumeration. -enum WasmEdge_CompilerOptimizationLevel { - // Disable as many optimizations as possible. - WasmEdge_CompilerOptimizationLevel_O0 = 0, - // Optimize quickly without destroying debuggability. - WasmEdge_CompilerOptimizationLevel_O1, - // Optimize for fast execution as much as possible without triggering - // significant incremental compile time or code size growth. - WasmEdge_CompilerOptimizationLevel_O2, - // Optimize for fast execution as much as possible. - WasmEdge_CompilerOptimizationLevel_O3, - // Optimize for small code size as much as possible without triggering - // significant incremental compile time or execution time slowdowns. - WasmEdge_CompilerOptimizationLevel_Os, - // Optimize for small code size as much as possible. - WasmEdge_CompilerOptimizationLevel_Oz -}; - -/// AOT compiler output binary format C enumeration. -enum WasmEdge_CompilerOutputFormat { - // Native dynamic library format. - WasmEdge_CompilerOutputFormat_Native = 0, - // WebAssembly with AOT compiled codes in custom sections. - WasmEdge_CompilerOutputFormat_Wasm -}; - -#endif // WASMEDGE_C_API_ENUM_CONFIGURE_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_errcode.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_errcode.h deleted file mode 100644 index 68292cbcd960105fcf6f53699407657f4c5b1d13..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_errcode.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_errcode.h - Error code enumerations ----------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the enumerations of WasmEdge error code. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_ERRCODE_H -#define WASMEDGE_C_API_ENUM_ERRCODE_H - -/// Error category C enumeration. -enum WasmEdge_ErrCategory { -#define UseErrCategory -#define Line(NAME, VALUE) WasmEdge_ErrCategory_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseErrCategory -}; - -/// Error code C enumeration. -enum WasmEdge_ErrCode { -#define UseErrCode -#define Line(NAME, VALUE, STRING) WasmEdge_ErrCode_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseErrCode -}; - -#endif // WASMEDGE_C_API_ENUM_ERRCODE_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_types.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_types.h deleted file mode 100644 index 4b89c003f2e6aaed143c22667c0a51a62315b1b8..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/enum_types.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_types.h - WASM types related enumerations ----===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definitions of WASM types related enumerations. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_TYPES_H -#define WASMEDGE_C_API_ENUM_TYPES_H - -/// WASM Type code C enumeration. -enum WasmEdge_TypeCode { -#define UseTypeCode -#define Line(NAME, VALUE, STRING) WasmEdge_TypeCode_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseTypeCode -}; - -/// WASM Mutability C enumeration. -enum WasmEdge_Mutability { -#define UseValMut -#define Line(NAME, VALUE, STRING) WasmEdge_Mutability_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseValMut -}; - -/// WASM External type C enumeration. -enum WasmEdge_ExternalType { -#define UseExternalType -#define Line(NAME, VALUE, STRING) WasmEdge_ExternalType_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseExternalType -}; - -#endif // WASMEDGE_C_API_ENUM_TYPES_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/int128.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/int128.h deleted file mode 100644 index c4706fb22b4104231b67d381ac2aeb6a740fc84d..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/int128.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/int128.h - WasmEdge C API --------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the int128 definitions of the WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_INT128_H -#define WASMEDGE_C_API_INT128_H - -#if defined(__x86_64__) || defined(__aarch64__) || \ - (defined(__riscv) && __riscv_xlen == 64) -typedef unsigned __int128 uint128_t; -typedef __int128 int128_t; -#else -typedef struct uint128_t { - uint64_t Low; - uint64_t High; -} uint128_t; - -typedef struct int128_t { - uint64_t Low; - int64_t High; -} int128_t; -#endif - -#endif /// WASMEDGE_C_API_INT128_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/version.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/version.h deleted file mode 100644 index 2e092f7dfa0ec2d217602a331f2c802d38757539..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/version.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/version.h - WasmEdge C API -------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the version definitions of the WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_VERSION_H -#define WASMEDGE_C_API_VERSION_H - -// WasmEdge version. -#define WASMEDGE_VERSION "0.14.1-rc.3" -#define WASMEDGE_VERSION_MAJOR 0 -#define WASMEDGE_VERSION_MINOR 14 -#define WASMEDGE_VERSION_PATCH 1 - -#define WasmEdge_Plugin_CurrentAPIVersion 4 - -#endif // WASMEDGE_C_API_VERSION_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/wasmedge.h b/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/wasmedge.h deleted file mode 100644 index 8585c2f734cb38410f316fdfbe64d48180cfcd7b..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/include/wasmedge/wasmedge.h +++ /dev/null @@ -1,4183 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/wasmedge.h - WasmEdge C API ------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the function declarations of WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_H -#define WASMEDGE_C_API_H - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ - defined(__TOS_WIN__) || defined(__WINDOWS__) -#ifdef WASMEDGE_COMPILE_LIBRARY -#define WASMEDGE_CAPI_EXPORT __declspec(dllexport) -#else -#define WASMEDGE_CAPI_EXPORT __declspec(dllimport) -#endif // WASMEDGE_COMPILE_LIBRARY -#ifdef WASMEDGE_PLUGIN -#define WASMEDGE_CAPI_PLUGIN_EXPORT __declspec(dllexport) -#else -#define WASMEDGE_CAPI_PLUGIN_EXPORT __declspec(dllimport) -#endif // WASMEDGE_PLUGIN -#else -#define WASMEDGE_CAPI_EXPORT __attribute__((visibility("default"))) -#define WASMEDGE_CAPI_PLUGIN_EXPORT __attribute__((visibility("default"))) -#endif // _WIN32 - -#include -#include - -#include "wasmedge/enum_configure.h" -#include "wasmedge/enum_errcode.h" -#include "wasmedge/enum_types.h" -#include "wasmedge/int128.h" -#include "wasmedge/version.h" - -/// WasmEdge WASM value type struct. -typedef struct WasmEdge_ValType { - // This struct contains the raw data which describes the value type in WASM. - // Developers should use the corresponding `WasmEdge_ValueTypeGen` functions - // to generate this struct. - uint8_t Data[8]; -} WasmEdge_ValType; - -/// WasmEdge WASM value struct. -typedef struct WasmEdge_Value { - uint128_t Value; - // The value type `Type` is used in the parameters or returns of invoking - // functions. Developers should use the corresponding `WasmEdge_ValueGen` - // functions to generate this struct, and the `WasmEdge_ValueGet` functions to - // retrieve the value from this struct. - WasmEdge_ValType Type; -} WasmEdge_Value; - -/// WasmEdge string struct. -typedef struct WasmEdge_String { - uint32_t Length; - const char *Buf; -} WasmEdge_String; - -/// WasmEdge bytes struct. -typedef struct WasmEdge_Bytes { - uint32_t Length; - const uint8_t *Buf; -} WasmEdge_Bytes; - -/// WasmEdge result struct. -typedef struct WasmEdge_Result { - uint32_t Code; -} WasmEdge_Result; -#ifdef __cplusplus -#define WasmEdge_Result_Success (WasmEdge_Result{/* Code */ 0x00}) -#define WasmEdge_Result_Terminate (WasmEdge_Result{/* Code */ 0x01}) -#define WasmEdge_Result_Fail (WasmEdge_Result{/* Code */ 0x02}) -#else -#define WasmEdge_Result_Success ((WasmEdge_Result){.Code = 0x00}) -#define WasmEdge_Result_Terminate ((WasmEdge_Result){.Code = 0x01}) -#define WasmEdge_Result_Fail ((WasmEdge_Result){.Code = 0x02}) -#endif -/// Struct of WASM limit. -typedef struct WasmEdge_Limit { - /// Boolean to describe has max value or not. - bool HasMax; - /// Boolean to describe is shared memory or not. - bool Shared; - /// Minimum value. - uint32_t Min; - /// Maximum value. Will be ignored if the `HasMax` is false. - uint32_t Max; -} WasmEdge_Limit; - -/// Opaque struct of WasmEdge configure. -typedef struct WasmEdge_ConfigureContext WasmEdge_ConfigureContext; - -/// Opaque struct of WasmEdge statistics. -typedef struct WasmEdge_StatisticsContext WasmEdge_StatisticsContext; - -/// Opaque struct of WasmEdge AST module. -typedef struct WasmEdge_ASTModuleContext WasmEdge_ASTModuleContext; - -/// Opaque struct of WasmEdge function type. -typedef struct WasmEdge_FunctionTypeContext WasmEdge_FunctionTypeContext; - -/// Opaque struct of WasmEdge memory type. -typedef struct WasmEdge_MemoryTypeContext WasmEdge_MemoryTypeContext; - -/// Opaque struct of WasmEdge table type. -typedef struct WasmEdge_TableTypeContext WasmEdge_TableTypeContext; - -/// Opaque struct of WasmEdge tag type. -typedef struct WasmEdge_TagTypeContext WasmEdge_TagTypeContext; - -/// Opaque struct of WasmEdge global type. -typedef struct WasmEdge_GlobalTypeContext WasmEdge_GlobalTypeContext; - -/// Opaque struct of WasmEdge import type. -typedef struct WasmEdge_ImportTypeContext WasmEdge_ImportTypeContext; - -/// Opaque struct of WasmEdge export type. -typedef struct WasmEdge_ExportTypeContext WasmEdge_ExportTypeContext; - -/// Opaque struct of WasmEdge AOT compiler. -typedef struct WasmEdge_CompilerContext WasmEdge_CompilerContext; - -/// Opaque struct of WasmEdge loader. -typedef struct WasmEdge_LoaderContext WasmEdge_LoaderContext; - -/// Opaque struct of WasmEdge validator. -typedef struct WasmEdge_ValidatorContext WasmEdge_ValidatorContext; - -/// Opaque struct of WasmEdge executor. -typedef struct WasmEdge_ExecutorContext WasmEdge_ExecutorContext; - -/// Opaque struct of WasmEdge store. -typedef struct WasmEdge_StoreContext WasmEdge_StoreContext; - -/// Opaque struct of WasmEdge module instance. -typedef struct WasmEdge_ModuleInstanceContext WasmEdge_ModuleInstanceContext; - -/// Opaque struct of WasmEdge function instance. -typedef struct WasmEdge_FunctionInstanceContext - WasmEdge_FunctionInstanceContext; - -/// Opaque struct of WasmEdge table instance. -typedef struct WasmEdge_TableInstanceContext WasmEdge_TableInstanceContext; - -/// Opaque struct of WasmEdge memory instance. -typedef struct WasmEdge_MemoryInstanceContext WasmEdge_MemoryInstanceContext; - -/// Opaque struct of WasmEdge tag instance. -typedef struct WasmEdge_TagInstanceContext WasmEdge_TagInstanceContext; - -/// Opaque struct of WasmEdge global instance. -typedef struct WasmEdge_GlobalInstanceContext WasmEdge_GlobalInstanceContext; - -/// Opaque struct of WasmEdge calling frame. -typedef struct WasmEdge_CallingFrameContext WasmEdge_CallingFrameContext; - -/// Opaque struct of WasmEdge asynchronous result. -typedef struct WasmEdge_Async WasmEdge_Async; - -/// Opaque struct of WasmEdge VM. -typedef struct WasmEdge_VMContext WasmEdge_VMContext; - -/// Opaque struct of WasmEdge Plugin. -typedef struct WasmEdge_PluginContext WasmEdge_PluginContext; - -/// Type of option value. -typedef enum WasmEdge_ProgramOptionType { - /// No option value. - WasmEdge_ProgramOptionType_None, - /// Boolean value. - WasmEdge_ProgramOptionType_Toggle, - WasmEdge_ProgramOptionType_Int8, - WasmEdge_ProgramOptionType_Int16, - WasmEdge_ProgramOptionType_Int32, - WasmEdge_ProgramOptionType_Int64, - WasmEdge_ProgramOptionType_UInt8, - WasmEdge_ProgramOptionType_UInt16, - WasmEdge_ProgramOptionType_UInt32, - WasmEdge_ProgramOptionType_UInt64, - WasmEdge_ProgramOptionType_Float, - WasmEdge_ProgramOptionType_Double, - /// WasmEdge_String. - WasmEdge_ProgramOptionType_String, -} WasmEdge_ProgramOptionType; - -/// Program option for plugins. -typedef struct WasmEdge_ProgramOption { - const char *Name; - const char *Description; - WasmEdge_ProgramOptionType Type; - void *Storage; - const void *DefaultValue; -} WasmEdge_ProgramOption; - -/// Module descriptor for plugins. -typedef struct WasmEdge_ModuleDescriptor { - const char *Name; - const char *Description; - WasmEdge_ModuleInstanceContext *(*Create)( - const struct WasmEdge_ModuleDescriptor *); -} WasmEdge_ModuleDescriptor; - -/// Version data for plugins. -typedef struct WasmEdge_PluginVersionData { - uint32_t Major; - uint32_t Minor; - uint32_t Patch; - uint32_t Build; -} WasmEdge_PluginVersionData; - -/// Plugin descriptor for plugins. -typedef struct WasmEdge_PluginDescriptor { - const char *Name; - const char *Description; - uint32_t APIVersion; - WasmEdge_PluginVersionData Version; - uint32_t ModuleCount; - uint32_t ProgramOptionCount; - WasmEdge_ModuleDescriptor *ModuleDescriptions; - WasmEdge_ProgramOption *ProgramOptions; -} WasmEdge_PluginDescriptor; - -#ifdef __cplusplus -extern "C" { -#endif - -// >>>>>>>> WasmEdge version functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the version string of the WasmEdge C API. -/// -/// The returned string must __NOT__ be destroyed. -/// -/// \returns NULL-terminated C string of version. -WASMEDGE_CAPI_EXPORT extern const char *WasmEdge_VersionGet(void); - -/// Get the major version value of the WasmEdge C API. -/// -/// \returns Value of the major version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetMajor(void); - -/// Get the minor version value of the WasmEdge C API. -/// -/// \returns Value of the minor version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetMinor(void); - -/// Get the patch version value of the WasmEdge C API. -/// -/// \returns Value of the patch version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetPatch(void); - -// <<<<<<<< WasmEdge version functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge logging functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Set the logging system to filter to error level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogSetErrorLevel(void); - -/// Set the logging system to filter to debug level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogSetDebugLevel(void); - -/// Set the logging system off. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogOff(void); - -// <<<<<<<< WasmEdge logging functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge valtype functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Generate the I32 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the I32 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenI32(void); - -/// Generate the I64 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the I64 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenI64(void); - -/// Generate the F32 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the F32 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenF32(void); - -/// Generate the F64 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the F64 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenF64(void); - -/// Generate the V128 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the V128 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenV128(void); - -/// Generate the FuncRef WASM value type. -/// -/// \returns WasmEdge_ValType struct with the FuncRef value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenFuncRef(void); - -/// Generate the ExternRef WASM value type. -/// -/// \returns WasmEdge_ValType struct with the ExternRef value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenExternRef(void); - -/// Compare the two WasmEdge_ValType objects. -/// -/// \param ValType1 the first WasmEdge_ValType object to compare. -/// \param ValType2 the second WasmEdge_ValType object to compare. -/// -/// \returns true if the content of two WasmEdge_ValType objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsEqual(const WasmEdge_ValType ValType1, - const WasmEdge_ValType ValType2); - -/// Specify the WASM value type is an I32 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an I32, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsI32(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is an I64 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an I64, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsI64(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a F32 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a F32, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsF32(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a F64 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a F64, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsF64(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a V128 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a V128, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsV128(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a FuncRef or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a FuncRef, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsFuncRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is an ExternRef or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an ExternRef, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsExternRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a Ref (includes nullable and non-nullable) or -/// not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a Ref, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a nullable Ref or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a nullable Ref, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsRefNull(const WasmEdge_ValType ValType); - -// <<<<<<<< WasmEdge valtype functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge value functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Generate the I32 WASM value. -/// -/// \param Val the I32 value. -/// -/// \returns WasmEdge_Value struct with the I32 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenI32(const int32_t Val); - -/// Generate the I64 WASM value. -/// -/// \param Val the I64 value. -/// -/// \returns WasmEdge_Value struct with the I64 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenI64(const int64_t Val); - -/// Generate the F32 WASM value. -/// -/// \param Val the F32 value. -/// -/// \returns WasmEdge_Value struct with the F32 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenF32(const float Val); - -/// Generate the F64 WASM value. -/// -/// \param Val the F64 value. -/// -/// \returns WasmEdge_Value struct with the F64 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenF64(const double Val); - -/// Generate the V128 WASM value. -/// -/// \param Val the V128 value. -/// -/// \returns WasmEdge_Value struct with the V128 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenV128(const int128_t Val); - -/// Generate the function reference WASM value. -/// -/// The values generated by this function are only meaningful when the -/// `WasmEdge_Proposal_BulkMemoryOperations` or the -/// `WasmEdge_Proposal_ReferenceTypes` turns on in configuration. -/// -/// \param Cxt the function instance context to convert to the reference. -/// -/// \returns WasmEdge_Value struct with the function reference. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenFuncRef(const WasmEdge_FunctionInstanceContext *Cxt); - -/// Generate the function reference WASM value. -/// -/// The values generated by this function are only meaningful when the -/// `WasmEdge_Proposal_ReferenceTypes` turns on in configuration. -/// -/// \param Ref the reference to the external object. -/// -/// \returns WasmEdge_Value struct with the external reference. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenExternRef(void *Ref); - -/// Retrieve the I32 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns I32 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int32_t -WasmEdge_ValueGetI32(const WasmEdge_Value Val); - -/// Retrieve the I64 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns I64 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int64_t -WasmEdge_ValueGetI64(const WasmEdge_Value Val); - -/// Retrieve the F32 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns F32 value in the input struct. -WASMEDGE_CAPI_EXPORT extern float -WasmEdge_ValueGetF32(const WasmEdge_Value Val); - -/// Retrieve the F64 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns F64 value in the input struct. -WASMEDGE_CAPI_EXPORT extern double -WasmEdge_ValueGetF64(const WasmEdge_Value Val); - -/// Retrieve the V128 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns V128 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int128_t -WasmEdge_ValueGetV128(const WasmEdge_Value Val); - -/// Specify the WASM value is a null reference or not. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns true if the value is a null reference, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValueIsNullRef(const WasmEdge_Value Val); - -/// Retrieve the function instance context from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns pointer to function instance context in the input struct. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionInstanceContext * -WasmEdge_ValueGetFuncRef(const WasmEdge_Value Val); - -/// Retrieve the external reference from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns external reference in the input struct. -WASMEDGE_CAPI_EXPORT extern void * -WasmEdge_ValueGetExternRef(const WasmEdge_Value Val); - -// <<<<<<<< WasmEdge value functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge string functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_String with the C string. -/// -/// The caller owns the object and should call `WasmEdge_StringDelete` to -/// destroy it. This function only supports the C string with NULL termination. -/// If the input string may have `\0` character, please use the -/// `WasmEdge_StringCreateByBuffer` instead. -/// -/// \param Str the NULL-terminated C string to copy into the WasmEdge_String -/// object. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed or -/// the input string is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringCreateByCString(const char *Str); - -/// Creation of the WasmEdge_String with the buffer and its length. -/// -/// The caller owns the object and should call `WasmEdge_StringDelete` to -/// destroy it. -/// -/// \param Buf the buffer to wrap to the WasmEdge_String object. -/// \param Len the buffer length. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed or -/// the input buffer is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringCreateByBuffer(const char *Buf, const uint32_t Len); - -/// Create the WasmEdge_String wraps to the buffer. -/// -/// This function creates a `WasmEdge_String` object which wraps to the input -/// buffer. The caller should guarantee the life cycle of the input buffer, and -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Buf the buffer to copy into the WasmEdge_String object. -/// \param Len the buffer length. -/// -/// \returns string object refer to the input buffer with its length. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringWrap(const char *Buf, const uint32_t Len); - -/// Compare the two WasmEdge_String objects. -/// -/// \param Str1 the first WasmEdge_String object to compare. -/// \param Str2 the second WasmEdge_String object to compare. -/// -/// \returns true if the content of two WasmEdge_String objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_StringIsEqual(const WasmEdge_String Str1, const WasmEdge_String Str2); - -/// Copy the content of WasmEdge_String object to the buffer. -/// -/// This function copy at most `Len` characters from the `WasmEdge_String` -/// object to the destination buffer. If the string length is less than `Len` -/// characters long, the remainder of the buffer is filled with `\0' characters. -/// Otherwise, the destination is not terminated. -/// -/// \param Str the source WasmEdge_String object to copy. -/// \param Buf the buffer to fill the string content. -/// \param Len the buffer length. -/// -/// \returns the copied length of string. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StringCopy(const WasmEdge_String Str, char *Buf, const uint32_t Len); - -/// Deletion of the WasmEdge_String. -/// -/// After calling this function, the resources in the WasmEdge_String object -/// will be released and the object should __NOT__ be used. -/// -/// \param Str the WasmEdge_String object to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_StringDelete(WasmEdge_String Str); - -// <<<<<<<< WasmEdge string functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge bytes functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_Bytes with the buffer and its length. -/// -/// The caller owns the object and should call `WasmEdge_BytesDelete` to destroy -/// it. -/// -/// \param Buf the buffer to copy into the WasmEdge_Bytes object. -/// \param Len the buffer length. -/// -/// \returns bytes object. Length will be 0 and Buf will be NULL if failed or -/// the input buffer is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Bytes -WasmEdge_BytesCreate(const uint8_t *Buf, const uint32_t Len); - -/// Create the WasmEdge_Bytes wraps to the buffer. -/// -/// This function creates a `WasmEdge_Bytes` object which wraps to the input -/// buffer. The caller should guarantee the life cycle of the input buffer, and -/// should __NOT__ call the `WasmEdge_BytesDelete`. -/// -/// \param Buf the buffer to wrap to the WasmEdge_Bytes object. -/// \param Len the buffer length. -/// -/// \returns bytes object refer to the input buffer with its length. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Bytes -WasmEdge_BytesWrap(const uint8_t *Buf, const uint32_t Len); - -/// Deletion of the WasmEdge_Bytes. -/// -/// After calling this function, the resources in the WasmEdge_Bytes object -/// will be released and the object should __NOT__ be used. -/// -/// \param Bytes the WasmEdge_Bytes object to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_BytesDelete(WasmEdge_Bytes Bytes); - -// <<<<<<<< WasmEdge bytes functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge result functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Check the result is a success or not. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns true if the error code is WasmEdge_Result_Success or -/// WasmEdge_Result_Terminate, false for others. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ResultOK(const WasmEdge_Result Res); - -/// Generate the result with code. -/// -/// \param Category the WasmEdge_ErrCategory to specify the error category. -/// \param Code the 24-bit length error code. The data exceeds 24 bits will be -/// stripped. -/// -/// \returns WasmEdge_Result struct with the given data. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ResultGen(const enum WasmEdge_ErrCategory Category, - const uint32_t Code); - -/// Get the result code. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns result code (24-bit size data) in the WasmEdge_Result struct. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ResultGetCode(const WasmEdge_Result Res); - -/// Get the error category. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns error category in the WasmEdge_Result struct. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ErrCategory -WasmEdge_ResultGetCategory(const WasmEdge_Result Res); - -/// Get the result message. -/// -/// The returned string must __NOT__ be destroyed. -/// If the error category of the result is __NOT__ `WasmEdge_ErrCategory_WASM`, -/// the message will always be "user defined error code". -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns NULL-terminated C string of the corresponding error message. -WASMEDGE_CAPI_EXPORT extern const char * -WasmEdge_ResultGetMessage(const WasmEdge_Result Res); - -// <<<<<<<< WasmEdge result functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge limit functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Compare the two WasmEdge_Limit objects. -/// -/// \param Lim1 the first WasmEdge_Limit object to compare. -/// \param Lim2 the second WasmEdge_Limit object to compare. -/// -/// \returns true if the content of two WasmEdge_Limit objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_LimitIsEqual(const WasmEdge_Limit Lim1, const WasmEdge_Limit Lim2); - -// <<<<<<<< WasmEdge limit functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge configure functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ConfigureContext. -/// -/// The caller owns the object and should call `WasmEdge_ConfigureDelete` to -/// destroy it. -/// -/// \returns pointer to the context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ConfigureContext * -WasmEdge_ConfigureCreate(void); - -/// Add a proposal setting into the WasmEdge_ConfigureContext. -/// -/// For turning on a specific WASM proposal in VM, loader, or compiler contexts, -/// etc., you can set the proposal value into the WasmEdge_ConfigureContext and -/// create the VM, loader, or compiler contexts, etc. with this context. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_BulkMemoryOperations); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_ReferenceTypes); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_SIMD); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to add the proposal value. -/// \param Prop the proposal value. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureAddProposal(WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Remove a proposal setting in the WasmEdge_ConfigureContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to remove the proposal. -/// \param Prop the proposal value. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureRemoveProposal(WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Check if a proposal setting exists in the WasmEdge_ConfigureContext or not. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to check the proposal value. -/// \param Prop the proposal value. -/// -/// \returns true if the proposal setting exists, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureHasProposal(const WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Add a built-in host registration setting into WasmEdge_ConfigureContext. -/// -/// For turning on the Wasi support in `WasmEdge_VMContext`, you can set the -/// built-in host registration value into the `WasmEdge_ConfigureContext` and -/// create VM with this context. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddHostRegistration(Conf, WasmEdge_HostRegistration_Wasi); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to add built-in host registration. -/// \param Host the built-in host registration value. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureAddHostRegistration( - WasmEdge_ConfigureContext *Cxt, const enum WasmEdge_HostRegistration Host); - -/// Remove a built-in host registration setting in the -/// WasmEdge_ConfigureContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to remove the host -/// pre-registration. -/// \param Host the built-in host registration value. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureRemoveHostRegistration( - WasmEdge_ConfigureContext *Cxt, const enum WasmEdge_HostRegistration Host); - -/// Check if a built-in host registration setting exists in the -/// WasmEdge_ConfigureContext or not. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to check the host pre-registration. -/// \param Host the built-in host registration value. -/// -/// \returns true if the built-in host registration setting exists, false if -/// not. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureHasHostRegistration( - const WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_HostRegistration Host); - -/// Set the page limit of memory instances. -/// -/// Limit the page count (64KiB per page) in memory instances. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the maximum page count. -/// \param Page the maximum page count. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetMaxMemoryPage(WasmEdge_ConfigureContext *Cxt, - const uint32_t Page); - -/// Get the setting of the page limit of memory instances. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the maximum page count -/// setting. -/// -/// \returns the page count limitation value. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ConfigureGetMaxMemoryPage(const WasmEdge_ConfigureContext *Cxt); - -/// Set the force interpreter mode execution option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsForceInterpreter the boolean value to determine to forcibly run -/// WASM in interpreter mode or not. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetForceInterpreter(WasmEdge_ConfigureContext *Cxt, - const bool IsForceInterpreter); - -/// Get the force interpreter mode execution option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to forcibly run WASM in interpreter -/// mode or not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureIsForceInterpreter(const WasmEdge_ConfigureContext *Cxt); - -/// Set the option of enabling/disabling AF_UNIX support in the WASI socket. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param EnableAFUNIX the boolean value to determine to enable -/// the AF_UNIX support in the WASI socket or not. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetAllowAFUNIX(WasmEdge_ConfigureContext *Cxt, - const bool EnableAFUNIX); - -/// Get the AllowAFUNIX option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to enable AF_UNIX support in the -/// WASI socket or not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureIsAllowAFUNIX(const WasmEdge_ConfigureContext *Cxt); - -/// Set the optimization level of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the optimization level. -/// \param Level the AOT compiler optimization level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureCompilerSetOptimizationLevel( - WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_CompilerOptimizationLevel Level); - -/// Get the optimization level of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the optimization level. -/// -/// \returns the AOT compiler optimization level. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_CompilerOptimizationLevel -WasmEdge_ConfigureCompilerGetOptimizationLevel( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the output binary format of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the output binary format. -/// \param Format the AOT compiler output binary format. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureCompilerSetOutputFormat( - WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_CompilerOutputFormat Format); - -/// Get the output binary format of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the output binary format. -/// -/// \returns the AOT compiler output binary format. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_CompilerOutputFormat -WasmEdge_ConfigureCompilerGetOutputFormat(const WasmEdge_ConfigureContext *Cxt); - -/// Set the dump IR option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsDump the boolean value to determine to dump IR or not when -/// compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetDumpIR(WasmEdge_ConfigureContext *Cxt, - const bool IsDump); - -/// Get the dump IR option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to dump IR or not when compilation -/// in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsDumpIR(const WasmEdge_ConfigureContext *Cxt); - -/// Set the generic binary option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsGeneric the boolean value to determine to generate the generic -/// binary or not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetGenericBinary(WasmEdge_ConfigureContext *Cxt, - const bool IsGeneric); - -/// Get the generic binary option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to generate the generic binary or -/// not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsGenericBinary(const WasmEdge_ConfigureContext *Cxt); - -/// Set the interruptible option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsInterruptible the boolean value to determine to generate -/// interruptible binary or not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetInterruptible(WasmEdge_ConfigureContext *Cxt, - const bool IsInterruptible); - -/// Get the interruptible option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to generate interruptible binary or -/// not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsInterruptible(const WasmEdge_ConfigureContext *Cxt); - -/// Set the instruction counting option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsCount the boolean value to determine to support instruction -/// counting when execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetInstructionCounting( - WasmEdge_ConfigureContext *Cxt, const bool IsCount); - -/// Get the instruction counting option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support instruction counting when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureStatisticsIsInstructionCounting( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the cost measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsMeasure the boolean value to determine to support cost measuring -/// when execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetCostMeasuring(WasmEdge_ConfigureContext *Cxt, - const bool IsMeasure); - -/// Get the cost measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support cost measuring when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureStatisticsIsCostMeasuring( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the time measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsMeasure the boolean value to determine to support time when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetTimeMeasuring(WasmEdge_ConfigureContext *Cxt, - const bool IsMeasure); - -/// Get the time measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support time measuring when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureStatisticsIsTimeMeasuring( - const WasmEdge_ConfigureContext *Cxt); - -/// Deletion of the WasmEdge_ConfigureContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureDelete(WasmEdge_ConfigureContext *Cxt); - -// <<<<<<<< WasmEdge configure functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge statistics functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_StatisticsContext. -/// -/// The caller owns the object and should call `WasmEdge_StatisticsDelete` to -/// destroy it. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StatisticsContext * -WasmEdge_StatisticsCreate(void); - -/// Get the instruction count in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the instruction count in total execution. -WASMEDGE_CAPI_EXPORT extern uint64_t -WasmEdge_StatisticsGetInstrCount(const WasmEdge_StatisticsContext *Cxt); - -/// Get the instruction count per second in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the instruction count per second. -WASMEDGE_CAPI_EXPORT extern double -WasmEdge_StatisticsGetInstrPerSecond(const WasmEdge_StatisticsContext *Cxt); - -/// Get the total cost in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the total cost. -WASMEDGE_CAPI_EXPORT extern uint64_t -WasmEdge_StatisticsGetTotalCost(const WasmEdge_StatisticsContext *Cxt); - -/// Set the costs of instructions. -/// -/// \param Cxt the WasmEdge_StatisticsContext to set the cost table. -/// \param CostArr the cost table array. -/// \param Len the length of the cost table array. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsSetCostTable(WasmEdge_StatisticsContext *Cxt, - uint64_t *CostArr, const uint32_t Len); - -/// Set the cost limit in execution. -/// -/// The WASM execution will be aborted if the instruction costs exceeded the -/// limit and the ErrCode::Value::CostLimitExceeded will be returned. -/// -/// \param Cxt the WasmEdge_StatisticsContext to set the cost table. -/// \param Limit the cost limit. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsSetCostLimit(WasmEdge_StatisticsContext *Cxt, - const uint64_t Limit); - -/// Clear all data in the WasmEdge_StatisticsContext. -/// -/// \param Cxt the WasmEdge_StatisticsContext to clear. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsClear(WasmEdge_StatisticsContext *Cxt); - -/// Deletion of the WasmEdge_StatisticsContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_StatisticsContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsDelete(WasmEdge_StatisticsContext *Cxt); - -// <<<<<<<< WasmEdge statistics functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge AST module functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the length of imports list of the AST module. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// -/// \returns length of the imports list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListImportsLength(const WasmEdge_ASTModuleContext *Cxt); - -/// List the imports of the AST module. -/// -/// If the `Imports` buffer length is smaller than the result of the imports -/// list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// \param [out] Imports the import type contexts buffer. Can be NULL if import -/// types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListImports(const WasmEdge_ASTModuleContext *Cxt, - const WasmEdge_ImportTypeContext **Imports, - const uint32_t Len); - -/// Get the length of exports list of the AST module. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// -/// \returns length of the exports list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListExportsLength(const WasmEdge_ASTModuleContext *Cxt); - -/// List the exports of the AST module. -/// -/// If the `Exports` buffer length is smaller than the result of the exports -/// list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// \param [out] Exports the export type contexts buffer. Can be NULL if export -/// types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListExports(const WasmEdge_ASTModuleContext *Cxt, - const WasmEdge_ExportTypeContext **Exports, - const uint32_t Len); - -/// Deletion of the WasmEdge_ASTModuleContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ASTModuleContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ASTModuleDelete(WasmEdge_ASTModuleContext *Cxt); - -// <<<<<<<< WasmEdge AST module functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge function type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_FunctionTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_FunctionTypeDelete` to -/// destroy it. -/// -/// \param ParamList the value types list of parameters. NULL if the length is -/// 0. -/// \param ParamLen the ParamList buffer length. -/// \param ReturnList the value types list of returns. NULL if the length is 0. -/// \param ReturnLen the ReturnList buffer length. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionTypeContext * -WasmEdge_FunctionTypeCreate(const WasmEdge_ValType *ParamList, - const uint32_t ParamLen, - const WasmEdge_ValType *ReturnList, - const uint32_t ReturnLen); - -/// Get the parameter types list length from the WasmEdge_FunctionTypeContext. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// -/// \returns the parameter types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_FunctionTypeGetParametersLength( - const WasmEdge_FunctionTypeContext *Cxt); - -/// Get the parameter types list from the WasmEdge_FunctionTypeContext. -/// -/// If the `List` buffer length is smaller than the length of the parameter type -/// list, the overflowed values will be discarded. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// \param [out] List the WasmEdge_ValType buffer to fill the parameter value -/// types. -/// \param Len the value type buffer length. -/// -/// \returns the actual parameter types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetParameters(const WasmEdge_FunctionTypeContext *Cxt, - WasmEdge_ValType *List, const uint32_t Len); - -/// Get the return types list length from the WasmEdge_FunctionTypeContext. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// -/// \returns the return types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetReturnsLength(const WasmEdge_FunctionTypeContext *Cxt); - -/// Get the return types list from the WasmEdge_FunctionTypeContext. -/// -/// If the `List` buffer length is smaller than the length of the return type -/// list, the overflowed values will be discarded. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// \param [out] List the WasmEdge_ValType buffer to fill the return value -/// types. -/// \param Len the value type buffer length. -/// -/// \returns the actual return types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetReturns(const WasmEdge_FunctionTypeContext *Cxt, - WasmEdge_ValType *List, const uint32_t Len); - -/// Deletion of the WasmEdge_FunctionTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_FunctionTypeDelete(WasmEdge_FunctionTypeContext *Cxt); - -// <<<<<<<< WasmEdge function type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge table type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_TableTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_TableTypeDelete` to -/// destroy it. -/// -/// \param RefType the value type of the table type. This value type should be a -/// reference type, or this function will fail. -/// \param Limit the limit struct of the table type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableTypeContext * -WasmEdge_TableTypeCreate(const WasmEdge_ValType RefType, - const WasmEdge_Limit Limit); - -/// Get the reference type from a table type. -/// -/// \param Cxt the WasmEdge_TableTypeContext. -/// -/// \returns the value type of the table type. This value type will must be a -/// reference type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType -WasmEdge_TableTypeGetRefType(const WasmEdge_TableTypeContext *Cxt); - -/// Get the limit from a table type. -/// -/// \param Cxt the WasmEdge_TableTypeContext. -/// -/// \returns the limit struct of the table type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Limit -WasmEdge_TableTypeGetLimit(const WasmEdge_TableTypeContext *Cxt); - -/// Deletion of the WasmEdge_TableTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_TableTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_TableTypeDelete(WasmEdge_TableTypeContext *Cxt); - -// <<<<<<<< WasmEdge table type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge memory type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_MemoryTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_MemoryTypeDelete` to -/// destroy it. -/// -/// \param Limit the limit struct of the memory type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryTypeContext * -WasmEdge_MemoryTypeCreate(const WasmEdge_Limit Limit); - -/// Get the limit from a memory type. -/// -/// \param Cxt the WasmEdge_MemoryTypeContext. -/// -/// \returns the limit struct of the memory type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Limit -WasmEdge_MemoryTypeGetLimit(const WasmEdge_MemoryTypeContext *Cxt); - -/// Deletion of the WasmEdge_MemoryTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_MemoryTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_MemoryTypeDelete(WasmEdge_MemoryTypeContext *Cxt); - -// <<<<<<<< WasmEdge memory type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge tag type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the function type from a tag type. -/// -/// \param Cxt the WasmEdge_TagTypeContext. -/// -/// \returns pointer to function type context of the tag type, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_TagTypeGetFunctionType(const WasmEdge_TagTypeContext *Cxt); - -// <<<<<<<< WasmEdge tag type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge global type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_GlobalTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_GlobalTypeDelete` to -/// destroy it. -/// -/// \param ValType the value type of the global type. -/// \param Mut the mutation of the global type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalTypeContext * -WasmEdge_GlobalTypeCreate(const WasmEdge_ValType ValType, - const enum WasmEdge_Mutability Mut); - -/// Get the value type from a global type. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext. -/// -/// \returns the value type of the global type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType -WasmEdge_GlobalTypeGetValType(const WasmEdge_GlobalTypeContext *Cxt); - -/// Get the mutability from a global type. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext. -/// -/// \returns the mutability of the global type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_Mutability -WasmEdge_GlobalTypeGetMutability(const WasmEdge_GlobalTypeContext *Cxt); - -/// Deletion of the WasmEdge_GlobalTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_GlobalTypeDelete(WasmEdge_GlobalTypeContext *Cxt); - -// <<<<<<<< WasmEdge global type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge import type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the external type from an import type. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns the external type of the import type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ExternalType -WasmEdge_ImportTypeGetExternalType(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the module name from an import type. -/// -/// The returned string object is linked to the module name of the import type, -/// and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ImportTypeGetModuleName(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external name from an import type. -/// -/// The returned string object is linked to the external name of the import -/// type, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ImportTypeGetExternalName(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is function type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The function type context links to the function type in the import type -/// context and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the function type. NULL if failed or the external type of the -/// import type is not `WasmEdge_ExternalType_Function`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_ImportTypeGetFunctionType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is table type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The table type context links to the table type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the table type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Table`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_ImportTypeGetTableType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is memory type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The memory type context links to the memory type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the memory type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Memory`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_ImportTypeGetMemoryType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is tag type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The tag type context links to the tag type in the import type context -/// and the AST module context. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the tag type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_TagType`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_ImportTypeGetTagType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is global type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The global type context links to the global type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the global type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Global`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_ImportTypeGetGlobalType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -// <<<<<<<< WasmEdge import type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge export type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the external type from an export type. -/// -/// \param Cxt the WasmEdge_ExportTypeContext. -/// -/// \returns the external type of the export type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ExternalType -WasmEdge_ExportTypeGetExternalType(const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external name from an export type. -/// -/// The returned string object is linked to the external name of the export -/// type, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ExportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ExportTypeGetExternalName(const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is function type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The function type context links to the function type in the export type -/// context and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the function type. NULL if failed or the external type of the -/// export type is not `WasmEdge_ExternalType_Function`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_ExportTypeGetFunctionType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is table type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The table type context links to the table type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the table type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Table`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_ExportTypeGetTableType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is memory type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The memory type context links to the memory type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the memory type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Memory`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_ExportTypeGetMemoryType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is tag type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The tag type context links to the tag type in the export type context -/// and the AST module context. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the tag type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Tag`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_ExportTypeGetTagType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is global type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The global type context links to the global type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the global type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Global`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_ExportTypeGetGlobalType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -// <<<<<<<< WasmEdge export type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge AOT compiler functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_CompilerContext. -/// -/// The caller owns the object and should call `WasmEdge_CompilerDelete` to -/// delete it. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_CompilerContext * -WasmEdge_CompilerCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Compile the input WASM from the file path. -/// -/// The compiler compiles the WASM from file path for the ahead-of-time mode and -/// store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param InPath the input WASM file path. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_CompilerCompile(WasmEdge_CompilerContext *Cxt, const char *InPath, - const char *OutPath); - -/// Compile the input WASM from the given buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_CompilerCompileFromBytes()` API in the future. -/// -/// The compiler compiles the WASM from the given buffer for the -/// ahead-of-time mode and store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param InBuffer the input WASM binary buffer. -/// \param InBufferLen the length of the input WASM binary buffer. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_CompilerCompileFromBuffer( - WasmEdge_CompilerContext *Cxt, const uint8_t *InBuffer, - const uint64_t InBufferLen, const char *OutPath); - -/// Compile the input WASM from a WasmEdge_Bytes. -/// -/// The compiler compiles the WASM from the WasmEdge_Bytes for the -/// ahead-of-time mode and store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_CompilerCompileFromBytes(WasmEdge_CompilerContext *Cxt, - const WasmEdge_Bytes Bytes, - const char *OutPath); - -/// Deletion of the WasmEdge_CompilerContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_CompilerContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_CompilerDelete(WasmEdge_CompilerContext *Cxt); - -// <<<<<<<< WasmEdge AOT compiler functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge loader functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_LoaderContext. -/// -/// The caller owns the object and should call `WasmEdge_LoaderDelete` to -/// destroy it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of Loader. -/// NULL for the default configuration. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_LoaderContext * -WasmEdge_LoaderCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Load and parse the WASM module from a WASM file into a -/// WasmEdge_ASTModuleContext. -/// -/// Load and parse the WASM module from the file path, and return a -/// `WasmEdge_ASTModuleContext` as the result. The caller owns the -/// `WasmEdge_ASTModuleContext` object and should call -/// `WasmEdge_ASTModuleDelete` to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromFile(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const char *Path); - -/// Load and parse the WASM module from a buffer into WasmEdge_ASTModuleContext. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_LoaderParseFromBytes()` API in the future. -/// -/// Load and parse the WASM module from a buffer, and return a -/// WasmEdge_ASTModuleContext as the result. The caller owns the -/// WasmEdge_ASTModuleContext object and should call `WasmEdge_ASTModuleDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromBuffer(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const uint8_t *Buf, const uint32_t BufLen); - -/// Load and parse the WASM module from a WasmEdge_Bytes into -/// WasmEdge_ASTModuleContext. -/// -/// Load and parse the WASM module from a buffer, and return a -/// WasmEdge_ASTModuleContext as the result. The caller owns the -/// WasmEdge_ASTModuleContext object and should call `WasmEdge_ASTModuleDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromBytes(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const WasmEdge_Bytes Bytes); - -/// Serialize the WasmEdge_ASTModuleContext into WASM binary. -/// -/// Serialize the loaded WasmEdge_ASTModuleContext into the WASM binary format. -/// If the serialization succeeded, this API will allocate a new -/// `WasmEdge_Bytes` object and fill into the `Buf`. The caller owns the -/// `WasmEdge_Bytes` object and should call `WasmEdge_BytesDelete` to destroy -/// it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param ASTCxt the WasmEdge_ASTModuleContext to serialize. -/// \param [out] Buf the WasmEdge_Bytes to fill the serialized WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderSerializeASTModule(WasmEdge_LoaderContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt, - WasmEdge_Bytes *Buf); - -/// Deletion of the WasmEdge_LoaderContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_LoaderContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_LoaderDelete(WasmEdge_LoaderContext *Cxt); - -// <<<<<<<< WasmEdge loader functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge validator functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ValidatorContext. -/// -/// The caller owns the object and should call `WasmEdge_ValidatorDelete` to -/// destroy it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of -/// Validator. NULL for the default configuration. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValidatorContext * -WasmEdge_ValidatorCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Validate the WasmEdge AST Module. -/// -/// \param Cxt the WasmEdge_ValidatorContext. -/// \param ASTCxt the WasmEdge_ASTModuleContext to validate. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ValidatorValidate(WasmEdge_ValidatorContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Deletion of the WasmEdge_ValidatorContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ValidatorContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ValidatorDelete(WasmEdge_ValidatorContext *Cxt); - -// <<<<<<<< WasmEdge validator functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge executor functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ExecutorContext. -/// -/// The caller owns the object and should call `WasmEdge_ExecutorDelete` to -/// delete it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of -/// Executor. NULL for the default configuration. -/// \param StatCxt the WasmEdge_StatisticsContext as the statistics object set -/// into Executor. The statistics will refer to this context, and the life cycle -/// should be guaranteed until the executor context is deleted. NULL for not -/// doing the statistics. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_ExecutorCreate(const WasmEdge_ConfigureContext *ConfCxt, - WasmEdge_StatisticsContext *StatCxt); - -/// Instantiate an AST Module into a module instance. -/// -/// Instantiate an AST Module, and return an instantiated module instance -/// context as the result. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. Developers can use the -/// `WasmEdge_ModuleInstanceListFunction`, -/// `WasmEdge_ModuleInstanceFindFunction`, etc. APIs to retrieve the exported -/// instances from the result module instance. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param [out] ModuleCxt the output WasmEdge_ModuleInstanceContext if -/// succeeded. -/// \param StoreCxt the WasmEdge_StoreContext to link the imports. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorInstantiate( - WasmEdge_ExecutorContext *Cxt, WasmEdge_ModuleInstanceContext **ModuleCxt, - WasmEdge_StoreContext *StoreCxt, const WasmEdge_ASTModuleContext *ASTCxt); - -/// Instantiate an AST Module into a named module instance and link into store. -/// -/// Instantiate an AST Module with the module name, return the instantiated -/// module instance context as the result, and also register the module instance -/// to the store. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// Developers can use the `WasmEdge_ModuleInstanceListFunction`, -/// `WasmEdge_ModuleInstanceFindFunction`, etc. APIs to retrieve the exported -/// instances from the result module instance. -/// After calling this function, the output module instance will also be -/// registered into the store, and the other modules can import the exported -/// instances for linking when instantiation. Developers SHOULD guarantee the -/// life cycle of this output module instance, or the error will occur when in -/// execution after the module instance being destroyed if it has been imported -/// by other modules. That is, developers have the responsibility to delete the -/// output module instance even though the store being destroyed. When the -/// module instance is deleted, it will be unregistered to the store -/// automatically. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param [out] ModuleCxt the output WasmEdge_ModuleInstanceContext if -/// succeeded. -/// \param StoreCxt the WasmEdge_StoreContext to link the imports. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param ModuleName the module name WasmEdge_String for all exported -/// instances. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorRegister( - WasmEdge_ExecutorContext *Cxt, WasmEdge_ModuleInstanceContext **ModuleCxt, - WasmEdge_StoreContext *StoreCxt, const WasmEdge_ASTModuleContext *ASTCxt, - WasmEdge_String ModuleName); - -/// Register a module instance into a store with exporting its module name. -/// -/// Register an existing module into the store with its module name. -/// After calling this function, the existing module instance will be registered -/// into the store, and the other modules can import the exported instances for -/// linking when instantiation. Developers SHOULD guarantee the life cycle of -/// this existing module instance, or the error will occur when in execution -/// after the module instance being destroyed if it has been imported by other -/// modules. When the module instance is deleted, it will be unregistered to the -/// store automatically. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param StoreCxt the WasmEdge_StoreContext to store the instantiated module. -/// \param ImportCxt the WasmEdge_ModuleInstanceContext to register. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorRegisterImport( - WasmEdge_ExecutorContext *Cxt, WasmEdge_StoreContext *StoreCxt, - const WasmEdge_ModuleInstanceContext *ImportCxt); - -/// Invoke a WASM function by the function instance. -/// -/// After instantiating a WASM module, developers can get the function instance -/// context from the module instance. Then developers can invoke the function -/// through this API. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param FuncCxt the function instance context to invoke. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ExecutorInvoke(WasmEdge_ExecutorContext *Cxt, - const WasmEdge_FunctionInstanceContext *FuncCxt, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Asynchronous invoke a WASM function by the function instance. -/// -/// After instantiating a WASM module, developers can get the function instance -/// context from the module instance. Then developers can invoke the function -/// asynchronously through this API. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param FuncCxt the function instance context to invoke. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_ExecutorAsyncInvoke(WasmEdge_ExecutorContext *Cxt, - const WasmEdge_FunctionInstanceContext *FuncCxt, - const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Deletion of the WasmEdge_ExecutorContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ExecutorContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorDelete(WasmEdge_ExecutorContext *Cxt); - -// <<<<<<<< WasmEdge executor functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge store functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_StoreContext. -/// -/// The caller owns the object and should call `WasmEdge_StoreDelete` to destroy -/// it. -/// The store is the linker for multiple WASM module instances. The store will -/// not own any module instance registered into it, and the module instances -/// will automatically be unregistered if they are destroyed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StoreContext *WasmEdge_StoreCreate(void); - -/// Get the module instance context by the module name. -/// -/// After registering a WASM module, developers can call this function to find -/// and get the registered module instance context by the module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// \param Name the module name WasmEdge_String. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_StoreFindModule(const WasmEdge_StoreContext *Cxt, - const WasmEdge_String Name); - -/// Get the length of registered module list in store. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// -/// \returns length of registered named module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StoreListModuleLength(const WasmEdge_StoreContext *Cxt); - -/// List the registered module names. -/// -/// This function will list all registered module names. -/// The returned module names filled into the `Names` array are linked to the -/// registered module names in the store context, and the caller should __NOT__ -/// call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the registered -/// named module list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// \param [out] Names the output names WasmEdge_String buffer of named modules. -/// \param Len the buffer length. -/// -/// \returns actual registered named module list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StoreListModule(const WasmEdge_StoreContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Deletion of the WasmEdge_StoreContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// If there are module instances registered into this store context, they will -/// be automatically un-link to this store context. -/// -/// \param Cxt the WasmEdge_StoreContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StoreDelete(WasmEdge_StoreContext *Cxt); - -// <<<<<<<< WasmEdge store functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge module instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ModuleInstanceContext. -/// -/// Create a module instance context with exported module name for host -/// instances. Developer can use this API to create a module instance for -/// collecting host functions, tables, memories, tags, and globals. -/// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` -/// to destroy it. -/// -/// \param ModuleName the module name WasmEdge_String of this host module to -/// import. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreate(const WasmEdge_String ModuleName); - -/// Creation of the WasmEdge_ModuleInstanceContext with host data. -/// -/// Create a module instance context with exported module name, host data, and -/// host data finalizer for host instances. Developer can use this API to create -/// a module instance for collecting host functions, tables, memories, and -/// globals. When this created module instance being destroyed, the host data -/// finalizer will be invoked. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// -/// \param ModuleName the module name WasmEdge_String of this host module to -/// import. -/// \param HostData the host data to set into the module instance. When calling -/// the finalizer, this pointer will become the argument of the finalizer -/// function. -/// \param Finalizer the function to finalize the host data. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreateWithData(const WasmEdge_String ModuleName, - void *HostData, - void (*Finalizer)(void *)); - -/// Creation of the WasmEdge_ModuleInstanceContext for the WASI specification. -/// -/// This function will create a WASI host module that contains the WASI host -/// functions and initialize it. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// -/// \param Args the command line arguments. The first argument suggests being -/// the program name. NULL if the length is 0. -/// \param ArgLen the length of the command line arguments. -/// \param Envs the environment variables in the format `ENV=VALUE`. NULL if the -/// length is 0. -/// \param EnvLen the length of the environment variables. -/// \param Preopens the directory paths to preopen. String format in -/// `GUEST_PATH:HOST_PATH` means the path mapping, or the same path will be -/// mapped. NULL if the length is 0. -/// \param PreopenLen the length of the directory paths to preopen. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreateWASI(const char *const *Args, - const uint32_t ArgLen, - const char *const *Envs, - const uint32_t EnvLen, - const char *const *Preopens, - const uint32_t PreopenLen); - -/// Initialize the WasmEdge_ModuleInstanceContext for the WASI specification. -/// -/// This function will initialize the WASI host module with the parameters. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// \param Args the command line arguments. The first argument suggests being -/// the program name. NULL if the length is 0. -/// \param ArgLen the length of the command line arguments. -/// \param Envs the environment variables in the format `ENV=VALUE`. NULL if the -/// length is 0. -/// \param EnvLen the length of the environment variables. -/// \param Preopens the directory paths to preopen. String format in -/// `GUEST_PATH:HOST_PATH` means the path mapping, or the same path will be -/// mapped. NULL if the length is 0. -/// \param PreopenLen the length of the directory paths to preopen. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ModuleInstanceInitWASI( - WasmEdge_ModuleInstanceContext *Cxt, const char *const *Args, - const uint32_t ArgLen, const char *const *Envs, const uint32_t EnvLen, - const char *const *Preopens, const uint32_t PreopenLen); - -/// Get the WASI exit code. -/// -/// This function will return the exit code after running the "_start" function -/// of a `wasm32-wasi` program. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// -/// \returns the exit code after executing the "_start" function. Return -/// `EXIT_FAILURE` if the `Cxt` is NULL or not a WASI host module. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceWASIGetExitCode( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the native handler from the WASI mapped FD/Handler. -/// -/// This function will return the raw FD/Handler from a given mapped Fd -/// or Handler. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// \param Fd the WASI mapped Fd. -/// \param [out] NativeHandler the raw Fd/Handler. -/// -/// \returns the error code. Return `0` if the Native Handler is found. -/// Return `1` if the `Cxt` is `NULL`. -/// Return `2` if the given mapped Fd/handler is not found. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceWASIGetNativeHandler( - const WasmEdge_ModuleInstanceContext *Cxt, int32_t Fd, - uint64_t *NativeHandler); - -/// Initialize the WasmEdge_ModuleInstanceContext for the wasmedge_process -/// specification. -/// -/// This function will initialize the wasmedge_process host module with the -/// parameters. -/// -/// \param AllowedCmds the allowed commands white list. NULL if the -/// length is 0. -/// \param CmdsLen the length of the allowed commands white list. -/// \param AllowAll the boolean value to allow all commands. `false` is -/// suggested. If this value is `true`, the allowed commands white list will not -/// be recorded and all commands can be executed by wasmedge_process. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceInitWasmEdgeProcess(const char *const *AllowedCmds, - const uint32_t CmdsLen, - const bool AllowAll); - -/// Get the export module name of a module instance. -/// -/// The returned string object is linked to the module name of the module -/// instance, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ModuleInstanceGetModuleName(const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the host data set into the module instance when creating. -/// -/// The returned data is owned by the module instance, and will be passed into -/// the finalizer when deleting this module instance. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns host data. NULL if the module instance context is NULL or no host -/// data set into the module instance. -WASMEDGE_CAPI_EXPORT extern void * -WasmEdge_ModuleInstanceGetHostData(const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the exported function instance context of a module instance. -/// -/// The result function instance context links to the function instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_FunctionInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the function name WasmEdge_String. -/// -/// \returns pointer to the function instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_ModuleInstanceFindFunction(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported table instance context of a module instance. -/// -/// The result table instance context links to the table instance in the module -/// instance context and owned by the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_TableInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the table name WasmEdge_String. -/// -/// \returns pointer to the table instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_ModuleInstanceFindTable(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported memory instance context of a module instance. -/// -/// The result memory instance context links to the memory instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_MemoryInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the memory name WasmEdge_String. -/// -/// \returns pointer to the memory instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_ModuleInstanceFindMemory(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported tag instance context of a module instance. -/// -/// The result tag instance context links to the tag instance in the -/// module instance context and owned by the module instance context. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the tag name WasmEdge_String. -/// -/// \returns pointer to the tag instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TagInstanceContext * -WasmEdge_ModuleInstanceFindTag(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported global instance context of a module instance. -/// -/// The result global instance context links to the global instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_GlobalInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the global name WasmEdge_String. -/// -/// \returns pointer to the global instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalInstanceContext * -WasmEdge_ModuleInstanceFindGlobal(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the length of exported function list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported function list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListFunctionLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported function names of a module instance. -/// -/// The returned function names filled into the `Names` array are linked to the -/// exported names of functions of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// function list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListFunction(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported table list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported table list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListTableLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported table names of a module instance. -/// -/// The returned table names filled into the `Names` array are linked to the -/// exported names of tables of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// table list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the table names. -/// \param Len the buffer length. -/// -/// \returns actual exported table list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTable(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported memory list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported memory list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListMemoryLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported memory names of a module instance. -/// -/// The returned memory names filled into the `Names` array are linked to the -/// exported names of memories of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// memory list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the memory names. -/// \param Len the buffer length. -/// -/// \returns actual exported memory list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListMemory(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported tag list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported tag list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTagLength(const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported tag names of a module instance. -/// -/// The returned tag names filled into the `Names` array are linked to the -/// exported names of tags of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// tag list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the tag names. -/// \param Len the buffer length. -/// -/// \returns actual exported tag list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTag(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported global list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported global list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListGlobalLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported global names of a module instance. -/// -/// The returned global names filled into the `Names` array are linked to the -/// exported names of globals of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// global list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the global names. -/// \param Len the buffer length. -/// -/// \returns actual exported global list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListGlobal(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Add a function instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the function instance into the module -/// instance. The caller should __NOT__ access or destroy the function instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the function instance. -/// \param Name the export function name WasmEdge_String. -/// \param FuncCxt the WasmEdge_FunctionInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddFunction(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_FunctionInstanceContext *FuncCxt); - -/// Add a table instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the table instance into the module -/// instance. The caller should __NOT__ access or destroy the table instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the table instance. -/// \param Name the export table name WasmEdge_String. -/// \param TableCxt the WasmEdge_TableInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddTable(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_TableInstanceContext *TableCxt); - -/// Add a memory instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the memory instance into the module -/// instance. The caller should __NOT__ access or destroy the memory instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the memory instance. -/// \param Name the export memory name WasmEdge_String. -/// \param MemoryCxt the WasmEdge_MemoryInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddMemory(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_MemoryInstanceContext *MemoryCxt); - -/// Add a global instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the global instance into the module -/// instance. The caller should __NOT__ access or destroy the global instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the global instance. -/// \param Name the export global name WasmEdge_String. -/// \param GlobalCxt the WasmEdge_GlobalInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddGlobal(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_GlobalInstanceContext *GlobalCxt); - -/// Deletion of the WasmEdge_ModuleInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// If the module instance has been registered into one or more store contexts, -/// it will be automatically unregistered. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceDelete(WasmEdge_ModuleInstanceContext *Cxt); - -// <<<<<<<< WasmEdge module instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge function instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -typedef WasmEdge_Result (*WasmEdge_HostFunc_t)( - void *Data, const WasmEdge_CallingFrameContext *CallFrameCxt, - const WasmEdge_Value *Params, WasmEdge_Value *Returns); -/// Creation of the WasmEdge_FunctionInstanceContext for host functions. -/// -/// The caller owns the object and should call `WasmEdge_FunctionInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. The following is an example to create a -/// host function context. -/// ```c -/// WasmEdge_Result FuncAdd(void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *In, WasmEdge_Value *Out) { -/// // Function to return A + B. -/// int32_t A = WasmEdge_ValueGetI32(In[0]); -/// int32_t B = WasmEdge_ValueGetI32(In[1]); -/// Out[0] = WasmEdge_ValueGenI32(A + B); -/// // Return execution status -/// return WasmEdge_Result_Success; -/// } -/// -/// WasmEdge_ValType Params[2] = {WasmEdge_ValTypeGenI32(), -/// WasmEdge_ValTypeGenI32()}; -/// WasmEdge_ValType Returns[1] = {WasmEdge_ValTypeGenI32()}; -/// WasmEdge_FunctionTypeContext *FuncType = -/// WasmEdge_FunctionTypeCreate(Params, 2, Returns, 1); -/// WasmEdge_FunctionInstanceContext *HostFunc = -/// WasmEdge_FunctionInstanceCreate(FuncType, FuncAdd, NULL, 0); -/// WasmEdge_FunctionTypeDelete(FuncType); -/// ... -/// ``` -/// -/// \param Type the function type context to describe the host function -/// signature. -/// \param HostFunc the host function pointer. The host function signature must -/// be as following: -/// ```c -/// typedef WasmEdge_Result (*WasmEdge_HostFunc_t)( -/// void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *Params, -/// WasmEdge_Value *Returns); -/// ``` -/// The `Params` is the input parameters array with length guaranteed to be the -/// same as the parameter types in the `Type`. The `Returns` is the output -/// results array with length guaranteed to be the same as the result types in -/// the `Type`. The return value is `WasmEdge_Result` for the execution status. -/// \param Data the additional object, such as the pointer to a data structure, -/// to set to this host function context. The caller should guarantee the life -/// cycle of the object. NULL if the additional data object is not needed. -/// \param Cost the function cost in statistics. Pass 0 if the calculation is -/// not needed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_FunctionInstanceCreate(const WasmEdge_FunctionTypeContext *Type, - WasmEdge_HostFunc_t HostFunc, void *Data, - const uint64_t Cost); - -typedef WasmEdge_Result (*WasmEdge_WrapFunc_t)( - void *This, void *Data, const WasmEdge_CallingFrameContext *CallFrameCxt, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); -/// Creation of the WasmEdge_FunctionInstanceContext for host functions. -/// -/// This function is for the languages which cannot pass the function pointer of -/// the host function into this shared library directly. The caller owns the -/// object and should call `WasmEdge_FunctionInstanceDelete` to destroy it if -/// the returned object is not added into a `WasmEdge_ModuleInstanceContext`. -/// The following is an example to create a host function context for other -/// languages. -/// ```c -/// // `RealFunc` is the pointer to the function in other languages. -/// -/// WasmEdge_Result FuncAddWrap( -/// void *This, void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *In, const uint32_t InLen, WasmEdge_Value *Out, -/// const uint32_t OutLen) { -/// // Wrapper function of host function to return A + B. -/// -/// // `This` is the same as `RealFunc`. -/// int32_t A = WasmEdge_ValueGetI32(In[0]); -/// int32_t B = WasmEdge_ValueGetI32(In[1]); -/// -/// // Call the function of `This` in the host language ... -/// int32_t Result = ...; -/// -/// Out[0] = Result; -/// // Return the execution status. -/// return WasmEdge_Result_Success; -/// } -/// -/// WasmEdge_ValType Params[2] = {WasmEdge_ValTypeGenI32(), -/// WasmEdge_ValTypeGenI32()}; -/// WasmEdge_ValType Returns[1] = {WasmEdge_ValTypeGenI32()}; -/// WasmEdge_FunctionTypeContext *FuncType = -/// WasmEdge_FunctionTypeCreate(Params, 2, Returns, 1); -/// WasmEdge_FunctionInstanceContext *HostFunc = -/// WasmEdge_FunctionInstanceCreateBinding( -/// FuncType, FuncAddWrap, RealFunc, NULL, 0); -/// WasmEdge_FunctionTypeDelete(FuncType); -/// ... -/// ``` -/// -/// \param Type the function type context to describe the host function -/// signature. -/// \param WrapFunc the wrapper function pointer. The wrapper function signature -/// must be as following: -/// ```c -/// typedef WasmEdge_Result (*WasmEdge_WrapFunc_t)( -/// void *This, -/// void *Data, -/// WasmEdge_CallingFrameContext *FrameCxt, -/// const WasmEdge_Value *Params, -/// const uint32_t ParamLen, -/// WasmEdge_Value *Returns, -/// const uint32_t ReturnLen); -/// ``` -/// The `This` is the pointer the same as the `Binding` parameter of this -/// function. The `Params` is the input parameters array with length guaranteed -/// to be the same as the parameter types in the `Type`, and the `ParamLen` is -/// the length of the array. The `Returns` is the output results array with -/// length guaranteed to be the same as the result types in the `Type`, and the -/// `ReturnLen` is the length of the array. The return value is -/// `WasmEdge_Result` for the execution status. -/// \param Binding the `this` pointer of the host function target or the -/// function indexing maintained by the caller which can specify the host -/// function. When invoking the host function, this pointer will be the first -/// argument of the wrapper function. -/// \param Data the additional object, such as the pointer to a data structure, -/// to set to this host function context. The caller should guarantee the life -/// cycle of the object. NULL if the additional data object is not needed. -/// \param Cost the function cost in statistics. Pass 0 if the calculation is -/// not needed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_FunctionInstanceCreateBinding(const WasmEdge_FunctionTypeContext *Type, - WasmEdge_WrapFunc_t WrapFunc, - void *Binding, void *Data, - const uint64_t Cost); - -/// Get the function data field of the function instance. -/// -/// The function data is passed when creating the FunctionInstance. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext. -/// -/// \returns pointer to Data, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const void * -WasmEdge_FunctionInstanceGetData(const WasmEdge_FunctionInstanceContext *Cxt); - -/// Get the function type context of the function instance. -/// -/// The function type context links to the function type in the function -/// instance context and owned by the context. The caller should __NOT__ call -/// the `WasmEdge_FunctionTypeDelete`. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_FunctionInstanceGetFunctionType( - const WasmEdge_FunctionInstanceContext *Cxt); - -/// Deletion of the WasmEdge_FunctionInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_FunctionInstanceDelete(WasmEdge_FunctionInstanceContext *Cxt); - -// <<<<<<<< WasmEdge function instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge table instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_TableInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_TableInstanceDelete` to -/// destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// The default value of the elements in the output table instance will be null -/// references with the same reference type in the table type when table grows. -/// If the reference type of the input table type is a non-nullable value type, -/// a non-null default init value is required. In this case, please use the -/// `WasmEdge_TableInstanceCreateWithInit` API instead. -/// -/// \param TabType the table type context to initialize the table instance -/// context. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_TableInstanceCreate(const WasmEdge_TableTypeContext *TabType); - -/// Creation of the WasmEdge_TableInstanceContext with the default init value. -/// -/// The caller owns the object and should call `WasmEdge_TableInstanceDelete` to -/// destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// The value type of the default init value should compatible with the -/// reference type of the input table type, otherwise this function will fail. -/// If the reference type of the input table type is a non-nullable value type, -/// this function will fail if the default init value is a null reference. -/// -/// \param TabType the table type context to initialize the table instance -/// context. -/// \param Value the default init value for the table element when table -/// grows. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_TableInstanceCreateWithInit(const WasmEdge_TableTypeContext *TabType, - const WasmEdge_Value Value); - -/// Get the table type context from a table instance. -/// -/// The table type context links to the table type in the table instance context -/// and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_TableInstanceGetTableType(const WasmEdge_TableInstanceContext *Cxt); - -/// Get the reference value in a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param [out] Data the result reference value. -/// \param Offset the reference value offset (index) in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceGetData(const WasmEdge_TableInstanceContext *Cxt, - WasmEdge_Value *Data, const uint32_t Offset); - -/// Set the reference value into a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param Data the reference value to set into the table instance. -/// \param Offset the reference value offset (index) in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceSetData(WasmEdge_TableInstanceContext *Cxt, - WasmEdge_Value Data, const uint32_t Offset); - -/// Get the size of a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// -/// \returns the size of the table instance. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_TableInstanceGetSize(const WasmEdge_TableInstanceContext *Cxt); - -/// Grow a table instance with a size. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param Size the count of reference values to grow in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceGrow(WasmEdge_TableInstanceContext *Cxt, - const uint32_t Size); - -/// Deletion of the WasmEdge_TableInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_TableInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_TableInstanceDelete(WasmEdge_TableInstanceContext *Cxt); - -// <<<<<<<< WasmEdge table instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge memory instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_MemoryInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_MemoryInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// -/// \param MemType the memory type context to initialize the memory instance -/// context. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_MemoryInstanceCreate(const WasmEdge_MemoryTypeContext *MemType); - -/// Get the memory type context from a memory instance. -/// -/// The memory type context links to the memory type in the memory instance -/// context and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_MemoryInstanceGetMemoryType(const WasmEdge_MemoryInstanceContext *Cxt); - -/// Copy the data to the output buffer from a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param [out] Data the result data buffer of copying destination. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will failed. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceGetData(const WasmEdge_MemoryInstanceContext *Cxt, - uint8_t *Data, const uint32_t Offset, - const uint32_t Length); - -/// Copy the data into a memory instance from the input buffer. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Data the data buffer to copy. -/// \param Offset the data start offset in the memory instance. -/// \param Length the data buffer length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will failed. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceSetData(WasmEdge_MemoryInstanceContext *Cxt, - const uint8_t *Data, const uint32_t Offset, - const uint32_t Length); - -/// Get the data pointer in a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will return NULL. -/// -/// \returns the pointer to data with the start offset. NULL if failed. -WASMEDGE_CAPI_EXPORT extern uint8_t * -WasmEdge_MemoryInstanceGetPointer(WasmEdge_MemoryInstanceContext *Cxt, - const uint32_t Offset, const uint32_t Length); - -/// Get the const data pointer in a const memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will return NULL. -/// -/// \returns the pointer to data with the start offset. NULL if failed. -WASMEDGE_CAPI_EXPORT extern const uint8_t * -WasmEdge_MemoryInstanceGetPointerConst( - const WasmEdge_MemoryInstanceContext *Cxt, const uint32_t Offset, - const uint32_t Length); - -/// Get the current page size (64 KiB of each page) of a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// -/// \returns the page size of the memory instance. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_MemoryInstanceGetPageSize(const WasmEdge_MemoryInstanceContext *Cxt); - -/// Grow a memory instance with a page size. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Page the page count to grow in the memory instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceGrowPage(WasmEdge_MemoryInstanceContext *Cxt, - const uint32_t Page); - -/// Deletion of the WasmEdge_MemoryInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_MemoryInstanceDelete(WasmEdge_MemoryInstanceContext *Cxt); - -// <<<<<<<< WasmEdge memory instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge tag instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the tag type context from a tag instance. -/// -/// The tag type context links to the tag type in the tag instance -/// context and owned by the context. -/// -/// \param Cxt the WasmEdge_TagInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_TagInstanceGetTagType(const WasmEdge_TagInstanceContext *Cxt); - -// <<<<<<<< WasmEdge tag instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge global instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_GlobalInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_GlobalInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// -/// \param GlobType the global type context to initialize the global instance -/// context. -/// \param Value the initial value with its value type of the global instance. -/// This function will fail if the value type of `GlobType` and `Value` are not -/// the same. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalInstanceContext * -WasmEdge_GlobalInstanceCreate(const WasmEdge_GlobalTypeContext *GlobType, - const WasmEdge_Value Value); - -/// Get the global type context from a global instance. -/// -/// The global type context links to the global type in the global instance -/// context and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_GlobalInstanceGetGlobalType(const WasmEdge_GlobalInstanceContext *Cxt); - -/// Get the value from a global instance. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// -/// \returns the current value of the global instance. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_GlobalInstanceGetValue(const WasmEdge_GlobalInstanceContext *Cxt); - -/// Set the value into a global instance. -/// -/// This function will return error if the global context is set as the `Const` -/// mutation or the value type not matched. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// \param Value the value to set into the global context. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_GlobalInstanceSetValue(WasmEdge_GlobalInstanceContext *Cxt, - const WasmEdge_Value Value); - -/// Deletion of the WasmEdge_GlobalInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_GlobalInstanceDelete(WasmEdge_GlobalInstanceContext *Cxt); - -// <<<<<<<< WasmEdge global instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge calling frame functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the executor context from the current calling frame. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// -/// \returns the executor context, NULL if the Cxt is NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_CallingFrameGetExecutor(const WasmEdge_CallingFrameContext *Cxt); - -/// Get the module instance of the current calling frame. -/// -/// When a WASM function is executing and start to call a host function, a frame -/// with the module instance which the WASM function belongs to will be pushed -/// onto the stack. And therefore the calling frame context will record that -/// module instance. -/// So in one case that the module instance will be `NULL`: developers execute -/// the function instance which is a host function and not added into a module -/// instance. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// -/// \returns the module instance of the current calling frame. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_CallingFrameGetModuleInstance(const WasmEdge_CallingFrameContext *Cxt); - -/// Get the memory instance by index from the module instance of the current -/// calling frame. -/// -/// By default, a WASM module only have one memory instance after instantiation. -/// Therefore, developers can use: -/// `WasmEdge_CallingFrameGetMemoryInstance(Cxt, 0)` -/// to get the memory instance in host function body. -/// This extension is for the WASM multiple memories proposal. After enabling -/// the proposal, there may be greater than 1 memory instances in a WASM module. -/// So developers can use this function to access the memory instances which are -/// not in 0 index. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// \param Idx the index of memory instance in the module instance. -/// -/// \returns the memory instance, NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_CallingFrameGetMemoryInstance(const WasmEdge_CallingFrameContext *Cxt, - const uint32_t Idx); - -// <<<<<<<< WasmEdge calling frame functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Async functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Wait a WasmEdge_Async execution. -/// -/// \param Cxt the WasmEdge_ASync. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncWait(const WasmEdge_Async *Cxt); - -/// Wait a WasmEdge_Async execution with timeout. -/// -/// \param Cxt the WasmEdge_ASync. -/// \param Milliseconds times to wait. -/// -/// \returns Result of waiting, true for execution ended, false for timeout -/// occurred. -WASMEDGE_CAPI_EXPORT bool WasmEdge_AsyncWaitFor(const WasmEdge_Async *Cxt, - uint64_t Milliseconds); - -/// Cancel a WasmEdge_Async execution. -/// -/// \param Cxt the WasmEdge_ASync. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncCancel(WasmEdge_Async *Cxt); - -/// Wait and get the return list length of the WasmEdge_Async execution. -/// -/// This function will wait until the execution finished and return the return -/// value list length of the executed function. This function will return 0 if -/// the `Cxt` is NULL, the execution was failed, or the execution was canceled. -/// Developers can call the `WasmEdge_AsyncGet` to get the execution status and -/// the return values. -/// -/// \param Cxt the WasmEdge_ASync. -/// -/// \returns the return list length of the executed function. -WASMEDGE_CAPI_EXPORT uint32_t -WasmEdge_AsyncGetReturnsLength(const WasmEdge_Async *Cxt); - -/// Wait and get the result of WasmEdge_Async execution. -/// -/// This function will wait until the execution finished and return the -/// execution status and the return values. -/// If the `Returns` buffer length is smaller than the arity of the function, -/// the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASync. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT WasmEdge_Result -WasmEdge_AsyncGet(const WasmEdge_Async *Cxt, WasmEdge_Value *Returns, - const uint32_t ReturnLen); - -/// Deletion of the WasmEdge_Async. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ASync to destroy. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncDelete(WasmEdge_Async *Cxt); - -// <<<<<<<< WasmEdge Async functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge VM functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_VMContext. -/// -/// The caller owns the object and should call `WasmEdge_VMDelete` to destroy -/// it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of VM. -/// NULL for the default configuration. -/// \param StoreCxt the WasmEdge_StoreContext as the external WASM store of VM. -/// The instantiation and execution will refer to this store context, and the -/// life cycle should be ensured until the VM context is deleted. NULL for the -/// default store owned by `WasmEdge_VMContext`. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_VMContext * -WasmEdge_VMCreate(const WasmEdge_ConfigureContext *ConfCxt, - WasmEdge_StoreContext *StoreCxt); - -/// Register and instantiate WASM into the store in VM from a WASM file. -/// -/// Load a WASM file from the path, and register all exported instances and -/// instantiate them into the store into the VM with their exported name and -/// module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromFile(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const char *Path); - -/// Register and instantiate WASM into the store in VM from a buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMRegisterModuleFromBytes()` API in the future. -/// -/// Load a WASM module from a buffer, and register all exported instances and -/// instantiate them into the store into the VM with their exported name and -/// module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromBuffer(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const uint8_t *Buf, const uint32_t BufLen); - -/// Register and instantiate WASM into the store in VM from a WasmEdge_Bytes. -/// -/// Load a WASM module from a WasmEdge_Bytes, and register all exported -/// instances and instantiate them into the store into the VM with their -/// exported name and module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromBytes(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_Bytes Bytes); - -/// Instantiate and register an AST Module into a named module instance in VM. -/// -/// Load from the AST Module, and register all exported instances and -/// instantiate them into the store in VM with their exported name and module -/// name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Register a module instance into the store in VM with exporting its module -/// name. -/// -/// After calling this function, the existing module instance will be registered -/// into the store context in this VM, and the other modules can import the -/// exported instances for linking when instantiation. Developers SHOULD -/// guarantee the life cycle of this existing module instance, or the error will -/// occur when in execution after the module instance being destroyed if it has -/// been imported by other modules. That is, developers should call the -/// `WasmEdge_ModuleInstanceDelete` if this existing module instance will not be -/// used anymore or after the deletion of this VM. When the module instance is -/// deleted, it will be unregistered to the store context in this VM -/// automatically. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ImportCxt the WasmEdge_ModuleInstanceContext to register. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRegisterModuleFromImport( - WasmEdge_VMContext *Cxt, const WasmEdge_ModuleInstanceContext *ImportCxt); - -/// Instantiate the WASM module from a WASM file and invoke a function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the file path, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromFile( - WasmEdge_VMContext *Cxt, const char *Path, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a buffer and invoke a function by name. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMRunWasmFromBytes()` API in the future. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a buffer, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromBuffer( - WasmEdge_VMContext *Cxt, const uint8_t *Buf, const uint32_t BufLen, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WasmEdge_Bytes and invoke a function by -/// name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a WasmEdge_Bytes, and then invoke -/// a function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromBytes( - WasmEdge_VMContext *Cxt, const WasmEdge_Bytes Bytes, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WasmEdge AST Module and invoke a function -/// by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the WasmEdge AST Module, and then -/// invoke the function by name and parameters. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromASTModule( - WasmEdge_VMContext *Cxt, const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WASM file and asynchronous invoke a -/// function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the file path, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromFile( - WasmEdge_VMContext *Cxt, const char *Path, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen); - -/// Instantiate the WASM module from a buffer and asynchronous invoke a function -/// by name. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMAsyncRunWasmFromBytes()` API in the future. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a buffer, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromBuffer( - WasmEdge_VMContext *Cxt, const uint8_t *Buf, const uint32_t BufLen, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Instantiate the WASM module from a WasmEdge_Bytes and asynchronous invoke a -/// function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a WasmEdge_Bytes, and then invoke -/// a function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromBytes( - WasmEdge_VMContext *Cxt, const WasmEdge_Bytes Bytes, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Instantiate the WASM module from a WasmEdge AST Module and asynchronous -/// invoke a function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the WasmEdge AST Module, and then -/// invoke the function by name and parameters. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_VMAsyncRunWasmFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_String FuncName, - const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Load the WASM module from a WASM file. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from the file path. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromFile(WasmEdge_VMContext *Cxt, const char *Path); - -/// Load the WASM module from a buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMLoadWasmFromBytes()` API in the future. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from a buffer. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromBuffer(WasmEdge_VMContext *Cxt, const uint8_t *Buf, - const uint32_t BufLen); - -/// Load the WASM module from a WasmEdge_Bytes. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from a WasmEdge_Bytes. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromBytes(WasmEdge_VMContext *Cxt, - const WasmEdge_Bytes Bytes); - -/// Load the WASM module from loaded WasmEdge AST Module. -/// -/// This is the first step to invoke a WASM function step by step. -/// Copy the loaded WasmEdge AST Module context into VM. The VM context has no -/// dependency on the input AST Module context. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Validate the WASM module loaded into the VM context. -/// -/// This is the second step to invoke a WASM function step by step. -/// After loading a WASM module into VM context, You can call this function to -/// validate it. And you can then call `WasmEdge_VMInstantiate` for the next -/// step. Note that only validated WASM modules can be instantiated in the VM -/// context. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMValidate(WasmEdge_VMContext *Cxt); - -/// Instantiate the validated WASM module in the VM context. -/// -/// This is the third step to invoke a WASM function step by step. -/// After validating a WASM module in the VM context, You can call this function -/// to instantiate it. And you can then call `WasmEdge_VMExecute` for invoking -/// the exported function in this WASM module. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMInstantiate(WasmEdge_VMContext *Cxt); - -/// Invoke a WASM function by name. -/// -/// This is the final step to invoke a WASM function step by step. -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can repeatedly call this function to invoke the exported WASM functions by -/// their names until the VM context is reset or a new WASM module is registered -/// or loaded. For calling the functions in registered WASM modules with module -/// names, please use `WasmEdge_VMExecuteRegistered` instead. If the `Returns` -/// buffer length is smaller than the arity of the function, the overflowed -/// return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMExecute(WasmEdge_VMContext *Cxt, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Invoke a WASM function by its module name and function name. -/// -/// After registering a WASM module in the VM context, you can repeatedly call -/// this function to invoke exported WASM functions by their module names and -/// function names until the VM context is reset. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMExecuteRegistered( - WasmEdge_VMContext *Cxt, const WasmEdge_String ModuleName, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Asynchronous invoke a WASM function by name. -/// -/// This is the final step to invoke a WASM function step by step. -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can repeatedly call this function to invoke the exported WASM functions by -/// their names until the VM context is reset or a new WASM module is registered -/// or loaded. For calling the functions in registered WASM modules with module -/// names, please use `WasmEdge_VMAsyncExecuteRegistered` instead. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_VMAsyncExecute(WasmEdge_VMContext *Cxt, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen); - -/// Asynchronous invoke a WASM function by its module name and function name. -/// -/// After registering a WASM module in the VM context, you can repeatedly call -/// this function to invoke exported WASM functions by their module names and -/// function names until the VM context is reset. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncExecuteRegistered( - WasmEdge_VMContext *Cxt, const WasmEdge_String ModuleName, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Get the function type by function name. -/// -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can call this function to get the function type by the exported function -/// name until the VM context is reset or a new WASM module is registered or -/// loaded. For getting the function type of functions in registered WASM -/// modules with module names, please use `WasmEdge_VMGetFunctionTypeRegistered` -/// instead. -/// The returned function type context are linked to the context owned by the VM -/// context, and the caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete` to destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// -/// \returns the function type. NULL if the function not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_VMGetFunctionType(const WasmEdge_VMContext *Cxt, - const WasmEdge_String FuncName); - -/// Get the function type by function name. -/// -/// After registering a WASM module in the VM context, you can call this -/// function to get the function type by the functions' exported module names -/// and function names until the VM context is reset. -/// The returned function type context are linked to the context owned by the VM -/// context, and the caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete` to destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// -/// \returns the function type. NULL if the function not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_VMGetFunctionTypeRegistered(const WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_String FuncName); - -/// Reset of WasmEdge_VMContext. -/// -/// After calling this function, the statistics, loaded module, the instantiated -/// instances, and the registered instances except the WASI and plug-ins will -/// all be cleared. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext to reset. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_VMCleanup(WasmEdge_VMContext *Cxt); - -/// Get the length of exported function list. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns length of exported function list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMGetFunctionListLength(const WasmEdge_VMContext *Cxt); - -/// Get the exported function list. -/// -/// The returned function names filled into the `Names` array link to the -/// exported names of functions owned by the vm context, and the caller should -/// __NOT__ call the `WasmEdge_StringDelete` to destroy them. -/// The function type contexts filled into the `FuncTypes` array of the -/// corresponding function names link to the context owned by the VM context. -/// The caller should __NOT__ call the `WasmEdge_FunctionTypeDelete` to destroy -/// them. -/// If the `Names` and `FuncTypes` buffer lengths are smaller than the result of -/// the exported function list size, the overflowed return values will be -/// discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param [out] Names the output names WasmEdge_String buffer of exported -/// functions. Can be NULL if names are not needed. -/// \param [out] FuncTypes the function type contexts buffer. Can be NULL if -/// function types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VMGetFunctionList( - const WasmEdge_VMContext *Cxt, WasmEdge_String *Names, - const WasmEdge_FunctionTypeContext **FuncTypes, const uint32_t Len); - -/// Get the module instance corresponding to the WasmEdge_HostRegistration -/// settings. -/// -/// When creating the VM context with a configuration, the built-in host module -/// will be registered according to the `WasmEdge_HostRegistration` settings -/// added into the `WasmEdge_ConfigureContext`. You can call this function to -/// get the `WasmEdge_ModuleInstanceContext` corresponding to the settings. The -/// module instance context links to the context owned by the VM context. The -/// caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete`. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddHostRegistration(Conf, WasmEdge_HostRegistration_Wasi); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// WasmEdge_ModuleInstanceContext *WasiMod = -/// WasmEdge_VMGetImportModuleContext(VM, WasmEdge_HostRegistration_Wasi); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Reg the host registration value to get the import module. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetImportModuleContext(const WasmEdge_VMContext *Cxt, - const enum WasmEdge_HostRegistration Reg); - -/// Get the current instantiated module in VM. -/// -/// After instantiating a module instance into the VM, developers can call this -/// API to get the active anonymous module instance to retrieve the exported -/// instances. The module instance context links to the context owned by the VM -/// context. The caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetActiveModule(const WasmEdge_VMContext *Cxt); - -/// Get the registered module in VM by the module name. -/// -/// After registering a WASM module into the VM context, developers can call -/// this function to get the module instance by the module name. The returned -/// module instance context links to the context owned by the VM context, and -/// the caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete` to -/// destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetRegisteredModule(const WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName); - -/// Get the length of registered module list in the WasmEdge_VMContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns length of registered module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMListRegisteredModuleLength(const WasmEdge_VMContext *Cxt); - -/// List the registered module names in the WasmEdge_VMContext. -/// -/// This function will list all registered module names. -/// The returned module names filled into the `Names` array are linked to the -/// registered module names in the VM context, and the caller should __NOT__ -/// call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the registered -/// named module list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param [out] Names the output names WasmEdge_String buffer of the registered -/// modules. -/// \param Len the buffer length. -/// -/// \returns actual registered module list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMListRegisteredModule(const WasmEdge_VMContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the store context used in the WasmEdge_VMContext. -/// -/// The returned store context links to the store in the VM context and owned by -/// the VM context. This function will return NULL if error occurs. The caller -/// should __NOT__ call the `WasmEdge_StoreDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the store context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StoreContext * -WasmEdge_VMGetStoreContext(WasmEdge_VMContext *Cxt); - -/// Get the loader context used in the WasmEdge_VMContext. -/// -/// The returned loader context links to the loader in the VM context and owned -/// by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_LoaderDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the loader context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_LoaderContext * -WasmEdge_VMGetLoaderContext(WasmEdge_VMContext *Cxt); - -/// Get the validator context used in the WasmEdge_VMContext. -/// -/// The returned validator context links to the validator in the VM context and -/// owned by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_ValidatorDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the validator context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValidatorContext * -WasmEdge_VMGetValidatorContext(WasmEdge_VMContext *Cxt); - -/// Get the executor context used in the WasmEdge_VMContext. -/// -/// The returned executor context links to the executor in the VM context and -/// owned by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_ExecutorDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the executor context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_VMGetExecutorContext(WasmEdge_VMContext *Cxt); - -/// Get the statistics context used in the WasmEdge_VMContext. -/// -/// The statistics context links to the statistics in the VM context and owned -/// by the VM context. The caller should __NOT__ call the -/// `WasmEdge_StatisticsDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the statistics context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StatisticsContext * -WasmEdge_VMGetStatisticsContext(WasmEdge_VMContext *Cxt); - -/// Deletion of the WasmEdge_VMContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_VMContext to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_VMDelete(WasmEdge_VMContext *Cxt); - -// <<<<<<<< WasmEdge VM functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Driver functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ - defined(__TOS_WIN__) || defined(__WINDOWS__) -/// Convert UTF16 Args to UTF8 Args -/// -/// This function is an argument converter for Windows platforms. -/// The caller owns the vector and should call `WasmEdge_Driver_ArgvDelete` to -/// destroy it. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns Allocated argument vector. -WASMEDGE_CAPI_EXPORT extern const char ** -WasmEdge_Driver_ArgvCreate(int Argc, const wchar_t *Argv[]); - -/// Deletion of the argument vector -/// -/// \param Argv the argument vector. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_Driver_ArgvDelete(const char *Argv[]); - -/// Set console output code page to UTF-8 on windows. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_Driver_SetConsoleOutputCPtoUTF8(void); -#endif - -/// Entrypoint for the compiler tool. -/// -/// This function provides an entrypoint to the WasmEdge AOT compiler tool with -/// the command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_Compiler(int Argc, - const char *Argv[]); - -/// Entrypoint for the runtime tool. -/// -/// This function provides an entrypoint to the WasmEdge runtime tool with the -/// command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_Tool(int Argc, - const char *Argv[]); - -#ifdef WASMEDGE_BUILD_WASI_NN_RPC -/// Entrypoint for the Wasi-NN RPC server tool. -/// -/// This function provides an entrypoint to the WasmEdge Wasi-NN RPC server tool -/// with the command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int -WasmEdge_Driver_WasiNNRPCServer(int Argc, const char *Argv[]); -#endif - -/// Entrypoint for the unified tool. -/// -/// This function provides an entrypoint to the WasmEdge unified tool with the -/// command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_UniTool(int Argc, - const char *Argv[]); - -// <<<<<<<< WasmEdge Driver functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Plugin functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Load plugins with the default search paths. -/// -/// The default paths are: -/// 1. The environment variable "WASMEDGE_PLUGIN_PATH". -/// 2. The "../plugin/" directory related to the WasmEdge installation path. -/// 3. The "wasmedge/" directory under the library path if the WasmEdge is -/// installed under the "/usr". -WASMEDGE_CAPI_EXPORT extern void WasmEdge_PluginLoadWithDefaultPaths(void); - -/// Load the plugin with the given file or directory. -/// -/// For the given file path, this function will load the plug-in. -/// For the given directory path, this function will load the plug-ins under the -/// directory recursively. -/// -/// \param Path the path to plug-in file or directory. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_PluginLoadFromPath(const char *Path); - -/// Get the length of loaded plug-in list. -/// -/// \returns length of loaded plug-in list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_PluginListPluginsLength(void); - -/// List the loaded plug-ins with their names. -/// -/// The returned plug-in names filled into the `Names` array are owned by the -/// internal WasmEdge plug-in storage, and the caller should __NOT__ call the -/// `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the loaded -/// plug-in list size, the overflowed return values will be discarded. -/// -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual loaded plug-in list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListPlugins(WasmEdge_String *Names, const uint32_t Len); - -/// Find the loaded plug-in context by name. -/// -/// After loading the plug-ins from default paths or the given path, developers -/// can use this API to retrieve the plug-in context by name. Then developers -/// can create the module instance from the plug-in contexts. -/// -/// \param Name the plug-in name WasmEdge_String. -/// -/// \returns pointer to the plug-in context. NULL if the plug-in not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_PluginContext * -WasmEdge_PluginFind(const WasmEdge_String Name); - -/// Get the plug-in name of the plug-in context. -/// -/// The returned string object is linked to the plug-in name of the plug-in -/// context, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_PluginContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_PluginGetPluginName(const WasmEdge_PluginContext *Cxt); - -/// Get the length of module list in the plug-in context. -/// -/// There may be several modules in a plug-in. Developers can use this function -/// to get the length of the module list in a plug-in. -/// -/// \param Cxt the WasmEdge_PluginContext to get the length of the module list. -/// -/// \returns length of module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListModuleLength(const WasmEdge_PluginContext *Cxt); - -/// List the modules in the plug-in context with their names. -/// -/// The returned module names filled into the `Names` array are owned by the -/// internal WasmEdge plug-in storage, and the caller should __NOT__ call the -/// `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the loaded -/// plug-in list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_PluginContext to list the modules. -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual module list size of the plug-in. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListModule(const WasmEdge_PluginContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Create the module instance in the plug-in by the module name. -/// -/// By giving the module name, developers can retrieve the module in the plug-in -/// and create the module instance. -/// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_PluginContext to retrieve and create module. -/// \param ModuleName the module name to retrieve. -/// -/// \returns pointer to the module instance context, NULL if the module name not -/// found in the plug-in or the plug-in is not valid. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_PluginCreateModule(const WasmEdge_PluginContext *Cxt, - const WasmEdge_String ModuleName); - -/// Initialize the wasi_nn plug-in. -/// -/// This function will initialize the wasi_nn plug-in with the preloads string -/// list. Only available after loading the wasi_nn plug-in and before creating -/// the module instance from the plug-in. -/// -/// \param NNPreloads the preload string list. NULL if the length is 0. -/// \param PreloadsLen the length of the preload list. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_PluginInitWASINN(const char *const *NNPreloads, - const uint32_t PreloadsLen); - -/// Implement by plugins for returning the plugin descriptor. -/// -/// \returns the plugin descriptor. -WASMEDGE_CAPI_PLUGIN_EXPORT extern const WasmEdge_PluginDescriptor * -WasmEdge_Plugin_GetDescriptor(void); - -// <<<<<<<< WasmEdge Pluginfunctions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Experimental functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Register a host function that will be invoked before executing any host -/// functions. -/// -/// There is only one pre-host-function. After calling this function, the -/// previous registered host function will be replaced. This is a experimental -/// feature. Use it at your own risk. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param Data the host data to set into the given host function. When calling -/// the Func, this pointer will be the argument of the Func function. -/// \param Func the function to be invoked before executing any other host -/// functions. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorExperimentalRegisterPreHostFunction( - WasmEdge_ExecutorContext *Cxt, void *Data, void (*Func)(void *)); - -/// Register a host function that will be invoked after executing any host -/// functions. -/// -/// There is only one post-host-function. After calling this function, the -/// previous registered host function will be replaced. This is a experimental -/// feature. Use it at your own risk. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Data the host data to set into the given host function. When calling -/// the Func, this pointer will be the argument of the Func function. -/// \param Func the function to be invoked after executing any other host -/// functions. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorExperimentalRegisterPostHostFunction( - WasmEdge_ExecutorContext *Cxt, void *Data, void (*Func)(void *)); - -// <<<<<<<< WasmEdge Experimental Functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -#ifdef __cplusplus -} /// extern "C" -#endif - -#endif /// WASMEDGE_C_API_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so b/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so deleted file mode 120000 index 145d5a021c32a26423bac2fecffd6a174664a3b3..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so +++ /dev/null @@ -1 +0,0 @@ -libwasmedge.so.0 \ No newline at end of file diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0 b/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0 deleted file mode 120000 index 6639f000114eaf75d312c5ce1153d5b25b079a87..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0 +++ /dev/null @@ -1 +0,0 @@ -libwasmedge.so.0.1.0 \ No newline at end of file diff --git a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0.1.0 b/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0.1.0 deleted file mode 100755 index 1e4332be599d9e6e7fb798450b9dd53ef0638437..0000000000000000000000000000000000000000 Binary files a/wasmedge/lib-0.14.1-manylinux2014/aarch64/lib/libwasmedge.so.0.1.0 and /dev/null differ diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum.inc b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum.inc deleted file mode 100644 index bf1c8f7c78cadc318de23d5319956d6bc6ce427d..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum.inc +++ /dev/null @@ -1,1201 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum.inc - Enumerations ---------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains all enumerations of WasmEdge. -/// -//===----------------------------------------------------------------------===// - -#ifndef Line -#error "this header file must not be included directly" -#endif - -// enum_ast.hpp - -#ifdef UseASTNodeAttr -#define A Line - -A(Component, "component") -A(Sec_CoreMod, "component core:module section") -A(Sec_CoreInstance, "component core:instance section") -A(Sec_Alias, "component alias section") -A(Sec_Comp, "nested component section") -A(Sec_Instance, "component instance section") -A(Sec_CompType, "component type section") -A(Sec_Canon, "component canonical section") -A(Sec_CompStart, "component start section") -A(Sec_CompImport, "component import section") -A(Sec_CompExport, "component export section") -A(ImportExportName, "import/export name") -A(Import, "import") -A(Export, "export") -A(Canonical, "canonical") -A(Alias, "alias") -A(DefType, "component defined type") -A(InstanceDecl, "instance decl") -A(ExternDesc, "extern desc") -A(Name, "import/export name") -A(AliasTarget, "alias target") -A(Sort, "sort") -A(Instance, "instance expr") -A(CoreInstance, "core:instance expr") -A(Module, "module") -A(Sec_Custom, "custom section") -A(Sec_Type, "type section") -A(Sec_Import, "import section") -A(Sec_Function, "function section") -A(Sec_Table, "table section") -A(Sec_Memory, "memory section") -A(Sec_Global, "global section") -A(Sec_Export, "export section") -A(Sec_Start, "start section") -A(Sec_Element, "element section") -A(Sec_Code, "code section") -A(Sec_Data, "data section") -A(Sec_DataCount, "data count section") -A(Sec_Tag, "tag section") -A(Desc_Import, "import description") -A(Desc_Export, "export description") -A(Seg_Table, "table segment") -A(Seg_Global, "global segment") -A(Seg_Element, "element segment") -A(Seg_Code, "code segment") -A(Seg_Data, "data segment") -A(Type_Module, "module type") -A(Type_Rec, "recursive type") -A(Type_Sub, "sub type") -A(Type_Limit, "limit") -A(Type_Function, "function type") -A(Type_Memory, "memory type") -A(Type_Table, "table type") -A(Type_Global, "global type") -A(Type_Instance, "instance type") -A(Type_Component, "component type") -A(Expression, "expression") -A(Instruction, "instruction") -A(Sec_AOT, "aot section") - -#undef A -#endif // UseASTNodeAttr - -#ifdef UseOpCode -#define O Line -#define OFB Line_FB -#define OFC Line_FC -#define OFD Line_FD -#define OFE Line_FE - -// OpCode: -// NAME | STRING | CODE [ | EXTEND ] - -// Control instructions (part 1) -O(Unreachable, "unreachable", 0x00) -O(Nop, "nop", 0x01) -O(Block, "block", 0x02) -O(Loop, "loop", 0x03) -O(If, "if", 0x04) -O(Else, "else", 0x05) -O(Try, "try", 0x06) // For legacy EH proposal -O(Catch, "catch", 0x07) // For legacy EH proposal -O(Throw, "throw", 0x08) -O(Rethrow, "rethrow", 0x09) // For legacy EH proposal -O(Throw_ref, "throw_ref", 0x0A) -O(End, "end", 0x0B) -O(Br, "br", 0x0C) -O(Br_if, "br_if", 0x0D) -O(Br_table, "br_table", 0x0E) -O(Return, "return", 0x0F) -O(Call, "call", 0x10) -O(Call_indirect, "call_indirect", 0x11) -O(Return_call, "return_call", 0x12) -O(Return_call_indirect, "return_call_indirect", 0x13) -O(Call_ref, "call_ref", 0x14) -O(Return_call_ref, "return_call_ref", 0x15) -// 0x16: Reserved -// 0x17: Reserved -O(Delegate, "delegate", 0x18) // For legacy EH proposal -O(Catch_all, "catch_all", 0x19) // For legacy EH proposal - -// Parametric Instructions -O(Drop, "drop", 0x1A) -O(Select, "select", 0x1B) -O(Select_t, "select", 0x1C) -// 0x1D: Reserved -// 0x1E: Reserved - -// Control instructions (part 2) -O(Try_table, "try_table", 0x1F) - -// Variable Instructions -O(Local__get, "local.get", 0x20) -O(Local__set, "local.set", 0x21) -O(Local__tee, "local.tee", 0x22) -O(Global__get, "global.get", 0x23) -O(Global__set, "global.set", 0x24) - -// Table Instructions (part 1) -O(Table__get, "table.get", 0x25) -O(Table__set, "table.set", 0x26) -// 0x27: Reserved - -// Memory Instructions (part 1) -O(I32__load, "i32.load", 0x28) -O(I64__load, "i64.load", 0x29) -O(F32__load, "f32.load", 0x2A) -O(F64__load, "f64.load", 0x2B) -O(I32__load8_s, "i32.load8_s", 0x2C) -O(I32__load8_u, "i32.load8_u", 0x2D) -O(I32__load16_s, "i32.load16_s", 0x2E) -O(I32__load16_u, "i32.load16_u", 0x2F) -O(I64__load8_s, "i64.load8_s", 0x30) -O(I64__load8_u, "i64.load8_u", 0x31) -O(I64__load16_s, "i64.load16_s", 0x32) -O(I64__load16_u, "i64.load16_u", 0x33) -O(I64__load32_s, "i64.load32_s", 0x34) -O(I64__load32_u, "i64.load32_u", 0x35) -O(I32__store, "i32.store", 0x36) -O(I64__store, "i64.store", 0x37) -O(F32__store, "f32.store", 0x38) -O(F64__store, "f64.store", 0x39) -O(I32__store8, "i32.store8", 0x3A) -O(I32__store16, "i32.store16", 0x3B) -O(I64__store8, "i64.store8", 0x3C) -O(I64__store16, "i64.store16", 0x3D) -O(I64__store32, "i64.store32", 0x3E) -O(Memory__size, "memory.size", 0x3F) -O(Memory__grow, "memory.grow", 0x40) - -// Const numeric instructions -O(I32__const, "i32.const", 0x41) -O(I64__const, "i64.const", 0x42) -O(F32__const, "f32.const", 0x43) -O(F64__const, "f64.const", 0x44) - -// Numeric instructions -O(I32__eqz, "i32.eqz", 0x45) -O(I32__eq, "i32.eq", 0x46) -O(I32__ne, "i32.ne", 0x47) -O(I32__lt_s, "i32.lt_s", 0x48) -O(I32__lt_u, "i32.lt_u", 0x49) -O(I32__gt_s, "i32.gt_s", 0x4A) -O(I32__gt_u, "i32.gt_u", 0x4B) -O(I32__le_s, "i32.le_s", 0x4C) -O(I32__le_u, "i32.le_u", 0x4D) -O(I32__ge_s, "i32.ge_s", 0x4E) -O(I32__ge_u, "i32.ge_u", 0x4F) -O(I64__eqz, "i64.eqz", 0x50) -O(I64__eq, "i64.eq", 0x51) -O(I64__ne, "i64.ne", 0x52) -O(I64__lt_s, "i64.lt_s", 0x53) -O(I64__lt_u, "i64.lt_u", 0x54) -O(I64__gt_s, "i64.gt_s", 0x55) -O(I64__gt_u, "i64.gt_u", 0x56) -O(I64__le_s, "i64.le_s", 0x57) -O(I64__le_u, "i64.le_u", 0x58) -O(I64__ge_s, "i64.ge_s", 0x59) -O(I64__ge_u, "i64.ge_u", 0x5A) -O(F32__eq, "f32.eq", 0x5B) -O(F32__ne, "f32.ne", 0x5C) -O(F32__lt, "f32.lt", 0x5D) -O(F32__gt, "f32.gt", 0x5E) -O(F32__le, "f32.le", 0x5F) -O(F32__ge, "f32.ge", 0x60) -O(F64__eq, "f64.eq", 0x61) -O(F64__ne, "f64.ne", 0x62) -O(F64__lt, "f64.lt", 0x63) -O(F64__gt, "f64.gt", 0x64) -O(F64__le, "f64.le", 0x65) -O(F64__ge, "f64.ge", 0x66) -O(I32__clz, "i32.clz", 0x67) -O(I32__ctz, "i32.ctz", 0x68) -O(I32__popcnt, "i32.popcnt", 0x69) -O(I32__add, "i32.add", 0x6A) -O(I32__sub, "i32.sub", 0x6B) -O(I32__mul, "i32.mul", 0x6C) -O(I32__div_s, "i32.div_s", 0x6D) -O(I32__div_u, "i32.div_u", 0x6E) -O(I32__rem_s, "i32.rem_s", 0x6F) -O(I32__rem_u, "i32.rem_u", 0x70) -O(I32__and, "i32.and", 0x71) -O(I32__or, "i32.or", 0x72) -O(I32__xor, "i32.xor", 0x73) -O(I32__shl, "i32.shl", 0x74) -O(I32__shr_s, "i32.shr_s", 0x75) -O(I32__shr_u, "i32.shr_u", 0x76) -O(I32__rotl, "i32.rotl", 0x77) -O(I32__rotr, "i32.rotr", 0x78) -O(I64__clz, "i64.clz", 0x79) -O(I64__ctz, "i64.ctz", 0x7A) -O(I64__popcnt, "i64.popcnt", 0x7B) -O(I64__add, "i64.add", 0x7C) -O(I64__sub, "i64.sub", 0x7D) -O(I64__mul, "i64.mul", 0x7E) -O(I64__div_s, "i64.div_s", 0x7F) -O(I64__div_u, "i64.div_u", 0x80) -O(I64__rem_s, "i64.rem_s", 0x81) -O(I64__rem_u, "i64.rem_u", 0x82) -O(I64__and, "i64.and", 0x83) -O(I64__or, "i64.or", 0x84) -O(I64__xor, "i64.xor", 0x85) -O(I64__shl, "i64.shl", 0x86) -O(I64__shr_s, "i64.shr_s", 0x87) -O(I64__shr_u, "i64.shr_u", 0x88) -O(I64__rotl, "i64.rotl", 0x89) -O(I64__rotr, "i64.rotr", 0x8A) -O(F32__abs, "f32.abs", 0x8B) -O(F32__neg, "f32.neg", 0x8C) -O(F32__ceil, "f32.ceil", 0x8D) -O(F32__floor, "f32.floor", 0x8E) -O(F32__trunc, "f32.trunc", 0x8F) -O(F32__nearest, "f32.nearest", 0x90) -O(F32__sqrt, "f32.sqrt", 0x91) -O(F32__add, "f32.add", 0x92) -O(F32__sub, "f32.sub", 0x93) -O(F32__mul, "f32.mul", 0x94) -O(F32__div, "f32.div", 0x95) -O(F32__min, "f32.min", 0x96) -O(F32__max, "f32.max", 0x97) -O(F32__copysign, "f32.copysign", 0x98) -O(F64__abs, "f64.abs", 0x99) -O(F64__neg, "f64.neg", 0x9A) -O(F64__ceil, "f64.ceil", 0x9B) -O(F64__floor, "f64.floor", 0x9C) -O(F64__trunc, "f64.trunc", 0x9D) -O(F64__nearest, "f64.nearest", 0x9E) -O(F64__sqrt, "f64.sqrt", 0x9F) -O(F64__add, "f64.add", 0xA0) -O(F64__sub, "f64.sub", 0xA1) -O(F64__mul, "f64.mul", 0xA2) -O(F64__div, "f64.div", 0xA3) -O(F64__min, "f64.min", 0xA4) -O(F64__max, "f64.max", 0xA5) -O(F64__copysign, "f64.copysign", 0xA6) -O(I32__wrap_i64, "i32.wrap_i64", 0xA7) -O(I32__trunc_f32_s, "i32.trunc_f32_s", 0xA8) -O(I32__trunc_f32_u, "i32.trunc_f32_u", 0xA9) -O(I32__trunc_f64_s, "i32.trunc_f64_s", 0xAA) -O(I32__trunc_f64_u, "i32.trunc_f64_u", 0xAB) -O(I64__extend_i32_s, "i64.extend_i32_s", 0xAC) -O(I64__extend_i32_u, "i64.extend_i32_u", 0xAD) -O(I64__trunc_f32_s, "i64.trunc_f32_s", 0xAE) -O(I64__trunc_f32_u, "i64.trunc_f32_u", 0xAF) -O(I64__trunc_f64_s, "i64.trunc_f64_s", 0xB0) -O(I64__trunc_f64_u, "i64.trunc_f64_u", 0xB1) -O(F32__convert_i32_s, "f32.convert_i32_s", 0xB2) -O(F32__convert_i32_u, "f32.convert_i32_u", 0xB3) -O(F32__convert_i64_s, "f32.convert_i64_s", 0xB4) -O(F32__convert_i64_u, "f32.convert_i64_u", 0xB5) -O(F32__demote_f64, "f32.demote_f64", 0xB6) -O(F64__convert_i32_s, "f64.convert_i32_s", 0xB7) -O(F64__convert_i32_u, "f64.convert_i32_u", 0xB8) -O(F64__convert_i64_s, "f64.convert_i64_s", 0xB9) -O(F64__convert_i64_u, "f64.convert_i64_u", 0xBA) -O(F64__promote_f32, "f64.promote_f32", 0xBB) -O(I32__reinterpret_f32, "i32.reinterpret_f32", 0xBC) -O(I64__reinterpret_f64, "i64.reinterpret_f64", 0xBD) -O(F32__reinterpret_i32, "f32.reinterpret_i32", 0xBE) -O(F64__reinterpret_i64, "f64.reinterpret_i64", 0xBF) -O(I32__extend8_s, "i32.extend8_s", 0xC0) -O(I32__extend16_s, "i32.extend16_s", 0xC1) -O(I64__extend8_s, "i64.extend8_s", 0xC2) -O(I64__extend16_s, "i64.extend16_s", 0xC3) -O(I64__extend32_s, "i64.extend32_s", 0xC4) -// 0xC5 ~ 0xCF: Reserved - -// Reference Instructions -O(Ref__null, "ref.null", 0xD0) -O(Ref__is_null, "ref.is_null", 0xD1) -O(Ref__func, "ref.func", 0xD2) -O(Ref__eq, "ref.eq", 0xD3) -O(Ref__as_non_null, "ref.as_non_null", 0xD4) - -// Control Instructions (part 3) -O(Br_on_null, "br_on_null", 0xD5) -O(Br_on_non_null, "br_on_non_null", 0xD6) -// 0xD7 ~ 0xFA: Reserved - -// 0xFB prefix - GC Instructions -OFB(Struct__new, "struct.new", 0xFB, 0) -OFB(Struct__new_default, "struct.new_default", 0xFB, 1) -OFB(Struct__get, "struct.get", 0xFB, 2) -OFB(Struct__get_s, "struct.get_s", 0xFB, 3) -OFB(Struct__get_u, "struct.get_u", 0xFB, 4) -OFB(Struct__set, "struct.set", 0xFB, 5) -OFB(Array__new, "array.new", 0xFB, 6) -OFB(Array__new_default, "array.new_default", 0xFB, 7) -OFB(Array__new_fixed, "array.new_fixed", 0xFB, 8) -OFB(Array__new_data, "array.new_data", 0xFB, 9) -OFB(Array__new_elem, "array.new_elem", 0xFB, 10) -OFB(Array__get, "array.get", 0xFB, 11) -OFB(Array__get_s, "array.get_s", 0xFB, 12) -OFB(Array__get_u, "array.get_u", 0xFB, 13) -OFB(Array__set, "array.set", 0xFB, 14) -OFB(Array__len, "array.len", 0xFB, 15) -OFB(Array__fill, "array.fill", 0xFB, 16) -OFB(Array__copy, "array.copy", 0xFB, 17) -OFB(Array__init_data, "array.init_data", 0xFB, 18) -OFB(Array__init_elem, "array.init_elem", 0xFB, 19) -OFB(Ref__test, "ref.test (ref)", 0xFB, 20) -OFB(Ref__test_null, "ref.test (ref.null)", 0xFB, 21) -OFB(Ref__cast, "ref.cast (ref)", 0xFB, 22) -OFB(Ref__cast_null, "ref.cast (ref.null)", 0xFB, 23) -OFB(Br_on_cast, "br_on_cast", 0xFB, 24) -OFB(Br_on_cast_fail, "br_on_cast_fail", 0xFB, 25) -OFB(Any__convert_extern, "any.convert_extern", 0xFB, 26) -OFB(Extern__convert_any, "extern.convert_any", 0xFB, 27) -OFB(Ref__i31, "ref.i31", 0xFB, 28) -OFB(I31__get_s, "i31.get_s", 0xFB, 29) -OFB(I31__get_u, "i31.get_u", 0xFB, 30) - -// 0xFC prefix - Saturating Truncation Instructions -OFC(I32__trunc_sat_f32_s, "i32.trunc_sat_f32_s", 0xFC, 0) -OFC(I32__trunc_sat_f32_u, "i32.trunc_sat_f32_u", 0xFC, 1) -OFC(I32__trunc_sat_f64_s, "i32.trunc_sat_f64_s", 0xFC, 2) -OFC(I32__trunc_sat_f64_u, "i32.trunc_sat_f64_u", 0xFC, 3) -OFC(I64__trunc_sat_f32_s, "i64.trunc_sat_f32_s", 0xFC, 4) -OFC(I64__trunc_sat_f32_u, "i64.trunc_sat_f32_u", 0xFC, 5) -OFC(I64__trunc_sat_f64_s, "i64.trunc_sat_f64_s", 0xFC, 6) -OFC(I64__trunc_sat_f64_u, "i64.trunc_sat_f64_u", 0xFC, 7) - -// 0xFC prefix - Memory Instructions (part 2) -OFC(Memory__init, "memory.init", 0xFC, 8) -OFC(Data__drop, "data.drop", 0xFC, 9) -OFC(Memory__copy, "memory.copy", 0xFC, 10) -OFC(Memory__fill, "memory.fill", 0xFC, 11) - -// 0xFC prefix - Table Instructions (part 2) -OFC(Table__init, "table.init", 0xFC, 12) -OFC(Elem__drop, "elem.drop", 0xFC, 13) -OFC(Table__copy, "table.copy", 0xFC, 14) -OFC(Table__grow, "table.grow", 0xFC, 15) -OFC(Table__size, "table.size", 0xFC, 16) -OFC(Table__fill, "table.fill", 0xFC, 17) - -// 0xFD prefix - Vector Memory Instructions (part 1) -OFD(V128__load, "v128.load", 0xFD, 0) -OFD(V128__load8x8_s, "v128.load8x8_s", 0xFD, 1) -OFD(V128__load8x8_u, "v128.load8x8_u", 0xFD, 2) -OFD(V128__load16x4_s, "v128.load16x4_s", 0xFD, 3) -OFD(V128__load16x4_u, "v128.load16x4_u", 0xFD, 4) -OFD(V128__load32x2_s, "v128.load32x2_s", 0xFD, 5) -OFD(V128__load32x2_u, "v128.load32x2_u", 0xFD, 6) -OFD(V128__load8_splat, "v128.load8_splat", 0xFD, 7) -OFD(V128__load16_splat, "v128.load16_splat", 0xFD, 8) -OFD(V128__load32_splat, "v128.load32_splat", 0xFD, 9) -OFD(V128__load64_splat, "v128.load64_splat", 0xFD, 10) -OFD(V128__store, "v128.store", 0xFD, 11) - -// 0xFD prefix - Vector Numeric Instructions (part 1) -OFD(V128__const, "v128.const", 0xFD, 12) -OFD(I8x16__shuffle, "i8x16.shuffle", 0xFD, 13) -OFD(I8x16__swizzle, "i8x16.swizzle", 0xFD, 14) -OFD(I8x16__splat, "i8x16.splat", 0xFD, 15) -OFD(I16x8__splat, "i16x8.splat", 0xFD, 16) -OFD(I32x4__splat, "i32x4.splat", 0xFD, 17) -OFD(I64x2__splat, "i64x2.splat", 0xFD, 18) -OFD(F32x4__splat, "f32x4.splat", 0xFD, 19) -OFD(F64x2__splat, "f64x2.splat", 0xFD, 20) - -// 0xFD prefix - Vector Lane Instructions -OFD(I8x16__extract_lane_s, "i8x16.extract_lane_s", 0xFD, 21) -OFD(I8x16__extract_lane_u, "i8x16.extract_lane_u", 0xFD, 22) -OFD(I8x16__replace_lane, "i8x16.replace_lane", 0xFD, 23) -OFD(I16x8__extract_lane_s, "i16x8.extract_lane_s", 0xFD, 24) -OFD(I16x8__extract_lane_u, "i16x8.extract_lane_u", 0xFD, 25) -OFD(I16x8__replace_lane, "i16x8.replace_lane", 0xFD, 26) -OFD(I32x4__extract_lane, "i32x4.extract_lane", 0xFD, 27) -OFD(I32x4__replace_lane, "i32x4.replace_lane", 0xFD, 28) -OFD(I64x2__extract_lane, "i64x2.extract_lane", 0xFD, 29) -OFD(I64x2__replace_lane, "i64x2.replace_lane", 0xFD, 30) -OFD(F32x4__extract_lane, "f32x4.extract_lane", 0xFD, 31) -OFD(F32x4__replace_lane, "f32x4.replace_lane", 0xFD, 32) -OFD(F64x2__extract_lane, "f64x2.extract_lane", 0xFD, 33) -OFD(F64x2__replace_lane, "f64x2.replace_lane", 0xFD, 34) - -// 0xFD prefix - Vector Numeric Instructions (part 2) -OFD(I8x16__eq, "i8x16.eq", 0xFD, 35) -OFD(I8x16__ne, "i8x16.ne", 0xFD, 36) -OFD(I8x16__lt_s, "i8x16.lt_s", 0xFD, 37) -OFD(I8x16__lt_u, "i8x16.lt_u", 0xFD, 38) -OFD(I8x16__gt_s, "i8x16.gt_s", 0xFD, 39) -OFD(I8x16__gt_u, "i8x16.gt_u", 0xFD, 40) -OFD(I8x16__le_s, "i8x16.le_s", 0xFD, 41) -OFD(I8x16__le_u, "i8x16.le_u", 0xFD, 42) -OFD(I8x16__ge_s, "i8x16.ge_s", 0xFD, 43) -OFD(I8x16__ge_u, "i8x16.ge_u", 0xFD, 44) -OFD(I16x8__eq, "i16x8.eq", 0xFD, 45) -OFD(I16x8__ne, "i16x8.ne", 0xFD, 46) -OFD(I16x8__lt_s, "i16x8.lt_s", 0xFD, 47) -OFD(I16x8__lt_u, "i16x8.lt_u", 0xFD, 48) -OFD(I16x8__gt_s, "i16x8.gt_s", 0xFD, 49) -OFD(I16x8__gt_u, "i16x8.gt_u", 0xFD, 50) -OFD(I16x8__le_s, "i16x8.le_s", 0xFD, 51) -OFD(I16x8__le_u, "i16x8.le_u", 0xFD, 52) -OFD(I16x8__ge_s, "i16x8.ge_s", 0xFD, 53) -OFD(I16x8__ge_u, "i16x8.ge_u", 0xFD, 54) -OFD(I32x4__eq, "i32x4.eq", 0xFD, 55) -OFD(I32x4__ne, "i32x4.ne", 0xFD, 56) -OFD(I32x4__lt_s, "i32x4.lt_s", 0xFD, 57) -OFD(I32x4__lt_u, "i32x4.lt_u", 0xFD, 58) -OFD(I32x4__gt_s, "i32x4.gt_s", 0xFD, 59) -OFD(I32x4__gt_u, "i32x4.gt_u", 0xFD, 60) -OFD(I32x4__le_s, "i32x4.le_s", 0xFD, 61) -OFD(I32x4__le_u, "i32x4.le_u", 0xFD, 62) -OFD(I32x4__ge_s, "i32x4.ge_s", 0xFD, 63) -OFD(I32x4__ge_u, "i32x4.ge_u", 0xFD, 64) -OFD(F32x4__eq, "f32x4.eq", 0xFD, 65) -OFD(F32x4__ne, "f32x4.ne", 0xFD, 66) -OFD(F32x4__lt, "f32x4.lt", 0xFD, 67) -OFD(F32x4__gt, "f32x4.gt", 0xFD, 68) -OFD(F32x4__le, "f32x4.le", 0xFD, 69) -OFD(F32x4__ge, "f32x4.ge", 0xFD, 70) -OFD(F64x2__eq, "f64x2.eq", 0xFD, 71) -OFD(F64x2__ne, "f64x2.ne", 0xFD, 72) -OFD(F64x2__lt, "f64x2.lt", 0xFD, 73) -OFD(F64x2__gt, "f64x2.gt", 0xFD, 74) -OFD(F64x2__le, "f64x2.le", 0xFD, 75) -OFD(F64x2__ge, "f64x2.ge", 0xFD, 76) -OFD(V128__not, "v128.not", 0xFD, 77) -OFD(V128__and, "v128.and", 0xFD, 78) -OFD(V128__andnot, "v128.andnot", 0xFD, 79) -OFD(V128__or, "v128.or", 0xFD, 80) -OFD(V128__xor, "v128.xor", 0xFD, 81) -OFD(V128__bitselect, "v128.bitselect", 0xFD, 82) -OFD(V128__any_true, "v128.any_true", 0xFD, 83) - -// 0xFD prefix - Vector Memory Instructions (part 2) -OFD(V128__load8_lane, "v128.load8_lane", 0xFD, 84) -OFD(V128__load16_lane, "v128.load16_lane", 0xFD, 85) -OFD(V128__load32_lane, "v128.load32_lane", 0xFD, 86) -OFD(V128__load64_lane, "v128.load64_lane", 0xFD, 87) -OFD(V128__store8_lane, "v128.store8_lane", 0xFD, 88) -OFD(V128__store16_lane, "v128.store16_lane", 0xFD, 89) -OFD(V128__store32_lane, "v128.store32_lane", 0xFD, 90) -OFD(V128__store64_lane, "v128.store64_lane", 0xFD, 91) -OFD(V128__load32_zero, "v128.load32_zero", 0xFD, 92) -OFD(V128__load64_zero, "v128.load64_zero", 0xFD, 93) - -// 0xFD prefix - Vector Numeric Instructions (part 3) -OFD(F32x4__demote_f64x2_zero, "f32x4.demote_f64x2_zero", 0xFD, 94) -OFD(F64x2__promote_low_f32x4, "f64x2.promote_low_f32x4", 0xFD, 95) -OFD(I8x16__abs, "i8x16.abs", 0xFD, 96) -OFD(I8x16__neg, "i8x16.neg", 0xFD, 97) -OFD(I8x16__popcnt, "i8x16.popcnt", 0xFD, 98) -OFD(I8x16__all_true, "i8x16.all_true", 0xFD, 99) -OFD(I8x16__bitmask, "i8x16.bitmask", 0xFD, 100) -OFD(I8x16__narrow_i16x8_s, "i8x16.narrow_i16x8_s", 0xFD, 101) -OFD(I8x16__narrow_i16x8_u, "i8x16.narrow_i16x8_u", 0xFD, 102) -OFD(F32x4__ceil, "f32x4.ceil", 0xFD, 103) -OFD(F32x4__floor, "f32x4.floor", 0xFD, 104) -OFD(F32x4__trunc, "f32x4.trunc", 0xFD, 105) -OFD(F32x4__nearest, "f32x4.nearest", 0xFD, 106) -OFD(I8x16__shl, "i8x16.shl", 0xFD, 107) -OFD(I8x16__shr_s, "i8x16.shr_s", 0xFD, 108) -OFD(I8x16__shr_u, "i8x16.shr_u", 0xFD, 109) -OFD(I8x16__add, "i8x16.add", 0xFD, 110) -OFD(I8x16__add_sat_s, "i8x16.add_sat_s", 0xFD, 111) -OFD(I8x16__add_sat_u, "i8x16.add_sat_u", 0xFD, 112) -OFD(I8x16__sub, "i8x16.sub", 0xFD, 113) -OFD(I8x16__sub_sat_s, "i8x16.sub_sat_s", 0xFD, 114) -OFD(I8x16__sub_sat_u, "i8x16.sub_sat_u", 0xFD, 115) -OFD(F64x2__ceil, "f64x2.ceil", 0xFD, 116) -OFD(F64x2__floor, "f64x2.floor", 0xFD, 117) -OFD(I8x16__min_s, "i8x16.min_s", 0xFD, 118) -OFD(I8x16__min_u, "i8x16.min_u", 0xFD, 119) -OFD(I8x16__max_s, "i8x16.max_s", 0xFD, 120) -OFD(I8x16__max_u, "i8x16.max_u", 0xFD, 121) -OFD(F64x2__trunc, "f64x2.trunc", 0xFD, 122) -OFD(I8x16__avgr_u, "i8x16.avgr_u", 0xFD, 123) -OFD(I16x8__extadd_pairwise_i8x16_s, "i16x8.extadd_pairwise_i8x16_s", 0xFD, 124) -OFD(I16x8__extadd_pairwise_i8x16_u, "i16x8.extadd_pairwise_i8x16_u", 0xFD, 125) -OFD(I32x4__extadd_pairwise_i16x8_s, "i32x4.extadd_pairwise_i16x8_s", 0xFD, 126) -OFD(I32x4__extadd_pairwise_i16x8_u, "i32x4.extadd_pairwise_i16x8_u", 0xFD, 127) -OFD(I16x8__abs, "i16x8.abs", 0xFD, 128) -OFD(I16x8__neg, "i16x8.neg", 0xFD, 129) -OFD(I16x8__q15mulr_sat_s, "i16x8.q15mulr_sat_s", 0xFD, 130) -OFD(I16x8__all_true, "i16x8.all_true", 0xFD, 131) -OFD(I16x8__bitmask, "i16x8.bitmask", 0xFD, 132) -OFD(I16x8__narrow_i32x4_s, "i16x8.narrow_i32x4_s", 0xFD, 133) -OFD(I16x8__narrow_i32x4_u, "i16x8.narrow_i32x4_u", 0xFD, 134) -OFD(I16x8__extend_low_i8x16_s, "i16x8.extend_low_i8x16_s", 0xFD, 135) -OFD(I16x8__extend_high_i8x16_s, "i16x8.extend_high_i8x16_s", 0xFD, 136) -OFD(I16x8__extend_low_i8x16_u, "i16x8.extend_low_i8x16_u", 0xFD, 137) -OFD(I16x8__extend_high_i8x16_u, "i16x8.extend_high_i8x16_u", 0xFD, 138) -OFD(I16x8__shl, "i16x8.shl", 0xFD, 139) -OFD(I16x8__shr_s, "i16x8.shr_s", 0xFD, 140) -OFD(I16x8__shr_u, "i16x8.shr_u", 0xFD, 141) -OFD(I16x8__add, "i16x8.add", 0xFD, 142) -OFD(I16x8__add_sat_s, "i16x8.add_sat_s", 0xFD, 143) -OFD(I16x8__add_sat_u, "i16x8.add_sat_u", 0xFD, 144) -OFD(I16x8__sub, "i16x8.sub", 0xFD, 145) -OFD(I16x8__sub_sat_s, "i16x8.sub_sat_s", 0xFD, 146) -OFD(I16x8__sub_sat_u, "i16x8.sub_sat_u", 0xFD, 147) -OFD(F64x2__nearest, "f64x2.nearest", 0xFD, 148) -OFD(I16x8__mul, "i16x8.mul", 0xFD, 149) -OFD(I16x8__min_s, "i16x8.min_s", 0xFD, 150) -OFD(I16x8__min_u, "i16x8.min_u", 0xFD, 151) -OFD(I16x8__max_s, "i16x8.max_s", 0xFD, 152) -OFD(I16x8__max_u, "i16x8.max_u", 0xFD, 153) -// 0xFD 154: Reserved -OFD(I16x8__avgr_u, "i16x8.avgr_u", 0xFD, 155) -OFD(I16x8__extmul_low_i8x16_s, "i16x8.extmul_low_i8x16_s", 0xFD, 156) -OFD(I16x8__extmul_high_i8x16_s, "i16x8.extmul_high_i8x16_s", 0xFD, 157) -OFD(I16x8__extmul_low_i8x16_u, "i16x8.extmul_low_i8x16_u", 0xFD, 158) -OFD(I16x8__extmul_high_i8x16_u, "i16x8.extmul_high_i8x16_u", 0xFD, 159) -OFD(I32x4__abs, "i32x4.abs", 0xFD, 160) -OFD(I32x4__neg, "i32x4.neg", 0xFD, 161) -// 0xFD 162: Reserved -OFD(I32x4__all_true, "i32x4.all_true", 0xFD, 163) -OFD(I32x4__bitmask, "i32x4.bitmask", 0xFD, 164) -// 0xFD 165: Reserved -// 0xFD 166: Reserved -OFD(I32x4__extend_low_i16x8_s, "i32x4.extend_low_i16x8_s", 0xFD, 167) -OFD(I32x4__extend_high_i16x8_s, "i32x4.extend_high_i16x8_s", 0xFD, 168) -OFD(I32x4__extend_low_i16x8_u, "i32x4.extend_low_i16x8_u", 0xFD, 169) -OFD(I32x4__extend_high_i16x8_u, "i32x4.extend_high_i16x8_u", 0xFD, 170) -OFD(I32x4__shl, "i32x4.shl", 0xFD, 171) -OFD(I32x4__shr_s, "i32x4.shr_s", 0xFD, 172) -OFD(I32x4__shr_u, "i32x4.shr_u", 0xFD, 173) -OFD(I32x4__add, "i32x4.add", 0xFD, 174) -// 0xFD 175: Reserved -// 0xFD 176: Reserved -OFD(I32x4__sub, "i32x4.sub", 0xFD, 177) -// 0xFD 178: Reserved -// 0xFD 179: Reserved -// 0xFD 180: Reserved -OFD(I32x4__mul, "i32x4.mul", 0xFD, 181) -OFD(I32x4__min_s, "i32x4.min_s", 0xFD, 182) -OFD(I32x4__min_u, "i32x4.min_u", 0xFD, 183) -OFD(I32x4__max_s, "i32x4.max_s", 0xFD, 184) -OFD(I32x4__max_u, "i32x4.max_u", 0xFD, 185) -OFD(I32x4__dot_i16x8_s, "i32x4.dot_i16x8_s", 0xFD, 186) -// 0xFD 187: Reserved -OFD(I32x4__extmul_low_i16x8_s, "i32x4.extmul_low_i16x8_s", 0xFD, 188) -OFD(I32x4__extmul_high_i16x8_s, "i32x4.extmul_high_i16x8_s", 0xFD, 189) -OFD(I32x4__extmul_low_i16x8_u, "i32x4.extmul_low_i16x8_u", 0xFD, 190) -OFD(I32x4__extmul_high_i16x8_u, "i32x4.extmul_high_i16x8_u", 0xFD, 191) -OFD(I64x2__abs, "i64x2.abs", 0xFD, 192) -OFD(I64x2__neg, "i64x2.neg", 0xFD, 193) -// 0xFD 194: Reserved -OFD(I64x2__all_true, "i64x2.all_true", 0xFD, 195) -OFD(I64x2__bitmask, "i64x2.bitmask", 0xFD, 196) -// 0xFD 197: Reserved -// 0xFD 198: Reserved -OFD(I64x2__extend_low_i32x4_s, "i64x2.extend_low_i32x4_s", 0xFD, 199) -OFD(I64x2__extend_high_i32x4_s, "i64x2.extend_high_i32x4_s", 0xFD, 200) -OFD(I64x2__extend_low_i32x4_u, "i64x2.extend_low_i32x4_u", 0xFD, 201) -OFD(I64x2__extend_high_i32x4_u, "i64x2.extend_high_i32x4_u", 0xFD, 202) -OFD(I64x2__shl, "i64x2.shl", 0xFD, 203) -OFD(I64x2__shr_s, "i64x2.shr_s", 0xFD, 204) -OFD(I64x2__shr_u, "i64x2.shr_u", 0xFD, 205) -OFD(I64x2__add, "i64x2.add", 0xFD, 206) -// 0xFD 207: Reserved -// 0xFD 208: Reserved -OFD(I64x2__sub, "i64x2.sub", 0xFD, 209) -// 0xFD 210: Reserved -// 0xFD 211: Reserved -// 0xFD 212: Reserved -OFD(I64x2__mul, "i64x2.mul", 0xFD, 213) -OFD(I64x2__eq, "i64x2.eq", 0xFD, 214) -OFD(I64x2__ne, "i64x2.ne", 0xFD, 215) -OFD(I64x2__lt_s, "i64x2.lt_s", 0xFD, 216) -OFD(I64x2__gt_s, "i64x2.gt_s", 0xFD, 217) -OFD(I64x2__le_s, "i64x2.le_s", 0xFD, 218) -OFD(I64x2__ge_s, "i64x2.ge_s", 0xFD, 219) -OFD(I64x2__extmul_low_i32x4_s, "i64x2.extmul_low_i32x4_s", 0xFD, 220) -OFD(I64x2__extmul_high_i32x4_s, "i64x2.extmul_high_i32x4_s", 0xFD, 221) -OFD(I64x2__extmul_low_i32x4_u, "i64x2.extmul_low_i32x4_u", 0xFD, 222) -OFD(I64x2__extmul_high_i32x4_u, "i64x2.extmul_high_i32x4_u", 0xFD, 223) -OFD(F32x4__abs, "f32x4.abs", 0xFD, 224) -OFD(F32x4__neg, "f32x4.neg", 0xFD, 225) -// 0xFD 226: Reserved -OFD(F32x4__sqrt, "f32x4.sqrt", 0xFD, 227) -OFD(F32x4__add, "f32x4.add", 0xFD, 228) -OFD(F32x4__sub, "f32x4.sub", 0xFD, 229) -OFD(F32x4__mul, "f32x4.mul", 0xFD, 230) -OFD(F32x4__div, "f32x4.div", 0xFD, 231) -OFD(F32x4__min, "f32x4.min", 0xFD, 232) -OFD(F32x4__max, "f32x4.max", 0xFD, 233) -OFD(F32x4__pmin, "f32x4.pmin", 0xFD, 234) -OFD(F32x4__pmax, "f32x4.pmax", 0xFD, 235) -OFD(F64x2__abs, "f64x2.abs", 0xFD, 236) -OFD(F64x2__neg, "f64x2.neg", 0xFD, 237) -OFD(F64x2__sqrt, "f64x2.sqrt", 0xFD, 239) -OFD(F64x2__add, "f64x2.add", 0xFD, 240) -OFD(F64x2__sub, "f64x2.sub", 0xFD, 241) -OFD(F64x2__mul, "f64x2.mul", 0xFD, 242) -OFD(F64x2__div, "f64x2.div", 0xFD, 243) -OFD(F64x2__min, "f64x2.min", 0xFD, 244) -OFD(F64x2__max, "f64x2.max", 0xFD, 245) -OFD(F64x2__pmin, "f64x2.pmin", 0xFD, 246) -OFD(F64x2__pmax, "f64x2.pmax", 0xFD, 247) -OFD(I32x4__trunc_sat_f32x4_s, "i32x4.trunc_sat_f32x4_s", 0xFD, 248) -OFD(I32x4__trunc_sat_f32x4_u, "i32x4.trunc_sat_f32x4_u", 0xFD, 249) -OFD(F32x4__convert_i32x4_s, "f32x4.convert_i32x4_s", 0xFD, 250) -OFD(F32x4__convert_i32x4_u, "f32x4.convert_i32x4_u", 0xFD, 251) -OFD(I32x4__trunc_sat_f64x2_s_zero, "i32x4.trunc_sat_f64x2_s_zero", 0xFD, 252) -OFD(I32x4__trunc_sat_f64x2_u_zero, "i32x4.trunc_sat_f64x2_u_zero", 0xFD, 253) -OFD(F64x2__convert_low_i32x4_s, "f64x2.convert_low_i32x4_s", 0xFD, 254) -OFD(F64x2__convert_low_i32x4_u, "f64x2.convert_low_i32x4_u", 0xFD, 255) - -// 0xFE prefix - Relaxed SIMD Instructions (part 4) -OFD(I8x16__relaxed_swizzle, "i8x16.relaxed_swizzle", 0xFD, 256) -OFD(I32x4__relaxed_trunc_f32x4_s, "i32x4.relaxed_trunc_f32x4_s", 0xFD, 257) -OFD(I32x4__relaxed_trunc_f32x4_u, "i32x4.relaxed_trunc_f32x4_u", 0xFD, 258) -OFD(I32x4__relaxed_trunc_f64x2_s_zero, "i32x4.relaxed_trunc_f64x2_s_zero", 0xFD, - 259) -OFD(I32x4__relaxed_trunc_f64x2_u_zero, "i32x4.relaxed_trunc_f64x2_u_zero", 0xFD, - 260) -OFD(F32x4__relaxed_madd, "f32x4.relaxed_madd", 0xFD, 261) -OFD(F32x4__relaxed_nmadd, "f32x4.relaxed_nmadd", 0xFD, 262) -OFD(F64x2__relaxed_madd, "f32x4.relaxed_madd", 0xFD, 263) -OFD(F64x2__relaxed_nmadd, "f32x4.relaxed_nmadd", 0xFD, 264) -OFD(I8x16__relaxed_laneselect, "i8x16.relaxed_laneselect", 0xFD, 265) -OFD(I16x8__relaxed_laneselect, "i16x8.relaxed_laneselect", 0xFD, 266) -OFD(I32x4__relaxed_laneselect, "i32x4.relaxed_laneselect", 0xFD, 267) -OFD(I64x2__relaxed_laneselect, "i64x2.relaxed_laneselect", 0xFD, 268) -OFD(F32x4__relaxed_min, "f32x4.relaxed_min", 0xFD, 269) -OFD(F32x4__relaxed_max, "f32x4.relaxed_max", 0xFD, 270) -OFD(F64x2__relaxed_min, "f64x2.relaxed_min", 0xFD, 271) -OFD(F64x2__relaxed_max, "f64x2.relaxed_max", 0xFD, 272) -OFD(I16x8__relaxed_q15mulr_s, "i16x8.relaxed_q15mulr_s", 0xFD, 273) -OFD(I16x8__relaxed_dot_i8x16_i7x16_s, "i16x8.relaxed_dot_i8x16_i7x16_s", 0xFD, - 274) -OFD(I32x4__relaxed_dot_i8x16_i7x16_add_s, "i32x4.relaxed_dot_i8x16_i7x16_add_s", - 0xFD, 275) -// 0xFD 276 ~ 303: Reserved - -// 0xFE prefix - Atomic instructions -OFE(Memory__atomic__notify, "memory.atomic.notify", 0xFE, 0) -OFE(Memory__atomic__wait32, "memory.atomic.wait32", 0xFE, 1) -OFE(Memory__atomic__wait64, "memory.atomic.wait64", 0xFE, 2) -OFE(Atomic__fence, "atomic.fence", 0xFE, 3) -// 0xFE 4 ~ 15: Reserved -OFE(I32__atomic__load, "i32.atomic.load", 0xFE, 16) -OFE(I64__atomic__load, "i64.atomic.load", 0xFE, 17) -OFE(I32__atomic__load8_u, "i32.atomic.load8_u", 0xFE, 18) -OFE(I32__atomic__load16_u, "i32.atomic.load16_u", 0xFE, 19) -OFE(I64__atomic__load8_u, "i64.atomic.load8_u", 0xFE, 20) -OFE(I64__atomic__load16_u, "i64.atomic.load16_u", 0xFE, 21) -OFE(I64__atomic__load32_u, "i64.atomic.load32_u", 0xFE, 22) -OFE(I32__atomic__store, "i32.atomic.store", 0xFE, 23) -OFE(I64__atomic__store, "i64.atomic.store", 0xFE, 24) -OFE(I32__atomic__store8, "i32.atomic.store8", 0xFE, 25) -OFE(I32__atomic__store16, "i32.atomic.store16", 0xFE, 26) -OFE(I64__atomic__store8, "i64.atomic.store8", 0xFE, 27) -OFE(I64__atomic__store16, "i64.atomic.store16", 0xFE, 28) -OFE(I64__atomic__store32, "i64.atomic.store32", 0xFE, 29) -OFE(I32__atomic__rmw__add, "i32.atomic.rmw.add", 0xFE, 30) -OFE(I64__atomic__rmw__add, "i64.atomic.rmw.add", 0xFE, 31) -OFE(I32__atomic__rmw8__add_u, "i32.atomic.rmw8.add_u", 0xFE, 32) -OFE(I32__atomic__rmw16__add_u, "i32.atomic.rmw16.add_u", 0xFE, 33) -OFE(I64__atomic__rmw8__add_u, "i64.atomic.rmw8.add_u", 0xFE, 34) -OFE(I64__atomic__rmw16__add_u, "i64.atomic.rmw16.add_u", 0xFE, 35) -OFE(I64__atomic__rmw32__add_u, "i64.atomic.rmw32.add_u", 0xFE, 36) -OFE(I32__atomic__rmw__sub, "i32.atomic.rmw.sub", 0xFE, 37) -OFE(I64__atomic__rmw__sub, "i64.atomic.rmw.sub", 0xFE, 38) -OFE(I32__atomic__rmw8__sub_u, "i32.atomic.rmw8.sub_u", 0xFE, 39) -OFE(I32__atomic__rmw16__sub_u, "i32.atomic.rmw16.sub_u", 0xFE, 40) -OFE(I64__atomic__rmw8__sub_u, "i64.atomic.rmw8.sub_u", 0xFE, 41) -OFE(I64__atomic__rmw16__sub_u, "i64.atomic.rmw16.sub_u", 0xFE, 42) -OFE(I64__atomic__rmw32__sub_u, "i64.atomic.rmw32.sub_u", 0xFE, 43) -OFE(I32__atomic__rmw__and, "i32.atomic.rmw.and", 0xFE, 44) -OFE(I64__atomic__rmw__and, "i64.atomic.rmw.and", 0xFE, 45) -OFE(I32__atomic__rmw8__and_u, "i32.atomic.rmw8.and_u", 0xFE, 46) -OFE(I32__atomic__rmw16__and_u, "i32.atomic.rmw16.and_u", 0xFE, 47) -OFE(I64__atomic__rmw8__and_u, "i64.atomic.rmw8.and_u", 0xFE, 48) -OFE(I64__atomic__rmw16__and_u, "i64.atomic.rmw16.and_u", 0xFE, 49) -OFE(I64__atomic__rmw32__and_u, "i64.atomic.rmw32.and_u", 0xFE, 50) -OFE(I32__atomic__rmw__or, "i32.atomic.rmw.or", 0xFE, 51) -OFE(I64__atomic__rmw__or, "i64.atomic.rmw.or", 0xFE, 52) -OFE(I32__atomic__rmw8__or_u, "i32.atomic.rmw8.or_u", 0xFE, 53) -OFE(I32__atomic__rmw16__or_u, "i32.atomic.rmw16.or_u", 0xFE, 54) -OFE(I64__atomic__rmw8__or_u, "i64.atomic.rmw8.or_u", 0xFE, 55) -OFE(I64__atomic__rmw16__or_u, "i64.atomic.rmw16.or_u", 0xFE, 56) -OFE(I64__atomic__rmw32__or_u, "i64.atomic.rmw32.or_u", 0xFE, 57) -OFE(I32__atomic__rmw__xor, "i32.atomic.rmw.xor", 0xFE, 58) -OFE(I64__atomic__rmw__xor, "i64.atomic.rmw.xor", 0xFE, 59) -OFE(I32__atomic__rmw8__xor_u, "i32.atomic.rmw8.xor_u", 0xFE, 60) -OFE(I32__atomic__rmw16__xor_u, "i32.atomic.rmw16.xor_u", 0xFE, 61) -OFE(I64__atomic__rmw8__xor_u, "i64.atomic.rmw8.xor_u", 0xFE, 62) -OFE(I64__atomic__rmw16__xor_u, "i64.atomic.rmw16.xor_u", 0xFE, 63) -OFE(I64__atomic__rmw32__xor_u, "i64.atomic.rmw32.xor_u", 0xFE, 64) -OFE(I32__atomic__rmw__xchg, "i32.atomic.rmw.xchg", 0xFE, 65) -OFE(I64__atomic__rmw__xchg, "i64.atomic.rmw.xchg", 0xFE, 66) -OFE(I32__atomic__rmw8__xchg_u, "i32.atomic.rmw8.xchg_u", 0xFE, 67) -OFE(I32__atomic__rmw16__xchg_u, "i32.atomic.rmw16.xchg_u", 0xFE, 68) -OFE(I64__atomic__rmw8__xchg_u, "i64.atomic.rmw8.xchg_u", 0xFE, 69) -OFE(I64__atomic__rmw16__xchg_u, "i64.atomic.rmw16.xchg_u", 0xFE, 70) -OFE(I64__atomic__rmw32__xchg_u, "i64.atomic.rmw32.xchg_u", 0xFE, 71) -OFE(I32__atomic__rmw__cmpxchg, "i32.atomic.rmw.cmpxchg", 0xFE, 72) -OFE(I64__atomic__rmw__cmpxchg, "i64.atomic.rmw.cmpxchg", 0xFE, 73) -OFE(I32__atomic__rmw8__cmpxchg_u, "i32.atomic.rmw8.cmpxchg_u", 0xFE, 74) -OFE(I32__atomic__rmw16__cmpxchg_u, "i32.atomic.rmw16.cmpxchg_u", 0xFE, 75) -OFE(I64__atomic__rmw8__cmpxchg_u, "i64.atomic.rmw8.cmpxchg_u", 0xFE, 76) -OFE(I64__atomic__rmw16__cmpxchg_u, "i64.atomic.rmw16.cmpxchg_u", 0xFE, 77) -OFE(I64__atomic__rmw32__cmpxchg_u, "i64.atomic.rmw32.cmpxchg_u", 0xFE, 78) - -#undef O -#undef OFB -#undef OFC -#undef OFD -#undef OFE -#endif // UseOpCode - -// enum_configure.h - -#ifdef UseProposal -#define P Line -// Finished and standardized proposals -P(ImportExportMutGlobals, "Import/Export of Mutable Globals") -P(NonTrapFloatToIntConversions, "Non-trapping float-to-int Conversions") -P(SignExtensionOperators, "Sign-extension Operators") -P(MultiValue, "Multi-value") -P(BulkMemoryOperations, "Bulk Memory Operations") -P(ReferenceTypes, "Reference Types") -P(SIMD, "Fixed-width SIMD") -// Phase 4 proposals -P(TailCall, "Tail Call") -P(ExtendedConst, "Extended Const Expressions") -P(FunctionReferences, "Typed Function References") -P(GC, "Garbage Collection") -P(MultiMemories, "Multiple Memories") -P(Threads, "Threads") -P(RelaxSIMD, "Relaxed SIMD") -// Phase 3 proposals -P(Annotations, "Custom Annotation Syntax in the Text Format") -P(Memory64, "Memory64") -P(ExceptionHandling, "Exception Handling") -// Phase 1 proposals -P(Component, "Component Model") -#undef P -#endif // UseProposal - -#ifdef UseHostRegistration -#define H Line -H(Wasi) -#undef H -#endif // UseHostRegistration - -// enum_errcode.h - -#ifdef UseErrCategory -#define C Line - -C(WASM, 0x00) -C(UserLevelError, 0x01) - -#undef C -#endif // UseErrCategory - -#ifdef UseErrCode -#define E Line - -E(Success, 0x0000, "success") -// Exit and return success. -E(Terminated, 0x0001, "terminated") -// Generic runtime error. -E(RuntimeError, 0x0002, "generic runtime error") -// Exceeded cost limit (out of gas). -E(CostLimitExceeded, 0x0003, "cost limit exceeded") -// Wrong VM's workflow -E(WrongVMWorkflow, 0x0004, "wrong VM workflow") -// Wasm function not found -E(FuncNotFound, 0x0005, "wasm function not found") -// AOT runtime is disabled -E(AOTDisabled, 0x0006, "AOT runtime is disabled in this build") -// Execution interrupted -E(Interrupted, 0x0007, "execution interrupted") -// Not validated module -E(NotValidated, 0x0008, "wasm module hasn't passed validation yet") -// Non-Null value is required -E(NonNullRequired, 0x0009, "set null value into non-nullable value type") -// Unable to set value due to const -E(SetValueToConst, 0x000A, "set value into const") -// Set value failed due to mismatch value type -E(SetValueErrorType, 0x000B, "set value type mismatch") -// User defined error -E(UserDefError, 0x000C, "user defined error code") - -// Load phase -// @{ -// File not found -E(IllegalPath, 0x0100, "invalid path") -// Error when reading -E(ReadError, 0x0101, "read error") -// Reach end of file when reading -E(UnexpectedEnd, 0x0102, "unexpected end") -// Not detected magic header -E(MalformedMagic, 0x0103, "magic header not detected") -// Unsupported version -E(MalformedVersion, 0x0104, "unknown binary version") -// Malformed section ID -E(MalformedSection, 0x0105, "malformed section id") -// Section size mismatched -E(SectionSizeMismatch, 0x0106, "section size mismatch") -// Length out of bounds -E(LengthOutOfBounds, 0x0107, "length out of bounds") -// Junk sections -E(JunkSection, 0x0108, "unexpected content after last section") -// Incompatible function and code section -E(IncompatibleFuncCode, 0x0109, - "function and code section have inconsistent lengths") -// Incompatible data and datacount section -E(IncompatibleDataCount, 0x010A, - "data count and data section have inconsistent lengths") -// Datacount section required -E(DataCountRequired, 0x010B, "data count section required") -// Malformed import kind -E(MalformedImportKind, 0x010C, "malformed import kind") -// Malformed export kind -E(MalformedExportKind, 0x010D, "malformed export kind") -// Not loaded an expected zero byte -E(ExpectedZeroByte, 0x010E, "zero byte expected") -// Malformed mutability -E(InvalidMut, 0x010F, "malformed mutability") -// Local size too large -E(TooManyLocals, 0x0110, "too many locals") -// Malformed value type -E(MalformedValType, 0x0111, "malformed value type") -// Malformed element type (Bulk-mem proposal) -E(MalformedElemType, 0x0112, "malformed element type") -// Malformed reference type (Ref-types proposal) -E(MalformedRefType, 0x0113, "malformed reference type") -// Invalid utf-8 encoding -E(MalformedUTF8, 0x0114, "malformed UTF-8 encoding") -// Invalid too large integer -E(IntegerTooLarge, 0x0115, "integer too large") -// Invalid presentation too long integer -E(IntegerTooLong, 0x0116, "integer representation too long") -// Illegal OpCode -E(IllegalOpCode, 0x0117, "illegal opcode") -// END OpCode expected -E(ENDCodeExpected, 0x0118, "END opcode expected") -// Parsing error -E(IllegalGrammar, 0x0119, "invalid wasm grammar") -// Shared memory must have max -E(SharedMemoryNoMax, 0x011A, "shared memory must have maximum") -// Intrinsics table not found -E(IntrinsicsTableNotFound, 0x011B, "intrinsics table not found") -// Malformed table (Ref-types proposal) -E(MalformedTable, 0x011C, "malformed table") -// Alignment must < 64 without and < 128 with multi-memory proposal. -E(InvalidStoreAlignment, 0x011D, "invalid store alignment") -// @} - -// Validation phase -// @{ -// Alignment > natural -E(InvalidAlignment, 0x0200, "alignment must not be larger than natural") -// Got unexpected type when checking -E(TypeCheckFailed, 0x0201, "type mismatch") -// Branch to unknown label index -E(InvalidLabelIdx, 0x0202, "unknown label") -// Access unknown local index -E(InvalidLocalIdx, 0x0203, "unknown local") -// Access unknown field index -E(InvalidFieldIdx, 0x0204, "unknown field") -// Type index not defined -E(InvalidFuncTypeIdx, 0x0205, "unknown type") -// Function index not defined -E(InvalidFuncIdx, 0x0206, "unknown function") -// Table index not defined -E(InvalidTableIdx, 0x0207, "unknown table") -// Memory index not defined -E(InvalidMemoryIdx, 0x0208, "unknown memory") -// Global index not defined -E(InvalidGlobalIdx, 0x0209, "unknown global") -// Tag index not defined -E(InvalidTagIdx, 0x020A, "unknown tag") -// Element segment index not defined -E(InvalidElemIdx, 0x020B, "unknown elem segment") -// Data segment index not defined -E(InvalidDataIdx, 0x020C, "unknown data segment") -// Undeclared reference -E(InvalidRefIdx, 0x020D, "undeclared function reference") -// Should be constant expression -E(ConstExprRequired, 0x020E, "constant expression required") -// Export name conflicted -E(DupExportName, 0x020F, "duplicate export name") -// Tried to store to const global value -E(ImmutableGlobal, 0x0210, "global is immutable") -// Tried to store to const field of structure -E(ImmutableField, 0x0211, "field is immutable") -// Tried to store to const array -E(ImmutableArray, 0x0212, "array is immutable") -// Invalid result arity in select t* instruction -E(InvalidResultArity, 0x0213, "invalid result arity") -// #Tables > 1 (without Ref-types proposal) -E(MultiTables, 0x0214, "multiple tables") -// #Memories > 1 -E(MultiMemories, 0x0215, "multiple memories") -// Invalid Limit grammar -E(InvalidLimit, 0x0216, "size minimum must not be greater than maximum") -// Memory pages > 65536 -E(InvalidMemPages, 0x0217, "memory size must be at most 65536 pages (4GiB)") -// Invalid start function signature -E(InvalidStartFunc, 0x0218, "start function") -// Invalid lane index -E(InvalidLaneIdx, 0x0219, "invalid lane index") -// Invalid uninitialized local -E(InvalidUninitLocal, 0x021A, "uninitialized local") -// Defaultable field type required -E(InvalidNotDefaultableField, 0x021B, "field type is not defaultable") -// Defaultable array type required -E(InvalidNotDefaultableArray, 0x021C, "array type is not defaultable") -// Unpacked field type required, but got packed one -E(InvalidPackedField, 0x021D, "field is packed") -// Unpacked array type required, but got packed one -E(InvalidPackedArray, 0x021E, "array is packed") -// Packed field type required, but got unpacked one -E(InvalidUnpackedField, 0x021F, "field is unpacked") -// Packed array type required, but got unpacked one -E(InvalidUnpackedArray, 0x0220, "array is unpacked") -// Invalid Br ref type -E(InvalidBrRefType, 0x0221, "invalid br ref type") -// 2 array types not matched -E(ArrayTypesMismatch, 0x0222, "array types do not match") -// Should be numeric type in array type -E(ArrayTypesNumtypeRequired, 0x0223, "array type is not numeric or vector") -// Sub type matching or validation failed -E(InvalidSubType, 0x0224, "sub type") -// Invalid Tag type -E(InvalidTagResultType, 0x0225, "non-empty tag result type") -// @} - -// Instantiation phase -// @{ -// Module name conflicted when importing. -E(ModuleNameConflict, 0x0300, "module name conflict") -// Import matching failed -E(IncompatibleImportType, 0x0301, "incompatible import type") -// Unknown import instances -E(UnknownImport, 0x0302, "unknown import") -// Init failed when instantiating data segment -E(DataSegDoesNotFit, 0x0303, "data segment does not fit") -// Init failed when instantiating element segment -E(ElemSegDoesNotFit, 0x0304, "elements segment does not fit") -// Invalid core sort for component export -E(InvalidCoreSort, 0x0305, "invalid core sort") -E(InvalidCanonOption, 0x0306, "invalid canonical option") -// @} - -// Execution phase -// @{ -// Wrong access of instances addresses -E(WrongInstanceAddress, 0x0400, "wrong instance address") -// Wrong access of instances indices -E(WrongInstanceIndex, 0x0401, "wrong instance index") -// Instruction type not match -E(InstrTypeMismatch, 0x0402, "instruction type mismatch") -// Function signature not match when invoking -E(FuncSigMismatch, 0x0403, "function signature mismatch") -// Divide by zero -E(DivideByZero, 0x0404, "integer divide by zero") -// Integer overflow -E(IntegerOverflow, 0x0405, "integer overflow") -// Cannot do convert to integer -E(InvalidConvToInt, 0x0406, "invalid conversion to integer") -// Out of bounds table access -E(TableOutOfBounds, 0x0407, "out of bounds table access") -// Out of bounds memory access -E(MemoryOutOfBounds, 0x0408, "out of bounds memory access") -// Out of bounds array access -E(ArrayOutOfBounds, 0x0409, "out of bounds array access") -// Meet an unreachable instruction -E(Unreachable, 0x040A, "unreachable") -// Uninitialized element in table instance -E(UninitializedElement, 0x040B, "uninitialized element") -// Access undefined element in table instances -E(UndefinedElement, 0x040C, "undefined element") -// Func type mismatch in call_indirect -E(IndirectCallTypeMismatch, 0x040D, "indirect call type mismatch") -// Host function execution failed -E(HostFuncError, 0x040E, "host function failed") -// Reference type not match -E(RefTypeMismatch, 0x040F, "reference type mismatch") -// Unaligned atomic memory access -E(UnalignedAtomicAccess, 0x0410, "unaligned atomic") -// wait32/wait64 on unshared memory -E(ExpectSharedMemory, 0x0411, "expected shared memory") -// Cast null pointer to non null -E(CastNullToNonNull, 0x0412, "null reference") -// Access to null function reference -E(AccessNullFunc, 0x0413, "null function reference") -// Access to null structure reference -E(AccessNullStruct, 0x0414, "null structure reference") -// Access to null array reference -E(AccessNullArray, 0x0415, "null array reference") -// Access to null i31 reference -E(AccessNullI31, 0x0416, "null i31 reference") -// Access to null exception reference -E(AccessNullException, 0x0417, "null exception reference") -// Fail to cast reference -E(CastFailed, 0x0418, "cast failure") -// Uncaught Exception -E(UncaughtException, 0x0419, "uncaught exception") -// @} - -// Component model load phase -// @{ -// Malformed sort -E(MalformedSort, 0x0500, "malformed sort") -// Malformed alias target -E(MalformedAliasTarget, 0x0501, "malformed alias target") -// Malformed core instance -E(MalformedCoreInstance, 0x0502, "malformed core instance") -// Malformed instance -E(MalformedInstance, 0x0503, "malformed instance") -// Malformed defType -E(MalformedDefType, 0x0504, "malformed defined type") -// Malformed record type -E(MalformedRecordType, 0x0505, "malformed record type") -// Malformed variant type -E(MalformedVariantType, 0x0506, "malformed variant type") -// Malformed tuple type -E(MalformedTupleType, 0x0507, "malformed tuple type") -// Malformed flags type -E(MalformedFlagsType, 0x0508, "malformed flags type") -// Malformed canonical -E(MalformedCanonical, 0x0509, "malformed canonical") -// Unknown canonical option -E(UnknownCanonicalOption, 0x050A, "unknown canonical option") -// Malformed name -E(MalformedName, 0x050B, "malformed name") -// @} - -// Component model instantiation phase -// @{ -E(CoreInvalidExport, 0x0600, "invalid export in core module") -// @} - -#undef E -#endif // UseErrCode - -#ifdef UseWasmPhase -#define P Line - -P(WasmEdge, 0x00, "wasmedge runtime") -P(Loading, 0x01, "loading") -P(Validation, 0x02, "validation") -P(Instantiation, 0x03, "instantiation") -P(Execution, 0x04, "execution") -P(UserDefined, 0x05, "user defined") - -#undef P -#endif // UseWasmPhase - -// enum_errinfo.hpp - -#ifdef UsePtrType -#define P Line - -P(Index, "index") // Index of instances -P(Address, "address") // Absolute address - -#undef P -#endif // UsePtrType - -#ifdef UseMismatchCategory -#define M Line - -M(Alignment, "memory alignment") // Alignment in memory instructions -M(ValueType, "value type") // Value type -M(ValueTypes, "value types") // Value type list -M(Mutation, "mutation") // Const or Var -M(ExternalType, "external type") // External typing -M(FunctionType, "function type") // Function type -M(Table, "table") // Table instance -M(Memory, "memory") // Memory instance -M(Global, "global") // Global instance -M(Version, "version") // Versions - -#undef M -#endif // UseMismatchCategory - -#ifdef UseIndexCategory -#define I Line - -I(Label, "label") -I(Local, "local") -I(DefinedType, "defined type") -I(FunctionType, "function type") -I(Function, "function") -I(Table, "table") -I(Memory, "memory") -I(Global, "global") -I(Element, "element") -I(Data, "data") -I(Lane, "lane") -I(Field, "field") -I(TagType, "tag type") -I(Tag, "tag") - -#undef I -#endif // UseIndexCategory - -// enum_types.h - -#ifdef UseTypeCode -#define T Line - -T(TypeIndex, 0x00, "type_index") // 0x00 reserved for type index case -T(I32, 0x7F, "i32") // -0x01 for number type -T(I64, 0x7E, "i64") // -0x02 for number type -T(F32, 0x7D, "f32") // -0x03 for number type -T(F64, 0x7C, "f64") // -0x04 for number type -T(V128, 0x7B, "v128") // -0x05 for vector type -T(I8, 0x78, "i8") // -0x08 for packed type -T(I16, 0x77, "i16") // -0x09 for packed type -T(NullFuncRef, 0x73, "nofunc") // -0x0D for heap type -T(NullExternRef, 0x72, "noextern") // -0x0E for heap type -T(NullRef, 0x71, "none") // -0x0F for heap type -T(FuncRef, 0x70, "func") // -0x10 for heap type -T(ExternRef, 0x6F, "extern") // -0x11 for heap type -T(AnyRef, 0x6E, "any") // -0x12 for heap type -T(EqRef, 0x6D, "eq") // -0x13 for heap type -T(I31Ref, 0x6C, "i31") // -0x14 for heap type -T(StructRef, 0x6B, "struct") // -0x15 for heap type -T(ArrayRef, 0x6A, "array") // -0x16 for heap type -T(ExnRef, 0x69, "exn") // -0x17 for reference type -T(Ref, 0x64, "ref") // -0x1C for reference type -T(RefNull, 0x63, "ref_null") // -0x1D for reference type -T(Func, 0x60, "func") // -0x20 for composite type -T(Struct, 0x5F, "struct") // -0x21 for composite type -T(Array, 0x5E, "array") // -0x22 for composite type -T(Sub, 0x50, "sub") // -0x30 for sub type -T(SubFinal, 0x4F, "sub_final") // -0x31 for sub type -T(Rec, 0x4E, "rec") // -0x32 for recursive type -T(Epsilon, 0x40, "-") // -0x40 for result type -// component model types -T(String, 0x80, "string") // string type - -#undef T -#endif // UseTypeCode - -#ifdef UseValMut -#define M Line - -M(Const, 0x00, "const") -M(Var, 0x01, "var") - -#undef M -#endif // UseValMut - -#ifdef UseExternalType -#define E Line - -E(Function, 0x00U, "function") -E(Table, 0x01U, "table") -E(Memory, 0x02U, "memory") -E(Global, 0x03U, "global") -E(Tag, 0x04U, "tag") - -#undef E -#endif // UseExternalType diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_configure.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_configure.h deleted file mode 100644 index eb40f76c94c9bf0f1e1ea1751c1fa5e473f70824..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_configure.h +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_configure.h - Configure related enumerations -===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definitions of configure related enumerations. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_CONFIGURE_H -#define WASMEDGE_C_API_ENUM_CONFIGURE_H - -/// WASM Proposal C enumeration. -enum WasmEdge_Proposal { -#define UseProposal -#define Line(NAME, STRING) WasmEdge_Proposal_##NAME, -#include "enum.inc" -#undef Line -#undef UseProposal -}; - -/// Host Module Registration C enumeration. -enum WasmEdge_HostRegistration { -#define UseHostRegistration -#define Line(NAME) WasmEdge_HostRegistration_##NAME, -#include "enum.inc" -#undef Line -#undef UseHostRegistration -}; - -/// AOT compiler optimization level C enumeration. -enum WasmEdge_CompilerOptimizationLevel { - // Disable as many optimizations as possible. - WasmEdge_CompilerOptimizationLevel_O0 = 0, - // Optimize quickly without destroying debuggability. - WasmEdge_CompilerOptimizationLevel_O1, - // Optimize for fast execution as much as possible without triggering - // significant incremental compile time or code size growth. - WasmEdge_CompilerOptimizationLevel_O2, - // Optimize for fast execution as much as possible. - WasmEdge_CompilerOptimizationLevel_O3, - // Optimize for small code size as much as possible without triggering - // significant incremental compile time or execution time slowdowns. - WasmEdge_CompilerOptimizationLevel_Os, - // Optimize for small code size as much as possible. - WasmEdge_CompilerOptimizationLevel_Oz -}; - -/// AOT compiler output binary format C enumeration. -enum WasmEdge_CompilerOutputFormat { - // Native dynamic library format. - WasmEdge_CompilerOutputFormat_Native = 0, - // WebAssembly with AOT compiled codes in custom sections. - WasmEdge_CompilerOutputFormat_Wasm -}; - -#endif // WASMEDGE_C_API_ENUM_CONFIGURE_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_errcode.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_errcode.h deleted file mode 100644 index 68292cbcd960105fcf6f53699407657f4c5b1d13..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_errcode.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_errcode.h - Error code enumerations ----------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the enumerations of WasmEdge error code. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_ERRCODE_H -#define WASMEDGE_C_API_ENUM_ERRCODE_H - -/// Error category C enumeration. -enum WasmEdge_ErrCategory { -#define UseErrCategory -#define Line(NAME, VALUE) WasmEdge_ErrCategory_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseErrCategory -}; - -/// Error code C enumeration. -enum WasmEdge_ErrCode { -#define UseErrCode -#define Line(NAME, VALUE, STRING) WasmEdge_ErrCode_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseErrCode -}; - -#endif // WASMEDGE_C_API_ENUM_ERRCODE_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_types.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_types.h deleted file mode 100644 index 4b89c003f2e6aaed143c22667c0a51a62315b1b8..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/enum_types.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/common/enum_types.h - WASM types related enumerations ----===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the definitions of WASM types related enumerations. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_ENUM_TYPES_H -#define WASMEDGE_C_API_ENUM_TYPES_H - -/// WASM Type code C enumeration. -enum WasmEdge_TypeCode { -#define UseTypeCode -#define Line(NAME, VALUE, STRING) WasmEdge_TypeCode_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseTypeCode -}; - -/// WASM Mutability C enumeration. -enum WasmEdge_Mutability { -#define UseValMut -#define Line(NAME, VALUE, STRING) WasmEdge_Mutability_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseValMut -}; - -/// WASM External type C enumeration. -enum WasmEdge_ExternalType { -#define UseExternalType -#define Line(NAME, VALUE, STRING) WasmEdge_ExternalType_##NAME = VALUE, -#include "enum.inc" -#undef Line -#undef UseExternalType -}; - -#endif // WASMEDGE_C_API_ENUM_TYPES_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/int128.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/int128.h deleted file mode 100644 index c4706fb22b4104231b67d381ac2aeb6a740fc84d..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/int128.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/int128.h - WasmEdge C API --------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the int128 definitions of the WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_INT128_H -#define WASMEDGE_C_API_INT128_H - -#if defined(__x86_64__) || defined(__aarch64__) || \ - (defined(__riscv) && __riscv_xlen == 64) -typedef unsigned __int128 uint128_t; -typedef __int128 int128_t; -#else -typedef struct uint128_t { - uint64_t Low; - uint64_t High; -} uint128_t; - -typedef struct int128_t { - uint64_t Low; - int64_t High; -} int128_t; -#endif - -#endif /// WASMEDGE_C_API_INT128_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/version.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/version.h deleted file mode 100644 index 2e092f7dfa0ec2d217602a331f2c802d38757539..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/version.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/version.h - WasmEdge C API -------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the version definitions of the WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_VERSION_H -#define WASMEDGE_C_API_VERSION_H - -// WasmEdge version. -#define WASMEDGE_VERSION "0.14.1-rc.3" -#define WASMEDGE_VERSION_MAJOR 0 -#define WASMEDGE_VERSION_MINOR 14 -#define WASMEDGE_VERSION_PATCH 1 - -#define WasmEdge_Plugin_CurrentAPIVersion 4 - -#endif // WASMEDGE_C_API_VERSION_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/wasmedge.h b/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/wasmedge.h deleted file mode 100644 index 8585c2f734cb38410f316fdfbe64d48180cfcd7b..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/include/wasmedge/wasmedge.h +++ /dev/null @@ -1,4183 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2019-2024 Second State INC - -//===-- wasmedge/wasmedge.h - WasmEdge C API ------------------------------===// -// -// Part of the WasmEdge Project. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file contains the function declarations of WasmEdge C API. -/// -//===----------------------------------------------------------------------===// - -#ifndef WASMEDGE_C_API_H -#define WASMEDGE_C_API_H - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ - defined(__TOS_WIN__) || defined(__WINDOWS__) -#ifdef WASMEDGE_COMPILE_LIBRARY -#define WASMEDGE_CAPI_EXPORT __declspec(dllexport) -#else -#define WASMEDGE_CAPI_EXPORT __declspec(dllimport) -#endif // WASMEDGE_COMPILE_LIBRARY -#ifdef WASMEDGE_PLUGIN -#define WASMEDGE_CAPI_PLUGIN_EXPORT __declspec(dllexport) -#else -#define WASMEDGE_CAPI_PLUGIN_EXPORT __declspec(dllimport) -#endif // WASMEDGE_PLUGIN -#else -#define WASMEDGE_CAPI_EXPORT __attribute__((visibility("default"))) -#define WASMEDGE_CAPI_PLUGIN_EXPORT __attribute__((visibility("default"))) -#endif // _WIN32 - -#include -#include - -#include "wasmedge/enum_configure.h" -#include "wasmedge/enum_errcode.h" -#include "wasmedge/enum_types.h" -#include "wasmedge/int128.h" -#include "wasmedge/version.h" - -/// WasmEdge WASM value type struct. -typedef struct WasmEdge_ValType { - // This struct contains the raw data which describes the value type in WASM. - // Developers should use the corresponding `WasmEdge_ValueTypeGen` functions - // to generate this struct. - uint8_t Data[8]; -} WasmEdge_ValType; - -/// WasmEdge WASM value struct. -typedef struct WasmEdge_Value { - uint128_t Value; - // The value type `Type` is used in the parameters or returns of invoking - // functions. Developers should use the corresponding `WasmEdge_ValueGen` - // functions to generate this struct, and the `WasmEdge_ValueGet` functions to - // retrieve the value from this struct. - WasmEdge_ValType Type; -} WasmEdge_Value; - -/// WasmEdge string struct. -typedef struct WasmEdge_String { - uint32_t Length; - const char *Buf; -} WasmEdge_String; - -/// WasmEdge bytes struct. -typedef struct WasmEdge_Bytes { - uint32_t Length; - const uint8_t *Buf; -} WasmEdge_Bytes; - -/// WasmEdge result struct. -typedef struct WasmEdge_Result { - uint32_t Code; -} WasmEdge_Result; -#ifdef __cplusplus -#define WasmEdge_Result_Success (WasmEdge_Result{/* Code */ 0x00}) -#define WasmEdge_Result_Terminate (WasmEdge_Result{/* Code */ 0x01}) -#define WasmEdge_Result_Fail (WasmEdge_Result{/* Code */ 0x02}) -#else -#define WasmEdge_Result_Success ((WasmEdge_Result){.Code = 0x00}) -#define WasmEdge_Result_Terminate ((WasmEdge_Result){.Code = 0x01}) -#define WasmEdge_Result_Fail ((WasmEdge_Result){.Code = 0x02}) -#endif -/// Struct of WASM limit. -typedef struct WasmEdge_Limit { - /// Boolean to describe has max value or not. - bool HasMax; - /// Boolean to describe is shared memory or not. - bool Shared; - /// Minimum value. - uint32_t Min; - /// Maximum value. Will be ignored if the `HasMax` is false. - uint32_t Max; -} WasmEdge_Limit; - -/// Opaque struct of WasmEdge configure. -typedef struct WasmEdge_ConfigureContext WasmEdge_ConfigureContext; - -/// Opaque struct of WasmEdge statistics. -typedef struct WasmEdge_StatisticsContext WasmEdge_StatisticsContext; - -/// Opaque struct of WasmEdge AST module. -typedef struct WasmEdge_ASTModuleContext WasmEdge_ASTModuleContext; - -/// Opaque struct of WasmEdge function type. -typedef struct WasmEdge_FunctionTypeContext WasmEdge_FunctionTypeContext; - -/// Opaque struct of WasmEdge memory type. -typedef struct WasmEdge_MemoryTypeContext WasmEdge_MemoryTypeContext; - -/// Opaque struct of WasmEdge table type. -typedef struct WasmEdge_TableTypeContext WasmEdge_TableTypeContext; - -/// Opaque struct of WasmEdge tag type. -typedef struct WasmEdge_TagTypeContext WasmEdge_TagTypeContext; - -/// Opaque struct of WasmEdge global type. -typedef struct WasmEdge_GlobalTypeContext WasmEdge_GlobalTypeContext; - -/// Opaque struct of WasmEdge import type. -typedef struct WasmEdge_ImportTypeContext WasmEdge_ImportTypeContext; - -/// Opaque struct of WasmEdge export type. -typedef struct WasmEdge_ExportTypeContext WasmEdge_ExportTypeContext; - -/// Opaque struct of WasmEdge AOT compiler. -typedef struct WasmEdge_CompilerContext WasmEdge_CompilerContext; - -/// Opaque struct of WasmEdge loader. -typedef struct WasmEdge_LoaderContext WasmEdge_LoaderContext; - -/// Opaque struct of WasmEdge validator. -typedef struct WasmEdge_ValidatorContext WasmEdge_ValidatorContext; - -/// Opaque struct of WasmEdge executor. -typedef struct WasmEdge_ExecutorContext WasmEdge_ExecutorContext; - -/// Opaque struct of WasmEdge store. -typedef struct WasmEdge_StoreContext WasmEdge_StoreContext; - -/// Opaque struct of WasmEdge module instance. -typedef struct WasmEdge_ModuleInstanceContext WasmEdge_ModuleInstanceContext; - -/// Opaque struct of WasmEdge function instance. -typedef struct WasmEdge_FunctionInstanceContext - WasmEdge_FunctionInstanceContext; - -/// Opaque struct of WasmEdge table instance. -typedef struct WasmEdge_TableInstanceContext WasmEdge_TableInstanceContext; - -/// Opaque struct of WasmEdge memory instance. -typedef struct WasmEdge_MemoryInstanceContext WasmEdge_MemoryInstanceContext; - -/// Opaque struct of WasmEdge tag instance. -typedef struct WasmEdge_TagInstanceContext WasmEdge_TagInstanceContext; - -/// Opaque struct of WasmEdge global instance. -typedef struct WasmEdge_GlobalInstanceContext WasmEdge_GlobalInstanceContext; - -/// Opaque struct of WasmEdge calling frame. -typedef struct WasmEdge_CallingFrameContext WasmEdge_CallingFrameContext; - -/// Opaque struct of WasmEdge asynchronous result. -typedef struct WasmEdge_Async WasmEdge_Async; - -/// Opaque struct of WasmEdge VM. -typedef struct WasmEdge_VMContext WasmEdge_VMContext; - -/// Opaque struct of WasmEdge Plugin. -typedef struct WasmEdge_PluginContext WasmEdge_PluginContext; - -/// Type of option value. -typedef enum WasmEdge_ProgramOptionType { - /// No option value. - WasmEdge_ProgramOptionType_None, - /// Boolean value. - WasmEdge_ProgramOptionType_Toggle, - WasmEdge_ProgramOptionType_Int8, - WasmEdge_ProgramOptionType_Int16, - WasmEdge_ProgramOptionType_Int32, - WasmEdge_ProgramOptionType_Int64, - WasmEdge_ProgramOptionType_UInt8, - WasmEdge_ProgramOptionType_UInt16, - WasmEdge_ProgramOptionType_UInt32, - WasmEdge_ProgramOptionType_UInt64, - WasmEdge_ProgramOptionType_Float, - WasmEdge_ProgramOptionType_Double, - /// WasmEdge_String. - WasmEdge_ProgramOptionType_String, -} WasmEdge_ProgramOptionType; - -/// Program option for plugins. -typedef struct WasmEdge_ProgramOption { - const char *Name; - const char *Description; - WasmEdge_ProgramOptionType Type; - void *Storage; - const void *DefaultValue; -} WasmEdge_ProgramOption; - -/// Module descriptor for plugins. -typedef struct WasmEdge_ModuleDescriptor { - const char *Name; - const char *Description; - WasmEdge_ModuleInstanceContext *(*Create)( - const struct WasmEdge_ModuleDescriptor *); -} WasmEdge_ModuleDescriptor; - -/// Version data for plugins. -typedef struct WasmEdge_PluginVersionData { - uint32_t Major; - uint32_t Minor; - uint32_t Patch; - uint32_t Build; -} WasmEdge_PluginVersionData; - -/// Plugin descriptor for plugins. -typedef struct WasmEdge_PluginDescriptor { - const char *Name; - const char *Description; - uint32_t APIVersion; - WasmEdge_PluginVersionData Version; - uint32_t ModuleCount; - uint32_t ProgramOptionCount; - WasmEdge_ModuleDescriptor *ModuleDescriptions; - WasmEdge_ProgramOption *ProgramOptions; -} WasmEdge_PluginDescriptor; - -#ifdef __cplusplus -extern "C" { -#endif - -// >>>>>>>> WasmEdge version functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the version string of the WasmEdge C API. -/// -/// The returned string must __NOT__ be destroyed. -/// -/// \returns NULL-terminated C string of version. -WASMEDGE_CAPI_EXPORT extern const char *WasmEdge_VersionGet(void); - -/// Get the major version value of the WasmEdge C API. -/// -/// \returns Value of the major version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetMajor(void); - -/// Get the minor version value of the WasmEdge C API. -/// -/// \returns Value of the minor version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetMinor(void); - -/// Get the patch version value of the WasmEdge C API. -/// -/// \returns Value of the patch version. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VersionGetPatch(void); - -// <<<<<<<< WasmEdge version functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge logging functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Set the logging system to filter to error level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogSetErrorLevel(void); - -/// Set the logging system to filter to debug level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogSetDebugLevel(void); - -/// Set the logging system off. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_LogOff(void); - -// <<<<<<<< WasmEdge logging functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge valtype functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Generate the I32 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the I32 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenI32(void); - -/// Generate the I64 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the I64 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenI64(void); - -/// Generate the F32 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the F32 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenF32(void); - -/// Generate the F64 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the F64 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenF64(void); - -/// Generate the V128 WASM value type. -/// -/// \returns WasmEdge_ValType struct with the V128 value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenV128(void); - -/// Generate the FuncRef WASM value type. -/// -/// \returns WasmEdge_ValType struct with the FuncRef value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenFuncRef(void); - -/// Generate the ExternRef WASM value type. -/// -/// \returns WasmEdge_ValType struct with the ExternRef value type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType WasmEdge_ValTypeGenExternRef(void); - -/// Compare the two WasmEdge_ValType objects. -/// -/// \param ValType1 the first WasmEdge_ValType object to compare. -/// \param ValType2 the second WasmEdge_ValType object to compare. -/// -/// \returns true if the content of two WasmEdge_ValType objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsEqual(const WasmEdge_ValType ValType1, - const WasmEdge_ValType ValType2); - -/// Specify the WASM value type is an I32 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an I32, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsI32(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is an I64 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an I64, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsI64(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a F32 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a F32, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsF32(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a F64 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a F64, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsF64(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a V128 or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a V128, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsV128(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a FuncRef or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a FuncRef, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsFuncRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is an ExternRef or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is an ExternRef, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsExternRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a Ref (includes nullable and non-nullable) or -/// not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a Ref, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsRef(const WasmEdge_ValType ValType); - -/// Specify the WASM value type is a nullable Ref or not. -/// -/// \param ValType the WasmEdge_ValType object to check. -/// -/// \returns true if the value type is a nullable Ref, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValTypeIsRefNull(const WasmEdge_ValType ValType); - -// <<<<<<<< WasmEdge valtype functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge value functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Generate the I32 WASM value. -/// -/// \param Val the I32 value. -/// -/// \returns WasmEdge_Value struct with the I32 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenI32(const int32_t Val); - -/// Generate the I64 WASM value. -/// -/// \param Val the I64 value. -/// -/// \returns WasmEdge_Value struct with the I64 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenI64(const int64_t Val); - -/// Generate the F32 WASM value. -/// -/// \param Val the F32 value. -/// -/// \returns WasmEdge_Value struct with the F32 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenF32(const float Val); - -/// Generate the F64 WASM value. -/// -/// \param Val the F64 value. -/// -/// \returns WasmEdge_Value struct with the F64 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenF64(const double Val); - -/// Generate the V128 WASM value. -/// -/// \param Val the V128 value. -/// -/// \returns WasmEdge_Value struct with the V128 value. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenV128(const int128_t Val); - -/// Generate the function reference WASM value. -/// -/// The values generated by this function are only meaningful when the -/// `WasmEdge_Proposal_BulkMemoryOperations` or the -/// `WasmEdge_Proposal_ReferenceTypes` turns on in configuration. -/// -/// \param Cxt the function instance context to convert to the reference. -/// -/// \returns WasmEdge_Value struct with the function reference. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenFuncRef(const WasmEdge_FunctionInstanceContext *Cxt); - -/// Generate the function reference WASM value. -/// -/// The values generated by this function are only meaningful when the -/// `WasmEdge_Proposal_ReferenceTypes` turns on in configuration. -/// -/// \param Ref the reference to the external object. -/// -/// \returns WasmEdge_Value struct with the external reference. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_ValueGenExternRef(void *Ref); - -/// Retrieve the I32 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns I32 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int32_t -WasmEdge_ValueGetI32(const WasmEdge_Value Val); - -/// Retrieve the I64 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns I64 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int64_t -WasmEdge_ValueGetI64(const WasmEdge_Value Val); - -/// Retrieve the F32 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns F32 value in the input struct. -WASMEDGE_CAPI_EXPORT extern float -WasmEdge_ValueGetF32(const WasmEdge_Value Val); - -/// Retrieve the F64 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns F64 value in the input struct. -WASMEDGE_CAPI_EXPORT extern double -WasmEdge_ValueGetF64(const WasmEdge_Value Val); - -/// Retrieve the V128 value from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns V128 value in the input struct. -WASMEDGE_CAPI_EXPORT extern int128_t -WasmEdge_ValueGetV128(const WasmEdge_Value Val); - -/// Specify the WASM value is a null reference or not. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns true if the value is a null reference, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ValueIsNullRef(const WasmEdge_Value Val); - -/// Retrieve the function instance context from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns pointer to function instance context in the input struct. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionInstanceContext * -WasmEdge_ValueGetFuncRef(const WasmEdge_Value Val); - -/// Retrieve the external reference from the WASM value. -/// -/// \param Val the WasmEdge_Value struct. -/// -/// \returns external reference in the input struct. -WASMEDGE_CAPI_EXPORT extern void * -WasmEdge_ValueGetExternRef(const WasmEdge_Value Val); - -// <<<<<<<< WasmEdge value functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge string functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_String with the C string. -/// -/// The caller owns the object and should call `WasmEdge_StringDelete` to -/// destroy it. This function only supports the C string with NULL termination. -/// If the input string may have `\0` character, please use the -/// `WasmEdge_StringCreateByBuffer` instead. -/// -/// \param Str the NULL-terminated C string to copy into the WasmEdge_String -/// object. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed or -/// the input string is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringCreateByCString(const char *Str); - -/// Creation of the WasmEdge_String with the buffer and its length. -/// -/// The caller owns the object and should call `WasmEdge_StringDelete` to -/// destroy it. -/// -/// \param Buf the buffer to wrap to the WasmEdge_String object. -/// \param Len the buffer length. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed or -/// the input buffer is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringCreateByBuffer(const char *Buf, const uint32_t Len); - -/// Create the WasmEdge_String wraps to the buffer. -/// -/// This function creates a `WasmEdge_String` object which wraps to the input -/// buffer. The caller should guarantee the life cycle of the input buffer, and -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Buf the buffer to copy into the WasmEdge_String object. -/// \param Len the buffer length. -/// -/// \returns string object refer to the input buffer with its length. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_StringWrap(const char *Buf, const uint32_t Len); - -/// Compare the two WasmEdge_String objects. -/// -/// \param Str1 the first WasmEdge_String object to compare. -/// \param Str2 the second WasmEdge_String object to compare. -/// -/// \returns true if the content of two WasmEdge_String objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_StringIsEqual(const WasmEdge_String Str1, const WasmEdge_String Str2); - -/// Copy the content of WasmEdge_String object to the buffer. -/// -/// This function copy at most `Len` characters from the `WasmEdge_String` -/// object to the destination buffer. If the string length is less than `Len` -/// characters long, the remainder of the buffer is filled with `\0' characters. -/// Otherwise, the destination is not terminated. -/// -/// \param Str the source WasmEdge_String object to copy. -/// \param Buf the buffer to fill the string content. -/// \param Len the buffer length. -/// -/// \returns the copied length of string. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StringCopy(const WasmEdge_String Str, char *Buf, const uint32_t Len); - -/// Deletion of the WasmEdge_String. -/// -/// After calling this function, the resources in the WasmEdge_String object -/// will be released and the object should __NOT__ be used. -/// -/// \param Str the WasmEdge_String object to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_StringDelete(WasmEdge_String Str); - -// <<<<<<<< WasmEdge string functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge bytes functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_Bytes with the buffer and its length. -/// -/// The caller owns the object and should call `WasmEdge_BytesDelete` to destroy -/// it. -/// -/// \param Buf the buffer to copy into the WasmEdge_Bytes object. -/// \param Len the buffer length. -/// -/// \returns bytes object. Length will be 0 and Buf will be NULL if failed or -/// the input buffer is a NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Bytes -WasmEdge_BytesCreate(const uint8_t *Buf, const uint32_t Len); - -/// Create the WasmEdge_Bytes wraps to the buffer. -/// -/// This function creates a `WasmEdge_Bytes` object which wraps to the input -/// buffer. The caller should guarantee the life cycle of the input buffer, and -/// should __NOT__ call the `WasmEdge_BytesDelete`. -/// -/// \param Buf the buffer to wrap to the WasmEdge_Bytes object. -/// \param Len the buffer length. -/// -/// \returns bytes object refer to the input buffer with its length. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Bytes -WasmEdge_BytesWrap(const uint8_t *Buf, const uint32_t Len); - -/// Deletion of the WasmEdge_Bytes. -/// -/// After calling this function, the resources in the WasmEdge_Bytes object -/// will be released and the object should __NOT__ be used. -/// -/// \param Bytes the WasmEdge_Bytes object to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_BytesDelete(WasmEdge_Bytes Bytes); - -// <<<<<<<< WasmEdge bytes functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge result functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Check the result is a success or not. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns true if the error code is WasmEdge_Result_Success or -/// WasmEdge_Result_Terminate, false for others. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ResultOK(const WasmEdge_Result Res); - -/// Generate the result with code. -/// -/// \param Category the WasmEdge_ErrCategory to specify the error category. -/// \param Code the 24-bit length error code. The data exceeds 24 bits will be -/// stripped. -/// -/// \returns WasmEdge_Result struct with the given data. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ResultGen(const enum WasmEdge_ErrCategory Category, - const uint32_t Code); - -/// Get the result code. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns result code (24-bit size data) in the WasmEdge_Result struct. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ResultGetCode(const WasmEdge_Result Res); - -/// Get the error category. -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns error category in the WasmEdge_Result struct. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ErrCategory -WasmEdge_ResultGetCategory(const WasmEdge_Result Res); - -/// Get the result message. -/// -/// The returned string must __NOT__ be destroyed. -/// If the error category of the result is __NOT__ `WasmEdge_ErrCategory_WASM`, -/// the message will always be "user defined error code". -/// -/// \param Res the WasmEdge_Result struct. -/// -/// \returns NULL-terminated C string of the corresponding error message. -WASMEDGE_CAPI_EXPORT extern const char * -WasmEdge_ResultGetMessage(const WasmEdge_Result Res); - -// <<<<<<<< WasmEdge result functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge limit functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Compare the two WasmEdge_Limit objects. -/// -/// \param Lim1 the first WasmEdge_Limit object to compare. -/// \param Lim2 the second WasmEdge_Limit object to compare. -/// -/// \returns true if the content of two WasmEdge_Limit objects are the same, -/// false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_LimitIsEqual(const WasmEdge_Limit Lim1, const WasmEdge_Limit Lim2); - -// <<<<<<<< WasmEdge limit functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge configure functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ConfigureContext. -/// -/// The caller owns the object and should call `WasmEdge_ConfigureDelete` to -/// destroy it. -/// -/// \returns pointer to the context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ConfigureContext * -WasmEdge_ConfigureCreate(void); - -/// Add a proposal setting into the WasmEdge_ConfigureContext. -/// -/// For turning on a specific WASM proposal in VM, loader, or compiler contexts, -/// etc., you can set the proposal value into the WasmEdge_ConfigureContext and -/// create the VM, loader, or compiler contexts, etc. with this context. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_BulkMemoryOperations); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_ReferenceTypes); -/// WasmEdge_ConfigureAddProposal(Conf, WasmEdge_Proposal_SIMD); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to add the proposal value. -/// \param Prop the proposal value. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureAddProposal(WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Remove a proposal setting in the WasmEdge_ConfigureContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to remove the proposal. -/// \param Prop the proposal value. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureRemoveProposal(WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Check if a proposal setting exists in the WasmEdge_ConfigureContext or not. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to check the proposal value. -/// \param Prop the proposal value. -/// -/// \returns true if the proposal setting exists, false if not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureHasProposal(const WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_Proposal Prop); - -/// Add a built-in host registration setting into WasmEdge_ConfigureContext. -/// -/// For turning on the Wasi support in `WasmEdge_VMContext`, you can set the -/// built-in host registration value into the `WasmEdge_ConfigureContext` and -/// create VM with this context. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddHostRegistration(Conf, WasmEdge_HostRegistration_Wasi); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to add built-in host registration. -/// \param Host the built-in host registration value. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureAddHostRegistration( - WasmEdge_ConfigureContext *Cxt, const enum WasmEdge_HostRegistration Host); - -/// Remove a built-in host registration setting in the -/// WasmEdge_ConfigureContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to remove the host -/// pre-registration. -/// \param Host the built-in host registration value. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureRemoveHostRegistration( - WasmEdge_ConfigureContext *Cxt, const enum WasmEdge_HostRegistration Host); - -/// Check if a built-in host registration setting exists in the -/// WasmEdge_ConfigureContext or not. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to check the host pre-registration. -/// \param Host the built-in host registration value. -/// -/// \returns true if the built-in host registration setting exists, false if -/// not. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureHasHostRegistration( - const WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_HostRegistration Host); - -/// Set the page limit of memory instances. -/// -/// Limit the page count (64KiB per page) in memory instances. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the maximum page count. -/// \param Page the maximum page count. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetMaxMemoryPage(WasmEdge_ConfigureContext *Cxt, - const uint32_t Page); - -/// Get the setting of the page limit of memory instances. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the maximum page count -/// setting. -/// -/// \returns the page count limitation value. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ConfigureGetMaxMemoryPage(const WasmEdge_ConfigureContext *Cxt); - -/// Set the force interpreter mode execution option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsForceInterpreter the boolean value to determine to forcibly run -/// WASM in interpreter mode or not. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetForceInterpreter(WasmEdge_ConfigureContext *Cxt, - const bool IsForceInterpreter); - -/// Get the force interpreter mode execution option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to forcibly run WASM in interpreter -/// mode or not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureIsForceInterpreter(const WasmEdge_ConfigureContext *Cxt); - -/// Set the option of enabling/disabling AF_UNIX support in the WASI socket. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param EnableAFUNIX the boolean value to determine to enable -/// the AF_UNIX support in the WASI socket or not. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureSetAllowAFUNIX(WasmEdge_ConfigureContext *Cxt, - const bool EnableAFUNIX); - -/// Get the AllowAFUNIX option. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to enable AF_UNIX support in the -/// WASI socket or not. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureIsAllowAFUNIX(const WasmEdge_ConfigureContext *Cxt); - -/// Set the optimization level of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the optimization level. -/// \param Level the AOT compiler optimization level. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureCompilerSetOptimizationLevel( - WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_CompilerOptimizationLevel Level); - -/// Get the optimization level of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the optimization level. -/// -/// \returns the AOT compiler optimization level. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_CompilerOptimizationLevel -WasmEdge_ConfigureCompilerGetOptimizationLevel( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the output binary format of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the output binary format. -/// \param Format the AOT compiler output binary format. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ConfigureCompilerSetOutputFormat( - WasmEdge_ConfigureContext *Cxt, - const enum WasmEdge_CompilerOutputFormat Format); - -/// Get the output binary format of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the output binary format. -/// -/// \returns the AOT compiler output binary format. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_CompilerOutputFormat -WasmEdge_ConfigureCompilerGetOutputFormat(const WasmEdge_ConfigureContext *Cxt); - -/// Set the dump IR option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsDump the boolean value to determine to dump IR or not when -/// compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetDumpIR(WasmEdge_ConfigureContext *Cxt, - const bool IsDump); - -/// Get the dump IR option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to dump IR or not when compilation -/// in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsDumpIR(const WasmEdge_ConfigureContext *Cxt); - -/// Set the generic binary option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsGeneric the boolean value to determine to generate the generic -/// binary or not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetGenericBinary(WasmEdge_ConfigureContext *Cxt, - const bool IsGeneric); - -/// Get the generic binary option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to generate the generic binary or -/// not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsGenericBinary(const WasmEdge_ConfigureContext *Cxt); - -/// Set the interruptible option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsInterruptible the boolean value to determine to generate -/// interruptible binary or not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureCompilerSetInterruptible(WasmEdge_ConfigureContext *Cxt, - const bool IsInterruptible); - -/// Get the interruptible option of the AOT compiler. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to generate interruptible binary or -/// not when compilation in AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureCompilerIsInterruptible(const WasmEdge_ConfigureContext *Cxt); - -/// Set the instruction counting option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsCount the boolean value to determine to support instruction -/// counting when execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetInstructionCounting( - WasmEdge_ConfigureContext *Cxt, const bool IsCount); - -/// Get the instruction counting option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support instruction counting when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool -WasmEdge_ConfigureStatisticsIsInstructionCounting( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the cost measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsMeasure the boolean value to determine to support cost measuring -/// when execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetCostMeasuring(WasmEdge_ConfigureContext *Cxt, - const bool IsMeasure); - -/// Get the cost measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support cost measuring when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureStatisticsIsCostMeasuring( - const WasmEdge_ConfigureContext *Cxt); - -/// Set the time measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to set the boolean value. -/// \param IsMeasure the boolean value to determine to support time when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureStatisticsSetTimeMeasuring(WasmEdge_ConfigureContext *Cxt, - const bool IsMeasure); - -/// Get the time measuring option for the statistics. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to get the boolean value. -/// -/// \returns the boolean value to determine to support time measuring when -/// execution or not after compilation by the AOT compiler. -WASMEDGE_CAPI_EXPORT extern bool WasmEdge_ConfigureStatisticsIsTimeMeasuring( - const WasmEdge_ConfigureContext *Cxt); - -/// Deletion of the WasmEdge_ConfigureContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ConfigureContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ConfigureDelete(WasmEdge_ConfigureContext *Cxt); - -// <<<<<<<< WasmEdge configure functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge statistics functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_StatisticsContext. -/// -/// The caller owns the object and should call `WasmEdge_StatisticsDelete` to -/// destroy it. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StatisticsContext * -WasmEdge_StatisticsCreate(void); - -/// Get the instruction count in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the instruction count in total execution. -WASMEDGE_CAPI_EXPORT extern uint64_t -WasmEdge_StatisticsGetInstrCount(const WasmEdge_StatisticsContext *Cxt); - -/// Get the instruction count per second in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the instruction count per second. -WASMEDGE_CAPI_EXPORT extern double -WasmEdge_StatisticsGetInstrPerSecond(const WasmEdge_StatisticsContext *Cxt); - -/// Get the total cost in execution. -/// -/// \param Cxt the WasmEdge_StatisticsContext to get data. -/// -/// \returns the total cost. -WASMEDGE_CAPI_EXPORT extern uint64_t -WasmEdge_StatisticsGetTotalCost(const WasmEdge_StatisticsContext *Cxt); - -/// Set the costs of instructions. -/// -/// \param Cxt the WasmEdge_StatisticsContext to set the cost table. -/// \param CostArr the cost table array. -/// \param Len the length of the cost table array. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsSetCostTable(WasmEdge_StatisticsContext *Cxt, - uint64_t *CostArr, const uint32_t Len); - -/// Set the cost limit in execution. -/// -/// The WASM execution will be aborted if the instruction costs exceeded the -/// limit and the ErrCode::Value::CostLimitExceeded will be returned. -/// -/// \param Cxt the WasmEdge_StatisticsContext to set the cost table. -/// \param Limit the cost limit. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsSetCostLimit(WasmEdge_StatisticsContext *Cxt, - const uint64_t Limit); - -/// Clear all data in the WasmEdge_StatisticsContext. -/// -/// \param Cxt the WasmEdge_StatisticsContext to clear. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsClear(WasmEdge_StatisticsContext *Cxt); - -/// Deletion of the WasmEdge_StatisticsContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_StatisticsContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StatisticsDelete(WasmEdge_StatisticsContext *Cxt); - -// <<<<<<<< WasmEdge statistics functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge AST module functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the length of imports list of the AST module. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// -/// \returns length of the imports list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListImportsLength(const WasmEdge_ASTModuleContext *Cxt); - -/// List the imports of the AST module. -/// -/// If the `Imports` buffer length is smaller than the result of the imports -/// list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// \param [out] Imports the import type contexts buffer. Can be NULL if import -/// types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListImports(const WasmEdge_ASTModuleContext *Cxt, - const WasmEdge_ImportTypeContext **Imports, - const uint32_t Len); - -/// Get the length of exports list of the AST module. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// -/// \returns length of the exports list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListExportsLength(const WasmEdge_ASTModuleContext *Cxt); - -/// List the exports of the AST module. -/// -/// If the `Exports` buffer length is smaller than the result of the exports -/// list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASTModuleContext. -/// \param [out] Exports the export type contexts buffer. Can be NULL if export -/// types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ASTModuleListExports(const WasmEdge_ASTModuleContext *Cxt, - const WasmEdge_ExportTypeContext **Exports, - const uint32_t Len); - -/// Deletion of the WasmEdge_ASTModuleContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ASTModuleContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ASTModuleDelete(WasmEdge_ASTModuleContext *Cxt); - -// <<<<<<<< WasmEdge AST module functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge function type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_FunctionTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_FunctionTypeDelete` to -/// destroy it. -/// -/// \param ParamList the value types list of parameters. NULL if the length is -/// 0. -/// \param ParamLen the ParamList buffer length. -/// \param ReturnList the value types list of returns. NULL if the length is 0. -/// \param ReturnLen the ReturnList buffer length. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionTypeContext * -WasmEdge_FunctionTypeCreate(const WasmEdge_ValType *ParamList, - const uint32_t ParamLen, - const WasmEdge_ValType *ReturnList, - const uint32_t ReturnLen); - -/// Get the parameter types list length from the WasmEdge_FunctionTypeContext. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// -/// \returns the parameter types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_FunctionTypeGetParametersLength( - const WasmEdge_FunctionTypeContext *Cxt); - -/// Get the parameter types list from the WasmEdge_FunctionTypeContext. -/// -/// If the `List` buffer length is smaller than the length of the parameter type -/// list, the overflowed values will be discarded. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// \param [out] List the WasmEdge_ValType buffer to fill the parameter value -/// types. -/// \param Len the value type buffer length. -/// -/// \returns the actual parameter types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetParameters(const WasmEdge_FunctionTypeContext *Cxt, - WasmEdge_ValType *List, const uint32_t Len); - -/// Get the return types list length from the WasmEdge_FunctionTypeContext. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// -/// \returns the return types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetReturnsLength(const WasmEdge_FunctionTypeContext *Cxt); - -/// Get the return types list from the WasmEdge_FunctionTypeContext. -/// -/// If the `List` buffer length is smaller than the length of the return type -/// list, the overflowed values will be discarded. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext. -/// \param [out] List the WasmEdge_ValType buffer to fill the return value -/// types. -/// \param Len the value type buffer length. -/// -/// \returns the actual return types list length. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_FunctionTypeGetReturns(const WasmEdge_FunctionTypeContext *Cxt, - WasmEdge_ValType *List, const uint32_t Len); - -/// Deletion of the WasmEdge_FunctionTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_FunctionTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_FunctionTypeDelete(WasmEdge_FunctionTypeContext *Cxt); - -// <<<<<<<< WasmEdge function type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge table type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_TableTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_TableTypeDelete` to -/// destroy it. -/// -/// \param RefType the value type of the table type. This value type should be a -/// reference type, or this function will fail. -/// \param Limit the limit struct of the table type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableTypeContext * -WasmEdge_TableTypeCreate(const WasmEdge_ValType RefType, - const WasmEdge_Limit Limit); - -/// Get the reference type from a table type. -/// -/// \param Cxt the WasmEdge_TableTypeContext. -/// -/// \returns the value type of the table type. This value type will must be a -/// reference type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType -WasmEdge_TableTypeGetRefType(const WasmEdge_TableTypeContext *Cxt); - -/// Get the limit from a table type. -/// -/// \param Cxt the WasmEdge_TableTypeContext. -/// -/// \returns the limit struct of the table type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Limit -WasmEdge_TableTypeGetLimit(const WasmEdge_TableTypeContext *Cxt); - -/// Deletion of the WasmEdge_TableTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_TableTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_TableTypeDelete(WasmEdge_TableTypeContext *Cxt); - -// <<<<<<<< WasmEdge table type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge memory type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_MemoryTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_MemoryTypeDelete` to -/// destroy it. -/// -/// \param Limit the limit struct of the memory type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryTypeContext * -WasmEdge_MemoryTypeCreate(const WasmEdge_Limit Limit); - -/// Get the limit from a memory type. -/// -/// \param Cxt the WasmEdge_MemoryTypeContext. -/// -/// \returns the limit struct of the memory type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Limit -WasmEdge_MemoryTypeGetLimit(const WasmEdge_MemoryTypeContext *Cxt); - -/// Deletion of the WasmEdge_MemoryTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_MemoryTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_MemoryTypeDelete(WasmEdge_MemoryTypeContext *Cxt); - -// <<<<<<<< WasmEdge memory type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge tag type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the function type from a tag type. -/// -/// \param Cxt the WasmEdge_TagTypeContext. -/// -/// \returns pointer to function type context of the tag type, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_TagTypeGetFunctionType(const WasmEdge_TagTypeContext *Cxt); - -// <<<<<<<< WasmEdge tag type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge global type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_GlobalTypeContext. -/// -/// The caller owns the object and should call `WasmEdge_GlobalTypeDelete` to -/// destroy it. -/// -/// \param ValType the value type of the global type. -/// \param Mut the mutation of the global type. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalTypeContext * -WasmEdge_GlobalTypeCreate(const WasmEdge_ValType ValType, - const enum WasmEdge_Mutability Mut); - -/// Get the value type from a global type. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext. -/// -/// \returns the value type of the global type. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValType -WasmEdge_GlobalTypeGetValType(const WasmEdge_GlobalTypeContext *Cxt); - -/// Get the mutability from a global type. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext. -/// -/// \returns the mutability of the global type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_Mutability -WasmEdge_GlobalTypeGetMutability(const WasmEdge_GlobalTypeContext *Cxt); - -/// Deletion of the WasmEdge_GlobalTypeContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_GlobalTypeContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_GlobalTypeDelete(WasmEdge_GlobalTypeContext *Cxt); - -// <<<<<<<< WasmEdge global type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge import type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the external type from an import type. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns the external type of the import type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ExternalType -WasmEdge_ImportTypeGetExternalType(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the module name from an import type. -/// -/// The returned string object is linked to the module name of the import type, -/// and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ImportTypeGetModuleName(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external name from an import type. -/// -/// The returned string object is linked to the external name of the import -/// type, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ImportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ImportTypeGetExternalName(const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is function type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The function type context links to the function type in the import type -/// context and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the function type. NULL if failed or the external type of the -/// import type is not `WasmEdge_ExternalType_Function`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_ImportTypeGetFunctionType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is table type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The table type context links to the table type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the table type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Table`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_ImportTypeGetTableType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is memory type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The memory type context links to the memory type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the memory type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Memory`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_ImportTypeGetMemoryType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is tag type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The tag type context links to the tag type in the import type context -/// and the AST module context. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the tag type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_TagType`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_ImportTypeGetTagType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -/// Get the external value (which is global type) from an import type. -/// -/// The import type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The global type context links to the global type in the import type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ImportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the global type. NULL if failed or the external type of the import -/// type is not `WasmEdge_ExternalType_Global`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_ImportTypeGetGlobalType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ImportTypeContext *Cxt); - -// <<<<<<<< WasmEdge import type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge export type functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the external type from an export type. -/// -/// \param Cxt the WasmEdge_ExportTypeContext. -/// -/// \returns the external type of the export type. -WASMEDGE_CAPI_EXPORT extern enum WasmEdge_ExternalType -WasmEdge_ExportTypeGetExternalType(const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external name from an export type. -/// -/// The returned string object is linked to the external name of the export -/// type, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ExportTypeContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ExportTypeGetExternalName(const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is function type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The function type context links to the function type in the export type -/// context and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the function type. NULL if failed or the external type of the -/// export type is not `WasmEdge_ExternalType_Function`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_ExportTypeGetFunctionType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is table type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The table type context links to the table type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the table type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Table`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_ExportTypeGetTableType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is memory type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The memory type context links to the memory type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the memory type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Memory`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_ExportTypeGetMemoryType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is tag type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The tag type context links to the tag type in the export type context -/// and the AST module context. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the tag type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Tag`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_ExportTypeGetTagType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -/// Get the external value (which is global type) from an export type. -/// -/// The export type context should be the one queried from the AST module -/// context, or this function will cause unexpected error. -/// The global type context links to the global type in the export type context -/// and the AST module context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param ASTCxt the WasmEdge_ASTModuleContext. -/// \param Cxt the WasmEdge_ExportTypeContext which queried from the `ASTCxt`. -/// -/// \returns the global type. NULL if failed or the external type of the export -/// type is not `WasmEdge_ExternalType_Global`. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_ExportTypeGetGlobalType(const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_ExportTypeContext *Cxt); - -// <<<<<<<< WasmEdge export type functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge AOT compiler functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_CompilerContext. -/// -/// The caller owns the object and should call `WasmEdge_CompilerDelete` to -/// delete it. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_CompilerContext * -WasmEdge_CompilerCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Compile the input WASM from the file path. -/// -/// The compiler compiles the WASM from file path for the ahead-of-time mode and -/// store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param InPath the input WASM file path. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_CompilerCompile(WasmEdge_CompilerContext *Cxt, const char *InPath, - const char *OutPath); - -/// Compile the input WASM from the given buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_CompilerCompileFromBytes()` API in the future. -/// -/// The compiler compiles the WASM from the given buffer for the -/// ahead-of-time mode and store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param InBuffer the input WASM binary buffer. -/// \param InBufferLen the length of the input WASM binary buffer. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_CompilerCompileFromBuffer( - WasmEdge_CompilerContext *Cxt, const uint8_t *InBuffer, - const uint64_t InBufferLen, const char *OutPath); - -/// Compile the input WASM from a WasmEdge_Bytes. -/// -/// The compiler compiles the WASM from the WasmEdge_Bytes for the -/// ahead-of-time mode and store the result to the output file path. -/// -/// \param Cxt the WasmEdge_CompilerContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param OutPath the output WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_CompilerCompileFromBytes(WasmEdge_CompilerContext *Cxt, - const WasmEdge_Bytes Bytes, - const char *OutPath); - -/// Deletion of the WasmEdge_CompilerContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_CompilerContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_CompilerDelete(WasmEdge_CompilerContext *Cxt); - -// <<<<<<<< WasmEdge AOT compiler functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge loader functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_LoaderContext. -/// -/// The caller owns the object and should call `WasmEdge_LoaderDelete` to -/// destroy it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of Loader. -/// NULL for the default configuration. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_LoaderContext * -WasmEdge_LoaderCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Load and parse the WASM module from a WASM file into a -/// WasmEdge_ASTModuleContext. -/// -/// Load and parse the WASM module from the file path, and return a -/// `WasmEdge_ASTModuleContext` as the result. The caller owns the -/// `WasmEdge_ASTModuleContext` object and should call -/// `WasmEdge_ASTModuleDelete` to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromFile(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const char *Path); - -/// Load and parse the WASM module from a buffer into WasmEdge_ASTModuleContext. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_LoaderParseFromBytes()` API in the future. -/// -/// Load and parse the WASM module from a buffer, and return a -/// WasmEdge_ASTModuleContext as the result. The caller owns the -/// WasmEdge_ASTModuleContext object and should call `WasmEdge_ASTModuleDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromBuffer(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const uint8_t *Buf, const uint32_t BufLen); - -/// Load and parse the WASM module from a WasmEdge_Bytes into -/// WasmEdge_ASTModuleContext. -/// -/// Load and parse the WASM module from a buffer, and return a -/// WasmEdge_ASTModuleContext as the result. The caller owns the -/// WasmEdge_ASTModuleContext object and should call `WasmEdge_ASTModuleDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param [out] Module the output WasmEdge_ASTModuleContext if succeeded. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderParseFromBytes(WasmEdge_LoaderContext *Cxt, - WasmEdge_ASTModuleContext **Module, - const WasmEdge_Bytes Bytes); - -/// Serialize the WasmEdge_ASTModuleContext into WASM binary. -/// -/// Serialize the loaded WasmEdge_ASTModuleContext into the WASM binary format. -/// If the serialization succeeded, this API will allocate a new -/// `WasmEdge_Bytes` object and fill into the `Buf`. The caller owns the -/// `WasmEdge_Bytes` object and should call `WasmEdge_BytesDelete` to destroy -/// it. -/// -/// \param Cxt the WasmEdge_LoaderContext. -/// \param ASTCxt the WasmEdge_ASTModuleContext to serialize. -/// \param [out] Buf the WasmEdge_Bytes to fill the serialized WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_LoaderSerializeASTModule(WasmEdge_LoaderContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt, - WasmEdge_Bytes *Buf); - -/// Deletion of the WasmEdge_LoaderContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_LoaderContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_LoaderDelete(WasmEdge_LoaderContext *Cxt); - -// <<<<<<<< WasmEdge loader functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge validator functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ValidatorContext. -/// -/// The caller owns the object and should call `WasmEdge_ValidatorDelete` to -/// destroy it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of -/// Validator. NULL for the default configuration. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValidatorContext * -WasmEdge_ValidatorCreate(const WasmEdge_ConfigureContext *ConfCxt); - -/// Validate the WasmEdge AST Module. -/// -/// \param Cxt the WasmEdge_ValidatorContext. -/// \param ASTCxt the WasmEdge_ASTModuleContext to validate. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ValidatorValidate(WasmEdge_ValidatorContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Deletion of the WasmEdge_ValidatorContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ValidatorContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ValidatorDelete(WasmEdge_ValidatorContext *Cxt); - -// <<<<<<<< WasmEdge validator functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge executor functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ExecutorContext. -/// -/// The caller owns the object and should call `WasmEdge_ExecutorDelete` to -/// delete it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of -/// Executor. NULL for the default configuration. -/// \param StatCxt the WasmEdge_StatisticsContext as the statistics object set -/// into Executor. The statistics will refer to this context, and the life cycle -/// should be guaranteed until the executor context is deleted. NULL for not -/// doing the statistics. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_ExecutorCreate(const WasmEdge_ConfigureContext *ConfCxt, - WasmEdge_StatisticsContext *StatCxt); - -/// Instantiate an AST Module into a module instance. -/// -/// Instantiate an AST Module, and return an instantiated module instance -/// context as the result. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. Developers can use the -/// `WasmEdge_ModuleInstanceListFunction`, -/// `WasmEdge_ModuleInstanceFindFunction`, etc. APIs to retrieve the exported -/// instances from the result module instance. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param [out] ModuleCxt the output WasmEdge_ModuleInstanceContext if -/// succeeded. -/// \param StoreCxt the WasmEdge_StoreContext to link the imports. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorInstantiate( - WasmEdge_ExecutorContext *Cxt, WasmEdge_ModuleInstanceContext **ModuleCxt, - WasmEdge_StoreContext *StoreCxt, const WasmEdge_ASTModuleContext *ASTCxt); - -/// Instantiate an AST Module into a named module instance and link into store. -/// -/// Instantiate an AST Module with the module name, return the instantiated -/// module instance context as the result, and also register the module instance -/// to the store. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// Developers can use the `WasmEdge_ModuleInstanceListFunction`, -/// `WasmEdge_ModuleInstanceFindFunction`, etc. APIs to retrieve the exported -/// instances from the result module instance. -/// After calling this function, the output module instance will also be -/// registered into the store, and the other modules can import the exported -/// instances for linking when instantiation. Developers SHOULD guarantee the -/// life cycle of this output module instance, or the error will occur when in -/// execution after the module instance being destroyed if it has been imported -/// by other modules. That is, developers have the responsibility to delete the -/// output module instance even though the store being destroyed. When the -/// module instance is deleted, it will be unregistered to the store -/// automatically. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param [out] ModuleCxt the output WasmEdge_ModuleInstanceContext if -/// succeeded. -/// \param StoreCxt the WasmEdge_StoreContext to link the imports. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param ModuleName the module name WasmEdge_String for all exported -/// instances. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorRegister( - WasmEdge_ExecutorContext *Cxt, WasmEdge_ModuleInstanceContext **ModuleCxt, - WasmEdge_StoreContext *StoreCxt, const WasmEdge_ASTModuleContext *ASTCxt, - WasmEdge_String ModuleName); - -/// Register a module instance into a store with exporting its module name. -/// -/// Register an existing module into the store with its module name. -/// After calling this function, the existing module instance will be registered -/// into the store, and the other modules can import the exported instances for -/// linking when instantiation. Developers SHOULD guarantee the life cycle of -/// this existing module instance, or the error will occur when in execution -/// after the module instance being destroyed if it has been imported by other -/// modules. When the module instance is deleted, it will be unregistered to the -/// store automatically. -/// -/// \param Cxt the WasmEdge_ExecutorContext to instantiate the module. -/// \param StoreCxt the WasmEdge_StoreContext to store the instantiated module. -/// \param ImportCxt the WasmEdge_ModuleInstanceContext to register. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_ExecutorRegisterImport( - WasmEdge_ExecutorContext *Cxt, WasmEdge_StoreContext *StoreCxt, - const WasmEdge_ModuleInstanceContext *ImportCxt); - -/// Invoke a WASM function by the function instance. -/// -/// After instantiating a WASM module, developers can get the function instance -/// context from the module instance. Then developers can invoke the function -/// through this API. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param FuncCxt the function instance context to invoke. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_ExecutorInvoke(WasmEdge_ExecutorContext *Cxt, - const WasmEdge_FunctionInstanceContext *FuncCxt, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Asynchronous invoke a WASM function by the function instance. -/// -/// After instantiating a WASM module, developers can get the function instance -/// context from the module instance. Then developers can invoke the function -/// asynchronously through this API. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param FuncCxt the function instance context to invoke. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_ExecutorAsyncInvoke(WasmEdge_ExecutorContext *Cxt, - const WasmEdge_FunctionInstanceContext *FuncCxt, - const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Deletion of the WasmEdge_ExecutorContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ExecutorContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorDelete(WasmEdge_ExecutorContext *Cxt); - -// <<<<<<<< WasmEdge executor functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge store functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_StoreContext. -/// -/// The caller owns the object and should call `WasmEdge_StoreDelete` to destroy -/// it. -/// The store is the linker for multiple WASM module instances. The store will -/// not own any module instance registered into it, and the module instances -/// will automatically be unregistered if they are destroyed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StoreContext *WasmEdge_StoreCreate(void); - -/// Get the module instance context by the module name. -/// -/// After registering a WASM module, developers can call this function to find -/// and get the registered module instance context by the module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// \param Name the module name WasmEdge_String. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_StoreFindModule(const WasmEdge_StoreContext *Cxt, - const WasmEdge_String Name); - -/// Get the length of registered module list in store. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// -/// \returns length of registered named module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StoreListModuleLength(const WasmEdge_StoreContext *Cxt); - -/// List the registered module names. -/// -/// This function will list all registered module names. -/// The returned module names filled into the `Names` array are linked to the -/// registered module names in the store context, and the caller should __NOT__ -/// call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the registered -/// named module list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_StoreContext. -/// \param [out] Names the output names WasmEdge_String buffer of named modules. -/// \param Len the buffer length. -/// -/// \returns actual registered named module list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_StoreListModule(const WasmEdge_StoreContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Deletion of the WasmEdge_StoreContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// If there are module instances registered into this store context, they will -/// be automatically un-link to this store context. -/// -/// \param Cxt the WasmEdge_StoreContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_StoreDelete(WasmEdge_StoreContext *Cxt); - -// <<<<<<<< WasmEdge store functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge module instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_ModuleInstanceContext. -/// -/// Create a module instance context with exported module name for host -/// instances. Developer can use this API to create a module instance for -/// collecting host functions, tables, memories, tags, and globals. -/// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` -/// to destroy it. -/// -/// \param ModuleName the module name WasmEdge_String of this host module to -/// import. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreate(const WasmEdge_String ModuleName); - -/// Creation of the WasmEdge_ModuleInstanceContext with host data. -/// -/// Create a module instance context with exported module name, host data, and -/// host data finalizer for host instances. Developer can use this API to create -/// a module instance for collecting host functions, tables, memories, and -/// globals. When this created module instance being destroyed, the host data -/// finalizer will be invoked. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// -/// \param ModuleName the module name WasmEdge_String of this host module to -/// import. -/// \param HostData the host data to set into the module instance. When calling -/// the finalizer, this pointer will become the argument of the finalizer -/// function. -/// \param Finalizer the function to finalize the host data. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreateWithData(const WasmEdge_String ModuleName, - void *HostData, - void (*Finalizer)(void *)); - -/// Creation of the WasmEdge_ModuleInstanceContext for the WASI specification. -/// -/// This function will create a WASI host module that contains the WASI host -/// functions and initialize it. The caller owns the object and should call -/// `WasmEdge_ModuleInstanceDelete` to destroy it. -/// -/// \param Args the command line arguments. The first argument suggests being -/// the program name. NULL if the length is 0. -/// \param ArgLen the length of the command line arguments. -/// \param Envs the environment variables in the format `ENV=VALUE`. NULL if the -/// length is 0. -/// \param EnvLen the length of the environment variables. -/// \param Preopens the directory paths to preopen. String format in -/// `GUEST_PATH:HOST_PATH` means the path mapping, or the same path will be -/// mapped. NULL if the length is 0. -/// \param PreopenLen the length of the directory paths to preopen. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_ModuleInstanceCreateWASI(const char *const *Args, - const uint32_t ArgLen, - const char *const *Envs, - const uint32_t EnvLen, - const char *const *Preopens, - const uint32_t PreopenLen); - -/// Initialize the WasmEdge_ModuleInstanceContext for the WASI specification. -/// -/// This function will initialize the WASI host module with the parameters. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// \param Args the command line arguments. The first argument suggests being -/// the program name. NULL if the length is 0. -/// \param ArgLen the length of the command line arguments. -/// \param Envs the environment variables in the format `ENV=VALUE`. NULL if the -/// length is 0. -/// \param EnvLen the length of the environment variables. -/// \param Preopens the directory paths to preopen. String format in -/// `GUEST_PATH:HOST_PATH` means the path mapping, or the same path will be -/// mapped. NULL if the length is 0. -/// \param PreopenLen the length of the directory paths to preopen. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_ModuleInstanceInitWASI( - WasmEdge_ModuleInstanceContext *Cxt, const char *const *Args, - const uint32_t ArgLen, const char *const *Envs, const uint32_t EnvLen, - const char *const *Preopens, const uint32_t PreopenLen); - -/// Get the WASI exit code. -/// -/// This function will return the exit code after running the "_start" function -/// of a `wasm32-wasi` program. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// -/// \returns the exit code after executing the "_start" function. Return -/// `EXIT_FAILURE` if the `Cxt` is NULL or not a WASI host module. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceWASIGetExitCode( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the native handler from the WASI mapped FD/Handler. -/// -/// This function will return the raw FD/Handler from a given mapped Fd -/// or Handler. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext of WASI import object. -/// \param Fd the WASI mapped Fd. -/// \param [out] NativeHandler the raw Fd/Handler. -/// -/// \returns the error code. Return `0` if the Native Handler is found. -/// Return `1` if the `Cxt` is `NULL`. -/// Return `2` if the given mapped Fd/handler is not found. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceWASIGetNativeHandler( - const WasmEdge_ModuleInstanceContext *Cxt, int32_t Fd, - uint64_t *NativeHandler); - -/// Initialize the WasmEdge_ModuleInstanceContext for the wasmedge_process -/// specification. -/// -/// This function will initialize the wasmedge_process host module with the -/// parameters. -/// -/// \param AllowedCmds the allowed commands white list. NULL if the -/// length is 0. -/// \param CmdsLen the length of the allowed commands white list. -/// \param AllowAll the boolean value to allow all commands. `false` is -/// suggested. If this value is `true`, the allowed commands white list will not -/// be recorded and all commands can be executed by wasmedge_process. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceInitWasmEdgeProcess(const char *const *AllowedCmds, - const uint32_t CmdsLen, - const bool AllowAll); - -/// Get the export module name of a module instance. -/// -/// The returned string object is linked to the module name of the module -/// instance, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_ModuleInstanceGetModuleName(const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the host data set into the module instance when creating. -/// -/// The returned data is owned by the module instance, and will be passed into -/// the finalizer when deleting this module instance. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns host data. NULL if the module instance context is NULL or no host -/// data set into the module instance. -WASMEDGE_CAPI_EXPORT extern void * -WasmEdge_ModuleInstanceGetHostData(const WasmEdge_ModuleInstanceContext *Cxt); - -/// Get the exported function instance context of a module instance. -/// -/// The result function instance context links to the function instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_FunctionInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the function name WasmEdge_String. -/// -/// \returns pointer to the function instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_ModuleInstanceFindFunction(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported table instance context of a module instance. -/// -/// The result table instance context links to the table instance in the module -/// instance context and owned by the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_TableInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the table name WasmEdge_String. -/// -/// \returns pointer to the table instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_ModuleInstanceFindTable(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported memory instance context of a module instance. -/// -/// The result memory instance context links to the memory instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_MemoryInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the memory name WasmEdge_String. -/// -/// \returns pointer to the memory instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_ModuleInstanceFindMemory(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported tag instance context of a module instance. -/// -/// The result tag instance context links to the tag instance in the -/// module instance context and owned by the module instance context. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the tag name WasmEdge_String. -/// -/// \returns pointer to the tag instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TagInstanceContext * -WasmEdge_ModuleInstanceFindTag(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the exported global instance context of a module instance. -/// -/// The result global instance context links to the global instance in the -/// module instance context and owned by the module instance context, and the -/// caller should __NOT__ call the `WasmEdge_GlobalInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param Name the global name WasmEdge_String. -/// -/// \returns pointer to the global instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalInstanceContext * -WasmEdge_ModuleInstanceFindGlobal(const WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name); - -/// Get the length of exported function list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported function list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListFunctionLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported function names of a module instance. -/// -/// The returned function names filled into the `Names` array are linked to the -/// exported names of functions of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// function list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListFunction(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported table list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported table list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListTableLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported table names of a module instance. -/// -/// The returned table names filled into the `Names` array are linked to the -/// exported names of tables of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// table list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the table names. -/// \param Len the buffer length. -/// -/// \returns actual exported table list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTable(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported memory list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported memory list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListMemoryLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported memory names of a module instance. -/// -/// The returned memory names filled into the `Names` array are linked to the -/// exported names of memories of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// memory list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the memory names. -/// \param Len the buffer length. -/// -/// \returns actual exported memory list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListMemory(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported tag list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported tag list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTagLength(const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported tag names of a module instance. -/// -/// The returned tag names filled into the `Names` array are linked to the -/// exported names of tags of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// tag list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the tag names. -/// \param Len the buffer length. -/// -/// \returns actual exported tag list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListTag(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the length of exported global list of a module instance. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// -/// \returns length of the exported global list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_ModuleInstanceListGlobalLength( - const WasmEdge_ModuleInstanceContext *Cxt); - -/// List the exported global names of a module instance. -/// -/// The returned global names filled into the `Names` array are linked to the -/// exported names of globals of the module instance context, and the caller -/// should __NOT__ call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the exported -/// global list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext. -/// \param [out] Names the output WasmEdge_String buffer of the global names. -/// \param Len the buffer length. -/// -/// \returns actual exported global list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_ModuleInstanceListGlobal(const WasmEdge_ModuleInstanceContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Add a function instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the function instance into the module -/// instance. The caller should __NOT__ access or destroy the function instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the function instance. -/// \param Name the export function name WasmEdge_String. -/// \param FuncCxt the WasmEdge_FunctionInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddFunction(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_FunctionInstanceContext *FuncCxt); - -/// Add a table instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the table instance into the module -/// instance. The caller should __NOT__ access or destroy the table instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the table instance. -/// \param Name the export table name WasmEdge_String. -/// \param TableCxt the WasmEdge_TableInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddTable(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_TableInstanceContext *TableCxt); - -/// Add a memory instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the memory instance into the module -/// instance. The caller should __NOT__ access or destroy the memory instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the memory instance. -/// \param Name the export memory name WasmEdge_String. -/// \param MemoryCxt the WasmEdge_MemoryInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddMemory(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_MemoryInstanceContext *MemoryCxt); - -/// Add a global instance context into a WasmEdge_ModuleInstanceContext. -/// -/// Export and move the ownership of the global instance into the module -/// instance. The caller should __NOT__ access or destroy the global instance -/// context after calling this function. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to add the global instance. -/// \param Name the export global name WasmEdge_String. -/// \param GlobalCxt the WasmEdge_GlobalInstanceContext to add. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceAddGlobal(WasmEdge_ModuleInstanceContext *Cxt, - const WasmEdge_String Name, - WasmEdge_GlobalInstanceContext *GlobalCxt); - -/// Deletion of the WasmEdge_ModuleInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// If the module instance has been registered into one or more store contexts, -/// it will be automatically unregistered. -/// -/// \param Cxt the WasmEdge_ModuleInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ModuleInstanceDelete(WasmEdge_ModuleInstanceContext *Cxt); - -// <<<<<<<< WasmEdge module instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge function instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -typedef WasmEdge_Result (*WasmEdge_HostFunc_t)( - void *Data, const WasmEdge_CallingFrameContext *CallFrameCxt, - const WasmEdge_Value *Params, WasmEdge_Value *Returns); -/// Creation of the WasmEdge_FunctionInstanceContext for host functions. -/// -/// The caller owns the object and should call `WasmEdge_FunctionInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. The following is an example to create a -/// host function context. -/// ```c -/// WasmEdge_Result FuncAdd(void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *In, WasmEdge_Value *Out) { -/// // Function to return A + B. -/// int32_t A = WasmEdge_ValueGetI32(In[0]); -/// int32_t B = WasmEdge_ValueGetI32(In[1]); -/// Out[0] = WasmEdge_ValueGenI32(A + B); -/// // Return execution status -/// return WasmEdge_Result_Success; -/// } -/// -/// WasmEdge_ValType Params[2] = {WasmEdge_ValTypeGenI32(), -/// WasmEdge_ValTypeGenI32()}; -/// WasmEdge_ValType Returns[1] = {WasmEdge_ValTypeGenI32()}; -/// WasmEdge_FunctionTypeContext *FuncType = -/// WasmEdge_FunctionTypeCreate(Params, 2, Returns, 1); -/// WasmEdge_FunctionInstanceContext *HostFunc = -/// WasmEdge_FunctionInstanceCreate(FuncType, FuncAdd, NULL, 0); -/// WasmEdge_FunctionTypeDelete(FuncType); -/// ... -/// ``` -/// -/// \param Type the function type context to describe the host function -/// signature. -/// \param HostFunc the host function pointer. The host function signature must -/// be as following: -/// ```c -/// typedef WasmEdge_Result (*WasmEdge_HostFunc_t)( -/// void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *Params, -/// WasmEdge_Value *Returns); -/// ``` -/// The `Params` is the input parameters array with length guaranteed to be the -/// same as the parameter types in the `Type`. The `Returns` is the output -/// results array with length guaranteed to be the same as the result types in -/// the `Type`. The return value is `WasmEdge_Result` for the execution status. -/// \param Data the additional object, such as the pointer to a data structure, -/// to set to this host function context. The caller should guarantee the life -/// cycle of the object. NULL if the additional data object is not needed. -/// \param Cost the function cost in statistics. Pass 0 if the calculation is -/// not needed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_FunctionInstanceCreate(const WasmEdge_FunctionTypeContext *Type, - WasmEdge_HostFunc_t HostFunc, void *Data, - const uint64_t Cost); - -typedef WasmEdge_Result (*WasmEdge_WrapFunc_t)( - void *This, void *Data, const WasmEdge_CallingFrameContext *CallFrameCxt, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); -/// Creation of the WasmEdge_FunctionInstanceContext for host functions. -/// -/// This function is for the languages which cannot pass the function pointer of -/// the host function into this shared library directly. The caller owns the -/// object and should call `WasmEdge_FunctionInstanceDelete` to destroy it if -/// the returned object is not added into a `WasmEdge_ModuleInstanceContext`. -/// The following is an example to create a host function context for other -/// languages. -/// ```c -/// // `RealFunc` is the pointer to the function in other languages. -/// -/// WasmEdge_Result FuncAddWrap( -/// void *This, void *Data, -/// const WasmEdge_CallingFrameContext *CallFrameCxt, -/// const WasmEdge_Value *In, const uint32_t InLen, WasmEdge_Value *Out, -/// const uint32_t OutLen) { -/// // Wrapper function of host function to return A + B. -/// -/// // `This` is the same as `RealFunc`. -/// int32_t A = WasmEdge_ValueGetI32(In[0]); -/// int32_t B = WasmEdge_ValueGetI32(In[1]); -/// -/// // Call the function of `This` in the host language ... -/// int32_t Result = ...; -/// -/// Out[0] = Result; -/// // Return the execution status. -/// return WasmEdge_Result_Success; -/// } -/// -/// WasmEdge_ValType Params[2] = {WasmEdge_ValTypeGenI32(), -/// WasmEdge_ValTypeGenI32()}; -/// WasmEdge_ValType Returns[1] = {WasmEdge_ValTypeGenI32()}; -/// WasmEdge_FunctionTypeContext *FuncType = -/// WasmEdge_FunctionTypeCreate(Params, 2, Returns, 1); -/// WasmEdge_FunctionInstanceContext *HostFunc = -/// WasmEdge_FunctionInstanceCreateBinding( -/// FuncType, FuncAddWrap, RealFunc, NULL, 0); -/// WasmEdge_FunctionTypeDelete(FuncType); -/// ... -/// ``` -/// -/// \param Type the function type context to describe the host function -/// signature. -/// \param WrapFunc the wrapper function pointer. The wrapper function signature -/// must be as following: -/// ```c -/// typedef WasmEdge_Result (*WasmEdge_WrapFunc_t)( -/// void *This, -/// void *Data, -/// WasmEdge_CallingFrameContext *FrameCxt, -/// const WasmEdge_Value *Params, -/// const uint32_t ParamLen, -/// WasmEdge_Value *Returns, -/// const uint32_t ReturnLen); -/// ``` -/// The `This` is the pointer the same as the `Binding` parameter of this -/// function. The `Params` is the input parameters array with length guaranteed -/// to be the same as the parameter types in the `Type`, and the `ParamLen` is -/// the length of the array. The `Returns` is the output results array with -/// length guaranteed to be the same as the result types in the `Type`, and the -/// `ReturnLen` is the length of the array. The return value is -/// `WasmEdge_Result` for the execution status. -/// \param Binding the `this` pointer of the host function target or the -/// function indexing maintained by the caller which can specify the host -/// function. When invoking the host function, this pointer will be the first -/// argument of the wrapper function. -/// \param Data the additional object, such as the pointer to a data structure, -/// to set to this host function context. The caller should guarantee the life -/// cycle of the object. NULL if the additional data object is not needed. -/// \param Cost the function cost in statistics. Pass 0 if the calculation is -/// not needed. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_FunctionInstanceContext * -WasmEdge_FunctionInstanceCreateBinding(const WasmEdge_FunctionTypeContext *Type, - WasmEdge_WrapFunc_t WrapFunc, - void *Binding, void *Data, - const uint64_t Cost); - -/// Get the function data field of the function instance. -/// -/// The function data is passed when creating the FunctionInstance. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext. -/// -/// \returns pointer to Data, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const void * -WasmEdge_FunctionInstanceGetData(const WasmEdge_FunctionInstanceContext *Cxt); - -/// Get the function type context of the function instance. -/// -/// The function type context links to the function type in the function -/// instance context and owned by the context. The caller should __NOT__ call -/// the `WasmEdge_FunctionTypeDelete`. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_FunctionInstanceGetFunctionType( - const WasmEdge_FunctionInstanceContext *Cxt); - -/// Deletion of the WasmEdge_FunctionInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_FunctionInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_FunctionInstanceDelete(WasmEdge_FunctionInstanceContext *Cxt); - -// <<<<<<<< WasmEdge function instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge table instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_TableInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_TableInstanceDelete` to -/// destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// The default value of the elements in the output table instance will be null -/// references with the same reference type in the table type when table grows. -/// If the reference type of the input table type is a non-nullable value type, -/// a non-null default init value is required. In this case, please use the -/// `WasmEdge_TableInstanceCreateWithInit` API instead. -/// -/// \param TabType the table type context to initialize the table instance -/// context. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_TableInstanceCreate(const WasmEdge_TableTypeContext *TabType); - -/// Creation of the WasmEdge_TableInstanceContext with the default init value. -/// -/// The caller owns the object and should call `WasmEdge_TableInstanceDelete` to -/// destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// The value type of the default init value should compatible with the -/// reference type of the input table type, otherwise this function will fail. -/// If the reference type of the input table type is a non-nullable value type, -/// this function will fail if the default init value is a null reference. -/// -/// \param TabType the table type context to initialize the table instance -/// context. -/// \param Value the default init value for the table element when table -/// grows. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_TableInstanceContext * -WasmEdge_TableInstanceCreateWithInit(const WasmEdge_TableTypeContext *TabType, - const WasmEdge_Value Value); - -/// Get the table type context from a table instance. -/// -/// The table type context links to the table type in the table instance context -/// and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_TableTypeDelete`. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TableTypeContext * -WasmEdge_TableInstanceGetTableType(const WasmEdge_TableInstanceContext *Cxt); - -/// Get the reference value in a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param [out] Data the result reference value. -/// \param Offset the reference value offset (index) in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceGetData(const WasmEdge_TableInstanceContext *Cxt, - WasmEdge_Value *Data, const uint32_t Offset); - -/// Set the reference value into a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param Data the reference value to set into the table instance. -/// \param Offset the reference value offset (index) in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceSetData(WasmEdge_TableInstanceContext *Cxt, - WasmEdge_Value Data, const uint32_t Offset); - -/// Get the size of a table instance. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// -/// \returns the size of the table instance. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_TableInstanceGetSize(const WasmEdge_TableInstanceContext *Cxt); - -/// Grow a table instance with a size. -/// -/// \param Cxt the WasmEdge_TableInstanceContext. -/// \param Size the count of reference values to grow in the table instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_TableInstanceGrow(WasmEdge_TableInstanceContext *Cxt, - const uint32_t Size); - -/// Deletion of the WasmEdge_TableInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_TableInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_TableInstanceDelete(WasmEdge_TableInstanceContext *Cxt); - -// <<<<<<<< WasmEdge table instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge memory instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_MemoryInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_MemoryInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// -/// \param MemType the memory type context to initialize the memory instance -/// context. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_MemoryInstanceCreate(const WasmEdge_MemoryTypeContext *MemType); - -/// Get the memory type context from a memory instance. -/// -/// The memory type context links to the memory type in the memory instance -/// context and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_MemoryTypeDelete`. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_MemoryTypeContext * -WasmEdge_MemoryInstanceGetMemoryType(const WasmEdge_MemoryInstanceContext *Cxt); - -/// Copy the data to the output buffer from a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param [out] Data the result data buffer of copying destination. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will failed. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceGetData(const WasmEdge_MemoryInstanceContext *Cxt, - uint8_t *Data, const uint32_t Offset, - const uint32_t Length); - -/// Copy the data into a memory instance from the input buffer. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Data the data buffer to copy. -/// \param Offset the data start offset in the memory instance. -/// \param Length the data buffer length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will failed. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceSetData(WasmEdge_MemoryInstanceContext *Cxt, - const uint8_t *Data, const uint32_t Offset, - const uint32_t Length); - -/// Get the data pointer in a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will return NULL. -/// -/// \returns the pointer to data with the start offset. NULL if failed. -WASMEDGE_CAPI_EXPORT extern uint8_t * -WasmEdge_MemoryInstanceGetPointer(WasmEdge_MemoryInstanceContext *Cxt, - const uint32_t Offset, const uint32_t Length); - -/// Get the const data pointer in a const memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Offset the data start offset in the memory instance. -/// \param Length the requested data length. If the `Offset + Length` is larger -/// than the data size in the memory instance, this function will return NULL. -/// -/// \returns the pointer to data with the start offset. NULL if failed. -WASMEDGE_CAPI_EXPORT extern const uint8_t * -WasmEdge_MemoryInstanceGetPointerConst( - const WasmEdge_MemoryInstanceContext *Cxt, const uint32_t Offset, - const uint32_t Length); - -/// Get the current page size (64 KiB of each page) of a memory instance. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// -/// \returns the page size of the memory instance. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_MemoryInstanceGetPageSize(const WasmEdge_MemoryInstanceContext *Cxt); - -/// Grow a memory instance with a page size. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext. -/// \param Page the page count to grow in the memory instance. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_MemoryInstanceGrowPage(WasmEdge_MemoryInstanceContext *Cxt, - const uint32_t Page); - -/// Deletion of the WasmEdge_MemoryInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_MemoryInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_MemoryInstanceDelete(WasmEdge_MemoryInstanceContext *Cxt); - -// <<<<<<<< WasmEdge memory instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge tag instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the tag type context from a tag instance. -/// -/// The tag type context links to the tag type in the tag instance -/// context and owned by the context. -/// -/// \param Cxt the WasmEdge_TagInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_TagTypeContext * -WasmEdge_TagInstanceGetTagType(const WasmEdge_TagInstanceContext *Cxt); - -// <<<<<<<< WasmEdge tag instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge global instance functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_GlobalInstanceContext. -/// -/// The caller owns the object and should call `WasmEdge_GlobalInstanceDelete` -/// to destroy it if the returned object is not added into a -/// `WasmEdge_ModuleInstanceContext`. -/// -/// \param GlobType the global type context to initialize the global instance -/// context. -/// \param Value the initial value with its value type of the global instance. -/// This function will fail if the value type of `GlobType` and `Value` are not -/// the same. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_GlobalInstanceContext * -WasmEdge_GlobalInstanceCreate(const WasmEdge_GlobalTypeContext *GlobType, - const WasmEdge_Value Value); - -/// Get the global type context from a global instance. -/// -/// The global type context links to the global type in the global instance -/// context and owned by the context. The caller should __NOT__ call the -/// `WasmEdge_GlobalTypeDelete`. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_GlobalTypeContext * -WasmEdge_GlobalInstanceGetGlobalType(const WasmEdge_GlobalInstanceContext *Cxt); - -/// Get the value from a global instance. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// -/// \returns the current value of the global instance. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Value -WasmEdge_GlobalInstanceGetValue(const WasmEdge_GlobalInstanceContext *Cxt); - -/// Set the value into a global instance. -/// -/// This function will return error if the global context is set as the `Const` -/// mutation or the value type not matched. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext. -/// \param Value the value to set into the global context. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_GlobalInstanceSetValue(WasmEdge_GlobalInstanceContext *Cxt, - const WasmEdge_Value Value); - -/// Deletion of the WasmEdge_GlobalInstanceContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_GlobalInstanceContext to destroy. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_GlobalInstanceDelete(WasmEdge_GlobalInstanceContext *Cxt); - -// <<<<<<<< WasmEdge global instance functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge calling frame functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Get the executor context from the current calling frame. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// -/// \returns the executor context, NULL if the Cxt is NULL. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_CallingFrameGetExecutor(const WasmEdge_CallingFrameContext *Cxt); - -/// Get the module instance of the current calling frame. -/// -/// When a WASM function is executing and start to call a host function, a frame -/// with the module instance which the WASM function belongs to will be pushed -/// onto the stack. And therefore the calling frame context will record that -/// module instance. -/// So in one case that the module instance will be `NULL`: developers execute -/// the function instance which is a host function and not added into a module -/// instance. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// -/// \returns the module instance of the current calling frame. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_CallingFrameGetModuleInstance(const WasmEdge_CallingFrameContext *Cxt); - -/// Get the memory instance by index from the module instance of the current -/// calling frame. -/// -/// By default, a WASM module only have one memory instance after instantiation. -/// Therefore, developers can use: -/// `WasmEdge_CallingFrameGetMemoryInstance(Cxt, 0)` -/// to get the memory instance in host function body. -/// This extension is for the WASM multiple memories proposal. After enabling -/// the proposal, there may be greater than 1 memory instances in a WASM module. -/// So developers can use this function to access the memory instances which are -/// not in 0 index. -/// -/// \param Cxt the WasmEdge_CallingFrameContext. -/// \param Idx the index of memory instance in the module instance. -/// -/// \returns the memory instance, NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_MemoryInstanceContext * -WasmEdge_CallingFrameGetMemoryInstance(const WasmEdge_CallingFrameContext *Cxt, - const uint32_t Idx); - -// <<<<<<<< WasmEdge calling frame functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Async functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Wait a WasmEdge_Async execution. -/// -/// \param Cxt the WasmEdge_ASync. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncWait(const WasmEdge_Async *Cxt); - -/// Wait a WasmEdge_Async execution with timeout. -/// -/// \param Cxt the WasmEdge_ASync. -/// \param Milliseconds times to wait. -/// -/// \returns Result of waiting, true for execution ended, false for timeout -/// occurred. -WASMEDGE_CAPI_EXPORT bool WasmEdge_AsyncWaitFor(const WasmEdge_Async *Cxt, - uint64_t Milliseconds); - -/// Cancel a WasmEdge_Async execution. -/// -/// \param Cxt the WasmEdge_ASync. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncCancel(WasmEdge_Async *Cxt); - -/// Wait and get the return list length of the WasmEdge_Async execution. -/// -/// This function will wait until the execution finished and return the return -/// value list length of the executed function. This function will return 0 if -/// the `Cxt` is NULL, the execution was failed, or the execution was canceled. -/// Developers can call the `WasmEdge_AsyncGet` to get the execution status and -/// the return values. -/// -/// \param Cxt the WasmEdge_ASync. -/// -/// \returns the return list length of the executed function. -WASMEDGE_CAPI_EXPORT uint32_t -WasmEdge_AsyncGetReturnsLength(const WasmEdge_Async *Cxt); - -/// Wait and get the result of WasmEdge_Async execution. -/// -/// This function will wait until the execution finished and return the -/// execution status and the return values. -/// If the `Returns` buffer length is smaller than the arity of the function, -/// the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_ASync. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT WasmEdge_Result -WasmEdge_AsyncGet(const WasmEdge_Async *Cxt, WasmEdge_Value *Returns, - const uint32_t ReturnLen); - -/// Deletion of the WasmEdge_Async. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_ASync to destroy. -WASMEDGE_CAPI_EXPORT void WasmEdge_AsyncDelete(WasmEdge_Async *Cxt); - -// <<<<<<<< WasmEdge Async functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge VM functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Creation of the WasmEdge_VMContext. -/// -/// The caller owns the object and should call `WasmEdge_VMDelete` to destroy -/// it. -/// -/// \param ConfCxt the WasmEdge_ConfigureContext as the configuration of VM. -/// NULL for the default configuration. -/// \param StoreCxt the WasmEdge_StoreContext as the external WASM store of VM. -/// The instantiation and execution will refer to this store context, and the -/// life cycle should be ensured until the VM context is deleted. NULL for the -/// default store owned by `WasmEdge_VMContext`. -/// -/// \returns pointer to context, NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_VMContext * -WasmEdge_VMCreate(const WasmEdge_ConfigureContext *ConfCxt, - WasmEdge_StoreContext *StoreCxt); - -/// Register and instantiate WASM into the store in VM from a WASM file. -/// -/// Load a WASM file from the path, and register all exported instances and -/// instantiate them into the store into the VM with their exported name and -/// module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromFile(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const char *Path); - -/// Register and instantiate WASM into the store in VM from a buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMRegisterModuleFromBytes()` API in the future. -/// -/// Load a WASM module from a buffer, and register all exported instances and -/// instantiate them into the store into the VM with their exported name and -/// module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromBuffer(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const uint8_t *Buf, const uint32_t BufLen); - -/// Register and instantiate WASM into the store in VM from a WasmEdge_Bytes. -/// -/// Load a WASM module from a WasmEdge_Bytes, and register all exported -/// instances and instantiate them into the store into the VM with their -/// exported name and module name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromBytes(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_Bytes Bytes); - -/// Instantiate and register an AST Module into a named module instance in VM. -/// -/// Load from the AST Module, and register all exported instances and -/// instantiate them into the store in VM with their exported name and module -/// name. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ModuleName the WasmEdge_String of module name for all exported -/// instances. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMRegisterModuleFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Register a module instance into the store in VM with exporting its module -/// name. -/// -/// After calling this function, the existing module instance will be registered -/// into the store context in this VM, and the other modules can import the -/// exported instances for linking when instantiation. Developers SHOULD -/// guarantee the life cycle of this existing module instance, or the error will -/// occur when in execution after the module instance being destroyed if it has -/// been imported by other modules. That is, developers should call the -/// `WasmEdge_ModuleInstanceDelete` if this existing module instance will not be -/// used anymore or after the deletion of this VM. When the module instance is -/// deleted, it will be unregistered to the store context in this VM -/// automatically. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext which contains the store. -/// \param ImportCxt the WasmEdge_ModuleInstanceContext to register. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRegisterModuleFromImport( - WasmEdge_VMContext *Cxt, const WasmEdge_ModuleInstanceContext *ImportCxt); - -/// Instantiate the WASM module from a WASM file and invoke a function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the file path, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromFile( - WasmEdge_VMContext *Cxt, const char *Path, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a buffer and invoke a function by name. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMRunWasmFromBytes()` API in the future. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a buffer, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromBuffer( - WasmEdge_VMContext *Cxt, const uint8_t *Buf, const uint32_t BufLen, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WasmEdge_Bytes and invoke a function by -/// name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a WasmEdge_Bytes, and then invoke -/// a function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromBytes( - WasmEdge_VMContext *Cxt, const WasmEdge_Bytes Bytes, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WasmEdge AST Module and invoke a function -/// by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the WasmEdge AST Module, and then -/// invoke the function by name and parameters. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMRunWasmFromASTModule( - WasmEdge_VMContext *Cxt, const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Instantiate the WASM module from a WASM file and asynchronous invoke a -/// function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the file path, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromFile( - WasmEdge_VMContext *Cxt, const char *Path, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen); - -/// Instantiate the WASM module from a buffer and asynchronous invoke a function -/// by name. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMAsyncRunWasmFromBytes()` API in the future. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a buffer, and then invoke a -/// function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromBuffer( - WasmEdge_VMContext *Cxt, const uint8_t *Buf, const uint32_t BufLen, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Instantiate the WASM module from a WasmEdge_Bytes and asynchronous invoke a -/// function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from a WasmEdge_Bytes, and then invoke -/// a function by name and parameters. If the `Returns` buffer length is smaller -/// than the arity of the function, the overflowed return values will be -/// discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncRunWasmFromBytes( - WasmEdge_VMContext *Cxt, const WasmEdge_Bytes Bytes, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Instantiate the WASM module from a WasmEdge AST Module and asynchronous -/// invoke a function by name. -/// -/// This is the function to invoke a WASM function rapidly. -/// Load and instantiate the WASM module from the WasmEdge AST Module, and then -/// invoke the function by name and parameters. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// The caller owns the object and should call `WasmEdge_AsyncDelete` to destroy -/// it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_VMAsyncRunWasmFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt, - const WasmEdge_String FuncName, - const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Load the WASM module from a WASM file. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from the file path. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Path the NULL-terminated C string of the WASM file path. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromFile(WasmEdge_VMContext *Cxt, const char *Path); - -/// Load the WASM module from a buffer. -/// -/// CAUTION: This function will be deprecated and replaced by -/// `WasmEdge_VMLoadWasmFromBytes()` API in the future. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from a buffer. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Buf the buffer of WASM binary. -/// \param BufLen the length of the buffer. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromBuffer(WasmEdge_VMContext *Cxt, const uint8_t *Buf, - const uint32_t BufLen); - -/// Load the WASM module from a WasmEdge_Bytes. -/// -/// This is the first step to invoke a WASM function step by step. -/// Load and parse the WASM module from a WasmEdge_Bytes. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Bytes the WasmEdge_Bytes of WASM binary. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromBytes(WasmEdge_VMContext *Cxt, - const WasmEdge_Bytes Bytes); - -/// Load the WASM module from loaded WasmEdge AST Module. -/// -/// This is the first step to invoke a WASM function step by step. -/// Copy the loaded WasmEdge AST Module context into VM. The VM context has no -/// dependency on the input AST Module context. You can then call -/// `WasmEdge_VMValidate` for the next step. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ASTCxt the WasmEdge AST Module context generated by loader or -/// compiler. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMLoadWasmFromASTModule(WasmEdge_VMContext *Cxt, - const WasmEdge_ASTModuleContext *ASTCxt); - -/// Validate the WASM module loaded into the VM context. -/// -/// This is the second step to invoke a WASM function step by step. -/// After loading a WASM module into VM context, You can call this function to -/// validate it. And you can then call `WasmEdge_VMInstantiate` for the next -/// step. Note that only validated WASM modules can be instantiated in the VM -/// context. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMValidate(WasmEdge_VMContext *Cxt); - -/// Instantiate the validated WASM module in the VM context. -/// -/// This is the third step to invoke a WASM function step by step. -/// After validating a WASM module in the VM context, You can call this function -/// to instantiate it. And you can then call `WasmEdge_VMExecute` for invoking -/// the exported function in this WASM module. -/// After calling this function, a new anonymous module instance owned by VM is -/// instantiated, and the old one will be destroyed. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMInstantiate(WasmEdge_VMContext *Cxt); - -/// Invoke a WASM function by name. -/// -/// This is the final step to invoke a WASM function step by step. -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can repeatedly call this function to invoke the exported WASM functions by -/// their names until the VM context is reset or a new WASM module is registered -/// or loaded. For calling the functions in registered WASM modules with module -/// names, please use `WasmEdge_VMExecuteRegistered` instead. If the `Returns` -/// buffer length is smaller than the arity of the function, the overflowed -/// return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result -WasmEdge_VMExecute(WasmEdge_VMContext *Cxt, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen, - WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Invoke a WASM function by its module name and function name. -/// -/// After registering a WASM module in the VM context, you can repeatedly call -/// this function to invoke exported WASM functions by their module names and -/// function names until the VM context is reset. If the `Returns` buffer length -/// is smaller than the arity of the function, the overflowed return values will -/// be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// \param [out] Returns the WasmEdge_Value buffer to fill the return values. -/// \param ReturnLen the return buffer length. -/// -/// \returns WasmEdge_Result. Call `WasmEdge_ResultGetMessage` for the error -/// message. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Result WasmEdge_VMExecuteRegistered( - WasmEdge_VMContext *Cxt, const WasmEdge_String ModuleName, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen, WasmEdge_Value *Returns, const uint32_t ReturnLen); - -/// Asynchronous invoke a WASM function by name. -/// -/// This is the final step to invoke a WASM function step by step. -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can repeatedly call this function to invoke the exported WASM functions by -/// their names until the VM context is reset or a new WASM module is registered -/// or loaded. For calling the functions in registered WASM modules with module -/// names, please use `WasmEdge_VMAsyncExecuteRegistered` instead. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async * -WasmEdge_VMAsyncExecute(WasmEdge_VMContext *Cxt, const WasmEdge_String FuncName, - const WasmEdge_Value *Params, const uint32_t ParamLen); - -/// Asynchronous invoke a WASM function by its module name and function name. -/// -/// After registering a WASM module in the VM context, you can repeatedly call -/// this function to invoke exported WASM functions by their module names and -/// function names until the VM context is reset. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// \param Params the WasmEdge_Value buffer with the parameter values. -/// \param ParamLen the parameter buffer length. -/// -/// \returns WasmEdge_Async. Call `WasmEdge_AsyncGet` for the result, and call -/// `WasmEdge_AsyncDelete` to destroy this object. -WASMEDGE_CAPI_EXPORT extern WasmEdge_Async *WasmEdge_VMAsyncExecuteRegistered( - WasmEdge_VMContext *Cxt, const WasmEdge_String ModuleName, - const WasmEdge_String FuncName, const WasmEdge_Value *Params, - const uint32_t ParamLen); - -/// Get the function type by function name. -/// -/// After instantiating a WASM module in the VM context, the WASM module is -/// registered into the store in the VM context as an anonymous module. Then you -/// can call this function to get the function type by the exported function -/// name until the VM context is reset or a new WASM module is registered or -/// loaded. For getting the function type of functions in registered WASM -/// modules with module names, please use `WasmEdge_VMGetFunctionTypeRegistered` -/// instead. -/// The returned function type context are linked to the context owned by the VM -/// context, and the caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete` to destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param FuncName the function name WasmEdge_String. -/// -/// \returns the function type. NULL if the function not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_VMGetFunctionType(const WasmEdge_VMContext *Cxt, - const WasmEdge_String FuncName); - -/// Get the function type by function name. -/// -/// After registering a WASM module in the VM context, you can call this -/// function to get the function type by the functions' exported module names -/// and function names until the VM context is reset. -/// The returned function type context are linked to the context owned by the VM -/// context, and the caller should __NOT__ call the -/// `WasmEdge_FunctionTypeDelete` to destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// \param FuncName the function name WasmEdge_String. -/// -/// \returns the function type. NULL if the function not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_FunctionTypeContext * -WasmEdge_VMGetFunctionTypeRegistered(const WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName, - const WasmEdge_String FuncName); - -/// Reset of WasmEdge_VMContext. -/// -/// After calling this function, the statistics, loaded module, the instantiated -/// instances, and the registered instances except the WASI and plug-ins will -/// all be cleared. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext to reset. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_VMCleanup(WasmEdge_VMContext *Cxt); - -/// Get the length of exported function list. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns length of exported function list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMGetFunctionListLength(const WasmEdge_VMContext *Cxt); - -/// Get the exported function list. -/// -/// The returned function names filled into the `Names` array link to the -/// exported names of functions owned by the vm context, and the caller should -/// __NOT__ call the `WasmEdge_StringDelete` to destroy them. -/// The function type contexts filled into the `FuncTypes` array of the -/// corresponding function names link to the context owned by the VM context. -/// The caller should __NOT__ call the `WasmEdge_FunctionTypeDelete` to destroy -/// them. -/// If the `Names` and `FuncTypes` buffer lengths are smaller than the result of -/// the exported function list size, the overflowed return values will be -/// discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param [out] Names the output names WasmEdge_String buffer of exported -/// functions. Can be NULL if names are not needed. -/// \param [out] FuncTypes the function type contexts buffer. Can be NULL if -/// function types are not needed. -/// \param Len the buffer length. -/// -/// \returns actual exported function list size. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_VMGetFunctionList( - const WasmEdge_VMContext *Cxt, WasmEdge_String *Names, - const WasmEdge_FunctionTypeContext **FuncTypes, const uint32_t Len); - -/// Get the module instance corresponding to the WasmEdge_HostRegistration -/// settings. -/// -/// When creating the VM context with a configuration, the built-in host module -/// will be registered according to the `WasmEdge_HostRegistration` settings -/// added into the `WasmEdge_ConfigureContext`. You can call this function to -/// get the `WasmEdge_ModuleInstanceContext` corresponding to the settings. The -/// module instance context links to the context owned by the VM context. The -/// caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete`. -/// -/// ```c -/// WasmEdge_ConfigureContext *Conf = WasmEdge_ConfigureCreate(); -/// WasmEdge_ConfigureAddHostRegistration(Conf, WasmEdge_HostRegistration_Wasi); -/// WasmEdge_VMContext *VM = WasmEdge_VMCreate(Conf, NULL); -/// WasmEdge_ModuleInstanceContext *WasiMod = -/// WasmEdge_VMGetImportModuleContext(VM, WasmEdge_HostRegistration_Wasi); -/// ``` -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Reg the host registration value to get the import module. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetImportModuleContext(const WasmEdge_VMContext *Cxt, - const enum WasmEdge_HostRegistration Reg); - -/// Get the current instantiated module in VM. -/// -/// After instantiating a module instance into the VM, developers can call this -/// API to get the active anonymous module instance to retrieve the exported -/// instances. The module instance context links to the context owned by the VM -/// context. The caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetActiveModule(const WasmEdge_VMContext *Cxt); - -/// Get the registered module in VM by the module name. -/// -/// After registering a WASM module into the VM context, developers can call -/// this function to get the module instance by the module name. The returned -/// module instance context links to the context owned by the VM context, and -/// the caller should __NOT__ call the `WasmEdge_ModuleInstanceDelete` to -/// destroy it. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param ModuleName the module name WasmEdge_String. -/// -/// \returns pointer to the module instance context. NULL if not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_ModuleInstanceContext * -WasmEdge_VMGetRegisteredModule(const WasmEdge_VMContext *Cxt, - const WasmEdge_String ModuleName); - -/// Get the length of registered module list in the WasmEdge_VMContext. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns length of registered module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMListRegisteredModuleLength(const WasmEdge_VMContext *Cxt); - -/// List the registered module names in the WasmEdge_VMContext. -/// -/// This function will list all registered module names. -/// The returned module names filled into the `Names` array are linked to the -/// registered module names in the VM context, and the caller should __NOT__ -/// call the `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the registered -/// named module list size, the overflowed return values will be discarded. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param [out] Names the output names WasmEdge_String buffer of the registered -/// modules. -/// \param Len the buffer length. -/// -/// \returns actual registered module list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_VMListRegisteredModule(const WasmEdge_VMContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Get the store context used in the WasmEdge_VMContext. -/// -/// The returned store context links to the store in the VM context and owned by -/// the VM context. This function will return NULL if error occurs. The caller -/// should __NOT__ call the `WasmEdge_StoreDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the store context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StoreContext * -WasmEdge_VMGetStoreContext(WasmEdge_VMContext *Cxt); - -/// Get the loader context used in the WasmEdge_VMContext. -/// -/// The returned loader context links to the loader in the VM context and owned -/// by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_LoaderDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the loader context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_LoaderContext * -WasmEdge_VMGetLoaderContext(WasmEdge_VMContext *Cxt); - -/// Get the validator context used in the WasmEdge_VMContext. -/// -/// The returned validator context links to the validator in the VM context and -/// owned by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_ValidatorDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the validator context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ValidatorContext * -WasmEdge_VMGetValidatorContext(WasmEdge_VMContext *Cxt); - -/// Get the executor context used in the WasmEdge_VMContext. -/// -/// The returned executor context links to the executor in the VM context and -/// owned by the VM context. This function will return NULL if error occurs. The -/// caller should __NOT__ call the `WasmEdge_ExecutorDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the executor context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ExecutorContext * -WasmEdge_VMGetExecutorContext(WasmEdge_VMContext *Cxt); - -/// Get the statistics context used in the WasmEdge_VMContext. -/// -/// The statistics context links to the statistics in the VM context and owned -/// by the VM context. The caller should __NOT__ call the -/// `WasmEdge_StatisticsDelete`. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// -/// \returns pointer to the statistics context. -WASMEDGE_CAPI_EXPORT extern WasmEdge_StatisticsContext * -WasmEdge_VMGetStatisticsContext(WasmEdge_VMContext *Cxt); - -/// Deletion of the WasmEdge_VMContext. -/// -/// After calling this function, the context will be destroyed and should -/// __NOT__ be used. -/// -/// \param Cxt the WasmEdge_VMContext to destroy. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_VMDelete(WasmEdge_VMContext *Cxt); - -// <<<<<<<< WasmEdge VM functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Driver functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || \ - defined(__TOS_WIN__) || defined(__WINDOWS__) -/// Convert UTF16 Args to UTF8 Args -/// -/// This function is an argument converter for Windows platforms. -/// The caller owns the vector and should call `WasmEdge_Driver_ArgvDelete` to -/// destroy it. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns Allocated argument vector. -WASMEDGE_CAPI_EXPORT extern const char ** -WasmEdge_Driver_ArgvCreate(int Argc, const wchar_t *Argv[]); - -/// Deletion of the argument vector -/// -/// \param Argv the argument vector. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_Driver_ArgvDelete(const char *Argv[]); - -/// Set console output code page to UTF-8 on windows. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_Driver_SetConsoleOutputCPtoUTF8(void); -#endif - -/// Entrypoint for the compiler tool. -/// -/// This function provides an entrypoint to the WasmEdge AOT compiler tool with -/// the command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_Compiler(int Argc, - const char *Argv[]); - -/// Entrypoint for the runtime tool. -/// -/// This function provides an entrypoint to the WasmEdge runtime tool with the -/// command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_Tool(int Argc, - const char *Argv[]); - -#ifdef WASMEDGE_BUILD_WASI_NN_RPC -/// Entrypoint for the Wasi-NN RPC server tool. -/// -/// This function provides an entrypoint to the WasmEdge Wasi-NN RPC server tool -/// with the command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int -WasmEdge_Driver_WasiNNRPCServer(int Argc, const char *Argv[]); -#endif - -/// Entrypoint for the unified tool. -/// -/// This function provides an entrypoint to the WasmEdge unified tool with the -/// command line arguments. -/// -/// \param Argc the argument count. -/// \param Argv the argument vector. -/// -/// \returns the execution status. -WASMEDGE_CAPI_EXPORT extern int WasmEdge_Driver_UniTool(int Argc, - const char *Argv[]); - -// <<<<<<<< WasmEdge Driver functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Plugin functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Load plugins with the default search paths. -/// -/// The default paths are: -/// 1. The environment variable "WASMEDGE_PLUGIN_PATH". -/// 2. The "../plugin/" directory related to the WasmEdge installation path. -/// 3. The "wasmedge/" directory under the library path if the WasmEdge is -/// installed under the "/usr". -WASMEDGE_CAPI_EXPORT extern void WasmEdge_PluginLoadWithDefaultPaths(void); - -/// Load the plugin with the given file or directory. -/// -/// For the given file path, this function will load the plug-in. -/// For the given directory path, this function will load the plug-ins under the -/// directory recursively. -/// -/// \param Path the path to plug-in file or directory. -WASMEDGE_CAPI_EXPORT extern void WasmEdge_PluginLoadFromPath(const char *Path); - -/// Get the length of loaded plug-in list. -/// -/// \returns length of loaded plug-in list. -WASMEDGE_CAPI_EXPORT extern uint32_t WasmEdge_PluginListPluginsLength(void); - -/// List the loaded plug-ins with their names. -/// -/// The returned plug-in names filled into the `Names` array are owned by the -/// internal WasmEdge plug-in storage, and the caller should __NOT__ call the -/// `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the loaded -/// plug-in list size, the overflowed return values will be discarded. -/// -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual loaded plug-in list size. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListPlugins(WasmEdge_String *Names, const uint32_t Len); - -/// Find the loaded plug-in context by name. -/// -/// After loading the plug-ins from default paths or the given path, developers -/// can use this API to retrieve the plug-in context by name. Then developers -/// can create the module instance from the plug-in contexts. -/// -/// \param Name the plug-in name WasmEdge_String. -/// -/// \returns pointer to the plug-in context. NULL if the plug-in not found. -WASMEDGE_CAPI_EXPORT extern const WasmEdge_PluginContext * -WasmEdge_PluginFind(const WasmEdge_String Name); - -/// Get the plug-in name of the plug-in context. -/// -/// The returned string object is linked to the plug-in name of the plug-in -/// context, and the caller should __NOT__ call the `WasmEdge_StringDelete`. -/// -/// \param Cxt the WasmEdge_PluginContext. -/// -/// \returns string object. Length will be 0 and Buf will be NULL if failed. -WASMEDGE_CAPI_EXPORT extern WasmEdge_String -WasmEdge_PluginGetPluginName(const WasmEdge_PluginContext *Cxt); - -/// Get the length of module list in the plug-in context. -/// -/// There may be several modules in a plug-in. Developers can use this function -/// to get the length of the module list in a plug-in. -/// -/// \param Cxt the WasmEdge_PluginContext to get the length of the module list. -/// -/// \returns length of module list. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListModuleLength(const WasmEdge_PluginContext *Cxt); - -/// List the modules in the plug-in context with their names. -/// -/// The returned module names filled into the `Names` array are owned by the -/// internal WasmEdge plug-in storage, and the caller should __NOT__ call the -/// `WasmEdge_StringDelete`. -/// If the `Names` buffer length is smaller than the result of the loaded -/// plug-in list size, the overflowed return values will be discarded. -/// -/// \param Cxt the WasmEdge_PluginContext to list the modules. -/// \param [out] Names the output WasmEdge_String buffer of the function names. -/// \param Len the buffer length. -/// -/// \returns actual module list size of the plug-in. -WASMEDGE_CAPI_EXPORT extern uint32_t -WasmEdge_PluginListModule(const WasmEdge_PluginContext *Cxt, - WasmEdge_String *Names, const uint32_t Len); - -/// Create the module instance in the plug-in by the module name. -/// -/// By giving the module name, developers can retrieve the module in the plug-in -/// and create the module instance. -/// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` -/// to destroy it. -/// -/// \param Cxt the WasmEdge_PluginContext to retrieve and create module. -/// \param ModuleName the module name to retrieve. -/// -/// \returns pointer to the module instance context, NULL if the module name not -/// found in the plug-in or the plug-in is not valid. -WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * -WasmEdge_PluginCreateModule(const WasmEdge_PluginContext *Cxt, - const WasmEdge_String ModuleName); - -/// Initialize the wasi_nn plug-in. -/// -/// This function will initialize the wasi_nn plug-in with the preloads string -/// list. Only available after loading the wasi_nn plug-in and before creating -/// the module instance from the plug-in. -/// -/// \param NNPreloads the preload string list. NULL if the length is 0. -/// \param PreloadsLen the length of the preload list. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_PluginInitWASINN(const char *const *NNPreloads, - const uint32_t PreloadsLen); - -/// Implement by plugins for returning the plugin descriptor. -/// -/// \returns the plugin descriptor. -WASMEDGE_CAPI_PLUGIN_EXPORT extern const WasmEdge_PluginDescriptor * -WasmEdge_Plugin_GetDescriptor(void); - -// <<<<<<<< WasmEdge Pluginfunctions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - -// >>>>>>>> WasmEdge Experimental functions >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - -/// Register a host function that will be invoked before executing any host -/// functions. -/// -/// There is only one pre-host-function. After calling this function, the -/// previous registered host function will be replaced. This is a experimental -/// feature. Use it at your own risk. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_ExecutorContext. -/// \param Data the host data to set into the given host function. When calling -/// the Func, this pointer will be the argument of the Func function. -/// \param Func the function to be invoked before executing any other host -/// functions. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorExperimentalRegisterPreHostFunction( - WasmEdge_ExecutorContext *Cxt, void *Data, void (*Func)(void *)); - -/// Register a host function that will be invoked after executing any host -/// functions. -/// -/// There is only one post-host-function. After calling this function, the -/// previous registered host function will be replaced. This is a experimental -/// feature. Use it at your own risk. -/// -/// This function is thread-safe. -/// -/// \param Cxt the WasmEdge_VMContext. -/// \param Data the host data to set into the given host function. When calling -/// the Func, this pointer will be the argument of the Func function. -/// \param Func the function to be invoked after executing any other host -/// functions. -WASMEDGE_CAPI_EXPORT extern void -WasmEdge_ExecutorExperimentalRegisterPostHostFunction( - WasmEdge_ExecutorContext *Cxt, void *Data, void (*Func)(void *)); - -// <<<<<<<< WasmEdge Experimental Functions <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -#ifdef __cplusplus -} /// extern "C" -#endif - -#endif /// WASMEDGE_C_API_H diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so b/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so deleted file mode 120000 index 145d5a021c32a26423bac2fecffd6a174664a3b3..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so +++ /dev/null @@ -1 +0,0 @@ -libwasmedge.so.0 \ No newline at end of file diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0 b/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0 deleted file mode 120000 index 6639f000114eaf75d312c5ce1153d5b25b079a87..0000000000000000000000000000000000000000 --- a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0 +++ /dev/null @@ -1 +0,0 @@ -libwasmedge.so.0.1.0 \ No newline at end of file diff --git a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0.1.0 b/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0.1.0 deleted file mode 100755 index e85e06a4229b8dcbd0e395c3768a6d060e0e405d..0000000000000000000000000000000000000000 Binary files a/wasmedge/lib-0.14.1-manylinux2014/x86_64/lib/libwasmedge.so.0.1.0 and /dev/null differ diff --git a/wasmedge/make b/wasmedge/make deleted file mode 100644 index fdecd5b1a3853632ba9f94ea590c137fa13693d4..0000000000000000000000000000000000000000 --- a/wasmedge/make +++ /dev/null @@ -1,26 +0,0 @@ -case "$CC" in - bcc32) - -cat << END - -$0: error: not allow build use bcc32 - -END - - ;; - - *) - CMAKE="cmake" - if command -v cmake3 > /dev/null; then - CMAKE="cmake3" - fi - cat << END >> $NJT_MAKEFILE - -$WASMEDGE/build/include/wasmedge/wasmedge.h: - cd $WASMEDGE \\ - && mkdir -p build \\ - && cp -r lib-0.14.1-manylinux2014/$wasm_arch/* build -END - ;; - -esac