feat: dl functions with context

This commit is contained in:
Paul Pan 2023-02-07 15:06:40 +08:00
parent c430e73549
commit 55d7e94a52
9 changed files with 257 additions and 89 deletions

View File

@ -4,7 +4,15 @@ project(wrt)
set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.")
add_definitions(-DWRT_DEBUG=4)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DWRT_DEBUG=4)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -fsanitize=address,undefined -fno-sanitize=alignment")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined -fno-sanitize=alignment")
else ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
endif ()
# math # math
find_library(M_LIBRARY m) find_library(M_LIBRARY m)

View File

@ -4,9 +4,21 @@
extern "C" { extern "C" {
#include "utils/defs.h" #include "utils/defs.h"
#include "wrt/dl.h" #include "wrt/dl.h"
#include "wasm_exec_env.h"
extern DLContext dl_context; extern bool signature_check(const char *signature, int *arg_count, bool *has_ret);
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) \ #define check_symbol_consistency(sym, postfix) \
@ -22,11 +34,15 @@ extern bool signature_check(const char *signature, int *arg_count, bool *ha
ASSERT_NE(dl_context.hnd[ref##postfix - 1].handle, nullptr); \ ASSERT_NE(dl_context.hnd[ref##postfix - 1].handle, nullptr); \
} while (0) } while (0)
#define check_empty(postfix) \ #define check_hnd_empty(postfix) \
do { \ do { \
for (auto &hnd##postfix : dl_context.hnd) { \ for (auto &hnd##postfix : dl_context.hnd) { \
ASSERT_EQ(hnd##postfix.handle, nullptr); \ ASSERT_EQ(hnd##postfix.handle, nullptr); \
} \ } \
} while (0)
#define check_sym_empty(postfix) \
do { \
for (auto &sym##postfix : dl_context.sym) { \ for (auto &sym##postfix : dl_context.sym) { \
ASSERT_EQ(sym##postfix.symbol, nullptr); \ ASSERT_EQ(sym##postfix.symbol, nullptr); \
ASSERT_EQ(sym##postfix.cif, nullptr); \ ASSERT_EQ(sym##postfix.cif, nullptr); \
@ -34,44 +50,72 @@ extern bool signature_check(const char *signature, int *arg_count, bool *ha
} \ } \
} while (0) } while (0)
TEST(DLTest, OpenAndClose) { #define check_empty(postfix) \
dl_init(); do { \
check_sym_empty(postfix); \
check_hnd_empty(postfix); \
} while (0)
int handle = dl_open(nullptr, "./SimpleLib.so", RTLD_LAZY); 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); ASSERT_GT(handle, 0);
int result = dl_close(nullptr, handle); int result = dl_close(&exec_env, handle);
ASSERT_EQ(result, WRT_OK); ASSERT_EQ(result, WRT_OK);
check_empty(0); check_empty(0);
handle = dl_open(nullptr, "not_exists", RTLD_LAZY); handle = dl_open(&exec_env, "not_exists", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR); ASSERT_EQ(handle, WRT_ERROR);
check_empty(1); check_empty(1);
handle = dl_open(nullptr, "", RTLD_LAZY); handle = dl_open(&exec_env, "", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR); ASSERT_EQ(handle, WRT_ERROR);
check_empty(2); check_empty(2);
handle = dl_open(nullptr, nullptr, RTLD_LAZY); handle = dl_open(&exec_env, nullptr, RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR); ASSERT_EQ(handle, WRT_ERROR);
check_empty(3); check_empty(3);
} }
TEST(DLTest, ManyOpen) { TEST(DLTest, ManyOpen) {
dl_init(); init();
int handles[DL_MAX_HANDLES]; int handles[DL_MAX_HANDLES];
for (int &handle : handles) { for (int &handle : handles) {
handle = dl_open(nullptr, "./SimpleLib.so", RTLD_LAZY); handle = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
ASSERT_GT(handle, 0); ASSERT_GT(handle, 0);
} }
{ {
int handle = dl_open(nullptr, "./SimpleLib.so", RTLD_LAZY); int handle = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
ASSERT_EQ(handle, WRT_ERROR); ASSERT_EQ(handle, WRT_ERROR);
} }
for (int handle : handles) { for (int handle : handles) {
int result = dl_close(nullptr, handle); int result = dl_close(&exec_env, handle);
ASSERT_EQ(result, WRT_OK); ASSERT_EQ(result, WRT_OK);
} }
@ -109,20 +153,25 @@ TEST(DLTest, SignatureCheck) {
} }
} }
TEST(DLTest, GetSym) { TEST(DLTest, GetCloseSym) {
dl_init(); init();
int hnd = dl_open(nullptr, "./SimpleLib.so", RTLD_LAZY); int hnd = dl_open(&exec_env, "./SimpleLib.so", RTLD_LAZY);
{ {
int sym = dl_sym(nullptr, hnd, "fib_fast", "(i)i"); int sym = dl_sym(&exec_env, hnd, "fib_fast", "(i)i");
check_symbol_consistency(sym, 0); check_symbol_consistency(sym, 0);
} }
{ {
int sym = dl_sym(nullptr, hnd, "fib_fast", "(v)i"); int sym = dl_sym(&exec_env, hnd, "fib_fast", "(v)i");
ASSERT_EQ(sym, WRT_ERROR); ASSERT_EQ(sym, WRT_ERROR);
} }
dl_close(nullptr, hnd); {
dl_close_sym(&exec_env, hnd, 1);
check_sym_empty(0);
}
dl_close(&exec_env, hnd);
check_empty(0); check_empty(0);
} }

14
tests/wasm/dl.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef WRT_DL_H
#define WRT_DL_H
typedef enum {
WRT_OK = 0,
WRT_ERROR = -1,
} Status;
int dl_open(const char *filename, int flags);
int dl_sym(int handle, const char *symbol, const char *signature);
Status dl_close_sym(int handle, int symbol);
Status dl_close(int handle);
#endif // WRT_DL_H

View File

@ -1,13 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include "dl.h"
typedef enum {
WRT_OK = 0,
WRT_ERROR = -1,
} Status;
int dl_open(const char *filename, int flags);
int dl_sym(int handle, const char *symbol, const char *signature);
Status dl_close(int handle);
unsigned fib(unsigned n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); } unsigned fib(unsigned n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); }
@ -18,6 +10,8 @@ void entry() {
printf("hnd = %d\n", hnd); printf("hnd = %d\n", hnd);
int fib_iterate_sym = dl_sym(hnd, "fib_iterate", "(i)i"); int fib_iterate_sym = dl_sym(hnd, "fib_iterate", "(i)i");
printf("fib_iterate_sym = %d\n", fib_iterate_sym); printf("fib_iterate_sym = %d\n", fib_iterate_sym);
Status status = dl_close(hnd); Status status = dl_close_sym(hnd, fib_iterate_sym);
printf("status = %d\n", status); printf("close sym status = %d\n", status);
status = dl_close(hnd);
printf("close lib status = %d\n", status);
} }

