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);