This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
wrt/tests/dl.cpp
Paul Pan a471519ff7 feat: basic dl_call support
1. add basic dl_call support
2. re-organize code structure
3. fix `wasm_runtime_call_wasm` error handler
4. update examples
2023-02-11 14:33:45 +08:00

178 lines
5.4 KiB
C++

#include <gtest/gtest.h>
#include <dlfcn.h>
extern "C" {
#include "utils/defs.h"
#include "wrt/lib/dl.h"
#include "wasm_exec_env.h"
extern bool signature_check(const char *signature, int *arg_count, bool *has_ret);
}
DLContext dl_context;
WASMExecEnv exec_env;
void init() {
dl_context.mem.malloc = malloc;
dl_context.mem.free = free;
dl_context.symTable = nullptr;
memset(dl_context.hnd, 0, sizeof(dl_context.hnd));
memset(dl_context.sym, 0, sizeof(dl_context.sym));
exec_env.attachment = &dl_context;
}
#define check_symbol_consistency(sym, postfix) \
do { \
ASSERT_GT((sym), 0); \
ASSERT_LT((sym), DL_MAX_SYMBOLS); \
ASSERT_NE(dl_context.sym[(sym)-1].symbol, nullptr); \
ASSERT_NE(dl_context.sym[(sym)-1].cif, nullptr); \
ASSERT_GT(dl_context.sym[(sym)-1].backref, 0); \
unsigned ref##postfix = dl_context.sym[(sym)-1].backref; \
ASSERT_GT(ref##postfix, 0); \
ASSERT_LE(ref##postfix, DL_MAX_HANDLES); \
ASSERT_NE(dl_context.hnd[ref##postfix - 1].handle, nullptr); \
} while (0)
#define check_hnd_empty(postfix) \
do { \
for (auto &hnd##postfix : dl_context.hnd) { \
ASSERT_EQ(hnd##postfix.handle, nullptr); \
} \
} while (0)
#define check_sym_empty(postfix) \
do { \
for (auto &sym##postfix : dl_context.sym) { \
ASSERT_EQ(sym##postfix.symbol, nullptr); \
ASSERT_EQ(sym##postfix.cif, nullptr); \
ASSERT_EQ(sym##postfix.backref, 0); \
} \
} while (0)
#define check_empty(postfix) \
do { \
check_sym_empty(postfix); \
check_hnd_empty(postfix); \
} while (0)
TEST(DLTest, InitAndFree) {
// use valgrind !
auto *context = (DLContext *)malloc(sizeof(DLContext));
ASSERT_NE(context, nullptr);
context->mem.malloc = malloc;
context->mem.free = free;
dl_init(context);
EXPECT_NE(context->symTable, nullptr);
for (auto &hnd : context->hnd) {
EXPECT_EQ(hnd.handle, nullptr);
}
for (auto &sym : context->sym) {
EXPECT_EQ(sym.symbol, nullptr);
EXPECT_EQ(sym.cif, nullptr);
EXPECT_EQ(sym.backref, 0);
}
dl_free(context);
free(context);
}
TEST(DLTest, OpenAndClose) {
init();
int handle = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
ASSERT_GT(handle, 0);
int result = dl_close(&exec_env, handle);
ASSERT_EQ(result, WRT_OK);
check_empty(0);
handle = dl_open(&exec_env, "not_exists", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR);
check_empty(1);
handle = dl_open(&exec_env, "", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR);
check_empty(2);
handle = dl_open(&exec_env, nullptr, RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR);
check_empty(3);
}
TEST(DLTest, ManyOpen) {
init();
int handles[DL_MAX_HANDLES];
for (int &handle : handles) {
handle = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
ASSERT_GT(handle, 0);
}
{
int handle = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR);
}
for (int handle : handles) {
int result = dl_close(&exec_env, handle);
ASSERT_EQ(result, WRT_OK);
}
check_empty(0);
}
TEST(DLTest, SignatureCheck) {
typedef struct {
const char *test;
bool result;
int arg_count;
bool has_ret;
} Case;
const static Case cases[] = {
{"", false, 0, false}, {"()", true, 0, false}, {"(i)", true, 1, false},
{"()i", true, 0, true}, {"(x)", false, 0, false}, {"()x", false, 0, false},
{"(i)f", true, 1, true}, {"(i)x", false, 0, false}, {"(x)f", false, 0, false},
{"i", false, 0, false}, {"i()", false, 0, false}, {"i(i)", false, 0, false},
{"(i)()", false, 0, false}, {"(ii", false, 0, false}, {"(iiffdd)l", true, 6, true},
{"(ffddii)ll", false, 0, false}, {"()ii", false, 0, false}, {"(i", false, 0, false},
{"(i(i))i", false, 0, false}, {"i)i", false, 0, false}, {"((i)i", false, 0, false},
{"(i))i", false, 0, false}, {"())", false, 0, false}};
for (const auto &cur_case : cases) {
int arg_count = 0;
bool has_ret = false;
bool ok = signature_check(cur_case.test, &arg_count, &has_ret);
EXPECT_EQ(ok, cur_case.result);
if (ok) {
EXPECT_EQ(arg_count, cur_case.arg_count);
EXPECT_EQ(has_ret, cur_case.has_ret);
}
}
}
TEST(DLTest, GetCloseSym) {
init();
int hnd = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
{
int sym = dl_sym(&exec_env, hnd, "fib_fast", "(i)i");
check_symbol_consistency(sym, 0);
}
{
int sym = dl_sym(&exec_env, hnd, "fib_fast", "(v)i");
ASSERT_EQ(sym, WRT_ERROR);
}
{
dl_close_sym(&exec_env, hnd, 1);
check_sym_empty(0);
}
dl_close(&exec_env, hnd);
check_empty(0);
}