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