View File

@ -1,32 +1,53 @@
#ifndef WRT_LOG_H #ifndef WRT_LOG_H
#define WRT_LOG_H #define WRT_LOG_H
#if WRT_DEBUG #if WRT_DEBUG > 0
#include <stdio.h> #include <stdio.h>
#define __COLOR_RED "\x1B[1;31m" #define _COLOR_RED "\x1B[1;31m"
#define __COLOR_YELLOW "\x1B[1;33m" #define _COLOR_YELLOW "\x1B[1;33m"
#define __COLOR_GREEN "\x1B[1;32m" #define _COLOR_GREEN "\x1B[1;32m"
#define __COLOR_CYAN "\x1B[1;36m" #define _COLOR_CYAN "\x1B[1;36m"
#define __COLOR_RESET "\x1B[0m" #define _COLOR_RESET "\x1B[0m"
#define _LOG(color, level, fmt, ...) \ #define _LOG(color, level, fmt, ...) \
do { \ do { \
fprintf(stdout, color "[" level "] (%s:%d): " fmt __COLOR_RESET "\n", __FILE__, \ fprintf(stdout, color "[" level "] (%s:%d): " fmt _COLOR_RESET "\n", __FILE__, \
__LINE__, ##__VA_ARGS__); \ __LINE__, ##__VA_ARGS__); \
} while (0) } while (0)
#define LOG_ERR(fmt, ...) _LOG(__COLOR_RED, "E", fmt, ##__VA_ARGS__) #define LOG_ERR(fmt, ...) _LOG(_COLOR_RED, "E", fmt, ##__VA_ARGS__)
#define LOG_WARN(fmt, ...) _LOG(__COLOR_YELLOW, "W", fmt, ##__VA_ARGS__) #define LOG_WARN(fmt, ...) _LOG(_COLOR_YELLOW, "W", fmt, ##__VA_ARGS__)
#define LOG_INFO(fmt, ...) _LOG(__COLOR_GREEN, "I", fmt, ##__VA_ARGS__) #define LOG_INFO(fmt, ...) _LOG(_COLOR_GREEN, "I", fmt, ##__VA_ARGS__)
#define LOG_DBG(fmt, ...) _LOG(__COLOR_CYAN, "D", fmt, ##__VA_ARGS__) #define LOG_DBG(fmt, ...) _LOG(_COLOR_CYAN, "D", fmt, ##__VA_ARGS__)
#else #if WRT_DEBUG == 1
#define LOG_ERR(fmt, ...) #undef LOG_DBG
#define LOG_WARN(fmt, ...) #undef LOG_INFO
#define LOG_INFO(fmt, ...) #undef LOG_WARN
#define LOG_DBG(fmt, ...) #elif WRT_DEBUG == 2
#undef LOG_DBG
#undef LOG_INFO
#elif WRT_DEBUG == 3
#undef LOG_DBG
#endif
#endif #endif
#ifndef LOG_ERR
#define LOG_ERR(fmt, ...)
#endif
#ifndef LOG_WARN
#define LOG_WARN(fmt, ...)
#endif
#ifndef LOG_INFO
#define LOG_INFO(fmt, ...)
#endif
#ifndef LOG_DBG
#define LOG_DBG(fmt, ...)
#endif
#endif // WRT_LOG_H #endif // WRT_LOG_H

117
wrt/dl.c
View File

@ -5,22 +5,65 @@
#include "utils/log.h" #include "utils/log.h"
#include "wrt/dl.h" #include "wrt/dl.h"
DLContext dl_context = {0}; // TODO: Stateful context -> per WRTContext
Allocator dl_malloc = malloc;
DeAllocator dl_free = free;
#warning "TODO: Permission Check" #warning "TODO: Permission Check"
Status dl_init() { Status dl_init(DLContext *ctx) {
memset(&dl_context, 0, sizeof(DLContext)); memset(ctx->hnd, 0, sizeof(ctx->hnd));
memset(ctx->sym, 0, sizeof(ctx->sym));
ctx->symTable = ctx->mem.malloc(sizeof(NativeSymbol) * DL_SYM_TABLE_SIZE);
if (ctx->symTable == NULL) {
LOG_ERR("dl_init: malloc failed");
return WRT_ERROR;
}
#define EXPORT(i, sym, sig) \
do { \
ctx->symTable[i].symbol = #sym; \
ctx->symTable[i].func_ptr = (void *)sym; \
ctx->symTable[i].signature = sig; \
ctx->symTable[i].attachment = ctx; \
} while (0)
EXPORT(0, dl_open, "($i)i");
EXPORT(1, dl_sym, "(i$$)i");
EXPORT(2, dl_call, "(i)i");
EXPORT(3, dl_close_sym, "(ii)i");
EXPORT(4, dl_close, "(i)i");
#undef EXPORT
return WRT_OK; return WRT_OK;
} }
Status dl_free(DLContext *ctx) {
ctx->mem.free(ctx->symTable);
for (int i = 0; i < DL_MAX_SYMBOLS; i++) {
if (ctx->sym[i].symbol) {
ctx->mem.free(ctx->sym[i].cif->arg_types);
ctx->mem.free(ctx->sym[i].cif);
}
}
for (int i = 0; i < DL_MAX_HANDLES; i++) {
if (ctx->hnd[i].handle) {
dlclose(ctx->hnd[i].handle);
}
}
return WRT_OK;
}
#define GET_CONTEXT \
DLContext *ctx = wasm_runtime_get_function_attachment(exec_env); \
if (ctx == NULL) return WRT_ERROR;
int dl_open(wasm_exec_env_t exec_env, const char *filename, int flags) { int dl_open(wasm_exec_env_t exec_env, const char *filename, int flags) {
if (filename == NULL) return WRT_ERROR; if (filename == NULL) return WRT_ERROR;
if (filename[0] == '\0') return WRT_ERROR; if (filename[0] == '\0') return WRT_ERROR;
GET_CONTEXT
void *handle = dlopen(filename, flags); void *handle = dlopen(filename, flags);
if (handle == NULL) { if (handle == NULL) {
LOG_ERR("dlopen failed: %s", dlerror()); LOG_ERR("dlopen failed: %s", dlerror());
@ -28,8 +71,8 @@ int dl_open(wasm_exec_env_t exec_env, const char *filename, int flags) {
} }
for (int i = 0; i < DL_MAX_HANDLES; i++) { for (int i = 0; i < DL_MAX_HANDLES; i++) {
if (dl_context.hnd[i].handle == NULL) { if (ctx->hnd[i].handle == NULL) {
dl_context.hnd[i].handle = handle; ctx->hnd[i].handle = handle;
LOG_DBG("dl_open: lib = %s, flags = %d, handle = %d", filename, flags, i + 1); LOG_DBG("dl_open: lib = %s, flags = %d, handle = %d", filename, flags, i + 1);
return i + 1; return i + 1;
} }
@ -96,14 +139,14 @@ bool signature_check(const char *signature, int *arg_count, bool *has_ret) {
return true; return true;
} }
ffi_cif *create_ffi_cif(const char *signature) { ffi_cif *create_ffi_cif(DLContext *ctx, const char *signature) {
int arg_count; int arg_count;
bool has_ret; bool has_ret;
if (!signature_check(signature, &arg_count, &has_ret)) return NULL; if (!signature_check(signature, &arg_count, &has_ret)) return NULL;
ffi_cif *cif = dl_malloc(sizeof(ffi_cif)); ffi_cif *cif = ctx->mem.malloc(sizeof(ffi_cif));
ffi_type **arg_types = dl_malloc(sizeof(ffi_type *) * arg_count); ffi_type **arg_types = ctx->mem.malloc(sizeof(ffi_type *) * arg_count);
ffi_type *ret_type; ffi_type *ret_type;
const char *ch = signature + 1; const char *ch = signature + 1;
@ -151,8 +194,8 @@ ffi_cif *create_ffi_cif(const char *signature) {
return cif; return cif;
fail: fail:
dl_free(arg_types); ctx->mem.free(arg_types);
dl_free(cif); ctx->mem.free(cif);
return NULL; return NULL;
} }
@ -160,7 +203,9 @@ int dl_sym(wasm_exec_env_t exec_env, int handle, const char *symbol, const char
if (handle < 1 || handle > DL_MAX_HANDLES) return WRT_ERROR; if (handle < 1 || handle > DL_MAX_HANDLES) return WRT_ERROR;
if (symbol == NULL || signature == NULL) return WRT_ERROR; if (symbol == NULL || signature == NULL) return WRT_ERROR;
void *ptr = dl_context.hnd[handle - 1].handle; GET_CONTEXT
void *ptr = ctx->hnd[handle - 1].handle;
if (ptr == NULL) return WRT_ERROR; if (ptr == NULL) return WRT_ERROR;
void *sym = dlsym(ptr, symbol); void *sym = dlsym(ptr, symbol);
@ -169,14 +214,14 @@ int dl_sym(wasm_exec_env_t exec_env, int handle, const char *symbol, const char
return WRT_ERROR; return WRT_ERROR;
} }
ffi_cif *cif = create_ffi_cif(signature); ffi_cif *cif = create_ffi_cif(ctx, signature);
if (cif == NULL) return WRT_ERROR; if (cif == NULL) return WRT_ERROR;
for (int i = 0; i < DL_MAX_SYMBOLS; i++) { for (int i = 0; i < DL_MAX_SYMBOLS; i++) {
if (dl_context.sym[i].symbol == NULL) { if (ctx->sym[i].symbol == NULL) {
dl_context.sym[i].backref = handle; ctx->sym[i].backref = handle;
dl_context.sym[i].symbol = sym; ctx->sym[i].symbol = sym;
dl_context.sym[i].cif = cif; ctx->sym[i].cif = cif;
LOG_DBG("dl_sym: lib_hnd = %d, sym = %s, sym_id = %d", handle, symbol, i + 1); LOG_DBG("dl_sym: lib_hnd = %d, sym = %s, sym_id = %d", handle, symbol, i + 1);
return i + 1; return i + 1;
} }
@ -218,21 +263,41 @@ void dl_call(wasm_exec_env_t exec_env) {
// } // }
} }
Status dl_close_sym(wasm_exec_env_t exec_env, int handle, int symbol) {
if (handle < 1 || handle > DL_MAX_HANDLES) return WRT_ERROR;
if (symbol < 1 || symbol > DL_MAX_SYMBOLS) return WRT_ERROR;
GET_CONTEXT
void *sym = ctx->sym[symbol - 1].symbol;
if (sym == NULL) return WRT_ERROR;
ctx->mem.free(ctx->sym[symbol - 1].cif->arg_types);
ctx->mem.free(ctx->sym[symbol - 1].cif);
ctx->sym[symbol - 1].cif = NULL;
ctx->sym[symbol - 1].backref = 0;
ctx->sym[symbol - 1].symbol = NULL;
return WRT_OK;
}
Status dl_close(wasm_exec_env_t exec_env, int handle) { Status dl_close(wasm_exec_env_t exec_env, int handle) {
if (handle < 1 || handle > DL_MAX_HANDLES) return WRT_ERROR; if (handle < 1 || handle > DL_MAX_HANDLES) return WRT_ERROR;
void *ptr = dl_context.hnd[handle - 1].handle; GET_CONTEXT
void *ptr = ctx->hnd[handle - 1].handle;
if (ptr == NULL) return WRT_ERROR; if (ptr == NULL) return WRT_ERROR;
dl_context.hnd[handle - 1].handle = NULL; ctx->hnd[handle - 1].handle = NULL;
for (int i = 0; i < DL_MAX_SYMBOLS; i++) { for (int i = 0; i < DL_MAX_SYMBOLS; i++) {
if (dl_context.sym[i].backref == handle) { if (ctx->sym[i].backref == handle) {
dl_context.sym[i].backref = 0; ctx->sym[i].backref = 0;
dl_context.sym[i].symbol = NULL; ctx->sym[i].symbol = NULL;
dl_free(dl_context.sym[i].cif->arg_types); ctx->mem.free(ctx->sym[i].cif->arg_types);
dl_free(dl_context.sym[i].cif); ctx->mem.free(ctx->sym[i].cif);
dl_context.sym[i].cif = NULL; ctx->sym[i].cif = NULL;
LOG_DBG("dl_close: destroy sym_id = %d", i + 1); LOG_DBG("dl_close: destroy sym_id = %d", i + 1);
} }

View File

@ -7,7 +7,14 @@
#include "utils/defs.h" #include "utils/defs.h"
#define DL_SYM_TABLE_SIZE 5
typedef struct { typedef struct {
struct {
Allocator malloc;
DeAllocator free;
} mem;
NativeSymbol *symTable;
struct { struct {
void *handle; void *handle;
} hnd[DL_MAX_HANDLES]; } hnd[DL_MAX_HANDLES];
@ -18,10 +25,12 @@ typedef struct {
} sym[DL_MAX_SYMBOLS]; } sym[DL_MAX_SYMBOLS];
} DLContext; } DLContext;
Status dl_init(); Status dl_init(DLContext *context);
Status dl_free(DLContext *context);
int dl_open(wasm_exec_env_t exec_env, const char *filename, int flags); int dl_open(wasm_exec_env_t exec_env, const char *filename, int flags);
int dl_sym(wasm_exec_env_t exec_env, int handle, const char *symbol, const char *signature); int dl_sym(wasm_exec_env_t exec_env, int handle, const char *symbol, const char *signature);
void dl_call(wasm_exec_env_t exec_env); // TODO void dl_call(wasm_exec_env_t exec_env); // TODO
Status dl_close_sym(wasm_exec_env_t exec_env, int handle, int symbol);
Status dl_close(wasm_exec_env_t exec_env, int handle); Status dl_close(wasm_exec_env_t exec_env, int handle);
#endif // WRT_DL_H #endif // WRT_DL_H

View File

@ -48,6 +48,12 @@ Status wrt_program_init(WRTContext *context, uint8_t *wasm_buffer, uint32_t wasm
context->program.native_symbols = native_symbols; context->program.native_symbols = native_symbols;
context->program.native_symbols_size = native_symbols_size; context->program.native_symbols_size = native_symbols_size;
// init dl
context->program.dl = context->platform.malloc(sizeof(DLContext));
context->program.dl->mem.malloc = context->platform.malloc;
context->program.dl->mem.free = context->platform.free;
dl_init(context->program.dl);
return WRT_OK; return WRT_OK;
} }
@ -72,18 +78,12 @@ Status wrt_wamr_init(WRTContext *context, char *entry_func, uint32_t stack_size,
return WRT_ERROR; return WRT_ERROR;
} }
// init dl
dl_init();
// register dl functions // register dl functions
static NativeSymbol native_symbols[] = { wasm_runtime_register_natives("env", context->program.dl->symTable, DL_SYM_TABLE_SIZE);
EXPORT_WASM_API_WITH_SIG(dl_open, "($i)i"),
EXPORT_WASM_API_WITH_SIG(dl_sym, "(i$$)i"), // register native symbols
EXPORT_WASM_API_WITH_SIG(dl_call, "(i)i"), // TODO wasm_runtime_register_natives("env", context->program.native_symbols,
EXPORT_WASM_API_WITH_SIG(dl_close, "(i)i"), context->program.native_symbols_size);
};
wasm_runtime_register_natives("env", native_symbols,
sizeof(native_symbols) / sizeof(NativeSymbol));
// load module // load module
context->wamr.module = context->wamr.module =
@ -131,6 +131,7 @@ fail:
} }
Status wrt_free(WRTContext *context) { Status wrt_free(WRTContext *context) {
// wamr
if (context->wamr.exec_env) { if (context->wamr.exec_env) {
wasm_runtime_destroy_exec_env(context->wamr.exec_env); wasm_runtime_destroy_exec_env(context->wamr.exec_env);
context->wamr.exec_env = NULL; context->wamr.exec_env = NULL;
@ -148,11 +149,17 @@ Status wrt_free(WRTContext *context) {
wasm_runtime_destroy(); wasm_runtime_destroy();
// mem
context->platform.free(context->mem.error_buf); context->platform.free(context->mem.error_buf);
context->mem.error_buf_size = 0; context->mem.error_buf_size = 0;
context->platform.free(context->mem.heap_buf); context->platform.free(context->mem.heap_buf);
context->mem.heap_buf_size = 0; context->mem.heap_buf_size = 0;
// program
dl_free(context->program.dl);
context->platform.free(context->program.dl);
context->program.dl = NULL;
return WRT_OK; return WRT_OK;
} }

View File

@ -28,6 +28,7 @@ typedef struct {
uint32_t wasm_buffer_size; uint32_t wasm_buffer_size;
NativeSymbol *native_symbols; NativeSymbol *native_symbols;
uint32_t native_symbols_size; uint32_t native_symbols_size;
DLContext *dl;
} program; } program;
} WRTContext; } WRTContext;