Wasm
Wasm
Plus 目前支援使用 C 語言編寫 Wasm32 或者 Wasm64 模組並在 OpenResty Plus 中執行。
Wasm 示例
這裡我們提供一個使用 Wasm 模組執行求和的實際用例。
在應用的 wasm64 目錄下建立一個 add.c
檔案。
#include "or-wasm.h"
int calc(or_wasm_func_args_t *args)
{
int a = get_args_int(args, 0);
int b = get_args_int(args, 1);
return or_wasm_return_int(a + b);
}
在 nginx.conf
中新增一個 location /t
。
location /t {
content_by_lua_block {
local wasm_loader = require "resty.wasm-elf-loader"
local fname = ngx.config.prefix() .. "/wasm64/add.so"
local lib, err = wasm_loader.init(fname)
if not lib then
ngx.say("failed to init ", fname, ", err: ", err)
return
end
ngx.say("add: ", lib:calc(10, 20))
}
}
新增測試請求。
儲存並執行,可以看到響應中已經是正確的求和結果了。
Wasm 引數傳遞
如以上 Wasm 示例中的 lib:calc(10, 20)
所示,呼叫 Wasm 函式和普通的 Lua 函式呼叫一樣。
local ret = class:method(arg1, arg2, arg3…)
引數數量不限,當前接受的引數型別有 int,double,string,table,boolean,nil。經過 or-wasm 執行庫整理到 or_wasm_func_args_t *args 的結構體中,由於 C 語言中沒有 Lua 的 table 和 nil 概念,故而引數從 Lua 到 C 會有一個對映關係,如下:
Int => int32/int64
double => double
string => addr in linear memory + string len
table => table index in Lua ctx table
boolean => Int 1 (true) / Int 0 (false)
nil => Int 0
Wasm 提取傳入的 Lua 引數
根據事先約定的傳入型別,呼叫相應的 API 來提取,注意,這裡第一個傳入的引數對應的索引為 0,後續依次遞增。
例如:
int first = get_args_int(args, 0);
Wasm 回傳返回值給 Lua
直接呼叫 API 回傳返回值給 Lua。
例如:
return or_wasm_return_int(100);
OR-Wasm API 列表
目前支援以下這些 API,未來會逐漸完善。
int32_t get_args_int(or_wasm_func_args_t *args, int idx);
int64_t get_args_int64(or_wasm_func_args_t *args, int idx);
int64_t get_args_int3264(or_wasm_func_args_t *args, int idx);
void get_args_str(or_wasm_func_args_t *args, int idx, or_wasm_str_t *str);
int or_wasm_return_str(char *addr, int len);
int or_wasm_return_int(int n);
int or_wasm_return_uint(uint32_t n);
int or_wasm_return_int64(int64_t n);