mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
Implement wasm-c-api frame/trap APIs for interpreter mode (#660)
And enable to cache compiled AOT file buffer for wasm-c-api JIT mode Avoid checks that rely on undefined C behavior Fix issues of wasm-c-api sample trap and callback_chain Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
parent
d91047cc37
commit
b554a9d05d
|
@ -1896,7 +1896,7 @@ aot_validate_app_addr(AOTModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* integer overflow check */
|
/* integer overflow check */
|
||||||
if(app_offset + size < app_offset) {
|
if(app_offset > UINT32_MAX - size) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1920,7 +1920,7 @@ aot_validate_native_addr(AOTModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* integer overflow check */
|
/* integer overflow check */
|
||||||
if (addr + size < addr) {
|
if ((uintptr_t)addr > UINTPTR_MAX - size) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -189,7 +189,7 @@ failed: \
|
||||||
size_t i = 0; \
|
size_t i = 0; \
|
||||||
memset(out, 0, sizeof(Vector)); \
|
memset(out, 0, sizeof(Vector)); \
|
||||||
\
|
\
|
||||||
if (!src->size) { \
|
if (!src || !src->size) { \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
@ -232,6 +232,7 @@ WASM_DEFINE_VEC_OWN(store, wasm_store_delete)
|
||||||
WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal)
|
WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal)
|
||||||
WASM_DEFINE_VEC_OWN(instance, wasm_instance_delete_internal)
|
WASM_DEFINE_VEC_OWN(instance, wasm_instance_delete_internal)
|
||||||
WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete)
|
WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete)
|
||||||
|
WASM_DEFINE_VEC_OWN(frame, wasm_frame_delete)
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
valid_module_type(uint32 module_type)
|
valid_module_type(uint32 module_type)
|
||||||
|
@ -255,6 +256,21 @@ valid_module_type(uint32 module_type)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* conflicting declaration between aot_export.h and aot.h */
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||||
|
bool
|
||||||
|
aot_compile_wasm_file_init();
|
||||||
|
|
||||||
|
void
|
||||||
|
aot_compile_wasm_file_destroy();
|
||||||
|
|
||||||
|
uint8*
|
||||||
|
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
|
uint32 opt_level, uint32 size_level,
|
||||||
|
char *error_buf, uint32 error_buf_size,
|
||||||
|
uint32 *p_aot_file_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Runtime Environment */
|
/* Runtime Environment */
|
||||||
static void
|
static void
|
||||||
wasm_engine_delete_internal(wasm_engine_t *engine)
|
wasm_engine_delete_internal(wasm_engine_t *engine)
|
||||||
|
@ -264,6 +280,10 @@ wasm_engine_delete_internal(wasm_engine_t *engine)
|
||||||
wasm_runtime_free(engine);
|
wasm_runtime_free(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||||
|
aot_compile_wasm_file_destroy();
|
||||||
|
#endif
|
||||||
|
|
||||||
wasm_runtime_destroy();
|
wasm_runtime_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,6 +331,12 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
|
||||||
bh_log_set_verbose_level(3);
|
bh_log_set_verbose_level(3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||||
|
if (!aot_compile_wasm_file_init()) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* create wasm_engine_t */
|
/* create wasm_engine_t */
|
||||||
if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) {
|
if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) {
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -1289,10 +1315,106 @@ wasm_val_same(const wasm_val_t *v1, const wasm_val_t *v2)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static wasm_frame_t *
|
||||||
|
wasm_frame_new(wasm_instance_t *instance,
|
||||||
|
size_t module_offset,
|
||||||
|
uint32 func_index,
|
||||||
|
size_t func_offset)
|
||||||
|
{
|
||||||
|
wasm_frame_t *frame;
|
||||||
|
|
||||||
|
if (!(frame = malloc_internal(sizeof(wasm_frame_t)))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->instance = instance;
|
||||||
|
frame->module_offset = module_offset;
|
||||||
|
frame->func_index = func_index;
|
||||||
|
frame->func_offset = func_offset;
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
own wasm_frame_t *
|
||||||
|
wasm_frame_copy(const wasm_frame_t *src)
|
||||||
|
{
|
||||||
|
if (!src) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wasm_frame_new(src->instance, src->module_offset, src->func_index,
|
||||||
|
src->func_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_frame_delete(own wasm_frame_t *frame)
|
||||||
|
{
|
||||||
|
if (!frame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_runtime_free(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wasm_instance_t *
|
||||||
|
wasm_frame_instance(const wasm_frame_t *frame)
|
||||||
|
{
|
||||||
|
return frame ? frame->instance : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
wasm_frame_module_offset(const wasm_frame_t *frame)
|
||||||
|
{
|
||||||
|
return frame ? frame->module_offset : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
wasm_frame_func_index(const wasm_frame_t *frame)
|
||||||
|
{
|
||||||
|
return frame ? frame->func_index : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
wasm_frame_func_offset(const wasm_frame_t *frame)
|
||||||
|
{
|
||||||
|
return frame ? frame->func_offset : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static wasm_trap_t *
|
static wasm_trap_t *
|
||||||
wasm_trap_new_internal(const char *string)
|
wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt,
|
||||||
|
const char *default_error_info)
|
||||||
{
|
{
|
||||||
wasm_trap_t *trap;
|
wasm_trap_t *trap;
|
||||||
|
const char *error_info = NULL;
|
||||||
|
wasm_instance_vec_t *instances;
|
||||||
|
wasm_instance_t *frame_instance = NULL;
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
if (!singleton_engine || !singleton_engine->stores
|
||||||
|
|| !singleton_engine->stores->num_elems) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
||||||
|
if (!(error_info =
|
||||||
|
wasm_get_exception((WASMModuleInstance *)inst_comm_rt))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_AOT != 0
|
||||||
|
if (inst_comm_rt->module_type == Wasm_Module_AoT) {
|
||||||
|
if (!(error_info =
|
||||||
|
aot_get_exception((AOTModuleInstance *)inst_comm_rt))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!error_info && !(error_info = default_error_info)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) {
|
if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1302,11 +1424,39 @@ wasm_trap_new_internal(const char *string)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_name_new_from_string(trap->message, string);
|
wasm_name_new_from_string_nt(trap->message, error_info);
|
||||||
if (strlen(string) && !trap->message->data) {
|
if (strlen(error_info) && !trap->message->data) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||||
|
#if WASM_ENABLE_INTERP != 0
|
||||||
|
if (inst_comm_rt->module_type == Wasm_Module_Bytecode) {
|
||||||
|
trap->frames = ((WASMModuleInstance *)inst_comm_rt)->frames;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */
|
||||||
|
|
||||||
|
/* allow a NULL frames list */
|
||||||
|
if (!trap->frames) {
|
||||||
|
return trap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(instances = singleton_engine->stores->data[0]->instances)) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < instances->num_elems; i++) {
|
||||||
|
if (instances->data[i]->inst_comm_rt == inst_comm_rt) {
|
||||||
|
frame_instance = instances->data[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < trap->frames->num_elems; i++) {
|
||||||
|
(((wasm_frame_t *)trap->frames->data) + i)->instance = frame_instance;
|
||||||
|
}
|
||||||
|
|
||||||
return trap;
|
return trap;
|
||||||
failed:
|
failed:
|
||||||
wasm_trap_delete(trap);
|
wasm_trap_delete(trap);
|
||||||
|
@ -1342,6 +1492,7 @@ wasm_trap_delete(wasm_trap_t *trap)
|
||||||
}
|
}
|
||||||
|
|
||||||
DEINIT_VEC(trap->message, wasm_byte_vec_delete);
|
DEINIT_VEC(trap->message, wasm_byte_vec_delete);
|
||||||
|
/* reuse frames of WASMModuleInstance, do not free it here */
|
||||||
|
|
||||||
wasm_runtime_free(trap);
|
wasm_runtime_free(trap);
|
||||||
}
|
}
|
||||||
|
@ -1356,6 +1507,65 @@ wasm_trap_message(const wasm_trap_t *trap, own wasm_message_t *out)
|
||||||
wasm_byte_vec_copy(out, trap->message);
|
wasm_byte_vec_copy(out, trap->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
own wasm_frame_t *
|
||||||
|
wasm_trap_origin(const wasm_trap_t *trap)
|
||||||
|
{
|
||||||
|
wasm_frame_t *latest_frame;
|
||||||
|
|
||||||
|
if (!trap || !trap->frames || !trap->frames->num_elems) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* first frame is the latest frame */
|
||||||
|
latest_frame = (wasm_frame_t *)trap->frames->data;
|
||||||
|
return wasm_frame_copy(latest_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wasm_trap_trace(const wasm_trap_t *trap, own wasm_frame_vec_t *out)
|
||||||
|
{
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
|
if (!trap || !out) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!trap->frames || !trap->frames->num_elems) {
|
||||||
|
wasm_frame_vec_new_empty(out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_frame_vec_new_uninitialized(out, trap->frames->num_elems);
|
||||||
|
if (out->size && !out->data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < trap->frames->num_elems; i++) {
|
||||||
|
wasm_frame_t *frame;
|
||||||
|
|
||||||
|
frame = ((wasm_frame_t *)trap->frames->data) + i;
|
||||||
|
|
||||||
|
if (!(out->data[i] =
|
||||||
|
wasm_frame_new(frame->instance, frame->module_offset,
|
||||||
|
frame->func_index, frame->func_offset))) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
out->num_elems++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
failed:
|
||||||
|
for (i = 0; i < out->num_elems; i++) {
|
||||||
|
if (out->data[i]) {
|
||||||
|
wasm_runtime_free(out->data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out->data) {
|
||||||
|
wasm_runtime_free(out->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct wasm_module_ex_t {
|
struct wasm_module_ex_t {
|
||||||
struct WASMModuleCommon *module_comm_rt;
|
struct WASMModuleCommon *module_comm_rt;
|
||||||
wasm_byte_vec_t *binary;
|
wasm_byte_vec_t *binary;
|
||||||
|
@ -1386,6 +1596,10 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
||||||
{
|
{
|
||||||
char error_buf[128] = { 0 };
|
char error_buf[128] = { 0 };
|
||||||
wasm_module_ex_t *module_ex = NULL;
|
wasm_module_ex_t *module_ex = NULL;
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||||
|
uint8 *aot_file_buf = NULL;
|
||||||
|
uint32 aot_file_size;
|
||||||
|
#endif
|
||||||
|
|
||||||
bh_assert(singleton_engine);
|
bh_assert(singleton_engine);
|
||||||
|
|
||||||
|
@ -1401,6 +1615,28 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
||||||
|
|
||||||
INIT_VEC(module_ex->binary, wasm_byte_vec_new, binary->size, binary->data);
|
INIT_VEC(module_ex->binary, wasm_byte_vec_new, binary->size, binary->data);
|
||||||
|
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
|
||||||
|
if (get_package_type((uint8 *)module_ex->binary->data,
|
||||||
|
(uint32)module_ex->binary->size)
|
||||||
|
== Wasm_Module_Bytecode) {
|
||||||
|
if (!(aot_file_buf = aot_compile_wasm_file(
|
||||||
|
(uint8 *)module_ex->binary->data,
|
||||||
|
(uint32)module_ex->binary->size, 3, 3, error_buf,
|
||||||
|
(uint32)sizeof(error_buf), &aot_file_size))) {
|
||||||
|
LOG_ERROR(error_buf);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(module_ex->module_comm_rt =
|
||||||
|
wasm_runtime_load(aot_file_buf, aot_file_size, error_buf,
|
||||||
|
(uint32)sizeof(error_buf)))) {
|
||||||
|
LOG_ERROR(error_buf);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
module_ex->module_comm_rt = wasm_runtime_load(
|
module_ex->module_comm_rt = wasm_runtime_load(
|
||||||
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
|
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
|
||||||
error_buf, (uint32)sizeof(error_buf));
|
error_buf, (uint32)sizeof(error_buf));
|
||||||
|
@ -1408,6 +1644,7 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
|
||||||
LOG_ERROR(error_buf);
|
LOG_ERROR(error_buf);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* add it to a watching list in store */
|
/* add it to a watching list in store */
|
||||||
if (!bh_vector_append((Vector *)store->modules, &module_ex)) {
|
if (!bh_vector_append((Vector *)store->modules, &module_ex)) {
|
||||||
|
@ -2255,12 +2492,13 @@ failed:
|
||||||
if (argv != argv_buf)
|
if (argv != argv_buf)
|
||||||
wasm_runtime_free(argv);
|
wasm_runtime_free(argv);
|
||||||
|
|
||||||
|
/* trap -> exception -> trap */
|
||||||
if (wasm_runtime_get_exception(func->inst_comm_rt)) {
|
if (wasm_runtime_get_exception(func->inst_comm_rt)) {
|
||||||
return wasm_trap_new_internal(
|
return wasm_trap_new_internal(func->inst_comm_rt, NULL);
|
||||||
wasm_runtime_get_exception(func->inst_comm_rt));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return wasm_trap_new_internal("wasm_func_call failed");
|
return wasm_trap_new_internal(func->inst_comm_rt,
|
||||||
|
"wasm_func_call failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3446,8 +3684,8 @@ wasm_instance_new(wasm_store_t *store,
|
||||||
own wasm_trap_t **traps)
|
own wasm_trap_t **traps)
|
||||||
{
|
{
|
||||||
char error_buf[128] = { 0 };
|
char error_buf[128] = { 0 };
|
||||||
const uint32 stack_size = 16 * 1024;
|
const uint32 stack_size = 32 * 1024;
|
||||||
const uint32 heap_size = 16 * 1024;
|
const uint32 heap_size = 32 * 1024;
|
||||||
uint32 import_count = 0;
|
uint32 import_count = 0;
|
||||||
wasm_instance_t *instance = NULL;
|
wasm_instance_t *instance = NULL;
|
||||||
uint32 i = 0;
|
uint32 i = 0;
|
||||||
|
|
|
@ -86,8 +86,16 @@ struct wasm_ref_t {
|
||||||
uint32 obj;
|
uint32 obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wasm_frame_t {
|
||||||
|
wasm_instance_t *instance;
|
||||||
|
uint32 module_offset;
|
||||||
|
uint32 func_index;
|
||||||
|
uint32 func_offset;
|
||||||
|
};
|
||||||
|
|
||||||
struct wasm_trap_t {
|
struct wasm_trap_t {
|
||||||
wasm_byte_vec_t *message;
|
wasm_byte_vec_t *message;
|
||||||
|
Vector *frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_func_t {
|
struct wasm_func_t {
|
||||||
|
|
|
@ -2135,19 +2135,82 @@ extern void
|
||||||
wasm_set_ref_types_flag(bool enable);
|
wasm_set_ref_types_flag(bool enable);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct AOTFileMap {
|
||||||
|
uint8 *wasm_file_buf;
|
||||||
|
uint32 wasm_file_size;
|
||||||
|
uint8 *aot_file_buf;
|
||||||
|
uint32 aot_file_size;
|
||||||
|
struct AOTFileMap *next;
|
||||||
|
} AOTFileMap;
|
||||||
|
|
||||||
|
static bool aot_compile_wasm_file_inited = false;
|
||||||
|
static AOTFileMap *aot_file_maps = NULL;
|
||||||
|
static korp_mutex aot_file_map_lock;
|
||||||
|
|
||||||
|
bool
|
||||||
|
aot_compile_wasm_file_init()
|
||||||
|
{
|
||||||
|
if (aot_compile_wasm_file_inited) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BHT_OK != os_mutex_init(&aot_file_map_lock)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aot_file_maps = NULL;
|
||||||
|
aot_compile_wasm_file_inited = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
aot_compile_wasm_file_destroy()
|
||||||
|
{
|
||||||
|
AOTFileMap *file_map = aot_file_maps, *file_map_next;
|
||||||
|
|
||||||
|
if (!aot_compile_wasm_file_inited) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (file_map) {
|
||||||
|
file_map_next = file_map->next;
|
||||||
|
|
||||||
|
wasm_runtime_free(file_map->wasm_file_buf);
|
||||||
|
wasm_runtime_free(file_map->aot_file_buf);
|
||||||
|
wasm_runtime_free(file_map);
|
||||||
|
|
||||||
|
file_map = file_map_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
aot_file_maps = NULL;
|
||||||
|
os_mutex_destroy(&aot_file_map_lock);
|
||||||
|
aot_compile_wasm_file_inited = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
|
||||||
|
{
|
||||||
|
if (error_buf != NULL) {
|
||||||
|
snprintf(error_buf, error_buf_size,
|
||||||
|
"WASM module load failed: %s", string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8*
|
uint8*
|
||||||
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
uint32 opt_level, uint32 size_level,
|
uint32 opt_level, uint32 size_level,
|
||||||
|
char *error_buf, uint32 error_buf_size,
|
||||||
uint32 *p_aot_file_size)
|
uint32 *p_aot_file_size)
|
||||||
{
|
{
|
||||||
WASMModuleCommon *wasm_module = NULL;
|
WASMModule *wasm_module = NULL;
|
||||||
AOTCompData *comp_data = NULL;
|
AOTCompData *comp_data = NULL;
|
||||||
AOTCompContext *comp_ctx = NULL;
|
AOTCompContext *comp_ctx = NULL;
|
||||||
RuntimeInitArgs init_args;
|
RuntimeInitArgs init_args;
|
||||||
AOTCompOption option = { 0 };
|
AOTCompOption option = { 0 };
|
||||||
|
AOTFileMap *file_map = NULL, *file_map_next;
|
||||||
|
uint8 *wasm_file_buf_cloned = NULL;
|
||||||
uint8 *aot_file_buf = NULL;
|
uint8 *aot_file_buf = NULL;
|
||||||
uint32 aot_file_size;
|
uint32 aot_file_size;
|
||||||
char error_buf[128];
|
|
||||||
|
|
||||||
option.is_jit_mode = false;
|
option.is_jit_mode = false;
|
||||||
option.opt_level = opt_level;
|
option.opt_level = opt_level;
|
||||||
|
@ -2155,7 +2218,6 @@ aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
option.output_format = AOT_FORMAT_FILE;
|
option.output_format = AOT_FORMAT_FILE;
|
||||||
/* default value, enable or disable depends on the platform */
|
/* default value, enable or disable depends on the platform */
|
||||||
option.bounds_checks = 2;
|
option.bounds_checks = 2;
|
||||||
option.enable_simd = true;
|
|
||||||
option.enable_aux_stack_check = true;
|
option.enable_aux_stack_check = true;
|
||||||
#if WASM_ENABLE_BULK_MEMORY != 0
|
#if WASM_ENABLE_BULK_MEMORY != 0
|
||||||
option.enable_bulk_memory = true;
|
option.enable_bulk_memory = true;
|
||||||
|
@ -2187,46 +2249,94 @@ aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
init_args.mem_alloc_option.allocator.realloc_func = realloc;
|
init_args.mem_alloc_option.allocator.realloc_func = realloc;
|
||||||
init_args.mem_alloc_option.allocator.free_func = free;
|
init_args.mem_alloc_option.allocator.free_func = free;
|
||||||
|
|
||||||
/* load WASM module */
|
os_mutex_lock(&aot_file_map_lock);
|
||||||
if (!(wasm_module = (WASMModuleCommon*)
|
|
||||||
wasm_load(wasm_file_buf, wasm_file_size,
|
/* lookup the file maps */
|
||||||
error_buf, sizeof(error_buf)))) {
|
file_map = aot_file_maps;
|
||||||
os_printf("%s\n", error_buf);
|
while (file_map) {
|
||||||
aot_set_last_error(error_buf);
|
file_map_next = file_map->next;
|
||||||
return NULL;
|
|
||||||
|
if (wasm_file_size == file_map->wasm_file_size
|
||||||
|
&& memcmp(wasm_file_buf, file_map->wasm_file_buf,
|
||||||
|
wasm_file_size) == 0) {
|
||||||
|
os_mutex_unlock(&aot_file_map_lock);
|
||||||
|
/* found */
|
||||||
|
*p_aot_file_size = file_map->aot_file_size;
|
||||||
|
return file_map->aot_file_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(comp_data = aot_create_comp_data((WASMModule*)wasm_module))) {
|
file_map = file_map_next;
|
||||||
os_printf("%s\n", aot_get_last_error());
|
}
|
||||||
|
|
||||||
|
/* not found, initialize file map and clone wasm file */
|
||||||
|
if (!(file_map = wasm_runtime_malloc(sizeof(AOTFileMap)))
|
||||||
|
|| !(wasm_file_buf_cloned = wasm_runtime_malloc(wasm_file_size))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
|
bh_memcpy_s(wasm_file_buf_cloned, wasm_file_size,
|
||||||
os_printf("%s\n", aot_get_last_error());
|
wasm_file_buf, wasm_file_size);
|
||||||
|
memset(file_map, 0, sizeof(AOTFileMap));
|
||||||
|
file_map->wasm_file_buf = wasm_file_buf_cloned;
|
||||||
|
file_map->wasm_file_size = wasm_file_size;
|
||||||
|
|
||||||
|
/* load WASM module */
|
||||||
|
if (!(wasm_module = wasm_load(wasm_file_buf, wasm_file_size,
|
||||||
|
error_buf, sizeof(error_buf)))) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(comp_data = aot_create_comp_data(wasm_module))) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aot_compile_wasm(comp_ctx)) {
|
if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
|
||||||
os_printf("%s\n", aot_get_last_error());
|
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
|
||||||
goto fail3;
|
goto fail3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!aot_compile_wasm(comp_ctx)) {
|
||||||
|
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
|
||||||
|
goto fail4;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data,
|
if (!(aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data,
|
||||||
&aot_file_size))) {
|
&aot_file_size))) {
|
||||||
os_printf("%s\n", aot_get_last_error());
|
set_error_buf(error_buf, error_buf_size, aot_get_last_error());
|
||||||
goto fail3;
|
goto fail4;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_map->aot_file_buf = aot_file_buf;
|
||||||
|
file_map->aot_file_size = aot_file_size;
|
||||||
|
|
||||||
|
if (!aot_file_maps)
|
||||||
|
aot_file_maps = file_map;
|
||||||
|
else {
|
||||||
|
file_map->next = aot_file_maps;
|
||||||
|
aot_file_maps = file_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p_aot_file_size = aot_file_size;
|
*p_aot_file_size = aot_file_size;
|
||||||
|
|
||||||
fail3:
|
fail4:
|
||||||
/* Destroy compiler context */
|
/* Destroy compiler context */
|
||||||
aot_destroy_comp_context(comp_ctx);
|
aot_destroy_comp_context(comp_ctx);
|
||||||
fail2:
|
fail3:
|
||||||
/* Destroy compile data */
|
/* Destroy compile data */
|
||||||
aot_destroy_comp_data(comp_data);
|
aot_destroy_comp_data(comp_data);
|
||||||
|
fail2:
|
||||||
|
wasm_unload(wasm_module);
|
||||||
fail1:
|
fail1:
|
||||||
wasm_runtime_unload(wasm_module);
|
if (!aot_file_buf) {
|
||||||
|
if (wasm_file_buf_cloned)
|
||||||
|
wasm_runtime_free(wasm_file_buf_cloned);
|
||||||
|
if (file_map)
|
||||||
|
wasm_runtime_free(file_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
os_mutex_unlock(&aot_file_map_lock);
|
||||||
|
|
||||||
return aot_file_buf;
|
return aot_file_buf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,18 +368,19 @@ aot_emit_aot_file(AOTCompContext *comp_ctx,
|
||||||
AOTCompData *comp_data,
|
AOTCompData *comp_data,
|
||||||
const char *file_name);
|
const char *file_name);
|
||||||
|
|
||||||
uint8_t*
|
uint8*
|
||||||
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
aot_emit_aot_file_buf(AOTCompContext *comp_ctx,
|
||||||
AOTCompData *comp_data,
|
AOTCompData *comp_data,
|
||||||
uint32_t *p_aot_file_size);
|
uint32 *p_aot_file_size);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
|
aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
|
||||||
|
|
||||||
uint8_t*
|
uint8*
|
||||||
aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size,
|
aot_compile_wasm_file(const uint8 *wasm_file_buf, uint32 wasm_file_size,
|
||||||
uint32_t opt_level, uint32_t size_level,
|
uint32 opt_level, uint32 size_level,
|
||||||
uint32_t *p_aot_file_size);
|
char *error_buf, uint32 error_buf_size,
|
||||||
|
uint32 *p_aot_file_size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
|
|
|
@ -77,11 +77,18 @@ aot_emit_aot_file(aot_comp_context_t comp_ctx,
|
||||||
void
|
void
|
||||||
aot_destroy_aot_file(uint8_t *aot_file);
|
aot_destroy_aot_file(uint8_t *aot_file);
|
||||||
|
|
||||||
|
bool
|
||||||
|
aot_compile_wasm_file_init();
|
||||||
|
|
||||||
uint8_t*
|
uint8_t*
|
||||||
aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size,
|
aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size,
|
||||||
uint32_t opt_level, uint32_t size_level,
|
uint32_t opt_level, uint32_t size_level,
|
||||||
|
char *error_buf, uint32_t error_buf_size,
|
||||||
uint32_t *p_aot_file_size);
|
uint32_t *p_aot_file_size);
|
||||||
|
|
||||||
|
void
|
||||||
|
aot_compile_wasm_file_destroy();
|
||||||
|
|
||||||
char*
|
char*
|
||||||
aot_get_last_error();
|
aot_get_last_error();
|
||||||
|
|
||||||
|
|
|
@ -1950,7 +1950,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
local_type_index = 0;
|
local_type_index = 0;
|
||||||
for (j = 0; j < local_set_count; j++) {
|
for (j = 0; j < local_set_count; j++) {
|
||||||
read_leb_uint32(p_code, buf_code_end, sub_local_count);
|
read_leb_uint32(p_code, buf_code_end, sub_local_count);
|
||||||
if (local_type_index + sub_local_count <= local_type_index
|
if (!sub_local_count
|
||||||
|
|| local_type_index > UINT32_MAX - sub_local_count
|
||||||
|| local_type_index + sub_local_count > local_count) {
|
|| local_type_index + sub_local_count > local_count) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"invalid local count");
|
"invalid local count");
|
||||||
|
|
|
@ -981,8 +981,10 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||||
local_type_index = 0;
|
local_type_index = 0;
|
||||||
for (j = 0; j < local_set_count; j++) {
|
for (j = 0; j < local_set_count; j++) {
|
||||||
read_leb_uint32(p_code, buf_code_end, sub_local_count);
|
read_leb_uint32(p_code, buf_code_end, sub_local_count);
|
||||||
bh_assert(!(local_type_index + sub_local_count <= local_type_index
|
bh_assert(sub_local_count
|
||||||
|| local_type_index + sub_local_count > local_count));
|
&& local_type_index <= UINT32_MAX - sub_local_count
|
||||||
|
&& local_type_index + sub_local_count
|
||||||
|
<= local_count);
|
||||||
|
|
||||||
CHECK_BUF(p_code, buf_code_end, 1);
|
CHECK_BUF(p_code, buf_code_end, 1);
|
||||||
/* 0x7F/0x7E/0x7D/0x7C */
|
/* 0x7F/0x7E/0x7D/0x7C */
|
||||||
|
|
|
@ -1580,6 +1580,14 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||||
if (module_inst->exec_env_singleton)
|
if (module_inst->exec_env_singleton)
|
||||||
wasm_exec_env_destroy(module_inst->exec_env_singleton);
|
wasm_exec_env_destroy(module_inst->exec_env_singleton);
|
||||||
|
|
||||||
|
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||||
|
if (module_inst->frames) {
|
||||||
|
bh_vector_destroy(module_inst->frames);
|
||||||
|
wasm_runtime_free(module_inst->frames);
|
||||||
|
module_inst->frames = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
wasm_runtime_free(module_inst);
|
wasm_runtime_free(module_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1925,7 +1933,7 @@ wasm_validate_app_addr(WASMModuleInstance *module_inst,
|
||||||
memory_data_size = memory->num_bytes_per_page * memory->cur_page_count;
|
memory_data_size = memory->num_bytes_per_page * memory->cur_page_count;
|
||||||
|
|
||||||
/* integer overflow check */
|
/* integer overflow check */
|
||||||
if (app_offset + size < app_offset) {
|
if (app_offset > UINT32_MAX - size) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1949,7 +1957,7 @@ wasm_validate_native_addr(WASMModuleInstance *module_inst,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* integer overflow check */
|
/* integer overflow check */
|
||||||
if (addr + size < addr) {
|
if ((uintptr_t)addr > UINTPTR_MAX - size) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2422,18 +2430,58 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||||
{
|
{
|
||||||
WASMModuleInstance *module_inst =
|
WASMModuleInstance *module_inst =
|
||||||
(WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env);
|
(WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env);
|
||||||
WASMInterpFrame *cur_frame =
|
WASMInterpFrame *first_frame,
|
||||||
wasm_exec_env_get_cur_frame(exec_env);
|
*cur_frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||||
WASMFunctionInstance *func_inst;
|
uint32 n = 0;
|
||||||
WASMExportFuncInstance *export_func;
|
|
||||||
const char *func_name = NULL;
|
|
||||||
uint32 n, i;
|
|
||||||
|
|
||||||
|
/* release previous stack frame */
|
||||||
|
if (module_inst->frames) {
|
||||||
|
bh_vector_destroy(module_inst->frames);
|
||||||
|
wasm_runtime_free(module_inst->frames);
|
||||||
|
module_inst->frames = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count frames includes a function */
|
||||||
|
first_frame = cur_frame;
|
||||||
|
while (cur_frame) {
|
||||||
|
if (cur_frame->function) {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
cur_frame = cur_frame->prev_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(module_inst->frames = runtime_malloc(
|
||||||
|
(uint64)sizeof(Vector), module_inst->cur_exception, 128))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bh_vector_init(module_inst->frames, n, sizeof(struct WASMFrame))) {
|
||||||
|
wasm_runtime_free(module_inst->frames);
|
||||||
|
module_inst->frames = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_frame = first_frame;
|
||||||
|
n = 0;
|
||||||
os_printf("\n");
|
os_printf("\n");
|
||||||
for (n = 0; cur_frame && cur_frame->function; n++) {
|
while (cur_frame) {
|
||||||
func_name = NULL;
|
struct WASMFrame frame = { 0 };
|
||||||
func_inst = cur_frame->function;
|
WASMFunctionInstance *func_inst = cur_frame->function;
|
||||||
|
const char *func_name = NULL;
|
||||||
|
|
||||||
|
if (!func_inst) {
|
||||||
|
cur_frame = cur_frame->prev_frame;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* place holder, will overwrite it in wasm_c_api */
|
||||||
|
frame.instance = module_inst;
|
||||||
|
frame.module_offset = 0;
|
||||||
|
frame.func_index = func_inst - module_inst->functions;
|
||||||
|
frame.func_offset =
|
||||||
|
cur_frame->ip ? cur_frame->ip - func_inst->u.func->code : 0;
|
||||||
|
|
||||||
|
/* look for the function name */
|
||||||
if (func_inst->is_import_func) {
|
if (func_inst->is_import_func) {
|
||||||
func_name = func_inst->u.func_import->field_name;
|
func_name = func_inst->u.func_import->field_name;
|
||||||
}
|
}
|
||||||
|
@ -2444,8 +2492,10 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||||
/* if custom name section is not generated,
|
/* if custom name section is not generated,
|
||||||
search symbols from export table */
|
search symbols from export table */
|
||||||
if (!func_name) {
|
if (!func_name) {
|
||||||
|
uint32 i;
|
||||||
for (i = 0; i < module_inst->export_func_count; i++) {
|
for (i = 0; i < module_inst->export_func_count; i++) {
|
||||||
export_func = module_inst->export_functions + i;
|
WASMExportFuncInstance *export_func =
|
||||||
|
module_inst->export_functions + i;
|
||||||
if (export_func->function == func_inst) {
|
if (export_func->function == func_inst) {
|
||||||
func_name = export_func->name;
|
func_name = export_func->name;
|
||||||
break;
|
break;
|
||||||
|
@ -2462,7 +2512,11 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||||
os_printf("#%02d %s \n", n, func_name);
|
os_printf("#%02d %s \n", n, func_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* keep print */
|
||||||
|
bh_vector_append(module_inst->frames, &frame);
|
||||||
|
|
||||||
cur_frame = cur_frame->prev_frame;
|
cur_frame = cur_frame->prev_frame;
|
||||||
|
n++;
|
||||||
}
|
}
|
||||||
os_printf("\n");
|
os_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,15 @@ typedef struct WASMExportMemInstance {
|
||||||
} WASMExportMemInstance;
|
} WASMExportMemInstance;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||||
|
struct WASMFrame {
|
||||||
|
void *instance;
|
||||||
|
uint32 module_offset;
|
||||||
|
uint32 func_index;
|
||||||
|
uint32 func_offset;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct WASMModuleInstance {
|
struct WASMModuleInstance {
|
||||||
/* Module instance type, for module instance loaded from
|
/* Module instance type, for module instance loaded from
|
||||||
WASM bytecode binary, this field is Wasm_Module_Bytecode;
|
WASM bytecode binary, this field is Wasm_Module_Bytecode;
|
||||||
|
@ -209,6 +218,10 @@ struct WASMModuleInstance {
|
||||||
/* The exception buffer of wasm interpreter for current thread. */
|
/* The exception buffer of wasm interpreter for current thread. */
|
||||||
char cur_exception[128];
|
char cur_exception[128];
|
||||||
|
|
||||||
|
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||||
|
Vector *frames;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The custom data that can be set/get by
|
/* The custom data that can be set/get by
|
||||||
* wasm_set_custom_data/wasm_get_custom_data */
|
* wasm_set_custom_data/wasm_get_custom_data */
|
||||||
void *custom_data;
|
void *custom_data;
|
||||||
|
|
|
@ -94,6 +94,12 @@ if (COLLECT_CODE_COVERAGE EQUAL 1)
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
# UNDEFINED BEHAVIOR
|
||||||
|
# refer to https://en.cppreference.com/w/cpp/language/ub
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=bounds-strict,undefined -fno-sanitize-recover")
|
||||||
|
endif()
|
||||||
|
|
||||||
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
||||||
|
|
||||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||||
|
|
|
@ -41,6 +41,7 @@ endif()
|
||||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||||
set(WAMR_BUILD_LIBC_WASI 0)
|
set(WAMR_BUILD_LIBC_WASI 0)
|
||||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||||
|
set(WAMR_BUILD_DUMP_CALL_STACK 1)
|
||||||
|
|
||||||
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
||||||
set(WAMR_BUILD_FAST_INTERP 1)
|
set(WAMR_BUILD_FAST_INTERP 1)
|
||||||
|
|
|
@ -92,32 +92,6 @@ DEFINE_FUNCTION(log)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
create_import_function_list(wasm_store_t *store,
|
|
||||||
const wasm_extern_t *import_function_list[])
|
|
||||||
{
|
|
||||||
#define IMPORT_FUNCTION_VARIABLE_NAME(name, ...) \
|
|
||||||
own wasm_func_t *function_##name = NULL;
|
|
||||||
IMPORT_FUNCTION_LIST(IMPORT_FUNCTION_VARIABLE_NAME)
|
|
||||||
#undef IMPORT_FUNCTION_VARIABLE_NAME
|
|
||||||
|
|
||||||
#define CREATE_WASM_FUNCTION(name, index, CREATE_FUNC_TYPE) \
|
|
||||||
{ \
|
|
||||||
own wasm_functype_t *type = CREATE_FUNC_TYPE; \
|
|
||||||
if (!(function_##name = wasm_func_new(store, type, STUB_##name))) { \
|
|
||||||
printf("> Error creating new function\n"); \
|
|
||||||
} \
|
|
||||||
wasm_functype_delete(type); \
|
|
||||||
}
|
|
||||||
IMPORT_FUNCTION_LIST(CREATE_WASM_FUNCTION)
|
|
||||||
#undef CREATE_WASM_FUNCTION
|
|
||||||
|
|
||||||
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
|
|
||||||
import_function_list[index] = wasm_func_as_extern(function_##name);
|
|
||||||
IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST)
|
|
||||||
#undef CREATE_IMPORT_FUNCTION
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j Export X.wasm"
|
// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j Export X.wasm"
|
||||||
// -1: memory
|
// -1: memory
|
||||||
|
@ -221,11 +195,33 @@ main(int argc, const char *argv[])
|
||||||
|
|
||||||
// Instantiate.
|
// Instantiate.
|
||||||
printf("Instantiating module...\n");
|
printf("Instantiating module...\n");
|
||||||
const wasm_extern_t *imports[10] = { 0 };
|
|
||||||
|
|
||||||
// Create external functions.
|
// Create external functions.
|
||||||
printf("Creating callback...\n");
|
printf("Creating callback...\n");
|
||||||
create_import_function_list(store, imports);
|
#define IMPORT_FUNCTION_VARIABLE_NAME(name, ...) \
|
||||||
|
own wasm_func_t *function_##name = NULL;
|
||||||
|
IMPORT_FUNCTION_LIST(IMPORT_FUNCTION_VARIABLE_NAME)
|
||||||
|
#undef IMPORT_FUNCTION_VARIABLE_NAME
|
||||||
|
|
||||||
|
const wasm_extern_t *imports[10] = { 0 };
|
||||||
|
|
||||||
|
#define CREATE_WASM_FUNCTION(name, index, CREATE_FUNC_TYPE) \
|
||||||
|
{ \
|
||||||
|
own wasm_functype_t *type = CREATE_FUNC_TYPE; \
|
||||||
|
if (!(function_##name = wasm_func_new(store, type, STUB_##name))) { \
|
||||||
|
printf("> Error creating new function\n"); \
|
||||||
|
return 1; \
|
||||||
|
} \
|
||||||
|
wasm_functype_delete(type); \
|
||||||
|
}
|
||||||
|
IMPORT_FUNCTION_LIST(CREATE_WASM_FUNCTION)
|
||||||
|
#undef CREATE_WASM_FUNCTION
|
||||||
|
|
||||||
|
#define ADD_TO_FUNCTION_LIST(name, index, ...) \
|
||||||
|
imports[index] = wasm_func_as_extern(function_##name);
|
||||||
|
IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST)
|
||||||
|
#undef CREATE_IMPORT_FUNCTION
|
||||||
|
|
||||||
|
|
||||||
own wasm_instance_t *instance =
|
own wasm_instance_t *instance =
|
||||||
wasm_instance_new(store, module, imports, NULL);
|
wasm_instance_new(store, module, imports, NULL);
|
||||||
|
@ -234,6 +230,11 @@ main(int argc, const char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DESTROY_WASM_FUNCITON(name, index, ...) \
|
||||||
|
wasm_func_delete(function_##name);
|
||||||
|
IMPORT_FUNCTION_LIST(DESTROY_WASM_FUNCITON)
|
||||||
|
#undef DESTROY_WASM_FUNCITON
|
||||||
|
|
||||||
// Extract export.
|
// Extract export.
|
||||||
printf("Extracting export...\n");
|
printf("Extracting export...\n");
|
||||||
wasm_instance_exports(instance, &exports);
|
wasm_instance_exports(instance, &exports);
|
||||||
|
|
|
@ -19,6 +19,17 @@ own wasm_trap_t* fail_callback(
|
||||||
return trap;
|
return trap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_frame(wasm_frame_t* frame) {
|
||||||
|
printf("> %p @ 0x%zx = %"PRIu32".0x%zx\n",
|
||||||
|
wasm_frame_instance(frame),
|
||||||
|
wasm_frame_module_offset(frame),
|
||||||
|
wasm_frame_func_index(frame),
|
||||||
|
wasm_frame_func_offset(frame)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, const char* argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
// Initialize.
|
// Initialize.
|
||||||
printf("Initializing...\n");
|
printf("Initializing...\n");
|
||||||
|
@ -93,7 +104,6 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
// Call.
|
// Call.
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
char buf[32];
|
|
||||||
const wasm_func_t* func = wasm_extern_as_func(exports.data[i]);
|
const wasm_func_t* func = wasm_extern_as_func(exports.data[i]);
|
||||||
if (func == NULL) {
|
if (func == NULL) {
|
||||||
printf("> Error accessing export!\n");
|
printf("> Error accessing export!\n");
|
||||||
|
@ -111,9 +121,29 @@ int main(int argc, const char* argv[]) {
|
||||||
printf("Printing message...\n");
|
printf("Printing message...\n");
|
||||||
own wasm_name_t message;
|
own wasm_name_t message;
|
||||||
wasm_trap_message(trap, &message);
|
wasm_trap_message(trap, &message);
|
||||||
snprintf(buf, sizeof(buf), "> %%.%us\n", (unsigned)message.size);
|
printf("> %s\n", message.data);
|
||||||
printf(buf, message.data);
|
|
||||||
|
|
||||||
|
printf("Printing origin...\n");
|
||||||
|
own wasm_frame_t* frame = wasm_trap_origin(trap);
|
||||||
|
if (frame) {
|
||||||
|
print_frame(frame);
|
||||||
|
wasm_frame_delete(frame);
|
||||||
|
} else {
|
||||||
|
printf("> Empty origin.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Printing trace...\n");
|
||||||
|
own wasm_frame_vec_t trace;
|
||||||
|
wasm_trap_trace(trap, &trace);
|
||||||
|
if (trace.size > 0) {
|
||||||
|
for (size_t i = 0; i < trace.size; ++i) {
|
||||||
|
print_frame(trace.data[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("> Empty trace.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_frame_vec_delete(&trace);
|
||||||
wasm_trap_delete(trap);
|
wasm_trap_delete(trap);
|
||||||
wasm_name_delete(&message);
|
wasm_name_delete(&message);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user