From 7fd5e42febd3e10b744c5f565d9af814d3780a58 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 7 Jul 2021 00:50:25 +0800 Subject: [PATCH 1/6] Implement wasm-c-api frame/trap APIs for interpreter mode Enable to cache compiled AOT file buffer for wasm-c-api JIT mode Fix issues of wasm-c-api sample trap and callback_chain Avoid checks that rely on undefined C behavior --- README.md | 2 +- TSC_Charter.md | 24 +- core/iwasm/aot/aot_runtime.c | 4 +- core/iwasm/common/wasm_c_api.c | 268 ++++++++++++++++++-- core/iwasm/common/wasm_c_api_internal.h | 8 + core/iwasm/compilation/aot_compiler.c | 150 +++++++++-- core/iwasm/compilation/aot_compiler.h | 13 +- core/iwasm/include/aot_export.h | 7 + core/iwasm/interpreter/wasm_loader.c | 3 +- core/iwasm/interpreter/wasm_mini_loader.c | 6 +- core/iwasm/interpreter/wasm_runtime.c | 80 +++++- core/iwasm/interpreter/wasm_runtime.h | 13 + product-mini/platforms/linux/CMakeLists.txt | 6 + samples/wasm-c-api/CMakeLists.txt | 1 + samples/wasm-c-api/src/callback_chain.c | 57 +++-- samples/wasm-c-api/src/trap.c | 36 ++- 16 files changed, 575 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index d12b5e8b47..6ee1c6bdf3 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a Project Technical Steering Committee ==================================== -The [WAMR PTSC Charter](./TSC_Charter.md) governs the operations of the project TSC. +The [WAMR PTSC Charter](./TSC_Charter.md) governs the operations of the project TSC. The current TSC members: - [lum1n0us](https://github.com/lum1n0us) - **Liang He**, - [qinxk-inter](https://github.com/qinxk-inter) - **Xiaokang Qin**, diff --git a/TSC_Charter.md b/TSC_Charter.md index 6cb8ddd282..56c4a024b9 100644 --- a/TSC_Charter.md +++ b/TSC_Charter.md @@ -2,23 +2,23 @@ ## Section 1. Guiding Principle -The WebAssembly Micro Runtime (WAMR) project is part of the -Bytecode Alliance (BA) which operates transparently, openly, -collaboratively, and ethically. Project proposals, timelines, and status +The WebAssembly Micro Runtime (WAMR) project is part of the +Bytecode Alliance (BA) which operates transparently, openly, +collaboratively, and ethically. Project proposals, timelines, and status must not merely be open, but also easily visible to outsiders. ## Section 2. Project Governance under Bytecode Alliance -Technical leadership for the WAMR projects within the Bytecode Alliance -is delegated to the projects through the project charter. Though the BA TSC +Technical leadership for the WAMR projects within the Bytecode Alliance +is delegated to the projects through the project charter. Though the BA TSC will not interfere with day-to-day discussions, votes or meetings of the PTSC, -the BA TSC may request additional amendments to the PTSC charter when +the BA TSC may request additional amendments to the PTSC charter when there is misalignment between the project charter and the BA mission and values. -The PTSC structure described in this document may be overhauled as part of -establishing a BA TSC in order to adhere to constraints or requirements that +The PTSC structure described in this document may be overhauled as part of +establishing a BA TSC in order to adhere to constraints or requirements that TSC will impose on project-level governance. ## Section 3. Establishment of the PTSC @@ -26,7 +26,7 @@ TSC will impose on project-level governance. PTSC memberships are not time-limited. There is no maximum size of the PTSC. The size is expected to vary in order to ensure adequate coverage of important areas of expertise, balanced with the ability to make decisions efficiently. -The PTSC must have at least four members. +The PTSC must have at least four members. There is no specific set of requirements or qualifications for PTSC membership beyond these rules. The PTSC may add additional members to the @@ -77,11 +77,11 @@ The PTSC will define WAMR project’s release vehicles. ## Section 5. WAMR Project Operations -The PTSC will establish and maintain a development process for the WAMR +The PTSC will establish and maintain a development process for the WAMR project. The development process will establish guidelines for how the developers and community will operate. It will, for example, establish appropriate timelines for PTSC review (e.g. agenda items must be -published at least a certain number of hours in advance of a PTSC +published at least a certain number of hours in advance of a PTSC meeting). The PTSC and entire technical community will follow any processes as may @@ -106,7 +106,7 @@ the candidate's election. Elections shall be done within the projects by the Collaborators active in the project. The PTSC will elect from amongst voting PTSC members a PTSC Chairperson to -work on building an agenda for PTSC meetings. The PTSC shall hold annual +work on building an agenda for PTSC meetings. The PTSC shall hold annual elections to select a PTSC Chairperson; there are no limits on the number of terms a PTSC Chairperson may serve. diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 90139788ca..f03d2a11f2 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1896,7 +1896,7 @@ aot_validate_app_addr(AOTModuleInstance *module_inst, } /* integer overflow check */ - if(app_offset + size < app_offset) { + if(app_offset > UINT32_MAX - size) { goto fail; } @@ -1920,7 +1920,7 @@ aot_validate_native_addr(AOTModuleInstance *module_inst, } /* integer overflow check */ - if (addr + size < addr) { + if ((uintptr_t)addr > UINTPTR_MAX - size) { goto fail; } diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 90d059e75d..3c44c6b9cb 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -189,7 +189,7 @@ failed: \ size_t i = 0; \ memset(out, 0, sizeof(Vector)); \ \ - if (!src->size) { \ + if (!src || !src->size) { \ 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(instance, wasm_instance_delete_internal) WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete) +WASM_DEFINE_VEC_OWN(frame, wasm_frame_delete) static inline bool valid_module_type(uint32 module_type) @@ -255,6 +256,21 @@ valid_module_type(uint32 module_type) 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 */ static void wasm_engine_delete_internal(wasm_engine_t *engine) @@ -264,6 +280,10 @@ wasm_engine_delete_internal(wasm_engine_t *engine) wasm_runtime_free(engine); } +#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0 + aot_compile_wasm_file_destroy(); +#endif + 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); #endif +#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0 + if (!aot_compile_wasm_file_init()) { + goto failed; + } +#endif + /* create wasm_engine_t */ if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) { goto failed; @@ -1289,10 +1315,106 @@ wasm_val_same(const wasm_val_t *v1, const wasm_val_t *v2) 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 * -wasm_trap_new_internal(const char *string) +wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt, + const char *default_error_info) { 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)))) { return NULL; @@ -1302,11 +1424,39 @@ wasm_trap_new_internal(const char *string) goto failed; } - wasm_name_new_from_string(trap->message, string); - if (strlen(string) && !trap->message->data) { + wasm_name_new_from_string_nt(trap->message, error_info); + if (strlen(error_info) && !trap->message->data) { 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; failed: wasm_trap_delete(trap); @@ -1342,6 +1492,7 @@ wasm_trap_delete(wasm_trap_t *trap) } DEINIT_VEC(trap->message, wasm_byte_vec_delete); + /* reuse frames of WASMModuleInstance, do not free it here */ 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); } +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 WASMModuleCommon *module_comm_rt; 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 }; 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); @@ -1401,12 +1615,35 @@ 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); - module_ex->module_comm_rt = wasm_runtime_load( - (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, - error_buf, (uint32)sizeof(error_buf)); - if (!(module_ex->module_comm_rt)) { - LOG_ERROR(error_buf); - goto failed; +#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( + (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, + error_buf, (uint32)sizeof(error_buf)); + if (!(module_ex->module_comm_rt)) { + LOG_ERROR(error_buf); + goto failed; + } } /* add it to a watching list in store */ @@ -2255,12 +2492,13 @@ wasm_func_call(const wasm_func_t *func, if (argv != argv_buf) wasm_runtime_free(argv); + /* trap -> exception -> trap */ if (wasm_runtime_get_exception(func->inst_comm_rt)) { - return wasm_trap_new_internal( - wasm_runtime_get_exception(func->inst_comm_rt)); + return wasm_trap_new_internal(func->inst_comm_rt, NULL); } 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) { char error_buf[128] = { 0 }; - const uint32 stack_size = 16 * 1024; - const uint32 heap_size = 16 * 1024; + const uint32 stack_size = 32 * 1024; + const uint32 heap_size = 32 * 1024; uint32 import_count = 0; wasm_instance_t *instance = NULL; uint32 i = 0; diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index 073eead867..0e413551ed 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -86,8 +86,16 @@ struct wasm_ref_t { uint32 obj; }; +struct wasm_frame_t { + wasm_instance_t *instance; + uint32 module_offset; + uint32 func_index; + uint32 func_offset; +}; + struct wasm_trap_t { wasm_byte_vec_t *message; + Vector *frames; }; struct wasm_func_t { diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index 3232448eee..58d9815e42 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -2135,19 +2135,82 @@ extern void wasm_set_ref_types_flag(bool enable); #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* 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) { - WASMModuleCommon *wasm_module = NULL; + WASMModule *wasm_module = NULL; AOTCompData *comp_data = NULL; AOTCompContext *comp_ctx = NULL; RuntimeInitArgs init_args; AOTCompOption option = { 0 }; + AOTFileMap *file_map = NULL, *file_map_next; + uint8 *wasm_file_buf_cloned = NULL; uint8 *aot_file_buf = NULL; uint32 aot_file_size; - char error_buf[128]; option.is_jit_mode = false; 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; /* default value, enable or disable depends on the platform */ option.bounds_checks = 2; - option.enable_simd = true; option.enable_aux_stack_check = true; #if WASM_ENABLE_BULK_MEMORY != 0 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.free_func = free; + os_mutex_lock(&aot_file_map_lock); + + /* lookup the file maps */ + file_map = aot_file_maps; + while (file_map) { + file_map_next = file_map->next; + + 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; + } + + file_map = file_map_next; + } + + /* 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; + } + + bh_memcpy_s(wasm_file_buf_cloned, wasm_file_size, + 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 = (WASMModuleCommon*) - wasm_load(wasm_file_buf, wasm_file_size, + if (!(wasm_module = wasm_load(wasm_file_buf, wasm_file_size, error_buf, sizeof(error_buf)))) { - os_printf("%s\n", error_buf); - aot_set_last_error(error_buf); - return NULL; + goto fail1; } - if (!(comp_data = aot_create_comp_data((WASMModule*)wasm_module))) { - os_printf("%s\n", aot_get_last_error()); - 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; } if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) { - os_printf("%s\n", aot_get_last_error()); - goto fail2; + set_error_buf(error_buf, error_buf_size, aot_get_last_error()); + goto fail3; } if (!aot_compile_wasm(comp_ctx)) { - os_printf("%s\n", aot_get_last_error()); - goto fail3; + 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, &aot_file_size))) { - os_printf("%s\n", aot_get_last_error()); - goto fail3; + set_error_buf(error_buf, error_buf_size, aot_get_last_error()); + 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; -fail3: +fail4: /* Destroy compiler context */ aot_destroy_comp_context(comp_ctx); -fail2: +fail3: /* Destroy compile data */ aot_destroy_comp_data(comp_data); +fail2: + wasm_unload(wasm_module); 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; } diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index feb2eaff4b..9f6a214711 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -368,18 +368,19 @@ aot_emit_aot_file(AOTCompContext *comp_ctx, AOTCompData *comp_data, const char *file_name); -uint8_t* +uint8* aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data, - uint32_t *p_aot_file_size); + uint32 *p_aot_file_size); bool aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name); -uint8_t* -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 *p_aot_file_size); +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); #ifdef __cplusplus } /* end of extern "C" */ diff --git a/core/iwasm/include/aot_export.h b/core/iwasm/include/aot_export.h index d209044cee..eb0aba05ca 100644 --- a/core/iwasm/include/aot_export.h +++ b/core/iwasm/include/aot_export.h @@ -77,11 +77,18 @@ aot_emit_aot_file(aot_comp_context_t comp_ctx, void aot_destroy_aot_file(uint8_t *aot_file); +bool +aot_compile_wasm_file_init(); + uint8_t* aot_compile_wasm_file(const uint8_t *wasm_file_buf, uint32_t wasm_file_size, uint32_t opt_level, uint32_t size_level, + char *error_buf, uint32_t error_buf_size, uint32_t *p_aot_file_size); +void +aot_compile_wasm_file_destroy(); + char* aot_get_last_error(); diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index a3db0a2d08..854911ff55 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -1950,7 +1950,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, local_type_index = 0; for (j = 0; j < local_set_count; j++) { 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) { set_error_buf(error_buf, error_buf_size, "invalid local count"); diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 9340682027..342838e4b1 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -981,8 +981,10 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, local_type_index = 0; for (j = 0; j < local_set_count; j++) { read_leb_uint32(p_code, buf_code_end, sub_local_count); - bh_assert(!(local_type_index + sub_local_count <= local_type_index - || local_type_index + sub_local_count > local_count)); + bh_assert(sub_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); /* 0x7F/0x7E/0x7D/0x7C */ diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 0b43f18958..5d47ba7805 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1580,6 +1580,14 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) if (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); } @@ -1925,7 +1933,7 @@ wasm_validate_app_addr(WASMModuleInstance *module_inst, memory_data_size = memory->num_bytes_per_page * memory->cur_page_count; /* integer overflow check */ - if (app_offset + size < app_offset) { + if (app_offset > UINT32_MAX - size) { goto fail; } @@ -1949,7 +1957,7 @@ wasm_validate_native_addr(WASMModuleInstance *module_inst, } /* integer overflow check */ - if (addr + size < addr) { + if ((uintptr_t)addr > UINTPTR_MAX - size) { goto fail; } @@ -2421,19 +2429,59 @@ void wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) { WASMModuleInstance *module_inst = - (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); - WASMInterpFrame *cur_frame = - wasm_exec_env_get_cur_frame(exec_env); - WASMFunctionInstance *func_inst; - WASMExportFuncInstance *export_func; - const char *func_name = NULL; - uint32 n, i; + (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + WASMInterpFrame *first_frame, + *cur_frame = wasm_exec_env_get_cur_frame(exec_env); + uint32 n = 0; + + /* 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"); - for (n = 0; cur_frame && cur_frame->function; n++) { - func_name = NULL; - func_inst = cur_frame->function; + while (cur_frame) { + struct WASMFrame frame = { 0 }; + 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) { 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, search symbols from export table */ if (!func_name) { + uint32 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) { func_name = export_func->name; break; @@ -2462,7 +2512,11 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) os_printf("#%02d %s \n", n, func_name); } + /* keep print */ + bh_vector_append(module_inst->frames, &frame); + cur_frame = cur_frame->prev_frame; + n++; } os_printf("\n"); } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 55c13c282d..473407ba3d 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -150,6 +150,15 @@ typedef struct WASMExportMemInstance { } WASMExportMemInstance; #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 +struct WASMFrame { + void *instance; + uint32 module_offset; + uint32 func_index; + uint32 func_offset; +}; +#endif + struct WASMModuleInstance { /* Module instance type, for module instance loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode; @@ -209,6 +218,10 @@ struct WASMModuleInstance { /* The exception buffer of wasm interpreter for current thread. */ char cur_exception[128]; +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + Vector *frames; +#endif + /* The custom data that can be set/get by * wasm_set_custom_data/wasm_get_custom_data */ void *custom_data; diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index 231bd0720e..e34d95a52e 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -94,6 +94,12 @@ if (COLLECT_CODE_COVERAGE EQUAL 1) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") 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}/../../..) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index 334232e8d6..d0bfffa595 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -41,6 +41,7 @@ endif() set(WAMR_BUILD_LIBC_BUILTIN 1) set(WAMR_BUILD_LIBC_WASI 0) set(WAMR_BUILD_MULTI_MODULE 1) +set(WAMR_BUILD_DUMP_CALL_STACK 1) if(NOT DEFINED WAMR_BUILD_FAST_INTERP) set(WAMR_BUILD_FAST_INTERP 1) diff --git a/samples/wasm-c-api/src/callback_chain.c b/samples/wasm-c-api/src/callback_chain.c index ab15d08235..38e8ab7690 100644 --- a/samples/wasm-c-api/src/callback_chain.c +++ b/samples/wasm-c-api/src/callback_chain.c @@ -92,32 +92,6 @@ DEFINE_FUNCTION(log) 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" // -1: memory @@ -221,11 +195,33 @@ main(int argc, const char *argv[]) // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t *imports[10] = { 0 }; // Create external functions. 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 = wasm_instance_new(store, module, imports, NULL); @@ -234,6 +230,11 @@ main(int argc, const char *argv[]) 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. printf("Extracting export...\n"); wasm_instance_exports(instance, &exports); diff --git a/samples/wasm-c-api/src/trap.c b/samples/wasm-c-api/src/trap.c index e121419036..6b42b35180 100644 --- a/samples/wasm-c-api/src/trap.c +++ b/samples/wasm-c-api/src/trap.c @@ -19,6 +19,17 @@ own wasm_trap_t* fail_callback( 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[]) { // Initialize. printf("Initializing...\n"); @@ -93,7 +104,6 @@ int main(int argc, const char* argv[]) { // Call. for (int i = 0; i < 2; ++i) { - char buf[32]; const wasm_func_t* func = wasm_extern_as_func(exports.data[i]); if (func == NULL) { printf("> Error accessing export!\n"); @@ -111,9 +121,29 @@ int main(int argc, const char* argv[]) { printf("Printing message...\n"); own wasm_name_t message; wasm_trap_message(trap, &message); - snprintf(buf, sizeof(buf), "> %%.%us\n", (unsigned)message.size); - printf(buf, message.data); + printf("> %s\n", 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_name_delete(&message); } From 60ff1efbb5f45655f494307672f8f78e1d42087e Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 13 Jul 2021 02:41:35 +0800 Subject: [PATCH 2/6] Implement wasm-c-api frame/trap APIs for AOT mode And update workflow to build/cache llvm and run wasm-c-api samples --- .github/workflows/linux.yml | 74 ++++++++++++++++++++++--- core/iwasm/aot/aot_runtime.c | 41 +++++++++++++- core/iwasm/aot/aot_runtime.h | 5 +- core/iwasm/common/wasm_c_api.c | 6 ++ core/iwasm/common/wasm_c_api_internal.h | 7 --- core/iwasm/common/wasm_runtime_common.h | 8 +++ core/iwasm/interpreter/wasm_runtime.c | 27 ++++----- core/iwasm/interpreter/wasm_runtime.h | 9 --- samples/wasm-c-api/CMakeLists.txt | 12 +++- samples/wasm-c-api/src/hello.c | 1 + 10 files changed, 146 insertions(+), 44 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 22d13e57eb..cae7b1b0f5 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,13 +6,16 @@ name: Linux # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the main branch on: + # triggers on every branch push: - branches: [ main ] + paths-ignore: + - 'doc/**' + # triggers on every PR pull_request: - branches: [ main ] + paths-ignore: + - 'doc/**' jobs: - build: runs-on: ${{ matrix.os }} strategy: @@ -84,27 +87,80 @@ jobs: cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1 make cd .. && rm -rf build + - name: Cache LLVM libraries + uses: actions/cache@v2 + id: cache_llvm + env: + cache-name: llvm_libraries + with: + path: ./core/deps/llvm + key: ${{ runner.os }}-build-${{env.cache-name}} + restore-keys: ${{ runner.os }}-build-${{env.cache-name}} + - name: Build llvm and clang from source + if: steps.cache_llvm.outputs.cache-hit != 'true' + run: | + cd wamr-compiler + ./build_llvm.sh + - name: Build wamrc + run: | + cd wamr-compiler + mkdir build && cd build + cmake .. + make + cd .. - name: download and install wasi-sdk run: | cd /opt - wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-8/wasi-sdk-8.0-linux.tar.gz - tar -xzf wasi-sdk-8.0-linux.tar.gz - mv wasi-sdk-8.0 wasi-sdk + wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-linux.tar.gz + tar -xzf wasi-sdk-12.0-linux.tar.gz + mv wasi-sdk-12.0 wasi-sdk + rm wasi-sdk-12.0-linux.tar.gz - name: download and install wabt run: | cd /opt - wget https://github.com/WebAssembly/wabt/releases/download/1.0.19/wabt-1.0.19-ubuntu.tar.gz - tar -xzf wabt-1.0.19-ubuntu.tar.gz - mv wabt-1.0.19 wabt + wget https://github.com/WebAssembly/wabt/releases/download/1.0.23/wabt-1.0.23-ubuntu.tar.gz + tar -xzf wabt-1.0.23-ubuntu.tar.gz + mv wabt-1.0.23 wabt + rm wabt-1.0.23-ubuntu.tar.gz - name: Build Sample [wasm-c-api] run: | cd samples/wasm-c-api mkdir build && cd build cmake .. make + ./callback + ./callback_chain + ./global ./hello + ./reflect + ./trap + cd .. && rm -r build + - name: Build Sample [wasm-c-api] [Jit] + run: | + cd samples/wasm-c-api + mkdir build && cd build + cmake -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_AOT=1 .. + make + ./callback + ./callback_chain ./global + ./hello + ./reflect + ./trap + cd .. && rm -r build + - name: Build Sample [wasm-c-api] [Aot] + run: | + cd samples/wasm-c-api + mkdir build && cd build + cmake -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_AOT=1 .. + make ./callback + ./callback_chain + ./global + ./hello + ./reflect + ./trap + cd .. && rm -r build - name: Build Sample [basic] run: | cd samples/basic diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index f03d2a11f2..16301f5249 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1061,6 +1061,13 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, } #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (!(module_inst->frames.ptr = + runtime_malloc(sizeof(Vector), error_buf, error_buf_size))) { + goto fail; + } +#endif + /* Execute __post_instantiate function and start function*/ if (!execute_post_inst_function(module_inst) || !execute_start_function(module_inst)) { @@ -1130,6 +1137,14 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) wasm_runtime_free(module_inst->func_perf_profilings.ptr); #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (module_inst->frames.ptr) { + bh_vector_destroy(module_inst->frames.ptr); + wasm_runtime_free(module_inst->frames.ptr); + module_inst->frames.ptr = NULL; + } +#endif + if (module_inst->memories.ptr) memories_deinstantiate(module_inst); @@ -2902,7 +2917,8 @@ aot_free_frame(WASMExecEnv *exec_env) void aot_dump_call_stack(WASMExecEnv *exec_env) { - AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame; + AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame, + *first_frame = cur_frame; AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst; const char *func_name; @@ -2925,6 +2941,29 @@ aot_dump_call_stack(WASMExecEnv *exec_env) n++; } os_printf("\n"); + + /* release previous stack frames and create new ones */ + if (!bh_vector_destroy(module_inst->frames.ptr) + || !bh_vector_init(module_inst->frames.ptr, n, + sizeof(WASMCApiFrame))) { + return; + } + + cur_frame = first_frame; + while (cur_frame) { + WASMCApiFrame frame = { 0 }; + frame.instance = module_inst; + frame.module_offset = 0; + frame.func_index = cur_frame->func_index; + frame.func_offset = 0; + + if (!bh_vector_append(module_inst->frames.ptr, &frame)) { + bh_vector_destroy(module_inst->frames.ptr); + return; + } + + cur_frame = cur_frame->prev_frame; + } } #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 237764b59e..af51347fde 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -353,8 +353,11 @@ typedef struct AOTModuleInstance { uint32 llvm_stack; uint32 default_wasm_stack_size; + uint32 _padding; + /* store stacktrace information */ + AOTPointer frames; /* reserved */ - uint32 reserved[9]; + uint32 reserved[6]; /* * +------------------------------+ <-- memories.ptr diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 3c44c6b9cb..3c084ebb59 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -1435,6 +1435,12 @@ wasm_trap_new_internal(WASMModuleInstanceCommon *inst_comm_rt, trap->frames = ((WASMModuleInstance *)inst_comm_rt)->frames; } #endif + +#if WASM_ENABLE_AOT != 0 + if (inst_comm_rt->module_type == Wasm_Module_AoT) { + trap->frames = ((AOTModuleInstance *)inst_comm_rt)->frames.ptr; + } +#endif #endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */ /* allow a NULL frames list */ diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index 0e413551ed..dc9fc452de 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -86,13 +86,6 @@ struct wasm_ref_t { uint32 obj; }; -struct wasm_frame_t { - wasm_instance_t *instance; - uint32 module_offset; - uint32 func_index; - uint32 func_offset; -}; - struct wasm_trap_t { wasm_byte_vec_t *message; Vector *frames; diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 83fd82dcc3..4b515bf8ff 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -336,6 +336,14 @@ typedef struct WASMMemoryInstanceCommon { typedef package_type_t PackageType; typedef wasm_section_t WASMSection, AOTSection; +typedef struct wasm_frame_t { + /* wasm_instance_t */ + void *instance; + uint32 module_offset; + uint32 func_index; + uint32 func_offset; +} WASMCApiFrame; + /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN bool wasm_runtime_init(void); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 5d47ba7805..233468ee0a 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1159,6 +1159,13 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, } #endif +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (!(module_inst->frames = runtime_malloc((uint64)sizeof(Vector), + error_buf, error_buf_size))) { + goto fail; + } +#endif + /* Instantiate global firstly to get the mutable data size */ global_count = module->import_global_count + module->global_count; if (global_count @@ -2434,13 +2441,6 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) *cur_frame = wasm_exec_env_get_cur_frame(exec_env); uint32 n = 0; - /* 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) { @@ -2450,14 +2450,9 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) 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; + /* release previous stack frames and create new ones */ + if (!bh_vector_destroy(module_inst->frames) + || !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame))) { return; } @@ -2465,7 +2460,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) n = 0; os_printf("\n"); while (cur_frame) { - struct WASMFrame frame = { 0 }; + WASMCApiFrame frame = { 0 }; WASMFunctionInstance *func_inst = cur_frame->function; const char *func_name = NULL; diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 473407ba3d..fb56881231 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -150,15 +150,6 @@ typedef struct WASMExportMemInstance { } WASMExportMemInstance; #endif -#if WASM_ENABLE_DUMP_CALL_STACK != 0 -struct WASMFrame { - void *instance; - uint32 module_offset; - uint32 func_index; - uint32 func_offset; -}; -#endif - struct WASMModuleInstance { /* Module instance type, for module instance loaded from WASM bytecode binary, this field is Wasm_Module_Bytecode; diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index d0bfffa595..2ad5b6eccf 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -62,7 +62,6 @@ if (NOT MSVC) endif() # build out vmlib set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) -set(WAMRC ${WAMR_ROOT_DIR}/wamr-compiler/build/wamrc) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE}) @@ -84,6 +83,17 @@ if(NOT WAT2WASM) message(SEND_ERROR "can not find wat2wasm") endif() +## locate wamrc +find_program(WAMRC + wamrc + PATHS ${WAMR_ROOT_DIR}/wamr-compiler/build/ + REQUIRED +) + +if(NOT WAMRC) + message(SEND_ERROR "can not find wamrc") +endif() + include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) set(MM_UTIL src/utils/multi_module_utils.c) diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index fde1b82d40..b9dedaaf0c 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -112,3 +112,4 @@ int main(int argc, const char* argv[]) { printf("Done.\n"); return 0; } + From 90e635a581aa1f72c23e28e6634b37009495d43d Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 13 Jul 2021 16:52:30 +0800 Subject: [PATCH 3/6] Fix CI error when building wasm-c-api samples with AOT mode --- samples/wasm-c-api/CMakeLists.txt | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index 2ad5b6eccf..2cf8d923e8 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -31,7 +31,7 @@ if(NOT DEFINED WAMR_BUILD_INTERP) endif() if(NOT DEFINED WAMR_BUILD_AOT) - set(WAMR_BUILD_AOT 1) + set(WAMR_BUILD_AOT 0) endif() if(NOT DEFINED WAMR_BUILD_JIT) @@ -83,17 +83,19 @@ if(NOT WAT2WASM) message(SEND_ERROR "can not find wat2wasm") endif() -## locate wamrc -find_program(WAMRC - wamrc - PATHS ${WAMR_ROOT_DIR}/wamr-compiler/build/ - REQUIRED -) +if(${WAMR_BUILD_AOT} EQUAL 1) + ## locate wamrc + find_program(WAMRC + wamrc + PATHS ${WAMR_ROOT_DIR}/wamr-compiler/build/ + ) -if(NOT WAMRC) - message(SEND_ERROR "can not find wamrc") + if(NOT WAMRC) + message(SEND_ERROR "can not find wamrc. refer to \ + https://github.com/bytecodealliance/wasm-micro-runtime#build-wamrc-aot-compiler" + ) + endif() endif() - include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) set(MM_UTIL src/utils/multi_module_utils.c) @@ -130,17 +132,15 @@ foreach(EX ${EXAMPLES}) # generate .aot file if(${WAMR_BUILD_AOT} EQUAL 1) - if(EXISTS ${WAMRC}) - add_custom_target(${EX}_AOT - COMMAND ${WAMRC} -o ${PROJECT_BINARY_DIR}/${EX}.aot - ${PROJECT_BINARY_DIR}/${EX}.wasm - DEPENDS ${EX}_WASM - BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot - VERBATIM - COMMENT "generate a aot file ${PROJECT_BINARY_DIR}/${EX}.aot" - ) - add_dependencies(${EX} ${EX}_AOT) - endif() + add_custom_target(${EX}_AOT + COMMAND ${WAMRC} -o ${PROJECT_BINARY_DIR}/${EX}.aot + ${PROJECT_BINARY_DIR}/${EX}.wasm + DEPENDS ${EX}_WASM + BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot + VERBATIM + COMMENT "generate a aot file ${PROJECT_BINARY_DIR}/${EX}.aot" + ) + add_dependencies(${EX} ${EX}_AOT) endif() endforeach() From ab5c42a01cb1bc078898120c972c51cb10428055 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 15 Jul 2021 00:50:00 +0800 Subject: [PATCH 4/6] Implement wasm_config related wasm-c-api APIs Add wasm_engine_new_with_args declaration in wasm_c_api.h Fix wasm-c-api frame func_offset issue in fast interp mode Remove bounds sanitize compiler flag --- core/iwasm/common/wasm_c_api.c | 34 ++++++++++++++++---- core/iwasm/include/wasm_c_api.h | 31 ++++++++++++++++++ core/iwasm/include/wasm_export.h | 3 ++ core/iwasm/interpreter/wasm_interp_classic.c | 1 + core/iwasm/interpreter/wasm_interp_fast.c | 1 + core/iwasm/interpreter/wasm_runtime.c | 11 +++++-- product-mini/platforms/linux/CMakeLists.txt | 2 +- 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 3c084ebb59..c41d59ec99 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -264,14 +264,29 @@ 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, +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 */ +own wasm_config_t * +wasm_config_new(void) +{ + return NULL; +} + +void +wasm_config_delete(own wasm_config_t *config) +{ + (void)config; +} + static void wasm_engine_delete_internal(wasm_engine_t *engine) { @@ -351,7 +366,7 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) /* global engine instance */ static wasm_engine_t *singleton_engine = NULL; -wasm_engine_t * +own wasm_engine_t * wasm_engine_new() { if (!singleton_engine) { @@ -361,7 +376,14 @@ wasm_engine_new() return singleton_engine; } -wasm_engine_t * +own wasm_engine_t * +wasm_engine_new_with_config(own wasm_config_t *config) +{ + (void)config; + return wasm_engine_new(); +} + +own wasm_engine_t * wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts) { if (!singleton_engine) { diff --git a/core/iwasm/include/wasm_c_api.h b/core/iwasm/include/wasm_c_api.h index 88e514be02..6079773e03 100644 --- a/core/iwasm/include/wasm_c_api.h +++ b/core/iwasm/include/wasm_c_api.h @@ -145,6 +145,37 @@ WASM_DECLARE_OWN(engine) WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void); WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*); +#ifndef MEM_ALLOC_OPTION_DEFINED +#define MEM_ALLOC_OPTION_DEFINED +/* same definition from wasm_export.h */ +/* Memory allocator type */ +typedef enum { + /* pool mode, allocate memory from user defined heap buffer */ + Alloc_With_Pool = 0, + /* user allocator mode, allocate memory from user defined + malloc function */ + Alloc_With_Allocator, + /* system allocator mode, allocate memory from system allocator, + or, platform's os_malloc function */ + Alloc_With_System_Allocator, +} mem_alloc_type_t; + +/* Memory allocator option */ +typedef union MemAllocOption { + struct { + void *heap_buf; + uint32_t heap_size; + } pool; + struct { + void *malloc_func; + void *realloc_func; + void *free_func; + } allocator; +} MemAllocOption; +#endif + +WASM_API_EXTERN own wasm_engine_t * +wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts); // Store diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 0fe46d61cd..85eb200381 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -93,6 +93,8 @@ typedef enum { Package_Type_Unknown = 0xFFFF } package_type_t; +#ifndef MEM_ALLOC_OPTION_DEFINED +#define MEM_ALLOC_OPTION_DEFINED /* Memory allocator type */ typedef enum { /* pool mode, allocate memory from user defined heap buffer */ @@ -117,6 +119,7 @@ typedef union MemAllocOption { void *free_func; } allocator; } MemAllocOption; +#endif /* WASM runtime initialize arguments */ typedef struct RuntimeInitArgs { diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index fdfa4b32ff..d85e180cd9 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -3371,6 +3371,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, wasm_set_exception(module, "out of bounds memory access"); got_exception: + SYNC_ALL_TO_FRAME(); return; #if WASM_ENABLE_LABELS_AS_VALUES == 0 diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 7c714ee96a..f5dc307358 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -3428,6 +3428,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, wasm_set_exception(module, "out of bounds memory access"); got_exception: + SYNC_ALL_TO_FRAME(); return; #if WASM_ENABLE_LABELS_AS_VALUES == 0 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 233468ee0a..179516913d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2463,6 +2463,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) WASMCApiFrame frame = { 0 }; WASMFunctionInstance *func_inst = cur_frame->function; const char *func_name = NULL; + const uint8 *func_code_base = NULL; if (!func_inst) { cur_frame = cur_frame->prev_frame; @@ -2473,8 +2474,14 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env) 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; + + func_code_base = wasm_get_func_code(func_inst); + if (!cur_frame->ip || !func_code_base) { + frame.func_offset = 0; + } + else { + frame.func_offset = cur_frame->ip - func_code_base; + } /* look for the function name */ if (func_inst->is_import_func) { diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index e34d95a52e..7471b41c1d 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -97,7 +97,7 @@ 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") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover") endif() set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) From bf41042760a63c66dab658764d76c6b08538273a Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 23 Jul 2021 02:17:35 +0800 Subject: [PATCH 5/6] Fix some compile warnings, update document --- core/app-mgr/app-manager/module_wasm_app.c | 2 +- .../libc-builtin/libc_builtin_wrapper.c | 23 +++++++++++++++++++ doc/build_wamr.md | 5 ++-- product-mini/platforms/linux/CMakeLists.txt | 10 ++++---- .../src/platform/zephyr/iwasm_main.c | 6 +++-- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index bbd5ad49bd..72e1f5e6f4 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -1674,7 +1674,7 @@ wasm_set_wasi_root_dir(const char *root_dir) if (!(path = realpath(root_dir, resolved_path))) return false; - strncpy(wasi_root_dir, path, sizeof(wasi_root_dir)); + snprintf(wasi_root_dir, sizeof(wasi_root_dir), "%s", path); return true; } diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index cb21bac771..008e19faf1 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -1068,6 +1068,28 @@ __cxa_throw_wrapper(wasm_exec_env_t exec_env, wasm_runtime_set_exception(module_inst, buf); } +struct timespec_app { + int64 tv_sec; + int32 tv_nsec; +}; + +static uint32 +clock_gettime_wrapper(wasm_exec_env_t exec_env, + uint32 clk_id, + struct timespec_app *ts_app){ + wasm_module_inst_t module_inst = get_module_inst(exec_env); + uint64 time; + + if (!validate_native_addr(ts_app, sizeof(const struct timespec_app))) + return (uint32)-1; + + time = os_time_get_boot_microsecond(); + ts_app->tv_sec = time / 1000000; + ts_app->tv_nsec = (time % 1000000) * 1000; + + return (uint32)0; +} + #if WASM_ENABLE_SPEC_TEST != 0 static void print_wrapper(wasm_exec_env_t exec_env) @@ -1167,6 +1189,7 @@ static NativeSymbol native_symbols_libc_builtin[] = { REG_NATIVE_FUNC(__cxa_allocate_exception, "(i)i"), REG_NATIVE_FUNC(__cxa_begin_catch, "(*)"), REG_NATIVE_FUNC(__cxa_throw, "(**i)"), + REG_NATIVE_FUNC(clock_gettime, "(i*)i"), }; #if WASM_ENABLE_SPEC_TEST != 0 diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 72eb1f16a9..b0d418a67a 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -20,7 +20,8 @@ The script `runtime_lib.cmake` defines a number of variables for configuring the - **WAMR_BUILD_PLATFORM**: set the target platform. It can be set to any platform name (folder name) under folder [core/shared/platform](../core/shared/platform). - **WAMR_BUILD_TARGET**: set the target CPU architecture. Current supported targets are: X86_64, X86_32, AARCH64, ARM, THUMB, XTENSA, RISCV64 and MIPS. - - For ARM and THUMB, the format is \\[\]\[_VFP], where \ is the ARM sub-architecture and the "_VFP" suffix means using VFP coprocessor registers s0-s15 (d0-d7) for passing arguments or returning results in standard procedure-call. For AARCH64, the format is\[\], VFP is enabled by default. Both \ and "_VFP" are optional, e.g. AARCH64, AARCH64V8, AARCHV8.1, ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on. + - For ARM and THUMB, the format is \\[\]\[_VFP], where \ is the ARM sub-architecture and the "_VFP" suffix means using VFP coprocessor registers s0-s15 (d0-d7) for passing arguments or returning results in standard procedure-call. Both \ and "_VFP" are optional, e.g. ARMV7, ARMV7_VFP, THUMBV7, THUMBV7_VFP and so on. + - For AARCH64, the format is\[\], VFP is enabled by default. \ is optional, e.g. AARCH64, AARCH64V8, AARCH64V8.1 and so on. - For RISCV64, the format is \[_abi], where "_abi" is optional, currently the supported formats are RISCV64, RISCV64_LP64D and RISCV64_LP64: RISCV64 and RISCV64_LP64D are identical, using [LP64D](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (LP64 with hardware floating-point calling convention for FLEN=64). And RISCV64_LP64 uses [LP64](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used). - For RISCV32, the format is \[_abi], where "_abi" is optional, currently the supported formats are RISCV32, RISCV32_ILP32D and RISCV32_ILP32: RISCV32 and RISCV32_ILP32D are identical, using [ILP32D](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (ILP32 with hardware floating-point calling convention for FLEN=64). And RISCV32_ILP32 uses [ILP32](https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md#-named-abis) as abi (Integer calling-convention only, and hardware floating-point calling convention is not used). @@ -465,4 +466,4 @@ $ ls ../build_out/ *build_wamr.sh* will generate *linux* compatible libraries ( libiwasm.so and libvmlib.a ) and an executable binary (*iwasm*) and copy *iwasm* to *build_out*. All original generated files are still under -*product-mini/platforms/linux/build*. \ No newline at end of file +*product-mini/platforms/linux/build*. diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index 7471b41c1d..b6d088b895 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -94,12 +94,6 @@ if (COLLECT_CODE_COVERAGE EQUAL 1) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") 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=undefined -fno-sanitize-recover") -endif() - set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) @@ -114,6 +108,10 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") 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=undefined -fno-sanitize-recover") + endif() endif () # The following flags are to enhance security, but it may impact performance, diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c index 391e48e047..e2f4a5c9eb 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/zephyr/iwasm_main.c @@ -27,7 +27,8 @@ extern int aee_host_msg_callback(void *msg, uint32_t msg_len); int uart_char_cnt = 0; -static void uart_irq_callback(struct device *dev) +static void uart_irq_callback(const struct device *dev, + void *user_data) { unsigned char ch; @@ -35,9 +36,10 @@ static void uart_irq_callback(struct device *dev) uart_char_cnt++; aee_host_msg_callback(&ch, 1); } + (void)user_data; } -struct device *uart_dev = NULL; +const struct device *uart_dev = NULL; static bool host_init() { From 2e967434c50892f239d3717ae37e08a3a9464598 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 23 Jul 2021 02:26:05 +0800 Subject: [PATCH 6/6] Fix coding style issue of clock_gettime_wrapper --- core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index 008e19faf1..6013199917 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -1075,12 +1075,12 @@ struct timespec_app { static uint32 clock_gettime_wrapper(wasm_exec_env_t exec_env, - uint32 clk_id, - struct timespec_app *ts_app){ + uint32 clk_id, struct timespec_app *ts_app) +{ wasm_module_inst_t module_inst = get_module_inst(exec_env); uint64 time; - if (!validate_native_addr(ts_app, sizeof(const struct timespec_app))) + if (!validate_native_addr(ts_app, sizeof(struct timespec_app))) return (uint32)-1; time = os_time_get_boot_microsecond();