diff --git a/build-scripts/build_llvm.py b/build-scripts/build_llvm.py index e5bcab750..4e37e390b 100755 --- a/build-scripts/build_llvm.py +++ b/build-scripts/build_llvm.py @@ -208,7 +208,7 @@ def main(): }, "xtensa": { "repo": "https://github.com/espressif/llvm-project.git", - "branch": "xtensa_release_11.0.0", + "branch": "xtensa_release_13.0.0", }, "default": { "repo": "https://github.com/llvm/llvm-project.git", diff --git a/core/app-framework/base/native/runtime_lib.h b/core/app-framework/base/native/runtime_lib.h index ec4d84cb7..477b663b2 100644 --- a/core/app-framework/base/native/runtime_lib.h +++ b/core/app-framework/base/native/runtime_lib.h @@ -8,7 +8,7 @@ #include "runtime_timer.h" -void +bool init_wasm_timer(); void exit_wasm_timer(); diff --git a/core/app-framework/base/native/timer_wrapper.c b/core/app-framework/base/native/timer_wrapper.c index 7ad350cf2..246868849 100644 --- a/core/app-framework/base/native/timer_wrapper.c +++ b/core/app-framework/base/native/timer_wrapper.c @@ -83,19 +83,36 @@ wakeup_modules_timer_thread(timer_ctx_t ctx) os_mutex_unlock(&g_timer_ctx_list_mutex); } -void +bool init_wasm_timer() { korp_tid tm_tid; bh_list_init(&g_timer_ctx_list); - os_cond_init(&g_timer_ctx_list_cond); + if (os_cond_init(&g_timer_ctx_list_cond) != 0) { + return false; + } /* temp solution for: thread_modulers_timer_check thread would recursive lock the mutex */ - os_recursive_mutex_init(&g_timer_ctx_list_mutex); + if (os_recursive_mutex_init(&g_timer_ctx_list_mutex) != 0) { + goto fail1; + } - os_thread_create(&tm_tid, thread_modulers_timer_check, NULL, - BH_APPLET_PRESERVED_STACK_SIZE); + if (0 + != os_thread_create(&tm_tid, thread_modulers_timer_check, NULL, + BH_APPLET_PRESERVED_STACK_SIZE)) { + goto fail2; + } + + return true; + +fail2: + os_mutex_destroy(&g_timer_ctx_list_mutex); + +fail1: + os_cond_destroy(&g_timer_ctx_list_cond); + + return false; } void diff --git a/core/app-framework/sensor/native/runtime_sensor.c b/core/app-framework/sensor/native/runtime_sensor.c index 8222ab3ce..ad7a3fbf5 100644 --- a/core/app-framework/sensor/native/runtime_sensor.c +++ b/core/app-framework/sensor/native/runtime_sensor.c @@ -309,7 +309,13 @@ add_sys_sensor(char *name, char *description, int instance, g_sys_sensors = s; } - os_mutex_init(&s->lock); + if (os_mutex_init(&s->lock) != 0) { + if (s->description) { + wasm_runtime_free(s->description); + } + wasm_runtime_free(s->name); + wasm_runtime_free(s); + } return s; } @@ -358,6 +364,7 @@ find_sensor_client(sys_sensor_t *sensor, unsigned int client_id, return c; } else { + prev = c; c = c->next; } } diff --git a/core/app-framework/sensor/native/runtime_sensor.h b/core/app-framework/sensor/native/runtime_sensor.h index b7fba805d..d7c893111 100644 --- a/core/app-framework/sensor/native/runtime_sensor.h +++ b/core/app-framework/sensor/native/runtime_sensor.h @@ -59,7 +59,7 @@ check_sensor_timers(); void reschedule_sensor_read(); -void +bool init_sensor_framework(); void start_sensor_framework(); diff --git a/core/app-framework/sensor/native/sensor_mgr_ref.c b/core/app-framework/sensor/native/sensor_mgr_ref.c index 304214f46..474ec738d 100644 --- a/core/app-framework/sensor/native/sensor_mgr_ref.c +++ b/core/app-framework/sensor/native/sensor_mgr_ref.c @@ -106,12 +106,18 @@ cb_wakeup_thread() void set_sensor_reshceduler(void (*callback)()); -void +bool init_sensor_framework() { - // init the mutext and conditions - os_cond_init(&cond); - os_mutex_init(&mutex); + /* init the mutext and conditions */ + if (os_cond_init(&cond) != 0) { + return false; + } + + if (os_mutex_init(&mutex) != 0) { + os_cond_destroy(&cond); + return false; + } set_sensor_reshceduler(cb_wakeup_thread); @@ -119,6 +125,8 @@ init_sensor_framework() app_mgr_sensor_event_callback); wasm_register_cleanup_callback(sensor_cleanup_callback); + + return true; } void diff --git a/core/app-mgr/app-manager/app_manager_host.c b/core/app-mgr/app-manager/app_manager_host.c index 6b1c3ba45..08b5df309 100644 --- a/core/app-mgr/app-manager/app_manager_host.c +++ b/core/app-mgr/app-manager/app_manager_host.c @@ -264,15 +264,21 @@ aee_host_msg_callback(void *msg, uint32_t msg_len) bool app_manager_host_init(host_interface *interface) { - os_mutex_init(&host_lock); + if (os_mutex_init(&host_lock) != 0) { + return false; + } memset(&recv_ctx, 0, sizeof(recv_ctx)); host_commu.init = interface->init; host_commu.send = interface->send; host_commu.destroy = interface->destroy; - if (host_commu.init != NULL) - return host_commu.init(); + if (host_commu.init != NULL) { + if (!host_commu.init()) { + os_mutex_destroy(&host_lock); + return false; + } + } return true; } diff --git a/core/app-mgr/app-manager/module_wasm_app.c b/core/app-mgr/app-manager/module_wasm_app.c index dd86524db..7b826d6d9 100644 --- a/core/app-mgr/app-manager/module_wasm_app.c +++ b/core/app-mgr/app-manager/module_wasm_app.c @@ -207,10 +207,12 @@ app_instance_queue_callback(void *queue_msg, void *arg) wasm_module_inst_t inst = (wasm_module_inst_t)arg; module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst); - wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data; - int message_type = bh_message_type(queue_msg); + wasm_data *wasm_app_data; + int message_type; bh_assert(m_data); + wasm_app_data = (wasm_data *)m_data->internal_data; + message_type = bh_message_type(queue_msg); if (message_type < BASE_EVENT_MAX) { switch (message_type) { @@ -410,16 +412,15 @@ wasm_app_prepare_wasi_dir(wasm_module_t module, const char *module_name, p += module_name_len; *p++ = '\0'; - /* Create a wasi dir for the module */ - if (stat(wasi_dir_buf, &st) == 0) { - /* exist, but is a regular file, not a dir */ - if (st.st_mode & S_IFREG) - return false; - } - else { - /* not exist, create it */ - if (mkdir(wasi_dir_buf, 0777) != 0) - return false; + if (mkdir(wasi_dir_buf, 0777) != 0) { + if (errno == EEXIST) { + /* Failed due to dir already exist */ + if ((stat(wasi_dir_buf, &st) == 0) && (st.st_mode & S_IFDIR)) { + return true; + } + } + + return false; } return true; @@ -491,9 +492,16 @@ wasm_app_routine(void *arg) fail2: /* Call WASM app onDestroy() method if there is */ func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()"); - if (func_onDestroy) - wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0, - NULL); + if (func_onDestroy) { + if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0, + NULL)) { + const char *exception = wasm_runtime_get_exception(inst); + bh_assert(exception); + app_manager_printf("Got exception running WASM code: %s\n", + exception); + wasm_runtime_clear_exception(inst); + } + } fail1: diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 9ff7356f1..d7728707f 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -261,48 +261,34 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module, char *str; uint16 str_len; - CHECK_BUF(p, p_end, 1); - if (*p & 0x80) { - /* The string has been adjusted */ - str = (char *)++p; - /* Ensure the whole string is in range */ - do { - CHECK_BUF(p, p_end, 1); - } while (*p++ != '\0'); + read_uint16(p, p_end, str_len); + CHECK_BUF(p, p_end, str_len); + + if (str_len == 0) { + str = ""; + } + else if (p[str_len - 1] == '\0') { + /* The string is terminated with '\0', use it directly */ + str = (char *)p; + } + else if (is_load_from_file_buf) { + /* As the file buffer can be referred to after loading, + we use the 2 bytes of size to adjust the string: + move string 2 byte backward and then append '\0' */ + str = (char *)(p - 2); + bh_memmove_s(str, (uint32)(str_len + 1), p, (uint32)str_len); + str[str_len] = '\0'; } else { - /* The string hasn't been adjusted */ - read_uint16(p, p_end, str_len); - CHECK_BUF(p, p_end, str_len); - - if (str_len == 0) { - str = ""; + /* Load from sections, the file buffer cannot be reffered to + after loading, we must create another string and insert it + into const string set */ + if (!(str = const_str_set_insert((uint8 *)p, str_len, module, error_buf, + error_buf_size))) { + goto fail; } - else if (p[str_len - 1] == '\0') { - /* The string is terminated with '\0', use it directly */ - str = (char *)p; - } - else if (is_load_from_file_buf) { - /* As the file buffer can be referred to after loading, - we use the 2 bytes of size to adjust the string: - mark the flag with the highest bit of size[0], - move string 1 byte backward and then append '\0' */ - *(p - 2) |= 0x80; - bh_memmove_s(p - 1, (uint32)(str_len + 1), p, (uint32)str_len); - p[str_len - 1] = '\0'; - str = (char *)(p - 1); - } - else { - /* Load from sections, the file buffer cannot be reffered to - after loading, we must create another string and insert it - into const string set */ - if (!(str = const_str_set_insert((uint8 *)p, str_len, module, - error_buf, error_buf_size))) { - goto fail; - } - } - p += str_len; } + p += str_len; *p_buf = p; return str; @@ -1850,7 +1836,9 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group, || !strcmp(symbol, ".rdata") || !strcmp(symbol, ".rodata") /* ".rodata.cst4/8/16/.." */ - || !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))) { + || !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst")) + /* ".rodata.strn.m" */ + || !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))) { symbol_addr = get_data_section_addr(module, symbol, NULL); if (!symbol_addr) { set_error_buf_v(error_buf, error_buf_size, @@ -2054,6 +2042,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, uint8 *symbol_buf, *symbol_buf_end; int map_prot, map_flags; bool ret = false; + char **symbols = NULL; read_uint32(buf, buf_end, symbol_count); @@ -2074,6 +2063,14 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, goto fail; } + if (symbol_count > 0) { + symbols = loader_malloc((uint64)sizeof(*symbols) * symbol_count, + error_buf, error_buf_size); + if (symbols == NULL) { + goto fail; + } + } + #if defined(BH_PLATFORM_WINDOWS) buf = symbol_buf_end; read_uint32(buf, buf_end, group_count); @@ -2208,7 +2205,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, for (i = 0, group = groups; i < group_count; i++, group++) { AOTRelocation *relocation; uint32 name_index; - uint8 *name_addr; /* section name address is 4 bytes aligned. */ buf = (uint8 *)align_ptr(buf, sizeof(uint32)); @@ -2220,8 +2216,12 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, goto fail; } - name_addr = symbol_buf + symbol_offsets[name_index]; - read_string(name_addr, buf_end, group->section_name); + if (symbols[name_index] == NULL) { + uint8 *name_addr = symbol_buf + symbol_offsets[name_index]; + + read_string(name_addr, buf_end, symbols[name_index]); + } + group->section_name = symbols[name_index]; read_uint32(buf, buf_end, group->relocation_count); @@ -2236,7 +2236,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, /* Load each relocation */ for (j = 0; j < group->relocation_count; j++, relocation++) { uint32 symbol_index; - uint8 *symbol_addr; if (sizeof(void *) == 8) { read_uint64(buf, buf_end, relocation->relocation_offset); @@ -2258,8 +2257,12 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, goto fail; } - symbol_addr = symbol_buf + symbol_offsets[symbol_index]; - read_string(symbol_addr, buf_end, relocation->symbol_name); + if (symbols[symbol_index] == NULL) { + uint8 *symbol_addr = symbol_buf + symbol_offsets[symbol_index]; + + read_string(symbol_addr, buf_end, symbols[symbol_index]); + } + relocation->symbol_name = symbols[symbol_index]; } if (!strcmp(group->section_name, ".rel.text") @@ -2314,7 +2317,10 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, || !strcmp(data_section->name, ".rodata") /* ".rodata.cst4/8/16/.." */ || !strncmp(data_section->name, ".rodata.cst", - strlen(".rodata.cst"))) { + strlen(".rodata.cst")) + /* ".rodata.strn.m" */ + || !strncmp(data_section->name, ".rodata.str", + strlen(".rodata.str"))) { os_mprotect(data_section->data, data_section->size, map_prot); } } @@ -2322,6 +2328,9 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, ret = true; fail: + if (symbols) { + wasm_runtime_free(symbols); + } if (groups) { for (i = 0, group = groups; i < group_count; i++, group++) if (group->relocations) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 19120b457..bab053fc1 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -14,6 +14,22 @@ #include "../libraries/thread-mgr/thread_manager.h" #endif +/* + * Note: These offsets need to match the values hardcoded in + * AoT compilation code: aot_create_func_context, check_suspend_flags. + */ + +bh_static_assert(offsetof(WASMExecEnv, module_inst) == 2 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, argv_buf) == 3 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, native_stack_boundary) + == 4 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, suspend_flags) == 5 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, aux_stack_boundary) + == 6 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, aux_stack_bottom) + == 7 * sizeof(uintptr_t)); +bh_static_assert(offsetof(WASMExecEnv, native_symbol) == 8 * sizeof(uintptr_t)); + static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) { @@ -638,6 +654,10 @@ memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module, /* Get default memory instance */ memory_inst = aot_get_default_memory(module_inst); + if (!memory_inst) { + /* Ignore setting memory init data if no memory inst is created */ + return true; + } for (i = 0; i < module->mem_init_data_count; i++) { data_seg = module->mem_init_data_list[i]; @@ -1778,9 +1798,9 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, malloc_func = aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig); - bh_assert(malloc_func); - if (!execute_malloc_function(module_inst, malloc_func, retain_func, - size, &offset)) { + if (!malloc_func + || !execute_malloc_function(module_inst, malloc_func, retain_func, + size, &offset)) { return 0; } addr = offset ? (uint8 *)memory_inst->memory_data.ptr + offset : NULL; @@ -1873,8 +1893,8 @@ aot_module_free(AOTModuleInstance *module_inst, uint32 ptr) if (!free_func && module->retain_func_index != (uint32)-1) free_func = aot_lookup_function(module_inst, "__unpin", "(i)i"); - bh_assert(free_func); - execute_free_function(module_inst, free_func, ptr); + if (free_func) + execute_free_function(module_inst, free_func, ptr); } } } @@ -2614,7 +2634,7 @@ aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size) static void const_string_node_size_cb(void *key, void *value, void *p_const_string_size) { - uint32 const_string_size = *(uint32 *)p_const_string_size; + uint32 const_string_size = 0; const_string_size += bh_hash_map_get_elem_struct_size(); const_string_size += strlen((const char *)value) + 1; *(uint32 *)p_const_string_size += const_string_size; @@ -2893,6 +2913,7 @@ aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx, #endif /* WASM_ENABLE_REF_TYPES != 0 */ #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0) +#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0 static const char * lookup_func_name(const char **func_names, uint32 *func_indexes, uint32 func_index_count, uint32 func_index) @@ -2913,6 +2934,7 @@ lookup_func_name(const char **func_names, uint32 *func_indexes, return NULL; } +#endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */ static const char * get_func_name_from_index(const AOTModuleInstance *module_inst, diff --git a/core/iwasm/aot/arch/aot_reloc_arm.c b/core/iwasm/aot/arch/aot_reloc_arm.c index 8da77a527..1389bfb25 100644 --- a/core/iwasm/aot/arch/aot_reloc_arm.c +++ b/core/iwasm/aot/arch/aot_reloc_arm.c @@ -8,6 +8,8 @@ #define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */ #define R_ARM_JMP24 29 /* PC relative 24 bit (B/BL). */ #define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 /* clang-format off */ void __adddf3(); @@ -339,6 +341,21 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr, + (intptr_t)reloc_addend; break; } + case R_ARM_MOVW_ABS_NC: + case R_ARM_MOVT_ABS: + { + uintptr_t *loc; + uintptr_t addr; + CHECK_RELOC_OFFSET(sizeof(void *)); + loc = (uintptr_t *)(target_section_addr + (uint32)reloc_offset); + addr = (uintptr_t)symbol_addr + (intptr_t)reloc_addend; + if (reloc_type == R_ARM_MOVT_ABS) { + addr >>= 16; + } + *loc = ((*loc) & 0xfff0f000) | ((addr << 4) & 0x000f0000) + | (addr & 0x00000fff); + break; + } default: if (error_buf != NULL) diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index ec3116c99..a139d1f4e 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -10,6 +10,9 @@ #if WASM_ENABLE_AOT != 0 #include "../aot/aot_runtime.h" #endif +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif static void set_error_buf(char *error_buf, uint32 error_buf_size, const char *string) @@ -76,9 +79,8 @@ check_main_func_type(const WASMType *type) return true; } -bool -wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, - char *argv[]) +static bool +execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) { WASMFunctionInstanceCommon *func; WASMType *func_type = NULL; @@ -203,6 +205,41 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, return ret; } +bool +wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, + char *argv[]) +{ + bool ret; +#if WASM_ENABLE_THREAD_MGR != 0 + WASMCluster *cluster; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 || WASM_ENABLE_MEMORY_PROFILING != 0 + WASMExecEnv *exec_env; +#endif + + ret = execute_main(module_inst, argc, argv); + +#if WASM_ENABLE_THREAD_MGR != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) { + wasm_cluster_wait_for_all_except_self(cluster, exec_env); + } +#endif + +#if WASM_ENABLE_MEMORY_PROFILING != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env) { + wasm_runtime_dump_mem_consumption(exec_env); + } +#endif + +#if WASM_ENABLE_PERF_PROFILING != 0 + wasm_runtime_dump_perf_profiling(module_inst); +#endif + + return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false; +} + #if WASM_ENABLE_MULTI_MODULE != 0 static WASMModuleInstance * get_sub_module_inst(const WASMModuleInstance *parent_module_inst, @@ -351,9 +388,9 @@ union ieee754_double { } ieee; }; -bool -wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, - const char *name, int32 argc, char *argv[]) +static bool +execute_func(WASMModuleInstanceCommon *module_inst, const char *name, + int32 argc, char *argv[]) { WASMFunctionInstanceCommon *target_func; WASMModuleInstanceCommon *target_inst; @@ -689,3 +726,38 @@ fail: os_printf("%s\n", exception); return false; } + +bool +wasm_application_execute_func(WASMModuleInstanceCommon *module_inst, + const char *name, int32 argc, char *argv[]) +{ + bool ret; +#if WASM_ENABLE_THREAD_MGR != 0 + WASMCluster *cluster; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 || WASM_ENABLE_MEMORY_PROFILING != 0 + WASMExecEnv *exec_env; +#endif + + ret = execute_func(module_inst, name, argc, argv); + +#if WASM_ENABLE_THREAD_MGR != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) { + wasm_cluster_wait_for_all_except_self(cluster, exec_env); + } +#endif + +#if WASM_ENABLE_MEMORY_PROFILING != 0 + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env) { + wasm_runtime_dump_mem_consumption(exec_env); + } +#endif + +#if WAMR_ENABLE_PERF_PROFILING != 0 + wasm_runtime_dump_perf_profiling(module_inst); +#endif + + return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false; +} diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 697beb7b3..7c3f5a83a 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -142,6 +142,9 @@ failed: \ void wasm_##name##_vec_copy(wasm_##name##_vec_t *out, \ const wasm_##name##_vec_t *src) \ { \ + if (!src) { \ + return; \ + } \ wasm_##name##_vec_new(out, src->size, src->data); \ } \ void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \ @@ -186,6 +189,10 @@ failed: \ const wasm_##name##_vec_t *src) \ { \ size_t i = 0; \ + \ + if (!out) { \ + return; \ + } \ memset(out, 0, sizeof(Vector)); \ \ if (!src || !src->size) { \ @@ -214,7 +221,7 @@ failed: \ if (!v) { \ return; \ } \ - for (i = 0; i != v->num_elems; ++i) { \ + for (i = 0; i != v->num_elems && v->data; ++i) { \ elem_destroy_func(*(v->data + i)); \ } \ bh_vector_destroy((Vector *)v); \ @@ -381,7 +388,8 @@ wasm_store_new(wasm_engine_t *engine) DEFAULT_VECTOR_INIT_LENGTH); if (!(store->foreigns = malloc_internal(sizeof(Vector))) - || !(bh_vector_init(store->foreigns, 24, sizeof(Vector *), true))) { + || !(bh_vector_init(store->foreigns, 24, sizeof(wasm_foreign_t *), + true))) { goto failed; } @@ -467,6 +475,14 @@ wasm_valtype_new(wasm_valkind_t kind) { wasm_valtype_t *val_type; + if (kind > WASM_F64 && WASM_FUNCREF != kind +#if WASM_ENABLE_REF_TYPES != 0 + && WASM_ANYREF != kind +#endif + ) { + return NULL; + } + if (!(val_type = malloc_internal(sizeof(wasm_valtype_t)))) { return NULL; } @@ -558,14 +574,6 @@ wasm_functype_new(own wasm_valtype_vec_t *params, { wasm_functype_t *type = NULL; - if (!params) { - return NULL; - } - - if (!results) { - return NULL; - } - if (!(type = malloc_internal(sizeof(wasm_functype_t)))) { goto failed; } @@ -576,14 +584,18 @@ wasm_functype_new(own wasm_valtype_vec_t *params, if (!(type->params = malloc_internal(sizeof(wasm_valtype_vec_t)))) { goto failed; } - bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params, - sizeof(wasm_valtype_vec_t)); + if (params) { + bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params, + sizeof(wasm_valtype_vec_t)); + } if (!(type->results = malloc_internal(sizeof(wasm_valtype_vec_t)))) { goto failed; } - bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results, - sizeof(wasm_valtype_vec_t)); + if (results) { + bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results, + sizeof(wasm_valtype_vec_t)); + } return type; @@ -775,7 +787,15 @@ wasm_tabletype_new(own wasm_valtype_t *val_type, const wasm_limits_t *limits) { wasm_tabletype_t *table_type = NULL; - if (!val_type) { + if (!val_type || !limits) { + return NULL; + } + + if (wasm_valtype_kind(val_type) != WASM_FUNCREF +#if WASM_ENABLE_REF_TYPES != 0 + && wasm_valtype_kind(val_type) != WASM_ANYREF +#endif + ) { return NULL; } @@ -979,7 +999,7 @@ wasm_externtype_copy(const wasm_externtype_t *src) COPY_EXTERNTYPE(TABLE, tabletype) #undef COPY_EXTERNTYPE default: - LOG_WARNING("%s meets unsupported kind", __FUNCTION__, + LOG_WARNING("%s meets unsupported kind %u", __FUNCTION__, src->extern_kind); break; } @@ -1007,7 +1027,8 @@ wasm_externtype_delete(wasm_externtype_t *extern_type) wasm_tabletype_delete(wasm_externtype_as_tabletype(extern_type)); break; default: - LOG_WARNING("%s meets unsupported type", __FUNCTION__, extern_type); + LOG_WARNING("%s meets unsupported type %u", __FUNCTION__, + wasm_externtype_kind(extern_type)); break; } } @@ -1019,6 +1040,10 @@ wasm_importtype_new(own wasm_byte_vec_t *module_name, { wasm_importtype_t *import_type = NULL; + if (!module_name || !field_name || !extern_type) { + return NULL; + } + if (!(import_type = malloc_internal(sizeof(wasm_importtype_t)))) { return NULL; } @@ -1055,6 +1080,7 @@ wasm_importtype_delete(own wasm_importtype_t *import_type) DEINIT_VEC(import_type->module_name, wasm_byte_vec_delete); DEINIT_VEC(import_type->name, wasm_byte_vec_delete); wasm_externtype_delete(import_type->extern_type); + import_type->extern_type = NULL; wasm_runtime_free(import_type); } @@ -1134,6 +1160,10 @@ wasm_exporttype_new(own wasm_byte_vec_t *name, { wasm_exporttype_t *export_type = NULL; + if (!name || !extern_type) { + return NULL; + } + if (!(export_type = malloc_internal(sizeof(wasm_exporttype_t)))) { return NULL; } @@ -1366,7 +1396,7 @@ wasm_ref_copy(const wasm_ref_t *src) void wasm_ref_delete(own wasm_ref_t *ref) { - if (!ref) + if (!ref || !ref->store) return; DELETE_HOST_INFO(ref); @@ -1619,7 +1649,7 @@ wasm_trap_new(wasm_store_t *store, const wasm_message_t *message) { wasm_trap_t *trap; - if (!store || !message) { + if (!store) { return NULL; } @@ -1627,7 +1657,10 @@ wasm_trap_new(wasm_store_t *store, const wasm_message_t *message) return NULL; } - INIT_VEC(trap->message, wasm_byte_vec_new, message->size, message->data); + if (message) { + INIT_VEC(trap->message, wasm_byte_vec_new, message->size, + message->data); + } return trap; failed: @@ -2279,7 +2312,7 @@ wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out) } default: { - LOG_WARNING("%s meets unsupported type", __FUNCTION__, + LOG_WARNING("%s meets unsupported type %u", __FUNCTION__, export->kind); break; } @@ -2310,6 +2343,10 @@ wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type, { wasm_func_t *func = NULL; + if (!type) { + goto failed; + } + if (!(func = malloc_internal(sizeof(wasm_func_t)))) { goto failed; } @@ -2334,6 +2371,10 @@ wasm_func_new_with_env_basic(wasm_store_t *store, const wasm_functype_t *type, { wasm_func_t *func = NULL; + if (!type) { + goto failed; + } + if (!(func = malloc_internal(sizeof(wasm_func_t)))) { goto failed; } @@ -2358,6 +2399,9 @@ wasm_func_new(wasm_store_t *store, const wasm_functype_t *type, wasm_func_callback_t callback) { bh_assert(singleton_engine); + if (!callback) { + return NULL; + } return wasm_func_new_basic(store, type, callback); } @@ -2367,6 +2411,9 @@ wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *type, void (*finalizer)(void *)) { bh_assert(singleton_engine); + if (!callback) { + return NULL; + } return wasm_func_new_with_env_basic(store, type, callback, env, finalizer); } @@ -2572,7 +2619,7 @@ argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs, return true; } - if (!results || !results->num_elems || !results->size || !results->data) { + if (!results || !results->size || !results->data) { return false; } @@ -2640,7 +2687,22 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params, WASMExecEnv *exec_env = NULL; size_t param_count, result_count, alloc_count; - bh_assert(func && func->type && func->inst_comm_rt); + if (!func) { + return NULL; + } + + if (!func->inst_comm_rt) { + wasm_name_t message = { 0 }; + wasm_trap_t *trap; + + wasm_name_new_from_string(&message, "failed to call unlinked function"); + trap = wasm_trap_new(func->store, &message); + wasm_byte_vec_delete(&message); + + return trap; + } + + bh_assert(func->type); #if WASM_ENABLE_INTERP != 0 if (func->inst_comm_rt->module_type == Wasm_Module_Bytecode) { @@ -2765,6 +2827,10 @@ wasm_global_new(wasm_store_t *store, const wasm_globaltype_t *global_type, bh_assert(singleton_engine); + if (!global_type || !init) { + goto failed; + } + global = malloc_internal(sizeof(wasm_global_t)); if (!global) { goto failed; @@ -2952,7 +3018,7 @@ aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, void wasm_global_set(wasm_global_t *global, const wasm_val_t *v) { - if (!global || !v) { + if (!global || !v || !global->inst_comm_rt) { return; } @@ -2986,6 +3052,10 @@ wasm_global_get(const wasm_global_t *global, wasm_val_t *out) return; } + if (!global->inst_comm_rt) { + return; + } + memset(out, 0, sizeof(wasm_val_t)); #if WASM_ENABLE_INTERP != 0 @@ -3276,7 +3346,7 @@ wasm_table_get(const wasm_table_t *table, wasm_table_size_t index) { uint32 ref_idx = NULL_REF; - if (!table) { + if (!table || !table->inst_comm_rt) { return NULL; } @@ -3336,7 +3406,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index, uint32 *p_ref_idx = NULL; uint32 function_count = 0; - if (!table) { + if (!table || !table->inst_comm_rt) { return false; } @@ -3417,7 +3487,7 @@ wasm_table_set(wasm_table_t *table, wasm_table_size_t index, wasm_table_size_t wasm_table_size(const wasm_table_t *table) { - if (!table) { + if (!table || !table->inst_comm_rt) { return 0; } @@ -3473,6 +3543,10 @@ wasm_memory_new_basic(wasm_store_t *store, const wasm_memorytype_t *type) { wasm_memory_t *memory = NULL; + if (!type) { + goto failed; + } + if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) { goto failed; } @@ -3606,8 +3680,13 @@ wasm_memory_type(const wasm_memory_t *memory) byte_t * wasm_memory_data(wasm_memory_t *memory) { - WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt; + WASMModuleInstanceCommon *module_inst_comm; + if (!memory || !memory->inst_comm_rt) { + return NULL; + } + + module_inst_comm = memory->inst_comm_rt; #if WASM_ENABLE_INTERP != 0 if (module_inst_comm->module_type == Wasm_Module_Bytecode) { WASMModuleInstance *module_inst = @@ -3638,8 +3717,13 @@ wasm_memory_data(wasm_memory_t *memory) size_t wasm_memory_data_size(const wasm_memory_t *memory) { - WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt; + WASMModuleInstanceCommon *module_inst_comm; + if (!memory || !memory->inst_comm_rt) { + return 0; + } + + module_inst_comm = memory->inst_comm_rt; #if WASM_ENABLE_INTERP != 0 if (module_inst_comm->module_type == Wasm_Module_Bytecode) { WASMModuleInstance *module_inst = @@ -3670,8 +3754,13 @@ wasm_memory_data_size(const wasm_memory_t *memory) wasm_memory_pages_t wasm_memory_size(const wasm_memory_t *memory) { - WASMModuleInstanceCommon *module_inst_comm = memory->inst_comm_rt; + WASMModuleInstanceCommon *module_inst_comm; + if (!memory || !memory->inst_comm_rt) { + return 0; + } + + module_inst_comm = memory->inst_comm_rt; #if WASM_ENABLE_INTERP != 0 if (module_inst_comm->module_type == Wasm_Module_Bytecode) { WASMModuleInstance *module_inst = @@ -3715,7 +3804,6 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, uint16 func_idx_rt, wasm_func_t *import) { WASMImport *imported_func_interp = NULL; - wasm_func_t *cloned = NULL; bh_assert(inst && module_interp && import); bh_assert(func_idx_rt < module_interp->import_function_count); @@ -3724,15 +3812,6 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, imported_func_interp = module_interp->import_functions + func_idx_rt; bh_assert(imported_func_interp); - if (!(cloned = wasm_func_copy(import))) { - return false; - } - - if (!bh_vector_append((Vector *)inst->imports, &cloned)) { - wasm_func_delete(cloned); - return false; - } - imported_func_interp->u.function.call_conv_wasm_c_api = true; imported_func_interp->u.function.wasm_c_api_with_env = import->with_env; if (import->with_env) { @@ -3936,30 +4015,22 @@ aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot, uint32 import_func_idx_rt, wasm_func_t *import) { AOTImportFunc *import_aot_func = NULL; - wasm_func_t *cloned = NULL; bh_assert(inst && module_aot && import); import_aot_func = module_aot->import_funcs + import_func_idx_rt; bh_assert(import_aot_func); - if (!(cloned = wasm_func_copy(import))) { - return false; - } - - if (!bh_vector_append((Vector *)inst->imports, &cloned)) { - wasm_func_delete(cloned); - return false; - } - import_aot_func->call_conv_wasm_c_api = true; import_aot_func->wasm_c_api_with_env = import->with_env; if (import->with_env) { import_aot_func->func_ptr_linked = import->u.cb_env.cb; import_aot_func->attachment = import->u.cb_env.env; } - else + else { import_aot_func->func_ptr_linked = import->u.cb; + import_aot_func->attachment = NULL; + } import->func_idx_rt = import_func_idx_rt; return true; @@ -4188,14 +4259,11 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, } /* link module and imports */ - if (imports) { + if (imports && imports->num_elems) { #if WASM_ENABLE_INTERP != 0 if ((*module)->module_type == Wasm_Module_Bytecode) { import_count = MODULE_INTERP(module)->import_count; - INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized, - import_count); - if (import_count) { uint32 actual_link_import_count = interp_link(instance, MODULE_INTERP(module), @@ -4217,9 +4285,6 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, + MODULE_AOT(module)->import_memory_count + MODULE_AOT(module)->import_table_count; - INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized, - import_count); - if (import_count) { import_count = aot_link(instance, MODULE_AOT(module), (wasm_extern_t **)imports->data); @@ -4344,7 +4409,6 @@ wasm_instance_delete_internal(wasm_instance_t *instance) return; } - DEINIT_VEC(instance->imports, wasm_extern_vec_delete); DEINIT_VEC(instance->exports, wasm_extern_vec_delete); if (instance->inst_comm_rt) { diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index 38954a68e..95bc5fac1 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -206,7 +206,6 @@ struct wasm_extern_t { struct wasm_instance_t { wasm_store_t *store; - wasm_extern_vec_t *imports; wasm_extern_vec_t *exports; struct wasm_host_info host_info; WASMModuleInstanceCommon *inst_comm_rt; diff --git a/core/iwasm/common/wasm_exec_env.c b/core/iwasm/common/wasm_exec_env.c index 1d5da5349..e98fdaa60 100644 --- a/core/iwasm/common/wasm_exec_env.c +++ b/core/iwasm/common/wasm_exec_env.c @@ -54,7 +54,6 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst, if (!(exec_env->current_status = wasm_cluster_create_exenv_status())) goto fail4; #endif - #endif exec_env->module_inst = module_inst; diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index 460580c4e..45319e641 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -109,6 +109,9 @@ typedef struct WASMExecEnv { korp_cond wait_cond; /* the count of threads which are joining current thread */ uint32 wait_count; + + /* whether current thread is detached */ + bool thread_is_detached; #endif #if WASM_ENABLE_DEBUG_INTERP != 0 @@ -188,8 +191,12 @@ wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size) bh_assert(!(size & 3)); - /* The outs area size cannot be larger than the frame size, so - multiplying by 2 is enough. */ + /* For classic interpreter, the outs area doesn't contain the const cells, + its size cannot be larger than the frame size, so here checking stack + overflow with multiplying by 2 is enough. For fast interpreter, since + the outs area contains const cells, its size may be larger than current + frame size, we should check again before putting the function arguments + into the outs area. */ if (addr + size * 2 > exec_env->wasm_stack.s.top_boundary) { /* WASM stack overflow. */ return NULL; diff --git a/core/iwasm/common/wasm_memory.c b/core/iwasm/common/wasm_memory.c index 42f52cacf..4f58bbc3c 100644 --- a/core/iwasm/common/wasm_memory.c +++ b/core/iwasm/common/wasm_memory.c @@ -86,7 +86,7 @@ wasm_runtime_memory_pool_size() if (memory_mode == MEMORY_MODE_POOL) return global_pool_size; else - return 1 * BH_GB; + return UINT32_MAX; } static inline void * diff --git a/core/iwasm/common/wasm_memory.h b/core/iwasm/common/wasm_memory.h index 8511ae647..b5f3f78c7 100644 --- a/core/iwasm/common/wasm_memory.h +++ b/core/iwasm/common/wasm_memory.h @@ -20,6 +20,9 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type, void wasm_runtime_memory_destroy(); +unsigned +wasm_runtime_memory_pool_size(); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index ae0711c31..d5e4f02b2 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -32,6 +32,28 @@ #endif #include "../common/wasm_c_api_internal.h" +/** + * For runtime build, BH_MALLOC/BH_FREE should be defined as + * wasm_runtime_malloc/wasm_runtime_free. + */ +#define CHECK(a) CHECK1(a) +#define CHECK1(a) SHOULD_BE_##a + +#define SHOULD_BE_wasm_runtime_malloc 1 +#if !CHECK(BH_MALLOC) +#error unexpected BH_MALLOC +#endif +#undef SHOULD_BE_wasm_runtime_malloc + +#define SHOULD_BE_wasm_runtime_free 1 +#if !CHECK(BH_FREE) +#error unexpected BH_FREE +#endif +#undef SHOULD_BE_wasm_runtime_free + +#undef CHECK +#undef CHECK1 + #if WASM_ENABLE_MULTI_MODULE != 0 /** * A safety insurance to prevent @@ -824,26 +846,28 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot, { WASMModuleCommon *module_common; -#if WASM_ENABLE_INTERP != 0 if (!is_aot) { +#if WASM_ENABLE_INTERP != 0 module_common = (WASMModuleCommon *)wasm_load_from_sections( section_list, error_buf, error_buf_size); return register_module_with_null_name(module_common, error_buf, error_buf_size); - } #endif + } + else { #if WASM_ENABLE_AOT != 0 - if (is_aot) { module_common = (WASMModuleCommon *)aot_load_from_sections( section_list, error_buf, error_buf_size); return register_module_with_null_name(module_common, error_buf, error_buf_size); - } #endif + } +#if WASM_ENABLE_INTERP == 0 || WASM_ENABLE_AOT == 0 set_error_buf(error_buf, error_buf_size, "WASM module load failed: invalid section list type"); return NULL; +#endif } void @@ -1268,7 +1292,7 @@ wasm_runtime_prepare_call_function(WASMExecEnv *exec_env, } if (!need_param_transform) { - bh_memcpy_s(new_argv, size, argv, size); + bh_memcpy_s(new_argv, (uint32)size, argv, (uint32)size); } else { for (param_i = 0; param_i < func_type->param_count && argv_i < argc @@ -1328,7 +1352,7 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env, bh_assert((argv && ret_argv) || (argc == 0)); - if (argv == ret_argv || argc == 0) { + if (argv == ret_argv) { /* no need to transfrom externref results */ return true; } diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 985861972..a0b4001e4 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -224,17 +224,22 @@ acquire_wait_info(void *address, bool create) AtomicWaitInfo *wait_info = NULL; bh_list_status ret; + os_mutex_lock(&shared_memory_list_lock); + if (address) wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address); - if (!create) + if (!create) { + os_mutex_unlock(&shared_memory_list_lock); return wait_info; + } /* No wait info on this address, create new info */ if (!wait_info) { if (!(wait_info = (AtomicWaitInfo *)wasm_runtime_malloc( - sizeof(AtomicWaitInfo)))) - return NULL; + sizeof(AtomicWaitInfo)))) { + goto fail1; + } memset(wait_info, 0, sizeof(AtomicWaitInfo)); /* init wait list */ @@ -244,20 +249,30 @@ acquire_wait_info(void *address, bool create) /* init wait list lock */ if (0 != os_mutex_init(&wait_info->wait_list_lock)) { - wasm_runtime_free(wait_info); - return NULL; + goto fail2; } if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) { - os_mutex_destroy(&wait_info->wait_list_lock); - wasm_runtime_free(wait_info); - return NULL; + goto fail3; } } + os_mutex_unlock(&shared_memory_list_lock); + bh_assert(wait_info); (void)ret; return wait_info; + +fail3: + os_mutex_destroy(&wait_info->wait_list_lock); + +fail2: + wasm_runtime_free(wait_info); + +fail1: + os_mutex_unlock(&shared_memory_list_lock); + + return NULL; } static void @@ -285,10 +300,14 @@ destroy_wait_info(void *wait_info) static void release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address) { + os_mutex_lock(&shared_memory_list_lock); + if (wait_info->wait_list->len == 0) { bh_hash_map_remove(wait_map_, address, NULL, NULL); destroy_wait_info(wait_info); } + + os_mutex_unlock(&shared_memory_list_lock); } uint32 @@ -405,8 +424,9 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, uint32 notify_result; AtomicWaitInfo *wait_info; - /* Nobody wait on this address */ wait_info = acquire_wait_info(address, false); + + /* Nobody wait on this address */ if (!wait_info) return 0; @@ -414,7 +434,5 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, notify_result = notify_wait_list(wait_info->wait_list, count); os_mutex_unlock(&wait_info->wait_list_lock); - release_wait_info(wait_map, wait_info, address); - return notify_result; } diff --git a/core/iwasm/compilation/aot_compiler.c b/core/iwasm/compilation/aot_compiler.c index e1516eebe..d1bb081ad 100644 --- a/core/iwasm/compilation/aot_compiler.c +++ b/core/iwasm/compilation/aot_compiler.c @@ -276,8 +276,13 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index) aot_set_last_error("allocate memory failed."); goto fail; } +#if WASM_ENABLE_FAST_INTERP != 0 for (i = 0; i <= br_count; i++) read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]); +#else + for (i = 0; i <= br_count; i++) + br_depths[i] = *frame_ip++; +#endif if (!aot_compile_op_br_table(comp_ctx, func_ctx, br_depths, br_count, &frame_ip)) { @@ -288,6 +293,35 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index) wasm_runtime_free(br_depths); break; +#if WASM_ENABLE_FAST_INTERP == 0 + case EXT_OP_BR_TABLE_CACHE: + { + BrTableCache *node = bh_list_first_elem( + comp_ctx->comp_data->wasm_module->br_table_cache_list); + BrTableCache *node_next; + uint8 *p_opcode = frame_ip - 1; + + read_leb_uint32(frame_ip, frame_ip_end, br_count); + + while (node) { + node_next = bh_list_elem_next(node); + if (node->br_table_op_addr == p_opcode) { + br_depths = node->br_depths; + if (!aot_compile_op_br_table(comp_ctx, func_ctx, + br_depths, br_count, + &frame_ip)) { + return false; + } + break; + } + node = node_next; + } + bh_assert(node); + + break; + } +#endif + case WASM_OP_RETURN: if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip)) return false; @@ -2636,7 +2670,7 @@ apply_func_passes(AOTCompContext *comp_ctx) return true; } -#if WASM_ENABLE_LLVM_LEGACY_PM != 0 +#if WASM_ENABLE_LLVM_LEGACY_PM != 0 || LLVM_VERSION_MAJOR < 12 static bool apply_lto_passes(AOTCompContext *comp_ctx) { @@ -2675,7 +2709,7 @@ apply_lto_passes(AOTCompContext *comp_ctx) LLVMPassManagerBuilderDispose(pass_mgr_builder); return true; } -#endif +#endif /* end of WASM_ENABLE_LLVM_LEGACY_PM != 0 || LLVM_VERSION_MAJOR < 12 */ /* Check whether the target supports hardware atomic instructions */ static bool @@ -2782,7 +2816,7 @@ aot_compile_wasm(AOTCompContext *comp_ctx) } } else { -#if WASM_ENABLE_LLVM_LEGACY_PM == 0 +#if WASM_ENABLE_LLVM_LEGACY_PM == 0 && LLVM_VERSION_MAJOR >= 12 /* Run llvm new pass manager for AOT compiler if llvm legacy pass manager isn't used */ bh_print_time("Begin to run llvm optimization passes"); diff --git a/core/iwasm/compilation/aot_compiler.h b/core/iwasm/compilation/aot_compiler.h index 8637b6d82..4efd1bfb0 100644 --- a/core/iwasm/compilation/aot_compiler.h +++ b/core/iwasm/compilation/aot_compiler.h @@ -371,11 +371,6 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data, bool aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name); -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" */ #endif diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 7b98482ec..dacb59c69 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -2103,8 +2103,10 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) return false; } - strncpy(obj_data->target_info.arch, comp_ctx->target_arch, - sizeof(obj_data->target_info.arch)); + bh_assert(sizeof(obj_data->target_info.arch) + == sizeof(comp_ctx->target_arch)); + bh_memcpy_s(obj_data->target_info.arch, sizeof(obj_data->target_info.arch), + comp_ctx->target_arch, sizeof(comp_ctx->target_arch)); return true; } @@ -2180,6 +2182,8 @@ is_data_section(LLVMSectionIteratorRef sec_itr, char *section_name) || !strcmp(section_name, ".rodata") /* ".rodata.cst4/8/16/.." */ || !strncmp(section_name, ".rodata.cst", strlen(".rodata.cst")) + /* ".rodata.strn.m" */ + || !strncmp(section_name, ".rodata.str", strlen(".rodata.str")) || (!strcmp(section_name, ".rdata") && get_relocations_count(sec_itr, &relocation_count) && relocation_count > 0)); @@ -2399,13 +2403,15 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data, relocation->relocation_type = (uint32)type; relocation->symbol_name = (char *)LLVMGetSymbolName(rel_sym); - /* for ".LCPIxxx", ".LJTIxxx" and ".LBBxxx" relocation, - * transform the symbol name to real section name and set + /* for ".LCPIxxx", ".LJTIxxx", ".LBBxxx" and switch lookup table + * relocation, transform the symbol name to real section name and set * addend to the offset of the symbol in the real section */ if (relocation->symbol_name && (str_starts_with(relocation->symbol_name, ".LCPI") || str_starts_with(relocation->symbol_name, ".LJTI") - || str_starts_with(relocation->symbol_name, ".LBB"))) { + || str_starts_with(relocation->symbol_name, ".LBB") + || str_starts_with(relocation->symbol_name, + ".Lswitch.table."))) { /* change relocation->relocation_addend and relocation->symbol_name */ LLVMSectionIteratorRef contain_section; diff --git a/core/iwasm/compilation/aot_emit_memory.c b/core/iwasm/compilation/aot_emit_memory.c index f1c62fd59..7bba057d3 100644 --- a/core/iwasm/compilation/aot_emit_memory.c +++ b/core/iwasm/compilation/aot_emit_memory.c @@ -141,7 +141,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, comp_ctx->comp_data->memories[0].num_bytes_per_page; uint32 init_page_count = comp_ctx->comp_data->memories[0].mem_init_page_count; - uint64 mem_data_size = num_bytes_per_page * init_page_count; + uint64 mem_data_size = (uint64)num_bytes_per_page * init_page_count; if (mem_offset + bytes <= mem_data_size) { /* inside memory space */ diff --git a/core/iwasm/compilation/aot_emit_numberic.c b/core/iwasm/compilation/aot_emit_numberic.c index 58285ca5f..ed1784e1a 100644 --- a/core/iwasm/compilation/aot_emit_numberic.c +++ b/core/iwasm/compilation/aot_emit_numberic.c @@ -529,7 +529,6 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx, default: bh_assert(0); return false; - ; } } diff --git a/core/iwasm/compilation/aot_llvm.c b/core/iwasm/compilation/aot_llvm.c index f9e03f9c5..9252fc2ab 100644 --- a/core/iwasm/compilation/aot_llvm.c +++ b/core/iwasm/compilation/aot_llvm.c @@ -2276,6 +2276,9 @@ aot_value_stack_destroy(AOTValueStack *stack) wasm_runtime_free(value); value = p; } + + stack->value_list_head = NULL; + stack->value_list_end = NULL; } void @@ -2319,6 +2322,9 @@ aot_block_stack_destroy(AOTBlockStack *stack) aot_block_destroy(block); block = p; } + + stack->block_list_head = NULL; + stack->block_list_end = NULL; } void diff --git a/core/iwasm/compilation/aot_llvm_extra.cpp b/core/iwasm/compilation/aot_llvm_extra.cpp index 45aeb9cdd..b25852cf4 100644 --- a/core/iwasm/compilation/aot_llvm_extra.cpp +++ b/core/iwasm/compilation/aot_llvm_extra.cpp @@ -111,9 +111,15 @@ WAMRCreateMCJITCompilerForModule(LLVMExecutionEngineRef *OutJIT, for (auto &F : *Mod) { auto Attrs = F.getAttributes(); StringRef Value = options.NoFramePointerElim ? "all" : "none"; +#if LLVM_VERSION_MAJOR <= 13 Attrs = Attrs.addAttribute(F.getContext(), AttributeList::FunctionIndex, "frame-pointer", Value); +#else + Attrs = Attrs.addAttributeAtIndex(F.getContext(), + AttributeList::FunctionIndex, + "frame-pointer", Value); +#endif F.setAttributes(Attrs); } } @@ -293,6 +299,8 @@ aot_check_simd_compatibility(const char *arch_c_str, const char *cpu_c_str) #endif /* WASM_ENABLE_SIMD */ } +#if WASM_ENABLE_LAZY_JIT != 0 + #if LLVM_VERSION_MAJOR < 12 LLVMOrcJITTargetMachineBuilderRef LLVMOrcJITTargetMachineBuilderFromTargetMachine(LLVMTargetMachineRef TM); @@ -304,8 +312,6 @@ LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM) } #endif -#if WASM_ENABLE_LAZY_JIT != 0 - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLJITBuilder, LLVMOrcLLJITBuilderRef) void @@ -348,7 +354,7 @@ aot_lookup_orcjit_func(LLVMOrcLLJITRef orc_lazyjit, void *module_inst, func_ptrs[func_idx] = (void *)func_addr; return (void *)func_addr; } -#endif +#endif /* end of WASM_ENABLE_LAZY_JIT != 0 */ void aot_func_disable_tce(LLVMValueRef func) @@ -356,11 +362,18 @@ aot_func_disable_tce(LLVMValueRef func) Function *F = unwrap(func); auto Attrs = F->getAttributes(); +#if LLVM_VERSION_MAJOR <= 13 Attrs = Attrs.addAttribute(F->getContext(), AttributeList::FunctionIndex, "disable-tail-calls", "true"); +#else + Attrs = + Attrs.addAttributeAtIndex(F->getContext(), AttributeList::FunctionIndex, + "disable-tail-calls", "true"); +#endif F->setAttributes(Attrs); } +#if LLVM_VERSION_MAJOR >= 12 void aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx) { @@ -403,6 +416,7 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx) ModulePassManager MPM; +#if LLVM_VERSION_MAJOR <= 13 PassBuilder::OptimizationLevel OL; switch (comp_ctx->opt_level) { @@ -420,6 +434,25 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx) OL = PassBuilder::OptimizationLevel::O3; break; } +#else + OptimizationLevel OL; + + switch (comp_ctx->opt_level) { + case 0: + OL = OptimizationLevel::O0; + break; + case 1: + OL = OptimizationLevel::O1; + break; + case 2: + OL = OptimizationLevel::O2; + break; + case 3: + default: + OL = OptimizationLevel::O3; + break; + } +#endif /* end of LLVM_VERSION_MAJOR */ if (comp_ctx->disable_llvm_lto) { disable_llvm_lto = true; @@ -478,3 +511,4 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx) } #endif } +#endif /* end of LLVM_VERSION_MAJOR >= 12 */ diff --git a/core/iwasm/fast-jit/jit_frontend.c b/core/iwasm/fast-jit/jit_frontend.c index 602ce52a7..b5955b3cb 100644 --- a/core/iwasm/fast-jit/jit_frontend.c +++ b/core/iwasm/fast-jit/jit_frontend.c @@ -1083,8 +1083,13 @@ jit_compile_func(JitCompContext *cc) jit_set_last_error(cc, "allocate memory failed."); goto fail; } +#if WASM_ENABLE_FAST_INTERP != 0 for (i = 0; i <= br_count; i++) read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]); +#else + for (i = 0; i <= br_count; i++) + br_depths[i] = *frame_ip++; +#endif if (!jit_compile_op_br_table(cc, br_depths, br_count, &frame_ip)) { @@ -1095,6 +1100,34 @@ jit_compile_func(JitCompContext *cc) jit_free(br_depths); break; +#if WASM_ENABLE_FAST_INTERP == 0 + case EXT_OP_BR_TABLE_CACHE: + { + BrTableCache *node = bh_list_first_elem( + cc->cur_wasm_module->br_table_cache_list); + BrTableCache *node_next; + uint8 *p_opcode = frame_ip - 1; + + read_leb_uint32(frame_ip, frame_ip_end, br_count); + + while (node) { + node_next = bh_list_elem_next(node); + if (node->br_table_op_addr == p_opcode) { + br_depths = node->br_depths; + if (!jit_compile_op_br_table(cc, br_depths, br_count, + &frame_ip)) { + return false; + } + break; + } + node = node_next; + } + bh_assert(node); + + break; + } +#endif + case WASM_OP_RETURN: if (!jit_compile_op_return(cc, &frame_ip)) return false; diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 8080fa809..d21a6cabf 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -637,6 +637,12 @@ wasm_runtime_get_custom_data(wasm_module_inst_t module_inst); /** * Allocate memory from the heap of WASM module instance * + * Note: wasm_runtime_module_malloc can call heap functions inside + * the module instance and thus cause a memory growth. + * This API needs to be used very carefully when you have a native + * pointers to the module instance memory obtained with + * wasm_runtime_addr_app_to_native or similar APIs. + * * @param module_inst the WASM module instance which contains heap * @param size the size bytes to allocate * @param p_native_addr return native address of the allocated memory @@ -699,6 +705,10 @@ wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst, * space or memory space. Moreover, it checks whether it is the offset of a * string that is end with '\0'. * + * Note: The validation result, especially the NUL termination check, + * is not reliable for a module instance with multiple threads because + * other threads can modify the heap behind us. + * * @param module_inst the WASM module instance * @param app_str_offset the app address of the string to validate, which is a * relative address @@ -729,6 +739,10 @@ wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst, /** * Convert app address(relative address) to native address(absolute address) * + * Note that native addresses to module instance memory can be invalidated + * on a memory growth. (Except shared memory, whose native addresses are + * stable.) + * * @param module_inst the WASM module instance * @param app_offset the app adress * diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 89ec5aa34..20478c586 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -330,6 +330,14 @@ typedef struct StringNode { char *str; } StringNode, *StringList; +typedef struct BrTableCache { + struct BrTableCache *next; + /* Address of br_table opcode */ + uint8 *br_table_op_addr; + uint32 br_count; + uint32 br_depths[1]; +} BrTableCache; + #if WASM_ENABLE_DEBUG_INTERP != 0 typedef struct WASMFastOPCodeNode { struct WASMFastOPCodeNode *next; @@ -415,6 +423,10 @@ struct WASMModule { bool possible_memory_grow; StringList const_str_list; +#if WASM_ENABLE_FAST_INTERP == 0 + bh_list br_table_cache_list_head; + bh_list *br_table_cache_list; +#endif #if WASM_ENABLE_LIBC_WASI != 0 WASIArguments wasi_args; diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index c6760b945..5dfdcbd78 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -259,19 +259,21 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign) --frame_csp; \ } while (0) -#define POP_CSP_N(n) \ - do { \ - uint32 *frame_sp_old = frame_sp; \ - uint32 cell_num_to_copy; \ - POP_CSP_CHECK_OVERFLOW(n + 1); \ - frame_csp -= n; \ - frame_ip = (frame_csp - 1)->target_addr; \ - /* copy arity values of block */ \ - frame_sp = (frame_csp - 1)->frame_sp; \ - cell_num_to_copy = (frame_csp - 1)->cell_num; \ - word_copy(frame_sp, frame_sp_old - cell_num_to_copy, \ - cell_num_to_copy); \ - frame_sp += cell_num_to_copy; \ +#define POP_CSP_N(n) \ + do { \ + uint32 *frame_sp_old = frame_sp; \ + uint32 cell_num_to_copy; \ + POP_CSP_CHECK_OVERFLOW(n + 1); \ + frame_csp -= n; \ + frame_ip = (frame_csp - 1)->target_addr; \ + /* copy arity values of block */ \ + frame_sp = (frame_csp - 1)->frame_sp; \ + cell_num_to_copy = (frame_csp - 1)->cell_num; \ + if (cell_num_to_copy > 0) { \ + word_copy(frame_sp, frame_sp_old - cell_num_to_copy, \ + cell_num_to_copy); \ + } \ + frame_sp += cell_num_to_copy; \ } while (0) /* Pop the given number of elements from the given frame's stack. */ @@ -697,7 +699,7 @@ static inline int64 sign_ext_8_64(int8 val) { if (val & 0x80) - return (int64)val | (int64)0xffffffffffffff00; + return (int64)val | (int64)0xffffffffffffff00LL; return val; } @@ -705,7 +707,7 @@ static inline int64 sign_ext_16_64(int16 val) { if (val & 0x8000) - return (int64)val | (int64)0xffffffffffff0000; + return (int64)val | (int64)0xffffffffffff0000LL; return val; } @@ -713,15 +715,22 @@ static inline int64 sign_ext_32_64(int32 val) { if (val & (int32)0x80000000) - return (int64)val | (int64)0xffffffff00000000; + return (int64)val | (int64)0xffffffff00000000LL; return val; } static inline void word_copy(uint32 *dest, uint32 *src, unsigned num) { - for (; num > 0; num--) - *dest++ = *src++; + bh_assert(dest != NULL); + bh_assert(src != NULL); + bh_assert(num > 0); + if (dest != src) { + /* No overlap buffer */ + bh_assert(!((src < dest) && (dest < src + num))); + for (; num > 0; num--) + *dest++ = *src++; + } } static inline WASMInterpFrame * @@ -765,7 +774,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, WASMFunctionImport *func_import = cur_func->u.func_import; unsigned local_cell_num = 2; WASMInterpFrame *frame; - uint32 argv_ret[2]; + uint32 argv_ret[2], cur_func_index; + void *native_func_pointer = NULL; char buf[128]; bool ret; @@ -780,7 +790,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, wasm_exec_env_set_cur_frame(exec_env, frame); - if (!func_import->func_ptr_linked) { + cur_func_index = (uint32)(cur_func - module_inst->functions); + bh_assert(cur_func_index < module_inst->module->import_function_count); + native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; + + if (!native_func_pointer) { snprintf(buf, sizeof(buf), "failed to call unlinked import function (%s, %s)", func_import->module_name, func_import->field_name); @@ -790,9 +804,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, if (func_import->call_conv_wasm_c_api) { ret = wasm_runtime_invoke_c_api_native( - (WASMModuleInstanceCommon *)module_inst, - func_import->func_ptr_linked, func_import->func_type, - cur_func->param_cell_num, frame->lp, + (WASMModuleInstanceCommon *)module_inst, native_func_pointer, + func_import->func_type, cur_func->param_cell_num, frame->lp, func_import->wasm_c_api_with_env, func_import->attachment); if (ret) { argv_ret[0] = frame->lp[0]; @@ -801,13 +814,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, } else if (!func_import->call_conv_raw) { ret = wasm_runtime_invoke_native( - exec_env, func_import->func_ptr_linked, func_import->func_type, + exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } else { ret = wasm_runtime_invoke_native_raw( - exec_env, func_import->func_ptr_linked, func_import->func_type, + exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } @@ -1084,7 +1097,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, { value_type = *frame_ip++; param_cell_num = 0; - cell_num = wasm_value_type_cell_num(value_type); + cell_num = 0; handle_op_loop: PUSH_CSP(LABEL_TYPE_LOOP, param_cell_num, cell_num, frame_ip); HANDLE_OP_END(); @@ -1207,12 +1220,33 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, lidx = POP_I32(); if (lidx > count) lidx = count; - for (i = 0; i < lidx; i++) - skip_leb(frame_ip); - read_leb_uint32(frame_ip, frame_ip_end, depth); + depth = frame_ip[lidx]; goto label_pop_csp_n; } + HANDLE_OP(EXT_OP_BR_TABLE_CACHE) + { + BrTableCache *node = + bh_list_first_elem(module->module->br_table_cache_list); + BrTableCache *node_next; + +#if WASM_ENABLE_THREAD_MGR != 0 + CHECK_SUSPEND_FLAGS(); +#endif + lidx = POP_I32(); + + while (node) { + node_next = bh_list_elem_next(node); + if (node->br_table_op_addr == frame_ip - 1) { + depth = node->br_depths[lidx]; + goto label_pop_csp_n; + } + node = node_next; + } + bh_assert(0); + HANDLE_OP_END(); + } + HANDLE_OP(WASM_OP_RETURN) { frame_sp -= cur_func->ret_cell_num; @@ -3594,7 +3628,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, call_func_from_return_call: { POP(cur_func->param_cell_num); - word_copy(frame->lp, frame_sp, cur_func->param_cell_num); + if (cur_func->param_cell_num > 0) { + word_copy(frame->lp, frame_sp, cur_func->param_cell_num); + } FREE_FRAME(exec_env, frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame); goto call_func_from_entry; @@ -3606,7 +3642,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, WASMInterpFrame *outs_area = wasm_exec_env_wasm_stack_top(exec_env); POP(cur_func->param_cell_num); SYNC_ALL_TO_FRAME(); - word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num); + if (cur_func->param_cell_num > 0) { + word_copy(outs_area->lp, frame_sp, cur_func->param_cell_num); + } prev_frame = frame; } diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 24ae38dfe..b64609d7a 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -764,7 +764,7 @@ static inline int64 sign_ext_8_64(int8 val) { if (val & 0x80) - return (int64)val | (int64)0xffffffffffffff00; + return (int64)val | (int64)0xffffffffffffff00LL; return val; } @@ -772,7 +772,7 @@ static inline int64 sign_ext_16_64(int16 val) { if (val & 0x8000) - return (int64)val | (int64)0xffffffffffff0000; + return (int64)val | (int64)0xffffffffffff0000LL; return val; } @@ -780,15 +780,22 @@ static inline int64 sign_ext_32_64(int32 val) { if (val & (int32)0x80000000) - return (int64)val | (int64)0xffffffff00000000; + return (int64)val | (int64)0xffffffff00000000LL; return val; } static inline void word_copy(uint32 *dest, uint32 *src, unsigned num) { - for (; num > 0; num--) - *dest++ = *src++; + bh_assert(dest != NULL); + bh_assert(src != NULL); + bh_assert(num > 0); + if (dest != src) { + /* No overlap buffer */ + bh_assert(!((src < dest) && (dest < src + num))); + for (; num > 0; num--) + *dest++ = *src++; + } } static inline WASMInterpFrame * @@ -832,7 +839,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, WASMFunctionImport *func_import = cur_func->u.func_import; unsigned local_cell_num = 2; WASMInterpFrame *frame; - uint32 argv_ret[2]; + uint32 argv_ret[2], cur_func_index; + void *native_func_pointer = NULL; bool ret; if (!(frame = ALLOC_FRAME(exec_env, @@ -846,7 +854,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, wasm_exec_env_set_cur_frame(exec_env, frame); - if (!func_import->func_ptr_linked) { + cur_func_index = (uint32)(cur_func - module_inst->functions); + bh_assert(cur_func_index < module_inst->module->import_function_count); + native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; + + if (!native_func_pointer) { char buf[128]; snprintf(buf, sizeof(buf), "failed to call unlinked import function (%s, %s)", @@ -857,9 +869,8 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, if (func_import->call_conv_wasm_c_api) { ret = wasm_runtime_invoke_c_api_native( - (WASMModuleInstanceCommon *)module_inst, - func_import->func_ptr_linked, func_import->func_type, - cur_func->param_cell_num, frame->lp, + (WASMModuleInstanceCommon *)module_inst, native_func_pointer, + func_import->func_type, cur_func->param_cell_num, frame->lp, func_import->wasm_c_api_with_env, func_import->attachment); if (ret) { argv_ret[0] = frame->lp[0]; @@ -868,13 +879,13 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, } else if (!func_import->call_conv_raw) { ret = wasm_runtime_invoke_native( - exec_env, func_import->func_ptr_linked, func_import->func_type, + exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } else { ret = wasm_runtime_invoke_native_raw( - exec_env, func_import->func_ptr_linked, func_import->func_type, + exec_env, native_func_pointer, func_import->func_type, func_import->signature, func_import->attachment, frame->lp, cur_func->param_cell_num, argv_ret); } @@ -3532,6 +3543,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, HANDLE_OP(EXT_OP_BLOCK) HANDLE_OP(EXT_OP_LOOP) HANDLE_OP(EXT_OP_IF) + HANDLE_OP(EXT_OP_BR_TABLE_CACHE) { wasm_set_exception(module, "unsupported opcode"); goto got_exception; @@ -3571,7 +3583,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } } frame->lp = frame->operand + cur_func->const_cell_num; - word_copy(frame->lp, lp_base, lp - lp_base); + if (lp - lp_base > 0) { + word_copy(frame->lp, lp_base, lp - lp_base); + } wasm_runtime_free(lp_base); FREE_FRAME(exec_env, frame); frame_ip += cur_func->param_count * sizeof(int16); @@ -3598,6 +3612,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, { outs_area->lp = outs_area->operand + cur_func->const_cell_num; } + + if ((uint8 *)(outs_area->lp + cur_func->param_cell_num) + > exec_env->wasm_stack.s.top_boundary) { + wasm_set_exception(module, "wasm operand stack overflow"); + goto got_exception; + } + for (i = 0; i < cur_func->param_count; i++) { if (cur_func->param_types[i] == VALUE_TYPE_I64 || cur_func->param_types[i] == VALUE_TYPE_F64) { @@ -3684,8 +3705,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, frame->operand + cur_wasm_func->const_cell_num; /* Initialize the consts */ - word_copy(frame->operand, (uint32 *)cur_wasm_func->consts, - cur_wasm_func->const_cell_num); + if (cur_wasm_func->const_cell_num > 0) { + word_copy(frame->operand, (uint32 *)cur_wasm_func->consts, + cur_wasm_func->const_cell_num); + } /* Initialize the local variables */ memset(frame_lp + cur_func->param_cell_num, 0, @@ -3786,6 +3809,13 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, frame->lp = frame->operand + 0; frame->ret_offset = 0; + if ((uint8 *)(outs_area->operand + function->const_cell_num + argc) + > exec_env->wasm_stack.s.top_boundary) { + wasm_set_exception((WASMModuleInstance *)exec_env->module_inst, + "wasm operand stack overflow"); + return; + } + if (argc > 0) word_copy(outs_area->operand + function->const_cell_num, argv, argc); diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 1886fc14d..e0b35d057 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -10,6 +10,7 @@ #include "wasm_opcode.h" #include "wasm_runtime.h" #include "../common/wasm_native.h" +#include "../common/wasm_memory.h" #if WASM_ENABLE_DEBUG_INTERP != 0 #include "../libraries/debug-engine/debug_engine.h" #endif @@ -1233,9 +1234,6 @@ fail: return false; } -unsigned -wasm_runtime_memory_pool_size(); - static bool check_memory_init_size(uint32 init_size, char *error_buf, uint32 error_buf_size) { @@ -3285,6 +3283,9 @@ create_module(char *error_buf, uint32 error_buf_size) { WASMModule *module = loader_malloc(sizeof(WASMModule), error_buf, error_buf_size); +#if WASM_ENABLE_FAST_INTERP == 0 + bh_list_status ret; +#endif if (!module) { return NULL; @@ -3295,6 +3296,13 @@ create_module(char *error_buf, uint32 error_buf_size) /* Set start_function to -1, means no start function */ module->start_function = (uint32)-1; +#if WASM_ENABLE_FAST_INTERP == 0 + module->br_table_cache_list = &module->br_table_cache_list_head; + ret = bh_list_init(module->br_table_cache_list); + bh_assert(ret == BH_LIST_SUCCESS); + (void)ret; +#endif + #if WASM_ENABLE_MULTI_MODULE != 0 module->import_module_list = &module->import_module_list_head; #endif @@ -3309,16 +3317,18 @@ create_module(char *error_buf, uint32 error_buf_size) } #if WASM_ENABLE_DEBUG_INTERP != 0 -static void -record_fast_op(WASMModule *module, uint8 *pos, uint8 orig_op) +static bool +record_fast_op(WASMModule *module, uint8 *pos, uint8 orig_op, char *error_buf, + uint32 error_buf_size) { WASMFastOPCodeNode *fast_op = - loader_malloc(sizeof(WASMFastOPCodeNode), NULL, 0); + loader_malloc(sizeof(WASMFastOPCodeNode), error_buf, error_buf_size); if (fast_op) { fast_op->offset = pos - module->load_addr; fast_op->orig_op = orig_op; bh_list_insert(&module->fast_opcode_list, fast_op); } + return fast_op ? true : false; } #endif @@ -3735,6 +3745,18 @@ wasm_loader_unload(WASMModule *module) } } +#if WASM_ENABLE_FAST_INTERP == 0 + if (module->br_table_cache_list) { + BrTableCache *node = bh_list_first_elem(module->br_table_cache_list); + BrTableCache *node_next; + while (node) { + node_next = bh_list_elem_next(node); + wasm_runtime_free(node); + node = node_next; + } + } +#endif + #if WASM_ENABLE_MULTI_MODULE != 0 /* just release the sub module list */ if (module->import_module_list) { @@ -3906,10 +3928,24 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, case WASM_OP_BR_TABLE: read_leb_uint32(p, p_end, count); /* lable num */ - for (i = 0; i <= count; i++) /* lableidxs */ +#if WASM_ENABLE_FAST_INTERP != 0 + for (i = 0; i <= count; i++) /* lableidxs */ skip_leb_uint32(p, p_end); +#else + p += count + 1; + while (*p == WASM_OP_NOP) + p++; +#endif break; +#if WASM_ENABLE_FAST_INTERP == 0 + case EXT_OP_BR_TABLE_CACHE: + read_leb_uint32(p, p_end, count); /* lable num */ + while (*p == WASM_OP_NOP) + p++; + break; +#endif + case WASM_OP_RETURN: break; @@ -5028,8 +5064,8 @@ wasm_loader_emit_const(WASMLoaderContext *ctx, void *value, bool is_32_bit) bh_assert(((uintptr_t)ctx->p_code_compiled & 1) == 0); #endif bh_memcpy_s(ctx->p_code_compiled, - ctx->p_code_compiled_end - ctx->p_code_compiled, value, - size); + (uint32)(ctx->p_code_compiled_end - ctx->p_code_compiled), + value, size); ctx->p_code_compiled += size; } else { @@ -6581,7 +6617,10 @@ re_scan: * the block quickly. */ #if WASM_ENABLE_DEBUG_INTERP != 0 - record_fast_op(module, p_org, *p_org); + if (!record_fast_op(module, p_org, *p_org, error_buf, + error_buf_size)) { + goto fail; + } #endif *p_org = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK); #endif @@ -6830,6 +6869,13 @@ re_scan: { uint8 *ret_types = NULL; uint32 ret_count = 0; +#if WASM_ENABLE_FAST_INTERP == 0 + uint8 *p_depth_begin, *p_depth; + uint32 depth, j; + BrTableCache *br_table_cache = NULL; + + p_org = p - 1; +#endif read_leb_uint32(p, p_end, count); #if WASM_ENABLE_FAST_INTERP != 0 @@ -6837,6 +6883,9 @@ re_scan: #endif POP_I32(); +#if WASM_ENABLE_FAST_INTERP == 0 + p_depth_begin = p_depth = p; +#endif for (i = 0; i <= count; i++) { if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, @@ -6870,8 +6919,57 @@ re_scan: goto fail; } } + +#if WASM_ENABLE_FAST_INTERP == 0 + depth = (uint32)(loader_ctx->frame_csp - 1 - frame_csp_tmp); + if (br_table_cache) { + br_table_cache->br_depths[i] = depth; + } + else { + if (depth > 255) { + /* The depth cannot be stored in one byte, + create br_table cache to store each depth */ +#if WASM_ENABLE_DEBUG_INTERP != 0 + if (!record_fast_op(module, p_org, *p_org, + error_buf, error_buf_size)) { + goto fail; + } +#endif + if (!(br_table_cache = loader_malloc( + offsetof(BrTableCache, br_depths) + + sizeof(uint32) + * (uint64)(count + 1), + error_buf, error_buf_size))) { + goto fail; + } + *p_org = EXT_OP_BR_TABLE_CACHE; + br_table_cache->br_table_op_addr = p_org; + br_table_cache->br_count = count; + /* Copy previous depths which are one byte */ + for (j = 0; j < i; j++) { + br_table_cache->br_depths[j] = p_depth_begin[j]; + } + br_table_cache->br_depths[i] = depth; + bh_list_insert(module->br_table_cache_list, + br_table_cache); + } + else { + /* The depth can be stored in one byte, use the + byte of the leb to store it */ + *p_depth++ = (uint8)depth; + } + } +#endif } +#if WASM_ENABLE_FAST_INTERP == 0 + /* Set the tailing bytes to nop */ + if (br_table_cache) + p_depth = p_depth_begin; + while (p_depth < p) + *p_depth++ = WASM_OP_NOP; +#endif + RESET_STACK(); SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true); break; @@ -7615,7 +7713,10 @@ re_scan: if (global_type == VALUE_TYPE_I64 || global_type == VALUE_TYPE_F64) { #if WASM_ENABLE_DEBUG_INTERP != 0 - record_fast_op(module, p_org, *p_org); + if (!record_fast_op(module, p_org, *p_org, error_buf, + error_buf_size)) { + goto fail; + } #endif *p_org = WASM_OP_GET_GLOBAL_64; } @@ -7669,14 +7770,20 @@ re_scan: if (global_type == VALUE_TYPE_I64 || global_type == VALUE_TYPE_F64) { #if WASM_ENABLE_DEBUG_INTERP != 0 - record_fast_op(module, p_org, *p_org); + if (!record_fast_op(module, p_org, *p_org, error_buf, + error_buf_size)) { + goto fail; + } #endif *p_org = WASM_OP_SET_GLOBAL_64; } else if (module->aux_stack_size > 0 && global_idx == module->aux_stack_top_global_index) { #if WASM_ENABLE_DEBUG_INTERP != 0 - record_fast_op(module, p_org, *p_org); + if (!record_fast_op(module, p_org, *p_org, error_buf, + error_buf_size)) { + goto fail; + } #endif *p_org = WASM_OP_SET_GLOBAL_AUX_STACK; } diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 500bf6215..e6a100d0b 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -10,6 +10,7 @@ #include "wasm_opcode.h" #include "wasm_runtime.h" #include "../common/wasm_native.h" +#include "../common/wasm_memory.h" #if WASM_ENABLE_FAST_JIT != 0 #include "../fast-jit/jit_compiler.h" #include "../fast-jit/jit_codecache.h" @@ -501,9 +502,6 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, return true; } -unsigned -wasm_runtime_memory_pool_size(); - static bool load_memory_import(const uint8 **p_buf, const uint8 *buf_end, WASMModule *parent_module, const char *sub_module_name, @@ -2167,6 +2165,9 @@ create_module(char *error_buf, uint32 error_buf_size) { WASMModule *module = loader_malloc(sizeof(WASMModule), error_buf, error_buf_size); +#if WASM_ENABLE_FAST_INTERP == 0 + bh_list_status ret; +#endif if (!module) { return NULL; @@ -2177,6 +2178,13 @@ create_module(char *error_buf, uint32 error_buf_size) /* Set start_function to -1, means no start function */ module->start_function = (uint32)-1; +#if WASM_ENABLE_FAST_INTERP == 0 + module->br_table_cache_list = &module->br_table_cache_list_head; + ret = bh_list_init(module->br_table_cache_list); + bh_assert(ret == BH_LIST_SUCCESS); + (void)ret; +#endif + return module; } @@ -2453,6 +2461,18 @@ wasm_loader_unload(WASMModule *module) } } +#if WASM_ENABLE_FAST_INTERP == 0 + if (module->br_table_cache_list) { + BrTableCache *node = bh_list_first_elem(module->br_table_cache_list); + BrTableCache *node_next; + while (node) { + node_next = bh_list_elem_next(node); + wasm_runtime_free(node); + node = node_next; + } + } +#endif + #if WASM_ENABLE_FAST_JIT != 0 if (module->fast_jit_func_ptrs) { for (i = 0; i < module->function_count; i++) { @@ -2588,10 +2608,24 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, case WASM_OP_BR_TABLE: read_leb_uint32(p, p_end, count); /* lable num */ - for (i = 0; i <= count; i++) /* lableidxs */ +#if WASM_ENABLE_FAST_INTERP != 0 + for (i = 0; i <= count; i++) /* lableidxs */ skip_leb_uint32(p, p_end); +#else + p += count + 1; + while (*p == WASM_OP_NOP) + p++; +#endif break; +#if WASM_ENABLE_FAST_INTERP == 0 + case EXT_OP_BR_TABLE_CACHE: + read_leb_uint32(p, p_end, count); /* lable num */ + while (*p == WASM_OP_NOP) + p++; + break; +#endif + case WASM_OP_RETURN: break; @@ -3532,8 +3566,8 @@ wasm_loader_emit_const(WASMLoaderContext *ctx, void *value, bool is_32_bit) bh_assert(((uintptr_t)ctx->p_code_compiled & 1) == 0); #endif bh_memcpy_s(ctx->p_code_compiled, - ctx->p_code_compiled_end - ctx->p_code_compiled, value, - size); + (uint32)(ctx->p_code_compiled_end - ctx->p_code_compiled), + value, size); ctx->p_code_compiled += size; } else { @@ -5180,6 +5214,13 @@ re_scan: { uint8 *ret_types = NULL; uint32 ret_count = 0; +#if WASM_ENABLE_FAST_INTERP == 0 + uint8 *p_depth_begin, *p_depth; + uint32 depth, j; + BrTableCache *br_table_cache = NULL; + + p_org = p - 1; +#endif read_leb_uint32(p, p_end, count); #if WASM_ENABLE_FAST_INTERP != 0 @@ -5187,13 +5228,65 @@ re_scan: #endif POP_I32(); +#if WASM_ENABLE_FAST_INTERP == 0 + p_depth_begin = p_depth = p; +#endif for (i = 0; i <= count; i++) { if (!(frame_csp_tmp = check_branch_block(loader_ctx, &p, p_end, error_buf, error_buf_size))) goto fail; + +#if WASM_ENABLE_FAST_INTERP == 0 + depth = (uint32)(loader_ctx->frame_csp - 1 - frame_csp_tmp); + if (br_table_cache) { + br_table_cache->br_depths[i] = depth; + } + else { + if (depth > 255) { + /* The depth cannot be stored in one byte, + create br_table cache to store each depth */ +#if WASM_ENABLE_DEBUG_INTERP != 0 + if (!record_fast_op(module, p_org, *p_org, + error_buf, error_buf_size)) { + goto fail; + } +#endif + if (!(br_table_cache = loader_malloc( + offsetof(BrTableCache, br_depths) + + sizeof(uint32) + * (uint64)(count + 1), + error_buf, error_buf_size))) { + goto fail; + } + *p_org = EXT_OP_BR_TABLE_CACHE; + br_table_cache->br_table_op_addr = p_org; + br_table_cache->br_count = count; + /* Copy previous depths which are one byte */ + for (j = 0; j < i; j++) { + br_table_cache->br_depths[j] = p_depth_begin[j]; + } + br_table_cache->br_depths[i] = depth; + bh_list_insert(module->br_table_cache_list, + br_table_cache); + } + else { + /* The depth can be stored in one byte, use the + byte of the leb to store it */ + *p_depth++ = (uint8)depth; + } + } +#endif } +#if WASM_ENABLE_FAST_INTERP == 0 + /* Set the tailing bytes to nop */ + if (br_table_cache) + p_depth = p_depth_begin; + while (p_depth < p) + *p_depth++ = WASM_OP_NOP; +#endif + RESET_STACK(); SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true); diff --git a/core/iwasm/interpreter/wasm_opcode.h b/core/iwasm/interpreter/wasm_opcode.h index f31d32626..cd7478a6b 100644 --- a/core/iwasm/interpreter/wasm_opcode.h +++ b/core/iwasm/interpreter/wasm_opcode.h @@ -263,12 +263,13 @@ typedef enum WASMOpcode { WASM_OP_REF_IS_NULL = 0xd1, /* ref.is_null */ WASM_OP_REF_FUNC = 0xd2, /* ref.func */ - EXT_OP_BLOCK = 0xd3, /* block with blocktype */ - EXT_OP_LOOP = 0xd4, /* loop with blocktype */ - EXT_OP_IF = 0xd5, /* if with blocktype */ + EXT_OP_BLOCK = 0xd3, /* block with blocktype */ + EXT_OP_LOOP = 0xd4, /* loop with blocktype */ + EXT_OP_IF = 0xd5, /* if with blocktype */ + EXT_OP_BR_TABLE_CACHE = 0xd6, /* br_table from cache */ #if WASM_ENABLE_DEBUG_INTERP != 0 - DEBUG_OP_BREAK = 0xd6, /* debug break point */ + DEBUG_OP_BREAK = 0xd7, /* debug break point */ #endif /* Post-MVP extend op prefix */ @@ -675,7 +676,7 @@ typedef enum WASMAtomicEXTOpcode { #if WASM_ENABLE_DEBUG_INTERP != 0 #define DEF_DEBUG_BREAK_HANDLE(_name) \ - _name[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK); /* 0xd6 */ + _name[DEBUG_OP_BREAK] = HANDLE_OPCODE(DEBUG_OP_BREAK); /* 0xd7 */ #else #define DEF_DEBUG_BREAK_HANDLE(_name) #endif @@ -901,6 +902,7 @@ typedef enum WASMAtomicEXTOpcode { HANDLE_OPCODE(EXT_OP_BLOCK), /* 0xd3 */ \ HANDLE_OPCODE(EXT_OP_LOOP), /* 0xd4 */ \ HANDLE_OPCODE(EXT_OP_IF), /* 0xd5 */ \ + HANDLE_OPCODE(EXT_OP_BR_TABLE_CACHE), /* 0xd6 */ \ }; \ do { \ _name[WASM_OP_MISC_PREFIX] = \ diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index d352b8e75..fdf207fe9 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -222,6 +222,8 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page, /* Adjust __heap_base global value */ global_idx = module->aux_heap_base_global_index; + bh_assert(module_inst->globals + && global_idx < module_inst->global_count); global_addr = module_inst->global_data + module_inst->globals[global_idx].data_offset; *(uint32 *)global_addr = aux_heap_base; @@ -421,19 +423,6 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, } } - if (mem_index == 0) { - /** - * no import memory and define memory, but still need heap - * for wasm code - */ - if (!(memory = memories[mem_index++] = - memory_instantiate(module_inst, 0, 0, 0, heap_size, 0, - error_buf, error_buf_size))) { - memories_deinstantiate(module_inst, memories, memory_count); - return NULL; - } - } - bh_assert(mem_index == memory_count); (void)module_inst; return memories; @@ -598,6 +587,14 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, return NULL; } + total_size = sizeof(void *) * (uint64)module->import_function_count; + if (total_size > 0 + && !(module_inst->import_func_ptrs = + runtime_malloc(total_size, error_buf, error_buf_size))) { + wasm_runtime_free(functions); + return NULL; + } + /* instantiate functions from import section */ function = functions; import = module->import_functions; @@ -626,6 +623,10 @@ functions_instantiate(const WASMModule *module, WASMModuleInstance *module_inst, function->local_count = 0; function->local_types = NULL; + /* Copy the function pointer to current instance */ + module_inst->import_func_ptrs[i] = + function->u.func_import->func_ptr_linked; + function++; } @@ -1117,18 +1118,12 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf, && !func->import_func_linked #endif ) { -#if WASM_ENABLE_SPEC_TEST != 0 - set_error_buf(error_buf, error_buf_size, - "unknown import or incompatible import type"); - return false; -#else #if WASM_ENABLE_WAMR_COMPILER == 0 LOG_WARNING("warning: failed to link import function (%s, %s)", func->module_name, func->field_name); #else /* do nothing to avoid confused message */ #endif /* WASM_ENABLE_WAMR_COMPILER == 0 */ -#endif /* WASM_ENABLE_SPEC_TEST != 0 */ } } @@ -1357,12 +1352,14 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, goto fail; } - data_seg->base_offset.u.i32 = + base_offset = globals[data_seg->base_offset.u.global_index].initial_value.i32; } + else { + base_offset = (uint32)data_seg->base_offset.u.i32; + } /* check offset */ - base_offset = (uint32)data_seg->base_offset.u.i32; if (base_offset > memory_size) { LOG_DEBUG("base_offset(%d) > memory_size(%d)", base_offset, memory_size); @@ -1619,6 +1616,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) memories_deinstantiate(module_inst, module_inst->memories, module_inst->memory_count); + if (module_inst->import_func_ptrs) { + wasm_runtime_free(module_inst->import_func_ptrs); + } + tables_deinstantiate(module_inst->tables, module_inst->table_count); functions_deinstantiate(module_inst->functions, module_inst->function_count); diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index e8f72152e..28a64e951 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -181,6 +181,9 @@ struct WASMModuleInstance { uint32 export_tab_count; #endif + /* Array of function pointers to import functions */ + void **import_func_ptrs; + WASMMemoryInstance **memories; WASMTableInstance **tables; WASMGlobalInstance *globals; diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index d39bb35b9..1b9bd8de4 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -471,7 +471,7 @@ handle_threadstop_request(WASMGDBServer *server, char *payload) void handle_set_current_thread(WASMGDBServer *server, char *payload) { - LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload, payload); + LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload); if ('g' == *payload++) { uint64 tid = strtoll(payload, NULL, 16); if (tid > 0) diff --git a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c index f5236fcf6..a96156f7e 100644 --- a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c +++ b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c @@ -154,8 +154,8 @@ recvmsg(int sockfd, struct msghdr *msg, int flags) // Prepare input parameters. __wasi_iovec_t *ri_data = NULL; size_t i = 0; - size_t ro_datalen; - __wasi_roflags_t ro_flags; + size_t ro_datalen = 0; + __wasi_roflags_t ro_flags = 0; if (NULL == msg) { HANDLE_ERROR(__WASI_ERRNO_INVAL) diff --git a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c index e4893239d..239ff38aa 100644 --- a/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c +++ b/core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c @@ -81,10 +81,11 @@ typedef char *_va_list; int32 n; \ \ /* additional 2 bytes: one is the format char, \ - * the other is `\0` */ \ - if (fmt - fmt_start_addr + 2 >= fmt_buf_len) { \ - bh_assert(fmt - fmt_start_addr <= UINT32_MAX - 2); \ - fmt_buf_len = fmt - fmt_start_addr + 2; \ + the other is `\0` */ \ + if ((uint32)(fmt - fmt_start_addr + 2) >= fmt_buf_len) { \ + bh_assert((uint32)(fmt - fmt_start_addr) <= \ + UINT32_MAX - 2); \ + fmt_buf_len = (uint32)(fmt - fmt_start_addr + 2); \ if (!(fmt_buf = wasm_runtime_malloc(fmt_buf_len))) { \ print_err(out, ctx); \ break; \ @@ -92,8 +93,8 @@ typedef char *_va_list; } \ \ memset(fmt_buf, 0, fmt_buf_len); \ - bh_memcpy_s(fmt_buf, fmt_buf_len, \ - fmt_start_addr, fmt - fmt_start_addr + 1); + bh_memcpy_s(fmt_buf, fmt_buf_len, fmt_start_addr, \ + (uint32)(fmt - fmt_start_addr + 1)); /* clang-format on */ #define OUTPUT_TEMP_FORMAT() \ @@ -125,7 +126,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, int long_ctr = 0; uint8 *native_end_addr; const char *fmt_start_addr = NULL; - bool is_signed; if (!wasm_runtime_get_native_addr_range(module_inst, (uint8 *)ap, NULL, &native_end_addr)) @@ -142,7 +142,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, might_format = 1; long_ctr = 0; fmt_start_addr = fmt; - is_signed = false; } } else { @@ -162,7 +161,11 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, case '7': case '8': case '9': + goto still_might_format; + case 't': /* ptrdiff_t */ + case 'z': /* size_t (32bit on wasm) */ + long_ctr = 1; goto still_might_format; case 'j': @@ -173,7 +176,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, case 'l': long_ctr++; /* Fall through */ - case 'z': case 'h': /* FIXME: do nothing for these modifiers */ goto still_might_format; @@ -181,8 +183,6 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, case 'o': case 'd': case 'i': - is_signed = true; - /* Fall through */ case 'u': case 'p': case 'x': @@ -193,34 +193,34 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, PREPARE_TEMP_FORMAT(); if (long_ctr < 2) { - CHECK_VA_ARG(ap, uint32); + int32 d; - if (is_signed) { - int32 d; - d = _va_arg(ap, int32); - n = snprintf(buf, sizeof(buf), fmt_buf, d); - } - else { - uint32 u; - u = _va_arg(ap, uint32); - n = snprintf(buf, sizeof(buf), fmt_buf, u); + CHECK_VA_ARG(ap, uint32); + d = _va_arg(ap, int32); + + if (long_ctr == 1) { + uint32 fmt_end_idx = (uint32)(fmt - fmt_start_addr); + + if (fmt_buf[fmt_end_idx - 1] == 'l' + || fmt_buf[fmt_end_idx - 1] == 'z' + || fmt_buf[fmt_end_idx - 1] == 't') { + /* The %ld, %zd and %td should be treated as + * 32bit integer in wasm */ + fmt_buf[fmt_end_idx - 1] = fmt_buf[fmt_end_idx]; + fmt_buf[fmt_end_idx] = '\0'; + } } + + n = snprintf(buf, sizeof(buf), fmt_buf, d); } else { + int64 lld; + /* Make 8-byte aligned */ ap = (_va_list)(((uintptr_t)ap + 7) & ~(uintptr_t)7); CHECK_VA_ARG(ap, uint64); - - if (is_signed) { - int64 lld; - lld = _va_arg(ap, int64); - n = snprintf(buf, sizeof(buf), fmt_buf, lld); - } - else { - uint64 llu; - llu = _va_arg(ap, uint64); - n = snprintf(buf, sizeof(buf), fmt_buf, llu); - } + lld = _va_arg(ap, int64); + n = snprintf(buf, sizeof(buf), fmt_buf, lld); } OUTPUT_TEMP_FORMAT(); @@ -247,7 +247,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap, s = start = addr_app_to_native(s_offset); - str_len = strlen(start); + str_len = (uint32)strlen(start); if (str_len >= UINT32_MAX - 64) { print_err(out, ctx); if (fmt_buf != temp_fmt) { @@ -1067,6 +1067,9 @@ static NativeSymbol native_symbols_libc_builtin[] = { REG_NATIVE_FUNC(printf, "($*)i"), REG_NATIVE_FUNC(sprintf, "($$*)i"), REG_NATIVE_FUNC(snprintf, "(*~$*)i"), + { "vprintf", printf_wrapper, "($*)i", NULL }, + { "vsprintf", sprintf_wrapper, "($$*)i", NULL }, + { "vsnprintf", snprintf_wrapper, "(*~$*)i", NULL }, REG_NATIVE_FUNC(puts, "($)i"), REG_NATIVE_FUNC(putchar, "(i)i"), REG_NATIVE_FUNC(memcmp, "(**~)i"), diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index c819c6d91..7611999ad 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -1185,10 +1185,19 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data, struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); uint64 total_size; uint32 i; + iovec_app_t *ri_data_orig = ri_data; + uint8 *buf = NULL; + uint8 *buf_begin = NULL; wasi_errno_t err; + size_t recv_bytes = 0; - if (!wasi_ctx) + if (!wasi_ctx) { return __WASI_EINVAL; + } + + if (ri_data_len == 0) { + return __WASI_EINVAL; + } total_size = sizeof(iovec_app_t) * (uint64)ri_data_len; if (!validate_native_addr(ro_data_len, (uint32)sizeof(uint32)) @@ -1197,27 +1206,49 @@ wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data, || !validate_native_addr(ri_data, (uint32)total_size)) return __WASI_EINVAL; - /* recv ri_data one by one */ + /* receive and scatter*/ + for (total_size = 0, i = 0; i < ri_data_len; i++, ri_data++) { + total_size += ri_data->buf_len; + } + if (total_size >= UINT32_MAX + || !(buf_begin = wasm_runtime_malloc((uint32)total_size))) { + return __WASI_ENOMEM; + } + memset(buf_begin, 0, total_size); + *ro_data_len = 0; + err = wasmtime_ssp_sock_recv(curfds, sock, buf_begin, total_size, + &recv_bytes); + if (err != __WASI_ESUCCESS) { + goto fail; + } + *ro_data_len = (uint32)recv_bytes; + + buf = buf_begin; + ri_data = ri_data_orig; for (i = 0; i < ri_data_len; ri_data++, i++) { - void *buf; - size_t bytes_recv; + char *native_addr; + + if ((uint32)(buf - buf_begin) >= *ro_data_len) { + break; + } if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) { - return __WASI_EINVAL; + err = __WASI_EINVAL; + goto fail; } - buf = (void *)addr_app_to_native(ri_data->buf_offset); - err = wasmtime_ssp_sock_recv(curfds, sock, buf, ri_data->buf_len, - &bytes_recv); - if (err != __WASI_ESUCCESS) { - return err; - } - *ro_data_len += bytes_recv; + native_addr = (void *)addr_app_to_native(ri_data->buf_offset); + bh_memcpy_s(native_addr, ri_data->buf_len, buf, ri_data->buf_len); + buf += ri_data->buf_len; } *ro_flags = ri_flags; - return __WASI_ESUCCESS; +fail: + if (buf_begin) { + wasm_runtime_free(buf_begin); + } + return err; } static wasi_errno_t @@ -1232,12 +1263,21 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock, wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); struct fd_table *curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - uint64 total_size; + uint64 total_size = 0; uint32 i; + const iovec_app_t *si_data_orig = si_data; + uint8 *buf = NULL; + uint8 *buf_begin = NULL; wasi_errno_t err; + size_t send_bytes = 0; - if (!wasi_ctx) + if (!wasi_ctx) { return __WASI_EINVAL; + } + + if (si_data_len == 0) { + return __WASI_EINVAL; + } total_size = sizeof(iovec_app_t) * (uint64)si_data_len; if (!validate_native_addr(so_data_len, sizeof(uint32)) @@ -1245,26 +1285,40 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock, || !validate_native_addr((void *)si_data, (uint32)total_size)) return __WASI_EINVAL; - /* send si_data one by one */ - *so_data_len = 0; - for (i = 0; i < si_data_len; i++, si_data++) { - void *buf; - size_t bytes_sent; - - if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) { - return __WASI_EINVAL; - } - - buf = (void *)addr_app_to_native(si_data->buf_offset); - err = wasmtime_ssp_sock_send(curfds, sock, buf, si_data->buf_len, - &bytes_sent); - if (err != __WASI_ESUCCESS) { - return err; - } - *so_data_len += bytes_sent; + /* gather and send */ + for (total_size = 0, i = 0; i < si_data_len; i++, si_data++) { + total_size += si_data->buf_len; + } + if (total_size >= UINT32_MAX + || !(buf_begin = wasm_runtime_malloc((uint32)total_size))) { + return __WASI_ENOMEM; } - return __WASI_ESUCCESS; + buf = buf_begin; + si_data = si_data_orig; + for (i = 0; i < si_data_len; i++, si_data++) { + char *native_addr; + + if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) { + err = __WASI_EINVAL; + goto fail; + } + + native_addr = (char *)addr_app_to_native(si_data->buf_offset); + bh_memcpy_s(buf, si_data->buf_len, native_addr, si_data->buf_len); + buf += si_data->buf_len; + } + + *so_data_len = 0; + err = wasmtime_ssp_sock_send(curfds, sock, buf_begin, total_size, + &send_bytes); + *so_data_len = (uint32)send_bytes; + +fail: + if (buf_begin) { + wasm_runtime_free(buf_begin); + } + return err; } static wasi_errno_t diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index d706c7ad2..4f1a1c990 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -181,15 +181,19 @@ convert_clockid(__wasi_clockid_t in, clockid_t *out) case __WASI_CLOCK_MONOTONIC: *out = CLOCK_MONOTONIC; return true; +#if defined(CLOCK_PROCESS_CPUTIME_ID) case __WASI_CLOCK_PROCESS_CPUTIME_ID: *out = CLOCK_PROCESS_CPUTIME_ID; return true; +#endif case __WASI_CLOCK_REALTIME: *out = CLOCK_REALTIME; return true; +#if defined(CLOCK_THREAD_CPUTIME_ID) case __WASI_CLOCK_THREAD_CPUTIME_ID: *out = CLOCK_THREAD_CPUTIME_ID; return true; +#endif default: return false; } @@ -652,12 +656,13 @@ fd_table_insert_fd(struct fd_table *ft, int in, __wasi_filetype_t type, REQUIRES_UNLOCKED(ft->lock) { struct fd_object *fo; - __wasi_errno_t error = fd_object_new(type, &fo); + __wasi_errno_t error = fd_object_new(type, &fo); if (error != 0) { close(in); return error; } + fo->number = in; if (type == __WASI_FILETYPE_DIRECTORY) { if (!mutex_init(&fo->directory.lock)) { @@ -877,7 +882,7 @@ wasmtime_ssp_fd_pread( // Copy data back to vectors. size_t bufoff = 0; for (size_t i = 0; i < iovcnt; ++i) { - if (bufoff + iov[i].buf_len < len) { + if (bufoff + iov[i].buf_len < (size_t)len) { bh_memcpy_s(iov[i].buf, iov[i].buf_len, buf + bufoff, iov[i].buf_len); bufoff += iov[i].buf_len; @@ -1356,8 +1361,9 @@ wasmtime_ssp_fd_allocate( // conditions. We may end up shrinking the file right now. struct stat sb; int ret = fstat(fd_number(fo), &sb); - if (ret == 0 && sb.st_size < offset + len) - ret = ftruncate(fd_number(fo), offset + len); + off_t newsize = (off_t)(offset + len); + if (ret == 0 && sb.st_size < newsize) + ret = ftruncate(fd_number(fo), newsize); #endif fd_object_release(fo); @@ -1991,7 +1997,11 @@ wasmtime_ssp_fd_readdir( size_t namlen = strlen(de->d_name); __wasi_dirent_t cde = { .d_next = fo->directory.offset, +#if CONFIG_HAS_D_INO .d_ino = de->d_ino, +#else + .d_ino = 0, +#endif .d_namlen = (uint32)namlen, }; switch (de->d_type) { @@ -2682,11 +2692,84 @@ wasmtime_ssp_proc_raise(__wasi_signal_t sig) { static const int signals[] = { #define X(v) [__WASI_##v] = v - X(SIGABRT), X(SIGALRM), X(SIGBUS), X(SIGCHLD), X(SIGCONT), X(SIGFPE), - X(SIGHUP), X(SIGILL), X(SIGINT), X(SIGKILL), X(SIGPIPE), X(SIGQUIT), - X(SIGSEGV), X(SIGSTOP), X(SIGSYS), X(SIGTERM), X(SIGTRAP), X(SIGTSTP), - X(SIGTTIN), X(SIGTTOU), X(SIGURG), X(SIGUSR1), X(SIGUSR2), X(SIGVTALRM), - X(SIGXCPU), X(SIGXFSZ), +#if defined(SIGABRT) + X(SIGABRT), +#endif +#if defined(SIGALRM) + X(SIGALRM), +#endif +#if defined(SIGBUS) + X(SIGBUS), +#endif +#if defined(SIGCHLD) + X(SIGCHLD), +#endif +#if defined(SIGCONT) + X(SIGCONT), +#endif +#if defined(SIGFPE) + X(SIGFPE), +#endif +#if defined(SIGHUP) + X(SIGHUP), +#endif +#if defined(SIGILL) + X(SIGILL), +#endif +#if defined(SIGINT) + X(SIGINT), +#endif +#if defined(SIGKILL) + X(SIGKILL), +#endif +#if defined(SIGPIPE) + X(SIGPIPE), +#endif +#if defined(SIGQUIT) + X(SIGQUIT), +#endif +#if defined(SIGSYS) + X(SIGSEGV), +#endif +#if defined(SIGSTOP) + X(SIGSTOP), +#endif +#if defined(SIGSYS) + X(SIGSYS), +#endif +#if defined(SIGTERM) + X(SIGTERM), +#endif +#if defined(SIGTRAP) + X(SIGTRAP), +#endif +#if defined(SIGTSTP) + X(SIGTSTP), +#endif +#if defined(SIGTTIN) + X(SIGTTIN), +#endif +#if defined(SIGTTOU) + X(SIGTTOU), +#endif +#if defined(SIGURG) + X(SIGURG), +#endif +#if defined(SIGUSR1) + X(SIGUSR1), +#endif +#if defined(SIGUSR2) + X(SIGUSR2), +#endif +#if defined(SIGVTALRM) + X(SIGVTALRM), +#endif +#if defined(SIGXCPU) + X(SIGXCPU), +#endif +#if defined(SIGXFSZ) + X(SIGXFSZ), +#endif #undef X }; if (sig >= sizeof(signals) / sizeof(signals[0]) || signals[sig] == 0) @@ -2726,33 +2809,42 @@ wasi_ssp_sock_accept( __wasi_filetype_t wasi_type; __wasi_rights_t max_base, max_inheriting; struct fd_object *fo; - bh_socket_t new_sock; + bh_socket_t new_sock = -1; int ret; __wasi_errno_t error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ACCEPT, 0); - if (error != __WASI_ESUCCESS) - return error; + if (error != __WASI_ESUCCESS) { + goto fail; + } ret = os_socket_accept(fd_number(fo), &new_sock, NULL, NULL); fd_object_release(fo); - if (ret == BHT_ERROR) - return convert_errno(errno); + if (BHT_OK != ret) { + error = convert_errno(errno); + goto fail; + } error = fd_determine_type_rights(new_sock, &wasi_type, &max_base, &max_inheriting); if (error != __WASI_ESUCCESS) { - os_socket_close(ret); - return error; + goto fail; } error = fd_table_insert_fd(curfds, new_sock, wasi_type, max_base, max_inheriting, fd_new); if (error != __WASI_ESUCCESS) { - os_socket_close(ret); - return error; + /* released in fd_table_insert_fd() */ + new_sock = -1; + goto fail; } return __WASI_ESUCCESS; + +fail: + if (-1 != new_sock) { + os_socket_close(new_sock); + } + return error; } __wasi_errno_t @@ -2816,7 +2908,7 @@ wasi_ssp_sock_bind( ret = os_socket_bind(fd_number(fo), buf, &port); fd_object_release(fo); - if (ret == BHT_ERROR) { + if (BHT_OK != ret) { return convert_errno(errno); } @@ -2849,7 +2941,7 @@ wasi_ssp_sock_connect( ret = os_socket_connect(fd_number(fo), buf, addr->addr.ip4.port); fd_object_release(fo); - if (ret == BHT_ERROR) { + if (BHT_OK != ret) { return convert_errno(errno); } @@ -2872,7 +2964,7 @@ wasi_ssp_sock_listen( ret = os_socket_listen(fd_number(fo), backlog); fd_object_release(fo); - if (ret == BHT_ERROR) { + if (BHT_OK != ret) { return convert_errno(errno); } @@ -2903,7 +2995,7 @@ wasi_ssp_sock_open( tcp_or_udp = SOCKET_DGRAM == socktype ? 0 : 1; ret = os_socket_create(&sock, tcp_or_udp); - if (ret == BHT_ERROR) { + if (BHT_OK != ret) { return convert_errno(errno); } @@ -2925,7 +3017,6 @@ wasi_ssp_sock_open( error = fd_table_insert_fd(curfds, sock, wasi_type, max_base, max_inheriting, sockfd); if (error != __WASI_ESUCCESS) { - os_socket_close(sock); return error; } @@ -2950,7 +3041,7 @@ wasmtime_ssp_sock_recv( ret = os_socket_recv(fd_number(fo), buf, buf_len); fd_object_release(fo); - if (ret == BHT_ERROR) { + if (-1 == ret) { return convert_errno(errno); } @@ -2976,7 +3067,7 @@ wasmtime_ssp_sock_send( ret = os_socket_send(fd_number(fo), buf, buf_len); fd_object_release(fo); - if (ret == BHT_ERROR) { + if (-1 == ret) { return convert_errno(errno); } @@ -3001,7 +3092,7 @@ wasmtime_ssp_sock_shutdown( ret = os_socket_shutdown(fd_number(fo)); fd_object_release(fo); - if (ret == BHT_ERROR) + if (BHT_OK != ret) return convert_errno(errno); return __WASI_ESUCCESS; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/signals.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/signals.h deleted file mode 100644 index cad78ad3c..000000000 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/signals.h +++ /dev/null @@ -1,20 +0,0 @@ -// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM -// Exceptions. See -// https://github.com/bytecodealliance/wasmtime/blob/main/LICENSE for license -// information. -// -// Significant parts of this file are derived from cloudabi-utils. See -// https://github.com/bytecodealliance/wasmtime/blob/main/lib/wasi/sandboxed-system-primitives/src/LICENSE -// for license information. -// -// The upstream file contains the following copyright notice: -// -// Copyright (c) 2016 Nuxi, https://nuxi.nl/ - -#ifndef SIGNALS_H -#define SIGNALS_H - -void -signals_init(void); - -#endif diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h index a64d90f3b..5ffcb6b37 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/ssp_config.h @@ -105,4 +105,10 @@ #define CONFIG_HAS_STD_ATOMIC 0 #endif +#if !defined(__NuttX__) +#define CONFIG_HAS_D_INO 1 +#else +#define CONFIG_HAS_D_INO 0 +#endif + #endif diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 768e0d7d7..16f73e132 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -681,8 +681,8 @@ wasm_cluster_join_thread(WASMExecEnv *exec_env, void **ret_val) korp_tid handle; os_mutex_lock(&cluster_list_lock); - if (!clusters_have_exec_env(exec_env)) { - /* Invalid thread or the thread has exited */ + if (!clusters_have_exec_env(exec_env) || exec_env->thread_is_detached) { + /* Invalid thread, thread has exited or thread has been detached */ if (ret_val) *ret_val = NULL; os_mutex_unlock(&cluster_list_lock); @@ -710,6 +710,7 @@ wasm_cluster_detach_thread(WASMExecEnv *exec_env) joining it, otherwise let the system resources for the thread be released after joining */ ret = os_thread_detach(exec_env->handle); + exec_env->thread_is_detached = true; } os_mutex_unlock(&cluster_list_lock); return ret; @@ -802,6 +803,32 @@ wasm_cluster_terminate_all_except_self(WASMCluster *cluster, (void *)exec_env); } +static void +wait_for_thread_visitor(void *node, void *user_data) +{ + WASMExecEnv *curr_exec_env = (WASMExecEnv *)node; + WASMExecEnv *exec_env = (WASMExecEnv *)user_data; + + if (curr_exec_env == exec_env) + return; + + wasm_cluster_join_thread(curr_exec_env, NULL); +} + +void +wams_cluster_wait_for_all(WASMCluster *cluster) +{ + traverse_list(&cluster->exec_env_list, wait_for_thread_visitor, NULL); +} + +void +wasm_cluster_wait_for_all_except_self(WASMCluster *cluster, + WASMExecEnv *exec_env) +{ + traverse_list(&cluster->exec_env_list, wait_for_thread_visitor, + (void *)exec_env); +} + bool wasm_cluster_register_destroy_callback(void (*callback)(WASMCluster *)) { diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 2d4962a2c..181851059 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -106,6 +106,13 @@ void wasm_cluster_terminate_all_except_self(WASMCluster *cluster, WASMExecEnv *exec_env); +void +wams_cluster_wait_for_all(WASMCluster *cluster); + +void +wasm_cluster_wait_for_all_except_self(WASMCluster *cluster, + WASMExecEnv *exec_env); + bool wasm_cluster_add_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env); @@ -148,8 +155,6 @@ typedef struct WASMCurrentEnvStatus { uint64 signal_flag : 32; uint64 step_count : 16; uint64 running_status : 16; - korp_mutex wait_lock; - korp_cond wait_cond; } WASMCurrentEnvStatus; WASMCurrentEnvStatus * diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index fb8c9ceb3..d3bcf148f 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -172,6 +172,7 @@ os_socket_inet_network(const char *cp, uint32 *out) if (!cp) return BHT_ERROR; - *out = inet_network(cp); + /* Note: ntohl(INADDR_NONE) == INADDR_NONE */ + *out = ntohl(inet_addr(cp)); return BHT_OK; -} \ No newline at end of file +} diff --git a/core/shared/platform/common/posix/posix_thread.c b/core/shared/platform/common/posix/posix_thread.c index 298390364..fcd7d50e3 100644 --- a/core/shared/platform/common/posix/posix_thread.c +++ b/core/shared/platform/common/posix/posix_thread.c @@ -411,6 +411,9 @@ init_stack_guard_pages() uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT; uint8 *stack_min_addr = os_thread_get_stack_boundary(); + if (stack_min_addr == NULL) + return false; + /* Touch each stack page to ensure that it has been mapped: the OS may lazily grow the stack mapping as a guard page is hit. */ (void)touch_pages(stack_min_addr, page_size); diff --git a/core/shared/platform/include/platform_common.h b/core/shared/platform/include/platform_common.h index 3f7d0c688..9890202d1 100644 --- a/core/shared/platform/include/platform_common.h +++ b/core/shared/platform/include/platform_common.h @@ -65,6 +65,14 @@ BH_VPRINTF(const char *format, va_list ap); #define NULL (void *)0 #endif +#if !defined(BH_HAS_DLFCN) +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) +#define BH_HAS_DLFCN 1 +#else +#define BH_HAS_DLFCN 0 +#endif +#endif + #ifndef __cplusplus #ifndef true diff --git a/core/shared/platform/linux-sgx/sgx_platform.c b/core/shared/platform/linux-sgx/sgx_platform.c index a383698fc..b1b741b06 100644 --- a/core/shared/platform/linux-sgx/sgx_platform.c +++ b/core/shared/platform/linux-sgx/sgx_platform.c @@ -90,8 +90,8 @@ strcpy(char *dest, const char *src) const unsigned char *s = src; unsigned char *d = dest; - while ((*d++ = *s++)) - ; + while ((*d++ = *s++)) { + } return dest; } diff --git a/core/shared/platform/nuttx/platform_internal.h b/core/shared/platform/nuttx/platform_internal.h index a4a2b6971..7acfc7305 100644 --- a/core/shared/platform/nuttx/platform_internal.h +++ b/core/shared/platform/nuttx/platform_internal.h @@ -41,6 +41,12 @@ typedef pthread_t korp_thread; #define os_printf printf #define os_vprintf vprintf +#if defined(CONFIG_LIBC_DLFCN) +#define BH_HAS_DLFCN 1 +#else +#define BH_HAS_DLFCN 0 +#endif + /* On NuttX, time_t is uint32_t */ #define BH_TIME_T_MAX 0xffffffff diff --git a/core/shared/utils/bh_assert.h b/core/shared/utils/bh_assert.h index ba89d12c0..06f7f3b6c 100644 --- a/core/shared/utils/bh_assert.h +++ b/core/shared/utils/bh_assert.h @@ -22,6 +22,19 @@ bh_assert_internal(int v, const char *file_name, int line_number, #define bh_assert(expr) (void)0 #endif /* end of BH_DEBUG */ +#if !defined(__has_extension) +#define __has_extension(a) 0 +#endif + +#if __STDC_VERSION__ >= 201112L \ + || (defined(__GNUC__) && __GNUC__ * 0x100 + __GNUC_MINOR__ >= 0x406) \ + || __has_extension(c_static_assert) + +#define bh_static_assert(expr) _Static_assert(expr, #expr) +#else +#define bh_static_assert(expr) /* nothing */ +#endif + #ifdef __cplusplus } #endif diff --git a/core/shared/utils/bh_common.c b/core/shared/utils/bh_common.c index 690d573de..e4b2eb15c 100644 --- a/core/shared/utils/bh_common.c +++ b/core/shared/utils/bh_common.c @@ -5,12 +5,6 @@ #include "bh_common.h" -#ifdef RSIZE_MAX -#undef RSIZE_MAX -#endif - -#define RSIZE_MAX 0x7FFFFFFF - int b_memcpy_s(void *s1, unsigned int s1max, const void *s2, unsigned int n) { @@ -20,7 +14,7 @@ b_memcpy_s(void *s1, unsigned int s1max, const void *s2, unsigned int n) return 0; } - if (s1 == NULL || s1max > RSIZE_MAX) { + if (s1 == NULL) { return -1; } if (s2 == NULL || n > s1max) { @@ -40,7 +34,7 @@ b_memmove_s(void *s1, unsigned int s1max, const void *s2, unsigned int n) return 0; } - if (s1 == NULL || s1max > RSIZE_MAX) { + if (s1 == NULL) { return -1; } if (s2 == NULL || n > s1max) { @@ -54,8 +48,7 @@ b_memmove_s(void *s1, unsigned int s1max, const void *s2, unsigned int n) int b_strcat_s(char *s1, unsigned int s1max, const char *s2) { - if (NULL == s1 || NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) - || s1max > RSIZE_MAX) { + if (NULL == s1 || NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1)) { return -1; } @@ -66,8 +59,7 @@ b_strcat_s(char *s1, unsigned int s1max, const char *s2) int b_strcpy_s(char *s1, unsigned int s1max, const char *s2) { - if (NULL == s1 || NULL == s2 || s1max < (strlen(s2) + 1) - || s1max > RSIZE_MAX) { + if (NULL == s1 || NULL == s2 || s1max < (strlen(s2) + 1)) { return -1; } diff --git a/doc/export_native_api.md b/doc/export_native_api.md index fba83d3ea..684c1cfb4 100644 --- a/doc/export_native_api.md +++ b/doc/export_native_api.md @@ -129,11 +129,19 @@ int main(int argc, char **argv) } ``` +## Build native lib into shared library and register it with `iwasm` application + +Developer can also build the native library into a shared library and register it with iwasm application: +```bash +iwasm --native-lib= +``` + +Refer to [native lib sample](../samples/native-lib) for more details. ## Buffer address conversion and boundary check - A WebAssembly sandbox ensures applications only access to its own memory with a private address space. When passing a pointer address from WASM to native, the address value must be converted to native address before the native function can access it. It is also the native world's responsibility to check the buffer length is not over its sandbox boundary. +A WebAssembly sandbox ensures applications only access to its own memory with a private address space. When passing a pointer address from WASM to native, the address value must be converted to native address before the native function can access it. It is also the native world's responsibility to check the buffer length is not over its sandbox boundary. diff --git a/doc/wamr_api.md b/doc/wamr_api.md index 5790fd13f..3eff86927 100644 --- a/doc/wamr_api.md +++ b/doc/wamr_api.md @@ -107,7 +107,7 @@ Below is the reference implementation of the pub application. It utilizes a time ``` C /* Timer callback */ -void timer_update(user_timer_t timer +void timer_update(user_timer_t timer) { attr_container_t *event; diff --git a/doc/wasm_c_api.md b/doc/wasm_c_api.md index dfcf0d851..131adadd0 100644 --- a/doc/wasm_c_api.md +++ b/doc/wasm_c_api.md @@ -1,5 +1,11 @@ # wasm-c-api introduction +wasm-c-api is an engine-agnostic API to embed a WASM engine. +In wasm-micro-runtime, it's provided by the header file `wasm_c_api.h`. +Its functionalities are overlapping with `wasm_export.h`, which is +a native API of wasm-micro-runtime. An embedder is supposed to pick +one of these APIs, rather than mixing both of them. + All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b of [wasm-c-api](https://github.com/WebAssembly/wasm-c-api). diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index d880e17bb..3f5683a0a 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -41,6 +41,9 @@ endif WAMR_BUILD_PLATFORM := nuttx +CFLAGS += -DBH_MALLOC=wasm_runtime_malloc +CFLAGS += -DBH_FREE=wasm_runtime_free + ifeq ($(WAMR_BUILD_TARGET), X86_32) CFLAGS += -DBUILD_TARGET_X86_32 INVOKE_NATIVE := invokeNative_ia32.s diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 466bda89b..c78ef399e 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -13,6 +13,10 @@ #include "bh_read_file.h" #include "wasm_export.h" +#if BH_HAS_DLFCN +#include +#endif + static int app_argc; static char **app_argv; @@ -39,13 +43,18 @@ print_help() printf(" --dir= Grant wasi access to the given host directories\n"); printf(" to the program, for example:\n"); printf(" --dir= --dir=\n"); - printf(" --addr-pool= Grant wasi access to the given network addresses in\n"); + printf(" --addr-pool= Grant wasi access to the given network addresses in\n"); printf(" CIRD notation to the program, seperated with ',',\n"); printf(" for example:\n"); printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n"); #endif +#if BH_HAS_DLFCN + printf(" --native-lib= Register native libraries to the WASM module, which\n"); + printf(" are shared object (.so) files, for example:\n"); + printf(" --native-lib=test1.so --native-lib=test2.so\n"); +#endif #if WASM_ENABLE_MULTI_MODULE != 0 - printf(" --module-path= Indicate a module search path. default is current\n" + printf(" --module-path= Indicate a module search path. default is current\n" " directory('./')\n"); #endif #if WASM_ENABLE_LIB_PTHREAD != 0 @@ -174,13 +183,57 @@ validate_env_str(char *env) } #endif -#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0 -#ifdef __NuttX__ -static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE * BH_KB] = { 0 }; -#else -static char global_heap_buf[10 * 1024 * 1024] = { 0 }; -#endif -#endif +#if BH_HAS_DLFCN +typedef uint32 (*get_native_lib_func)(char **p_module_name, + NativeSymbol **p_native_symbols); + +static uint32 +load_and_register_native_libs(const char **native_lib_list, + uint32 native_lib_count, + void **native_handle_list) +{ + uint32 i, native_handle_count = 0, n_native_symbols; + NativeSymbol *native_symbols; + char *module_name; + void *handle; + + for (i = 0; i < native_lib_count; i++) { + /* open the native library */ + if (!(handle = dlopen(native_lib_list[i], RTLD_NOW | RTLD_GLOBAL)) + && !(handle = dlopen(native_lib_list[i], RTLD_LAZY))) { + LOG_WARNING("warning: failed to load native library %s", + native_lib_list[i]); + continue; + } + + /* lookup get_native_lib func */ + get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib"); + if (!get_native_lib) { + LOG_WARNING("warning: failed to lookup `get_native_lib` function " + "from native lib %s", + native_lib_list[i]); + dlclose(handle); + continue; + } + + n_native_symbols = get_native_lib(&module_name, &native_symbols); + + /* register native symbols */ + if (!(n_native_symbols > 0 && module_name && native_symbols + && wasm_runtime_register_natives(module_name, native_symbols, + n_native_symbols))) { + LOG_WARNING("warning: failed to register native lib %s", + native_lib_list[i]); + dlclose(handle); + continue; + } + + native_handle_list[native_handle_count++] = handle; + } + + return native_handle_count; +} +#endif /* BH_HAS_DLFCN */ #if WASM_ENABLE_MULTI_MODULE != 0 static char * @@ -224,6 +277,14 @@ moudle_destroyer(uint8 *buffer, uint32 size) } #endif /* WASM_ENABLE_MULTI_MODULE */ +#if WASM_ENABLE_GLOBAL_HEAP_POOL != 0 +#ifdef __NuttX__ +static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE * BH_KB] = { 0 }; +#else +static char global_heap_buf[10 * 1024 * 1024] = { 0 }; +#endif +#endif + int main(int argc, char *argv[]) { @@ -249,6 +310,12 @@ main(int argc, char *argv[]) const char *addr_pool[8] = { NULL }; uint32 addr_pool_size = 0; #endif +#if BH_HAS_DLFCN + const char *native_lib_list[8] = { NULL }; + uint32 native_lib_count = 0; + void *native_handle_list[8] = { NULL }; + uint32 native_handle_count = 0, native_handle_idx; +#endif #if WASM_ENABLE_DEBUG_INTERP != 0 char *ip_addr = NULL; /* int platform_port = 0; */ @@ -337,6 +404,18 @@ main(int argc, char *argv[]) } } #endif /* WASM_ENABLE_LIBC_WASI */ +#if BH_HAS_DLFCN + else if (!strncmp(argv[0], "--native-lib=", 13)) { + if (argv[0][13] == '\0') + return print_help(); + if (native_lib_count >= sizeof(native_lib_list) / sizeof(char *)) { + printf("Only allow max native lib number %d\n", + (int)(sizeof(native_lib_list) / sizeof(char *))); + return -1; + } + native_lib_list[native_lib_count++] = argv[0] + 13; + } +#endif #if WASM_ENABLE_MULTI_MODULE != 0 else if (!strncmp(argv[0], "--module-path=", strlen("--module-path="))) { @@ -407,6 +486,11 @@ main(int argc, char *argv[]) bh_log_set_verbose_level(log_verbose_level); #endif +#if BH_HAS_DLFCN + native_handle_count = load_and_register_native_libs( + native_lib_list, native_lib_count, native_handle_list); +#endif + /* load WASM byte buffer from WASM bin file */ if (!(wasm_file_buf = (uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size))) @@ -481,6 +565,13 @@ fail2: os_munmap(wasm_file_buf, wasm_file_size); fail1: +#if BH_HAS_DLFCN + /* unload the native libraries */ + for (native_handle_idx = 0; native_handle_idx < native_handle_count; + native_handle_idx++) + dlclose(native_handle_list[native_handle_idx]); +#endif + /* destroy runtime environment */ wasm_runtime_destroy(); return 0; diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 6e25c4359..9baecc1a4 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -40,7 +40,7 @@ print_help() printf(" --dir= --dir=\n"); #endif #if WASM_ENABLE_MULTI_MODULE != 0 - printf(" --module-path= Indicate a module search path. default is current\n" + printf(" --module-path= Indicate a module search path. default is current\n" " directory('./')\n"); #endif #if WASM_ENABLE_LIB_PTHREAD != 0 diff --git a/product-mini/platforms/zephyr/simple/build_and_run.sh b/product-mini/platforms/zephyr/simple/build_and_run.sh index d2948af32..921f88363 100755 --- a/product-mini/platforms/zephyr/simple/build_and_run.sh +++ b/product-mini/platforms/zephyr/simple/build_and_run.sh @@ -28,6 +28,7 @@ usage () echo " $0 $QEMU_XTENSA_TARGET" echo " $0 $QEMU_RISCV64_TARGET" echo " $0 $QEMU_RISCV32_TARGET" + echo " $0 $QEMU_ARC_TARGET" exit 1 } diff --git a/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c index 4a9732f31..61c7bb39d 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/linux/iwasm_main.c @@ -45,7 +45,7 @@ static char *uart_device = "/dev/ttyS2"; static int baudrate = B115200; #endif -extern void +extern bool init_sensor_framework(); extern void exit_sensor_framework(); @@ -175,9 +175,11 @@ func_server_mode(void *arg) struct sockaddr_in serv_addr, cli_addr; int n; char buff[MAX]; - struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, 0); /* First call to socket() function */ @@ -525,10 +527,14 @@ iwasm_main(int argc, char *argv[]) hal_init(); - init_sensor_framework(); + if (!init_sensor_framework()) { + goto fail2; + } - // timer manager - init_wasm_timer(); + /* timer manager */ + if (!init_wasm_timer()) { + goto fail3; + } #ifndef CONNECTION_UART if (server_mode) @@ -544,7 +550,11 @@ iwasm_main(int argc, char *argv[]) app_manager_startup(&interface); exit_wasm_timer(); + +fail3: exit_sensor_framework(); + +fail2: wgl_exit(); exit_connection_framework(); diff --git a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c index 9050fa4a1..6a88f8007 100644 --- a/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c +++ b/samples/gui/wasm-runtime-wgl/src/platform/zephyr/iwasm_main.c @@ -16,7 +16,7 @@ #include "display.h" #include "lvgl.h" -extern void +extern bool init_sensor_framework(); extern void exit_sensor_framework(); @@ -177,12 +177,14 @@ iwasm_main() wgl_init(); hal_init(); - // timer manager - init_wasm_timer(); + /* timer manager */ + if (!init_wasm_timer()) { + goto fail; + } - // TODO: app_manager_startup(&interface); +fail: wasm_runtime_destroy(); return -1; } diff --git a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c index 420f06495..e2253bb5e 100644 --- a/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c +++ b/samples/littlevgl/vgl-wasm-runtime/src/platform/linux/iwasm_main.c @@ -43,7 +43,7 @@ static char *uart_device = "/dev/ttyS2"; static int baudrate = B115200; #endif -extern void +extern bool init_sensor_framework(); extern void exit_sensor_framework(); @@ -169,9 +169,11 @@ func_server_mode(void *arg) struct sockaddr_in serv_addr, cli_addr; int n; char buff[MAX]; - struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, 0); /* First call to socket() function */ @@ -505,10 +507,14 @@ iwasm_main(int argc, char *argv[]) extern void display_SDL_init(); display_SDL_init(); - init_sensor_framework(); + if (!init_sensor_framework()) { + goto fail2; + } - // timer manager - init_wasm_timer(); + /* timer manager */ + if (!init_wasm_timer()) { + goto fail3; + } #ifndef CONNECTION_UART if (server_mode) @@ -524,7 +530,11 @@ iwasm_main(int argc, char *argv[]) app_manager_startup(&interface); exit_wasm_timer(); + +fail3: exit_sensor_framework(); + +fail2: exit_connection_framework(); fail1: 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 ae9e4305d..dceb5786b 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 @@ -20,7 +20,7 @@ #include #include -extern void +extern bool init_sensor_framework(); extern void exit_sensor_framework(); @@ -118,12 +118,14 @@ iwasm_main() display_init(); - // timer manager - init_wasm_timer(); + /* timer manager */ + if (!init_wasm_timer()) { + goto fail; + } - // TODO: app_manager_startup(&interface); +fail: wasm_runtime_destroy(); return -1; } diff --git a/samples/multi-thread/CMakeLists.txt b/samples/multi-thread/CMakeLists.txt index 89b59833a..89c983862 100644 --- a/samples/multi-thread/CMakeLists.txt +++ b/samples/multi-thread/CMakeLists.txt @@ -70,5 +70,5 @@ set (RUNTIME_SOURCE_ALL ${UNCOMMON_SHARED_SOURCE} ) add_executable (iwasm ${RUNTIME_SOURCE_ALL}) -target_link_libraries(iwasm vmlib -lpthread -lm) +target_link_libraries(iwasm vmlib -lpthread -lm -ldl) diff --git a/samples/native-lib/CMakeLists.txt b/samples/native-lib/CMakeLists.txt new file mode 100644 index 000000000..3968393c6 --- /dev/null +++ b/samples/native-lib/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.0) +project(native_lib) + +################ runtime settings ############## +string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) +if (APPLE) + add_definitions(-DBH_PLATFORM_DARWIN) +endif () + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +# WAMR features switch + +# Set WAMR_BUILD_TARGET, currently values supported are: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + else () + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set (CMAKE_BUILD_TYPE Release) +endif () + +set (WAMR_BUILD_INTERP 1) +set (WAMR_BUILD_AOT 1) +set (WAMR_BUILD_JIT 0) +set (WAMR_BUILD_LIBC_BUILTIN 1) +set (WAMR_BUILD_FAST_INTERP 1) + +# compiling and linking flags +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE") +if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") +endif () +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") + +# build out vmlib +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) + +add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) + +################ wamr runtime ################### +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +set (RUNTIME_SOURCE_ALL + ${WAMR_ROOT_DIR}/product-mini/platforms/posix/main.c + ${UNCOMMON_SHARED_SOURCE} +) + +add_executable (iwasm ${RUNTIME_SOURCE_ALL}) + +target_link_libraries(iwasm vmlib -lpthread -lm -ldl) + +################ native libraries ############### +add_library (test_add SHARED test_add.c) +add_library (test_sqrt SHARED test_sqrt.c) + +################ wasm application ############### +add_subdirectory(wasm-app) diff --git a/samples/native-lib/README.md b/samples/native-lib/README.md new file mode 100644 index 000000000..668d28b66 --- /dev/null +++ b/samples/native-lib/README.md @@ -0,0 +1,59 @@ +# "native-lib" sample introduction + +This sample demonstrates how to write required interfaces in native library, build it into a shared library and register the shared library to iwasm. + +The native library should provide `get_native_lib` API for iwasm to return the native library info, including the module name, the native symbol list and the native symbol count, so that iwasm can use them to regiter the native library, for example: + +```C +static int +foo_wrapper(wasm_exec_env_t *exec_env, int x, int y) +{ + return x + y; +} + +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } + +static NativeSymbol native_symbols[] = { + REG_NATIVE_FUNC(foo, "(ii)i") +}; + +uint32_t +get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols) +{ + *p_module_name = "env"; + *p_native_symbols = native_symbols; + return sizeof(native_symbols) / sizeof(NativeSymbol); +} +``` + +## Preparation + +Please install WASI SDK, download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`. + +## Build the sample + +```bash +mkdir build +cd build +cmake .. +make +``` + +`iwasm`, one wasm module `test.wasm` and two shared libraries `libtest_add.so`, `libtest_sqrt.so` +will be generated. + +## Run workload + +```bash +cd build +./iwasm --native-lib=libtest_add.so --native-lib=libtest_sqrt.so wasm-app/test.wasm +``` + +The output is: + +```bash +Hello World! +10 + 20 = 30 +sqrt(10, 20) = 500 +``` diff --git a/samples/native-lib/test_add.c b/samples/native-lib/test_add.c new file mode 100644 index 000000000..d66ba81fc --- /dev/null +++ b/samples/native-lib/test_add.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include + +#include "wasm_export.h" + +static int +test_add_wrapper(wasm_exec_env_t *exec_env, int x, int y) +{ + return x + y; +} + +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } + +static NativeSymbol native_symbols[] = { + REG_NATIVE_FUNC(test_add, "(ii)i") +}; +/* clang-format on */ + +uint32_t +get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols) +{ + *p_module_name = "env"; + *p_native_symbols = native_symbols; + return sizeof(native_symbols) / sizeof(NativeSymbol); +} diff --git a/samples/native-lib/test_sqrt.c b/samples/native-lib/test_sqrt.c new file mode 100644 index 000000000..e867a2c94 --- /dev/null +++ b/samples/native-lib/test_sqrt.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include + +#include "wasm_export.h" + +static int +test_sqrt_wrapper(wasm_exec_env_t *exec_env, int x, int y) +{ + return x * x + y * y; +} + +/* clang-format off */ +#define REG_NATIVE_FUNC(func_name, signature) \ + { #func_name, func_name##_wrapper, signature, NULL } + +static NativeSymbol native_symbols[] = { + REG_NATIVE_FUNC(test_sqrt, "(ii)i") +}; +/* clang-format on */ + +uint32_t +get_native_lib(char **p_module_name, NativeSymbol **p_native_symbols) +{ + *p_module_name = "env"; + *p_native_symbols = native_symbols; + return sizeof(native_symbols) / sizeof(NativeSymbol); +} diff --git a/samples/native-lib/wasm-app/CMakeLists.txt b/samples/native-lib/wasm-app/CMakeLists.txt new file mode 100644 index 000000000..ffcd9005a --- /dev/null +++ b/samples/native-lib/wasm-app/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required(VERSION 3.0) +project(wasm-app) + +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) + +if (APPLE) + set (HAVE_FLAG_SEARCH_PATHS_FIRST 0) + set (CMAKE_C_LINK_FLAGS "") + set (CMAKE_CXX_LINK_FLAGS "") +endif () + +set (CMAKE_SYSTEM_PROCESSOR wasm32) +set (CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot) + +if (NOT DEFINED WASI_SDK_DIR) + set (WASI_SDK_DIR "/opt/wasi-sdk") +endif () + +set (CMAKE_C_FLAGS "-nostdlib") +set (CMAKE_C_COMPILER_TARGET "wasm32") +set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang") + +set (CMAKE_EXE_LINKER_FLAGS + "-Wl,--max-memory=131072 -z stack-size=8192 \ + -Wl,--no-entry,--strip-all \ + -Wl,--export=__main_argc_argv \ + -Wl,--export=__heap_base,--export=__data_end \ + -Wl,--allow-undefined" +) + +add_executable(test.wasm main.c) +target_link_libraries(test.wasm) diff --git a/samples/native-lib/wasm-app/main.c b/samples/native-lib/wasm-app/main.c new file mode 100644 index 000000000..f00ec0602 --- /dev/null +++ b/samples/native-lib/wasm-app/main.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include + +int +test_add(int x, int y); + +int +test_sqrt(int x, int y); + +int +main(int argc, char **argv) +{ + int x = 10, y = 20, res; + + printf("Hello World!\n"); + + res = test_add(x, y); + printf("%d + %d = %d\n", x, y, res); + + res = test_sqrt(x, y); + printf("sqrt(%d, %d) = %d\n", x, y, res); + + return 0; +} diff --git a/samples/ref-types/src/hello.c b/samples/ref-types/src/hello.c index 024d026b8..db2f7997f 100644 --- a/samples/ref-types/src/hello.c +++ b/samples/ref-types/src/hello.c @@ -30,8 +30,8 @@ local_chk_externref(wasm_exec_env_t exec_env, int32 index, uintptr_t externref) /* clang-format off */ static NativeSymbol native_symbols[] = { - { "native-cmp-externref", local_cmp_externref, "(II)i", NULL }, - { "native-chk-externref", local_chk_externref, "(iI)i", NULL }, + { "native-cmp-externref", local_cmp_externref, "(rr)i", NULL }, + { "native-chk-externref", local_chk_externref, "(ir)i", NULL }, }; /* clang-format on */ diff --git a/samples/simple/src/iwasm_main.c b/samples/simple/src/iwasm_main.c index 121671ffd..36fb35b12 100644 --- a/samples/simple/src/iwasm_main.c +++ b/samples/simple/src/iwasm_main.c @@ -45,7 +45,7 @@ static char *uart_device = "/dev/ttyS2"; static int baudrate = B115200; #endif -extern void +extern bool init_sensor_framework(); extern void exit_sensor_framework(); @@ -178,9 +178,11 @@ func_server_mode(void *arg) struct sockaddr_in serv_addr, cli_addr; int n; char buff[MAX]; - struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); sigaction(SIGPIPE, &sa, 0); /* First call to socket() function */ @@ -516,16 +518,21 @@ iwasm_main(int argc, char *argv[]) return -1; } - /* timer manager */ - init_wasm_timer(); - /* connection framework */ if (!init_connection_framework()) { goto fail1; } /* sensor framework */ - init_sensor_framework(); + if (!init_sensor_framework()) { + goto fail2; + } + + /* timer manager */ + if (!init_wasm_timer()) { + goto fail3; + } + /* add the sys sensor objects */ add_sys_sensor("sensor_test1", "This is a sensor for test", 0, 1000, read_test_sensor, config_test_sensor); @@ -547,7 +554,11 @@ iwasm_main(int argc, char *argv[]) app_manager_startup(&interface); exit_wasm_timer(); + +fail3: exit_sensor_framework(); + +fail2: exit_connection_framework(); fail1: diff --git a/samples/socket-api/CMakeLists.txt b/samples/socket-api/CMakeLists.txt index 12b979517..936287c7d 100644 --- a/samples/socket-api/CMakeLists.txt +++ b/samples/socket-api/CMakeLists.txt @@ -162,4 +162,4 @@ set (RUNTIME_SOURCE_ALL ${UNCOMMON_SHARED_SOURCE} ) add_executable (iwasm ${RUNTIME_SOURCE_ALL}) -target_link_libraries(iwasm vmlib -lpthread -lm) +target_link_libraries(iwasm vmlib -lpthread -lm -ldl) diff --git a/samples/socket-api/wasm-src/send_recv.c b/samples/socket-api/wasm-src/send_recv.c index 9ac0aad31..228fd598c 100644 --- a/samples/socket-api/wasm-src/send_recv.c +++ b/samples/socket-api/wasm-src/send_recv.c @@ -2,8 +2,8 @@ * Copyright (C) 2019 Intel Corporation. All rights reserved. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ - #include +#include #include #include #include @@ -109,7 +109,8 @@ run_as_client(void *arg) { int sock = -1; struct sockaddr_in addr = { 0 }; - char buf[256] = { 0 }; + /* buf of server is 106 bytes */ + char buf[110] = { 0 }; struct iovec iov = { .iov_base = buf, .iov_len = sizeof(buf) }; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t recv_len = 0; @@ -145,11 +146,11 @@ run_as_client(void *arg) } printf("Receive %ld bytes successlly!\n", recv_len); - printf("Data:\n"); + assert(recv_len == 106); - uint8_t i = 0; + printf("Data:\n"); char *s = msg.msg_iov->iov_base; - for (i = 0; i < 6; i++) { + while (strlen(s) > 0) { printf(" %s\n", s); s += strlen(s) + 1; } diff --git a/samples/wasm-c-api/src/callback.c b/samples/wasm-c-api/src/callback.c index fc6c109db..b1294670d 100644 --- a/samples/wasm-c-api/src/callback.c +++ b/samples/wasm-c-api/src/callback.c @@ -77,9 +77,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/callback_chain.c b/samples/wasm-c-api/src/callback_chain.c index 64f42d960..891f30a99 100644 --- a/samples/wasm-c-api/src/callback_chain.c +++ b/samples/wasm-c-api/src/callback_chain.c @@ -16,52 +16,61 @@ static const byte_t * get_memory_data(uint32_t offset, uint32_t length); static bool -call_wasm_function(uint32_t export_id, - const wasm_val_vec_t *args, - wasm_val_vec_t *results, - const char *name); +call_wasm_function(uint32_t export_id, const wasm_val_vec_t *args, + wasm_val_vec_t *results, const char *name); /************************ IMPORTED FUNCTIONS **************************/ // (nil) -> i32 #define FUNCTION_TYPE_NIL_I32 wasm_functype_new_0_1(wasm_valtype_new_i32()) // (i32, i32) -> nil -#define FUNCTION_TYPE_I32X2_NIL \ +#define FUNCTION_TYPE_I32X2_NIL \ wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32()) /* IMPORT FUNCTION LIST */ -#define IMPORT_FUNCTION_LIST(V) \ - V(get_pairs, 0, FUNCTION_TYPE_NIL_I32) \ +#define IMPORT_FUNCTION_LIST(V) \ + V(get_pairs, 0, FUNCTION_TYPE_NIL_I32) \ V(log, 1, FUNCTION_TYPE_I32X2_NIL) /* EXPORT FUNCTION LIST */ -#define EXPORT_FUNCTION_LIST(V) \ - V(on_start) \ - V(on_stop) \ - V(malloc) \ +#define EXPORT_FUNCTION_LIST(V) \ + V(on_start) \ + V(on_stop) \ + V(malloc) \ V(free) enum EXPORT_ITEM_NAME { #define DEFINE_ENUM(name) e_##name, EXPORT_FUNCTION_LIST(DEFINE_ENUM) #undef DEFINE_ENUM - e_MEMORY, + e_MEMORY, }; -#define DEFINE_FUNCTION(name) \ - wasm_trap_t *STUB_##name(const wasm_val_vec_t* args, wasm_val_vec_t* results) +#define DEFINE_FUNCTION(name) \ + wasm_trap_t *STUB_##name(const wasm_val_vec_t *args, \ + wasm_val_vec_t *results) -#define DEFINE_EMPTY_FUNCTION(name) \ - DEFINE_FUNCTION(name) \ - { \ - printf("[WASM -> NATIVE] calling back %s\n", __FUNCTION__); \ - return NULL; \ +#define DEFINE_EMPTY_FUNCTION(name) \ + DEFINE_FUNCTION(name) \ + { \ + printf("[WASM -> NATIVE] calling back %s\n", __FUNCTION__); \ + return NULL; \ } #undef DEFINE_EMPTY_FUNCTION DEFINE_FUNCTION(get_pairs) { - call_wasm_function(e_malloc, args, results, "malloc"); + wasm_val_vec_t as = { 0 }; + wasm_val_t data[1] = { WASM_I32_VAL(10) }; + wasm_val_vec_new(&as, 1, data); + if (as.data == NULL) { + printf("ERROR: create parameters failed\n"); + return NULL; + } + + call_wasm_function(e_malloc, &as, results, "malloc"); + + wasm_val_vec_delete(&as); return NULL; } @@ -91,9 +100,8 @@ DEFINE_FUNCTION(log) } /**********************************************************************/ -// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j Export X.wasm" -// -1: memory -// 0-32: functions +// all exportted wasm functions. check with "/opt/wabt/bin/wasm-objdump -x -j +// Export X.wasm" -1: memory 0-32: functions static own wasm_extern_vec_t exports = { 0 }; static const byte_t * @@ -117,10 +125,8 @@ get_memory_data(uint32_t offset, uint32_t length) } static bool -call_wasm_function(uint32_t export_id, - const wasm_val_vec_t *args, - wasm_val_vec_t *results, - const char *name) +call_wasm_function(uint32_t export_id, const wasm_val_vec_t *args, + wasm_val_vec_t *results, const char *name) { const wasm_func_t *function; wasm_trap_t *trap; @@ -169,9 +175,28 @@ main(int argc, const char *argv[]) printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { @@ -196,38 +221,38 @@ main(int argc, const char *argv[]) // Create external functions. printf("Creating callback...\n"); -#define IMPORT_FUNCTION_VARIABLE_NAME(name, ...) \ +#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"); \ - return 1; \ - } \ - wasm_functype_delete(type); \ +#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 - wasm_extern_t *fs[10] = {0}; -#define ADD_TO_FUNCTION_LIST(name, index, ...) \ + wasm_extern_t *fs[10] = { 0 }; +#define ADD_TO_FUNCTION_LIST(name, index, ...) \ fs[index] = wasm_func_as_extern(function_##name); IMPORT_FUNCTION_LIST(ADD_TO_FUNCTION_LIST) #undef ADD_TO_FUNCTION_LIST wasm_extern_vec_t imports = WASM_ARRAY_VEC(fs); own wasm_instance_t *instance = - wasm_instance_new(store, module, &imports, NULL); + wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; } -#define DESTROY_WASM_FUNCITON(name, index, ...) \ +#define DESTROY_WASM_FUNCITON(name, index, ...) \ wasm_func_delete(function_##name); IMPORT_FUNCTION_LIST(DESTROY_WASM_FUNCITON) #undef DESTROY_WASM_FUNCITON diff --git a/samples/wasm-c-api/src/empty_imports.c b/samples/wasm-c-api/src/empty_imports.c index 902704ed8..5858ed6b5 100644 --- a/samples/wasm-c-api/src/empty_imports.c +++ b/samples/wasm-c-api/src/empty_imports.c @@ -21,9 +21,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/global.c b/samples/wasm-c-api/src/global.c index f16af9cc9..bc4671d23 100644 --- a/samples/wasm-c-api/src/global.c +++ b/samples/wasm-c-api/src/global.c @@ -64,9 +64,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index 6b566447b..5a2b9843e 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -34,9 +34,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/hostref.c b/samples/wasm-c-api/src/hostref.c index 211f0cffd..a411ddd9f 100644 --- a/samples/wasm-c-api/src/hostref.c +++ b/samples/wasm-c-api/src/hostref.c @@ -139,9 +139,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/memory.c b/samples/wasm-c-api/src/memory.c index c09a410ee..64d1c0777 100644 --- a/samples/wasm-c-api/src/memory.c +++ b/samples/wasm-c-api/src/memory.c @@ -110,9 +110,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/reflect.c b/samples/wasm-c-api/src/reflect.c index 5967bad1e..a595fd3e0 100644 --- a/samples/wasm-c-api/src/reflect.c +++ b/samples/wasm-c-api/src/reflect.c @@ -111,9 +111,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/table.c b/samples/wasm-c-api/src/table.c index 739385e93..0bf68e05a 100644 --- a/samples/wasm-c-api/src/table.c +++ b/samples/wasm-c-api/src/table.c @@ -90,9 +90,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/samples/wasm-c-api/src/trap.c b/samples/wasm-c-api/src/trap.c index 5feb9511d..230b2d4e2 100644 --- a/samples/wasm-c-api/src/trap.c +++ b/samples/wasm-c-api/src/trap.c @@ -47,9 +47,28 @@ int main(int argc, const char* argv[]) { printf("> Error loading module!\n"); return 1; } - fseek(file, 0L, SEEK_END); - size_t file_size = ftell(file); - fseek(file, 0L, SEEK_SET); + + int ret = fseek(file, 0L, SEEK_END); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + long file_size = ftell(file); + if (file_size == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + + ret = fseek(file, 0L, SEEK_SET); + if (ret == -1) { + printf("> Error loading module!\n"); + fclose(file); + return 1; + } + wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { diff --git a/test-tools/host-tool/external/cJSON/cJSON.c b/test-tools/host-tool/external/cJSON/cJSON.c index 5bec53a7a..2e35351db 100644 --- a/test-tools/host-tool/external/cJSON/cJSON.c +++ b/test-tools/host-tool/external/cJSON/cJSON.c @@ -1113,10 +1113,6 @@ fail: hooks->deallocate(buffer->buffer); } - if (printed != NULL) { - hooks->deallocate(printed); - } - return NULL; } @@ -1818,9 +1814,9 @@ add_item_to_array(cJSON *array, cJSON *item) } /* Add item to array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) { - add_item_to_array(array, item); + return add_item_to_array(array, item); } #if defined(__clang__) \ @@ -1878,37 +1874,39 @@ add_item_to_object(cJSON *const object, const char *const string, return add_item_to_array(object, item); } -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) { - add_item_to_object(object, string, item, &global_hooks, false); + return add_item_to_object(object, string, item, &global_hooks, false); } /* Add an item to an object with constant string as key */ -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) { - add_item_to_object(object, string, item, &global_hooks, true); + return add_item_to_object(object, string, item, &global_hooks, true); } -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +CJSON_PUBLIC(cJSON_bool) +cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) { if (array == NULL) { - return; + return false; } - add_item_to_array(array, create_reference(item, &global_hooks)); + return add_item_to_array(array, create_reference(item, &global_hooks)); } -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) { if ((object == NULL) || (string == NULL)) { - return; + return false; } - add_item_to_object(object, string, create_reference(item, &global_hooks), - &global_hooks, false); + return add_item_to_object(object, string, + create_reference(item, &global_hooks), + &global_hooks, false); } CJSON_PUBLIC(cJSON *) @@ -2093,19 +2091,18 @@ cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) } /* Replace array/object items with new ones. */ -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) { cJSON *after_inserted = NULL; if (which < 0) { - return; + return false; } after_inserted = get_array_item(array, (size_t)which); if (after_inserted == NULL) { - add_item_to_array(array, newitem); - return; + return add_item_to_array(array, newitem); } newitem->next = after_inserted; @@ -2117,6 +2114,7 @@ cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) else { newitem->prev->next = newitem; } + return true; } CJSON_PUBLIC(cJSON_bool) diff --git a/test-tools/host-tool/external/cJSON/cJSON.h b/test-tools/host-tool/external/cJSON/cJSON.h index fc26d64ca..d437196a3 100644 --- a/test-tools/host-tool/external/cJSON/cJSON.h +++ b/test-tools/host-tool/external/cJSON/cJSON.h @@ -247,20 +247,21 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count); /* Append item to the specified array/object. */ -CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); /* Use this when string is definitely const (i.e. a literal, or as good as), and * will definitely survive the cJSON object. WARNING: When this function was * used, make sure to always check that (item->type & cJSON_StringIsConst) is * zero before writing to `item->string` */ -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); /* Append reference to item to the specified array/object. Use this when you * want to add an existing cJSON to a new cJSON, but don't want to corrupt your * existing cJSON. */ -CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) +cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); /* Remove/Detatch items from Arrays/Objects. */ @@ -278,7 +279,7 @@ CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); /* Update array items. */ -CJSON_PUBLIC(void) +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray( cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ diff --git a/test-tools/host-tool/src/main.c b/test-tools/host-tool/src/main.c index f08e9490e..dbddbf81b 100644 --- a/test-tools/host-tool/src/main.c +++ b/test-tools/host-tool/src/main.c @@ -808,7 +808,8 @@ int main(int argc, char *argv[]) } if (g_conn_fd == -1) { - if (init() != 0) { + if ((init() != 0) + || (g_conn_fd == -1)) { sleep(1); continue; } diff --git a/test-tools/host-tool/src/transport.c b/test-tools/host-tool/src/transport.c index edadde25f..d4edf4f1d 100644 --- a/test-tools/host-tool/src/transport.c +++ b/test-tools/host-tool/src/transport.c @@ -125,6 +125,7 @@ bool udp_send(const char *address, int port, const char *buf, int len) { int sockfd; + ssize_t size_sent; struct sockaddr_in servaddr; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) @@ -136,11 +137,11 @@ udp_send(const char *address, int port, const char *buf, int len) servaddr.sin_port = htons(port); servaddr.sin_addr.s_addr = INADDR_ANY; - sendto(sockfd, buf, len, MSG_CONFIRM, (const struct sockaddr *)&servaddr, - sizeof(servaddr)); + size_sent = sendto(sockfd, buf, len, MSG_CONFIRM, + (const struct sockaddr *)&servaddr, sizeof(servaddr)); close(sockfd); - return true; + return (size_sent != -1) ? true : false; } bool diff --git a/wamr-compiler/CMakeLists.txt b/wamr-compiler/CMakeLists.txt index 665da9441..df32251b3 100644 --- a/wamr-compiler/CMakeLists.txt +++ b/wamr-compiler/CMakeLists.txt @@ -203,7 +203,7 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \ -fno-sanitize=bounds,bounds-strict,alignment \ -fno-sanitize-recover") - set(lib_ubsan ubsan) + set(lib_ubsan -fsanitize=undefined) endif() else () # UNDEFINED BEHAVIOR, refer to https://en.cppreference.com/w/cpp/language/ub @@ -211,7 +211,7 @@ if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined \ -fno-sanitize=bounds,alignment \ -fno-sanitize-recover") - set(lib_ubsan ubsan) + set(lib_ubsan -fsanitize=undefined) endif() endif() endif () diff --git a/wamr-sdk/app/libc-builtin-sysroot/include/stdarg.h b/wamr-sdk/app/libc-builtin-sysroot/include/stdarg.h new file mode 100644 index 000000000..509595734 --- /dev/null +++ b/wamr-sdk/app/libc-builtin-sysroot/include/stdarg.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef _WAMR_LIBC_STDARG_H +#define _WAMR_LIBC_STDARG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _VA_LIST +typedef __builtin_va_list va_list; +#define _VA_LIST +#endif +#define va_start(ap, param) __builtin_va_start(ap, param) +#define va_end(ap) __builtin_va_end(ap) +#define va_arg(ap, type) __builtin_va_arg(ap, type) + +#define __va_copy(d, s) __builtin_va_copy(d, s) + +#ifdef __cplusplus +} +#endif + +#endif /* end of _WAMR_LIBC_STDARG_H */ diff --git a/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt b/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt index 332aedb7d..fc9c400a6 100644 --- a/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt +++ b/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt @@ -26,6 +26,9 @@ wasm_get_sys_tick_ms printf sprintf snprintf +vprintf +vsprintf +vsnprintf puts putchar memcmp