From ea6cef7e51614a66c2b8158eeb6dc4b65d5c0013 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Sat, 11 Mar 2023 03:44:37 +0100 Subject: [PATCH 01/61] Fix malloc non-thread-safe usage in lib-wasi-threads test (#2022) In the WASI thread test modified in this PR, malloc was used in multiple threads without a lock. But wasi-libc implementation of malloc is not thread-safe. --- .../test/update_shared_data_and_alloc_heap.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c index b8cf56495..2bfd196da 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "wasi_thread_start.h" @@ -29,6 +30,7 @@ typedef struct { int *pval; } shared_t; +pthread_mutex_t mutex; int *vals[NUM_THREADS]; void @@ -39,7 +41,9 @@ __wasi_thread_start_C(int thread_id, int *start_arg) for (int i = 0; i < NUM_ITER; i++) __atomic_fetch_add(data->count, 1, __ATOMIC_SEQ_CST); + pthread_mutex_lock(&mutex); /* malloc is not thread-safe in wasi-libc */ vals[data->iteration] = malloc(sizeof(int)); + pthread_mutex_unlock(&mutex); *vals[data->iteration] = data->iteration; __atomic_store_n(&data->th_done, 1, __ATOMIC_SEQ_CST); @@ -53,6 +57,9 @@ main(int argc, char **argv) int thread_ids[NUM_THREADS]; int *count = calloc(1, sizeof(int)); + assert(count != NULL && "Failed to call calloc"); + assert(pthread_mutex_init(&mutex, NULL) == 0 && "Failed to init mutex"); + for (int i = 0; i < NUM_THREADS; i++) { assert(start_args_init(&data[i].base) && "Stack allocation for thread failed"); @@ -82,5 +89,7 @@ main(int argc, char **argv) } free(count); + assert(pthread_mutex_destroy(&mutex) == 0 && "Failed to destroy mutex"); + return EXIT_SUCCESS; } From 578fbc5a55276576f3cc68742e31275e95535c2b Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sun, 12 Mar 2023 20:17:49 +0800 Subject: [PATCH 02/61] Fix fast-jit build error (#2023) --- core/iwasm/fast-jit/iwasm_fast_jit.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/fast-jit/iwasm_fast_jit.cmake b/core/iwasm/fast-jit/iwasm_fast_jit.cmake index 67c4b975b..cd880a34b 100644 --- a/core/iwasm/fast-jit/iwasm_fast_jit.cmake +++ b/core/iwasm/fast-jit/iwasm_fast_jit.cmake @@ -16,11 +16,13 @@ if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") FetchContent_Declare( asmjit GIT_REPOSITORY https://github.com/asmjit/asmjit.git + GIT_TAG c1019f1642a588107148f64ba54584b0ae3ec8d1 ) else () FetchContent_Declare( asmjit GIT_REPOSITORY https://github.com/asmjit/asmjit.git + GIT_TAG c1019f1642a588107148f64ba54584b0ae3ec8d1 PATCH_COMMAND git apply ${IWASM_FAST_JIT_DIR}/asmjit_sgx_patch.diff ) endif () From 2de24587a81751108938a994c13710bca1b23891 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 13 Mar 2023 02:19:17 +0000 Subject: [PATCH 03/61] Fix wait_info data race for deletion and fix atomic_wait logic (#2016) Fix a data race for test main_proc_exit_wait.c from #1963. And fix atomic_wait logic that was wrong before: - a thread 1 started executing wasm instruction wasm_atomic_wait but hasn't reached waiting on condition variable - a main thread calls proc_exit and notifies all the threads that reached waiting on condition variable Which leads to thread 1 hang on waiting on condition variable after that Now it's atomically checked whether proc_exit was already called. --- core/iwasm/common/wasm_shared_memory.c | 125 +++++++++++------- core/iwasm/common/wasm_shared_memory.h | 1 + .../libraries/lib-wasi-threads/test/common.h | 11 +- 3 files changed, 82 insertions(+), 55 deletions(-) diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index eb66f2f09..dc7cf1f99 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -5,6 +5,9 @@ #include "bh_log.h" #include "wasm_shared_memory.h" +#if WASM_ENABLE_THREAD_MGR != 0 +#include "../libraries/thread-mgr/thread_manager.h" +#endif static bh_list shared_memory_list_head; static bh_list *const shared_memory_list = &shared_memory_list_head; @@ -21,6 +24,8 @@ typedef struct AtomicWaitInfo { korp_mutex wait_list_lock; bh_list wait_list_head; bh_list *wait_list; + /* WARNING: insert to the list allowed only in acquire_wait_info + otherwise there will be data race as described in PR #2016 */ } AtomicWaitInfo; typedef struct AtomicWaitNode { @@ -298,7 +303,7 @@ notify_wait_list(bh_list *wait_list, uint32 count) } static AtomicWaitInfo * -acquire_wait_info(void *address, bool create) +acquire_wait_info(void *address, AtomicWaitNode *wait_node) { AtomicWaitInfo *wait_info = NULL; bh_list_status ret; @@ -308,7 +313,7 @@ acquire_wait_info(void *address, bool create) if (address) wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address); - if (!create) { + if (!wait_node) { os_mutex_unlock(&wait_map_lock); return wait_info; } @@ -336,6 +341,12 @@ acquire_wait_info(void *address, bool create) } } + os_mutex_lock(&wait_info->wait_list_lock); + ret = bh_list_insert(wait_info->wait_list, wait_node); + os_mutex_unlock(&wait_info->wait_list_lock); + bh_assert(ret == BH_LIST_SUCCESS); + (void)ret; + os_mutex_unlock(&wait_map_lock); bh_assert(wait_info); @@ -376,16 +387,22 @@ destroy_wait_info(void *wait_info) } } -static bool -map_remove_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, - void *address) +static void +map_try_release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, + void *address) { + os_mutex_lock(&wait_map_lock); + os_mutex_lock(&wait_info->wait_list_lock); if (wait_info->wait_list->len > 0) { - return false; + os_mutex_unlock(&wait_info->wait_list_lock); + os_mutex_unlock(&wait_map_lock); + return; } + os_mutex_unlock(&wait_info->wait_list_lock); bh_hash_map_remove(wait_map_, address, NULL, NULL); - return true; + os_mutex_unlock(&wait_map_lock); + destroy_wait_info(wait_info); } uint32 @@ -396,7 +413,8 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, AtomicWaitInfo *wait_info; AtomicWaitNode *wait_node; WASMSharedMemNode *node; - bool check_ret, is_timeout, no_wait, removed_from_map; + WASMExecEnv *exec_env; + bool check_ret, is_timeout, no_wait; bh_assert(module->module_type == Wasm_Module_Bytecode || module->module_type == Wasm_Module_AoT); @@ -418,14 +436,6 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, return -1; } - /* acquire the wait info, create new one if not exists */ - wait_info = acquire_wait_info(address, true); - - if (!wait_info) { - wasm_runtime_set_exception(module, "failed to acquire wait_info"); - return -1; - } - node = search_module((WASMModuleCommon *)module_inst->module); os_mutex_lock(&node->shared_mem_lock); no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) @@ -435,40 +445,59 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, if (no_wait) { return 1; } - else { - bh_list_status ret; - if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { - wasm_runtime_set_exception(module, "failed to create wait node"); - return -1; - } - memset(wait_node, 0, sizeof(AtomicWaitNode)); - - if (0 != os_mutex_init(&wait_node->wait_lock)) { - wasm_runtime_free(wait_node); - return -1; - } - - if (0 != os_cond_init(&wait_node->wait_cond)) { - os_mutex_destroy(&wait_node->wait_lock); - wasm_runtime_free(wait_node); - return -1; - } - - wait_node->status = S_WAITING; - os_mutex_lock(&wait_info->wait_list_lock); - ret = bh_list_insert(wait_info->wait_list, wait_node); - os_mutex_unlock(&wait_info->wait_list_lock); - bh_assert(ret == BH_LIST_SUCCESS); - (void)ret; + if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { + wasm_runtime_set_exception(module, "failed to create wait node"); + return -1; } + memset(wait_node, 0, sizeof(AtomicWaitNode)); + + if (0 != os_mutex_init(&wait_node->wait_lock)) { + wasm_runtime_free(wait_node); + return -1; + } + + if (0 != os_cond_init(&wait_node->wait_cond)) { + os_mutex_destroy(&wait_node->wait_lock); + wasm_runtime_free(wait_node); + return -1; + } + + wait_node->status = S_WAITING; + + /* acquire the wait info, create new one if not exists */ + wait_info = acquire_wait_info(address, wait_node); + + if (!wait_info) { + os_mutex_destroy(&wait_node->wait_lock); + wasm_runtime_free(wait_node); + wasm_runtime_set_exception(module, "failed to acquire wait_info"); + return -1; + } + +#if WASM_ENABLE_THREAD_MGR != 0 + exec_env = + wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); + bh_assert(exec_env); +#endif + + os_mutex_lock(&node->shared_mem_lock); + no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) + || (wait64 && *(uint64 *)address != expect); + os_mutex_unlock(&node->shared_mem_lock); /* condition wait start */ os_mutex_lock(&wait_node->wait_lock); - os_cond_reltimedwait(&wait_node->wait_cond, &wait_node->wait_lock, - timeout < 0 ? BHT_WAIT_FOREVER - : (uint64)timeout / 1000); + if (!no_wait +#if WASM_ENABLE_THREAD_MGR != 0 + && !wasm_cluster_is_thread_terminated(exec_env) +#endif + ) { + os_cond_reltimedwait(&wait_node->wait_cond, &wait_node->wait_lock, + timeout < 0 ? BHT_WAIT_FOREVER + : (uint64)timeout / 1000); + } is_timeout = wait_node->status == S_WAITING ? true : false; os_mutex_unlock(&wait_node->wait_lock); @@ -486,14 +515,12 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, wasm_runtime_free(wait_node); /* Release wait info if no wait nodes attached */ - removed_from_map = map_remove_wait_info(wait_map, wait_info, address); os_mutex_unlock(&wait_info->wait_list_lock); - if (removed_from_map) - destroy_wait_info(wait_info); + map_try_release_wait_info(wait_map, wait_info, address); os_mutex_unlock(&node->shared_mem_lock); (void)check_ret; - return is_timeout ? 2 : 0; + return no_wait ? 1 : is_timeout ? 2 : 0; } uint32 @@ -523,7 +550,7 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, return -1; } - wait_info = acquire_wait_info(address, false); + wait_info = acquire_wait_info(address, NULL); /* Nobody wait on this address */ if (!wait_info) { diff --git a/core/iwasm/common/wasm_shared_memory.h b/core/iwasm/common/wasm_shared_memory.h index 98683f32b..27019ff53 100644 --- a/core/iwasm/common/wasm_shared_memory.h +++ b/core/iwasm/common/wasm_shared_memory.h @@ -7,6 +7,7 @@ #define _WASM_SHARED_MEMORY_H #include "bh_common.h" +#include "wasm_exec_env.h" #if WASM_ENABLE_INTERP != 0 #include "wasm_runtime.h" #endif diff --git a/core/iwasm/libraries/lib-wasi-threads/test/common.h b/core/iwasm/libraries/lib-wasi-threads/test/common.h index a531e39dc..d032f824c 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/common.h +++ b/core/iwasm/libraries/lib-wasi-threads/test/common.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "wasi_thread_start.h" @@ -23,7 +24,6 @@ static bool termination_by_trap; static bool termination_in_main_thread; static blocking_task_type_t blocking_task_type; -#define TIMEOUT_SECONDS 10ll #define NUM_THREADS 3 static pthread_barrier_t barrier; @@ -36,15 +36,14 @@ void run_long_task() { if (blocking_task_type == BLOCKING_TASK_BUSY_WAIT) { - for (int i = 0; i < TIMEOUT_SECONDS; i++) - sleep(1); + for (;;) { + } } else if (blocking_task_type == BLOCKING_TASK_ATOMIC_WAIT) { - __builtin_wasm_memory_atomic_wait32( - 0, 0, TIMEOUT_SECONDS * 1000 * 1000 * 1000); + __builtin_wasm_memory_atomic_wait32(0, 0, -1); } else { - sleep(TIMEOUT_SECONDS); + sleep(UINT_MAX); } } From bab2402b6e9d4990094d3226b3fb39f83528aa78 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 15 Mar 2023 07:47:36 +0800 Subject: [PATCH 04/61] Fix atomic.wait, get wasi_ctx exit code and thread mgr issues (#2024) - Remove notify_stale_threads_on_exception and change atomic.wait to be interruptible by keep waiting and checking every one second, like the implementation of poll_oneoff in libc-wasi - Wait all other threads exit and then get wasi exit_code to avoid getting invalid value - Inherit suspend_flags of parent thread while creating new thread to avoid terminated flag isn't set for new thread - Fix wasi-threads test case update_shared_data_and_alloc_heap - Add "Lib wasi-threads enabled" prompt for cmake - Fix aot get exception, use aot_copy_exception instead --- build-scripts/config_common.cmake | 3 + core/iwasm/aot/aot_runtime.c | 23 ++-- core/iwasm/aot/aot_runtime.h | 9 ++ core/iwasm/common/wasm_runtime_common.c | 21 ++-- core/iwasm/common/wasm_shared_memory.c | 102 +++++++----------- core/iwasm/common/wasm_shared_memory.h | 4 - .../test/update_shared_data_and_alloc_heap.c | 8 +- .../libraries/thread-mgr/thread_manager.c | 6 ++ 8 files changed, 95 insertions(+), 81 deletions(-) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 8d52efda6..4b29ec869 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -223,6 +223,9 @@ endif () if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1) message (" Lib pthread semaphore enabled") endif () +if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1) + message (" Lib wasi-threads enabled") +endif () if (WAMR_BUILD_LIBC_EMCC EQUAL 1) message (" Libc emcc enabled") endif () diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index ca2ad4f7c..c0fc23746 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1321,8 +1321,9 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr, uint16 result_count = func_type->result_count; const uint8 *types = func_type->types; #ifdef BH_PLATFORM_WINDOWS - const char *exce; int result; + bool has_exception; + char exception[EXCEPTION_BUF_LEN]; #endif bool ret; @@ -1356,14 +1357,14 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr, void (*NativeFunc)(WASMExecEnv *, uint32) = (void (*)(WASMExecEnv *, uint32))func_ptr; NativeFunc(exec_env, argv[0]); - ret = aot_get_exception(module_inst) ? false : true; + ret = aot_copy_exception(module_inst, NULL) ? false : true; } else if (result_count == 1 && types[param_count] == VALUE_TYPE_I32) { uint32 (*NativeFunc)(WASMExecEnv *, uint32) = (uint32(*)(WASMExecEnv *, uint32))func_ptr; argv_ret[0] = NativeFunc(exec_env, argv[0]); - ret = aot_get_exception(module_inst) ? false : true; + ret = aot_copy_exception(module_inst, NULL) ? false : true; } else { ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type, @@ -1377,8 +1378,8 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr, argv_ret); } #ifdef BH_PLATFORM_WINDOWS - if ((exce = aot_get_exception(module_inst)) - && strstr(exce, "native stack overflow")) { + has_exception = aot_copy_exception(module_inst, exception); + if (has_exception && strstr(exception, "native stack overflow")) { /* After a stack overflow, the stack was left in a damaged state, let the CRT repair it */ result = _resetstkoflw(); @@ -1541,7 +1542,7 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, func_type, NULL, NULL, argv, argc, argv); #if WASM_ENABLE_DUMP_CALL_STACK != 0 - if (aot_get_exception(module_inst)) { + if (aot_copy_exception(module_inst, NULL)) { if (aot_create_call_stack(exec_env)) { aot_dump_call_stack(exec_env, true, NULL, 0); } @@ -1552,7 +1553,7 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, aot_free_frame(exec_env); #endif - return ret && !aot_get_exception(module_inst) ? true : false; + return ret && !aot_copy_exception(module_inst, NULL) ? true : false; } } @@ -1611,6 +1612,14 @@ aot_get_exception(AOTModuleInstance *module_inst) return wasm_get_exception(module_inst); } +bool +aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf) +{ + /* The field offsets of cur_exception in AOTModuleInstance and + WASMModuleInstance are the same */ + return wasm_copy_exception(module_inst, exception_buf); +} + static bool execute_malloc_function(AOTModuleInstance *module_inst, AOTFunctionInstance *malloc_func, diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index de12bdaa5..35a1ccb4b 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -415,6 +415,15 @@ aot_set_exception_with_id(AOTModuleInstance *module_inst, uint32 id); const char * aot_get_exception(AOTModuleInstance *module_inst); +/** + * @brief Copy exception in buffer passed as parameter. Thread-safe version of + * `aot_get_exception()` + * @note Buffer size must be no smaller than EXCEPTION_BUF_LEN + * @return true if exception found, false otherwise + */ +bool +aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf); + uint32 aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, void **p_native_addr); diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index e92370c79..99e04ee98 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2331,12 +2331,6 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception) if (exec_env) { wasm_cluster_spread_exception(exec_env, exception ? false : true); } -#if WASM_ENABLE_SHARED_MEMORY - if (exception) { - notify_stale_threads_on_exception( - (WASMModuleInstanceCommon *)module_inst); - } -#endif #else (void)exec_env; #endif @@ -3144,6 +3138,21 @@ uint32_t wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst) { WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst); +#if WASM_ENABLE_THREAD_MGR != 0 + WASMCluster *cluster; + WASMExecEnv *exec_env; + + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) { + /** + * The main thread may exit earlier than other threads, and + * the exit_code of wasi_ctx may be changed by other thread + * when it runs into wasi_proc_exit, here we wait until all + * other threads exit to avoid getting invalid exit_code. + */ + wasm_cluster_wait_for_all_except_self(cluster, exec_env); + } +#endif return wasi_ctx->exit_code; } diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index dc7cf1f99..3b896d9b4 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -106,61 +106,6 @@ search_module(WASMModuleCommon *module) return NULL; } -static void -wait_map_address_count_callback(void *key, void *value, - void *p_total_elem_count) -{ - *(uint32 *)p_total_elem_count = *(uint32 *)p_total_elem_count + 1; -} - -static void -create_list_of_waiter_addresses(void *key, void *value, void *user_data) -{ - AtomicWaitAddressArgs *data = (AtomicWaitAddressArgs *)user_data; - data->addr[data->index++] = key; -} - -void -notify_stale_threads_on_exception(WASMModuleInstanceCommon *module_inst) -{ - AtomicWaitAddressArgs args = { 0 }; - uint32 i = 0, total_elem_count = 0; - uint64 total_elem_count_size = 0; - - os_mutex_lock(&wait_map_lock); /* Make the two traversals atomic */ - - /* count number of addresses in wait_map */ - bh_hash_map_traverse(wait_map, wait_map_address_count_callback, - (void *)&total_elem_count); - - if (!total_elem_count) { - os_mutex_unlock(&wait_map_lock); - return; - } - - /* allocate memory */ - total_elem_count_size = (uint64)sizeof(void *) * total_elem_count; - if (total_elem_count_size >= UINT32_MAX - || !(args.addr = wasm_runtime_malloc((uint32)total_elem_count_size))) { - LOG_ERROR( - "failed to allocate memory for list of atomic wait addresses"); - os_mutex_unlock(&wait_map_lock); - return; - } - - /* set values in list of addresses */ - bh_hash_map_traverse(wait_map, create_list_of_waiter_addresses, &args); - os_mutex_unlock(&wait_map_lock); - - /* notify */ - for (i = 0; i < args.index; i++) { - wasm_runtime_atomic_notify(module_inst, args.addr[i], UINT32_MAX); - } - - /* free memory allocated to args data */ - wasm_runtime_free(args.addr); -} - WASMSharedMemNode * wasm_module_get_shared_memory(WASMModuleCommon *module) { @@ -413,7 +358,9 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, AtomicWaitInfo *wait_info; AtomicWaitNode *wait_node; WASMSharedMemNode *node; +#if WASM_ENABLE_THREAD_MGR != 0 WASMExecEnv *exec_env; +#endif bool check_ret, is_timeout, no_wait; bh_assert(module->module_type == Wasm_Module_Bytecode @@ -489,14 +436,47 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, /* condition wait start */ os_mutex_lock(&wait_node->wait_lock); - if (!no_wait + if (!no_wait) { + /* unit of timeout is nsec, convert it to usec */ + uint64 timeout_left = (uint64)timeout / 1000, timeout_wait; + uint64 timeout_1sec = 1e6; + + while (1) { + if (timeout < 0) { + /* wait forever until it is notified or terminatied + here we keep waiting and checking every second */ + os_cond_reltimedwait(&wait_node->wait_cond, + &wait_node->wait_lock, + (uint64)timeout_1sec); + if (wait_node->status + == S_NOTIFIED /* notified by atomic.notify */ #if WASM_ENABLE_THREAD_MGR != 0 - && !wasm_cluster_is_thread_terminated(exec_env) + /* terminated by other thread */ + || wasm_cluster_is_thread_terminated(exec_env) #endif - ) { - os_cond_reltimedwait(&wait_node->wait_cond, &wait_node->wait_lock, - timeout < 0 ? BHT_WAIT_FOREVER - : (uint64)timeout / 1000); + ) { + break; + } + /* continue to wait */ + } + else { + timeout_wait = + timeout_left < timeout_1sec ? timeout_left : timeout_1sec; + os_cond_reltimedwait(&wait_node->wait_cond, + &wait_node->wait_lock, timeout_wait); + if (wait_node->status + == S_NOTIFIED /* notified by atomic.notify */ + || timeout_left <= timeout_wait /* time out */ +#if WASM_ENABLE_THREAD_MGR != 0 + /* terminated by other thread */ + || wasm_cluster_is_thread_terminated(exec_env) +#endif + ) { + break; + } + timeout_left -= timeout_wait; + } + } } is_timeout = wait_node->status == S_WAITING ? true : false; diff --git a/core/iwasm/common/wasm_shared_memory.h b/core/iwasm/common/wasm_shared_memory.h index 27019ff53..6c1c49210 100644 --- a/core/iwasm/common/wasm_shared_memory.h +++ b/core/iwasm/common/wasm_shared_memory.h @@ -7,7 +7,6 @@ #define _WASM_SHARED_MEMORY_H #include "bh_common.h" -#include "wasm_exec_env.h" #if WASM_ENABLE_INTERP != 0 #include "wasm_runtime.h" #endif @@ -40,9 +39,6 @@ wasm_shared_memory_init(); void wasm_shared_memory_destroy(); -void -notify_stale_threads_on_exception(WASMModuleInstanceCommon *module); - WASMSharedMemNode * wasm_module_get_shared_memory(WASMModuleCommon *module); diff --git a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c index 2bfd196da..b7fb9afba 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/update_shared_data_and_alloc_heap.c @@ -41,9 +41,6 @@ __wasi_thread_start_C(int thread_id, int *start_arg) for (int i = 0; i < NUM_ITER; i++) __atomic_fetch_add(data->count, 1, __ATOMIC_SEQ_CST); - pthread_mutex_lock(&mutex); /* malloc is not thread-safe in wasi-libc */ - vals[data->iteration] = malloc(sizeof(int)); - pthread_mutex_unlock(&mutex); *vals[data->iteration] = data->iteration; __atomic_store_n(&data->th_done, 1, __ATOMIC_SEQ_CST); @@ -60,6 +57,11 @@ main(int argc, char **argv) assert(count != NULL && "Failed to call calloc"); assert(pthread_mutex_init(&mutex, NULL) == 0 && "Failed to init mutex"); + for (int i = 0; i < NUM_THREADS; i++) { + vals[i] = malloc(sizeof(int)); + assert(vals[i] != NULL && "Failed to call calloc"); + } + for (int i = 0; i < NUM_THREADS; i++) { assert(start_args_init(&data[i].base) && "Stack allocation for thread failed"); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index e61915d52..bfb7d0a48 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -525,6 +525,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env) goto fail4; } + /* Inherit suspend_flags of parent thread */ + new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags; + if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) goto fail4; @@ -674,6 +677,9 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env, new_exec_env->aux_stack_bottom.bottom = UINT32_MAX; } + /* Inherit suspend_flags of parent thread */ + new_exec_env->suspend_flags.flags = exec_env->suspend_flags.flags; + if (!wasm_cluster_add_exec_env(cluster, new_exec_env)) goto fail3; From 05d7ec30b11871488d8339a8f64a6c8392adceaa Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 15 Mar 2023 08:24:08 +0800 Subject: [PATCH 05/61] Add libsodium benchmark (#2025) --- .../compilation_on_android_ubuntu.yml | 2 +- tests/benchmarks/coremark/README.md | 2 +- tests/benchmarks/coremark/build.sh | 4 +- tests/benchmarks/jetstream/README.md | 2 +- tests/benchmarks/libsodium/README.md | 23 ++++++++ tests/benchmarks/libsodium/build.sh | 42 +++++++++++++ tests/benchmarks/libsodium/test_aot.sh | 59 +++++++++++++++++++ tests/benchmarks/polybench/README.md | 2 +- tests/benchmarks/sightglass/README.md | 2 +- 9 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 tests/benchmarks/libsodium/README.md create mode 100755 tests/benchmarks/libsodium/build.sh create mode 100755 tests/benchmarks/libsodium/test_aot.sh diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 0fa9acb09..0cb961bc8 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -515,7 +515,7 @@ jobs: git fetch https://github.com/WebAssembly/wasi-libc \ 8f5275796a82f8ecfd0833a4f3f444fa37ed4546 git checkout FETCH_HEAD - make \ + make -j \ AR=/opt/wasi-sdk/bin/llvm-ar \ NM=/opt/wasi-sdk/bin/llvm-nm \ CC=/opt/wasi-sdk/bin/clang \ diff --git a/tests/benchmarks/coremark/README.md b/tests/benchmarks/coremark/README.md index 2a36e9de3..1631cc5c0 100644 --- a/tests/benchmarks/coremark/README.md +++ b/tests/benchmarks/coremark/README.md @@ -8,7 +8,7 @@ Please build iwasm and wamrc, refer to: - [Build iwasm on Linux](../../../doc/build_wamr.md#linux), or [Build iwasm on MacOS](../../../doc/build_wamr.md#macos) -- [build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) +- [Build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) And install WASI SDK, please download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`. diff --git a/tests/benchmarks/coremark/build.sh b/tests/benchmarks/coremark/build.sh index df6b9a305..14c179ce5 100755 --- a/tests/benchmarks/coremark/build.sh +++ b/tests/benchmarks/coremark/build.sh @@ -13,7 +13,7 @@ cd coremark echo "Build coremark with gcc .." gcc -O3 -Iposix -I. -DFLAGS_STR=\""-O3 -DPERFORMANCE_RUN=1 -lrt"\" \ - -DITERATIONS=0 -DPERFORMANCE_RUN=1 \ + -DITERATIONS=400000 -DSEED_METHOD=SEED_VOLATILE -DPERFORMANCE_RUN=1 \ core_list_join.c core_main.c core_matrix.c core_state.c \ core_util.c posix/core_portme.c \ -o ../coremark.exe -lrt @@ -21,7 +21,7 @@ gcc -O3 -Iposix -I. -DFLAGS_STR=\""-O3 -DPERFORMANCE_RUN=1 -lrt"\" \ echo "Build coremark with wasi-sdk .." /opt/wasi-sdk/bin/clang -O3 -Iposix -I. -DFLAGS_STR=\""-O3 -DPERFORMANCE_RUN=1"\" \ -Wl,--export=main \ - -DITERATIONS=0 -DPERFORMANCE_RUN=1 \ + -DITERATIONS=400000 -DSEED_METHOD=SEED_VOLATILE -DPERFORMANCE_RUN=1 \ -Wl,--allow-undefined \ core_list_join.c core_main.c core_matrix.c core_state.c \ core_util.c posix/core_portme.c \ diff --git a/tests/benchmarks/jetstream/README.md b/tests/benchmarks/jetstream/README.md index 9e9bcb021..f6c593d11 100644 --- a/tests/benchmarks/jetstream/README.md +++ b/tests/benchmarks/jetstream/README.md @@ -8,7 +8,7 @@ Please build iwasm and wamrc, refer to: - [Build iwasm on Linux](../../../doc/build_wamr.md#linux), or [Build iwasm on MacOS](../../../doc/build_wamr.md#macos) -- [build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) +- [Build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) And install emsdk, refer to [the guide](https://emscripten.org/docs/getting_started/downloads.html). Don't forget to activate emsdk and set up environment variables. For example, use instructions below to install it under /opt and activate it: diff --git a/tests/benchmarks/libsodium/README.md b/tests/benchmarks/libsodium/README.md new file mode 100644 index 000000000..19500afe6 --- /dev/null +++ b/tests/benchmarks/libsodium/README.md @@ -0,0 +1,23 @@ +# Introduction + +[libsodium](https://github.com/jedisct1/libsodium) is a new, easy-to-use software library for encryption, decryption, signatures, password hashing and more. + +**Source**: https://github.com/jedisct1/libsodium + +# Building + +Please build iwasm and wamrc, refer to: +- [Build iwasm on Linux](../../../doc/build_wamr.md#linux), or [Build iwasm on MacOS](../../../doc/build_wamr.md#macos) +- [Build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) + +And install [zig toolchain](https://ziglang.org/learn/getting-started), refer to [Install Zig from a Package Manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager) for how to install it. + +And then run `./build.sh` to build the source code, the libsodium source code will be cloned, and test benchmarks of native version, wasm files and AOT files will be generated under `libsodium/zig-out/bin`. + +# Running + +Run `./run_aot.sh` to test the benchmark, the native mode and iwasm aot mode will be tested respectively. + +# Others + +Refer to [Performance of WebAssembly runtimes in 2023](https://00f.net/2023/01/04/webassembly-benchmark-2023) for more about the performance comparison of wasm runtimes on running the libsodium benchmarks. diff --git a/tests/benchmarks/libsodium/build.sh b/tests/benchmarks/libsodium/build.sh new file mode 100755 index 000000000..1e9cc21a7 --- /dev/null +++ b/tests/benchmarks/libsodium/build.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +libsodium_CASES="aead_aes256gcm2 aead_aes256gcm aead_chacha20poly13052 aead_chacha20poly1305 \ + aead_xchacha20poly1305 auth2 auth3 auth5 auth6 auth7 auth box2 box7 box8 \ + box_easy2 box_easy box_seal box_seed box chacha20 codecs core1 core2 core3 \ + core4 core5 core6 core_ed25519 core_ristretto255 ed25519_convert generichash2 \ + generichash3 generichash hash3 hash kdf keygen kx metamorphic misuse \ + onetimeauth2 onetimeauth7 onetimeauth pwhash_argon2id pwhash_argon2i \ + pwhash_scrypt_ll pwhash_scrypt randombytes scalarmult2 scalarmult5 \ + scalarmult6 scalarmult7 scalarmult8 scalarmult_ed25519 scalarmult_ristretto255 \ + scalarmult secretbox2 secretbox7 secretbox8 secretbox_easy2 secretbox_easy \ + secretbox secretstream shorthash sign siphashx24 sodium_core sodium_utils2 \ + sodium_utils3 sodium_utils sodium_version stream2 stream3 stream4 stream verify1 \ + xchacha20" + +readonly WAMRC_CMD=$PWD/../../../wamr-compiler/build/wamrc +readonly OUT_DIR=$PWD/libsodium/zig-out/bin + +if [ ! -d libsodium ]; then + git clone -b stable https://github.com/jedisct1/libsodium.git +fi + +cd libsodium + +echo "Build libsodium native" +zig build -Drelease-fast -Denable_benchmarks=true + +echo "Build libsodium wasm32-wasi" +zig build -Drelease-fast -Denable_benchmarks=true -Dtarget=wasm32-wasi + +for case in ${libsodium_CASES} +do + ${WAMRC_CMD} -o ${OUT_DIR}/${case}.aot ${OUT_DIR}/${case}.wasm + + if [ "$?" != 0 ]; then + echo -e "Error while compiling ${case}.wasm to ${case}.aot" + exit + fi +done diff --git a/tests/benchmarks/libsodium/test_aot.sh b/tests/benchmarks/libsodium/test_aot.sh new file mode 100755 index 000000000..2e4e3e357 --- /dev/null +++ b/tests/benchmarks/libsodium/test_aot.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +libsodium_CASES="aead_aes256gcm2 aead_aes256gcm aead_chacha20poly13052 aead_chacha20poly1305 \ + aead_xchacha20poly1305 auth2 auth3 auth5 auth6 auth7 auth box2 box7 box8 \ + box_easy2 box_easy box_seal box_seed box chacha20 codecs core1 core2 core3 \ + core4 core5 core6 core_ed25519 core_ristretto255 ed25519_convert generichash2 \ + generichash3 generichash hash3 hash kdf keygen kx metamorphic misuse \ + onetimeauth2 onetimeauth7 onetimeauth pwhash_argon2id pwhash_argon2i \ + pwhash_scrypt_ll pwhash_scrypt randombytes scalarmult2 scalarmult5 \ + scalarmult6 scalarmult7 scalarmult8 scalarmult_ed25519 scalarmult_ristretto255 \ + scalarmult secretbox2 secretbox7 secretbox8 secretbox_easy2 secretbox_easy \ + secretbox secretstream shorthash sign siphashx24 sodium_core sodium_utils2 \ + sodium_utils3 sodium_utils sodium_version stream2 stream3 stream4 stream verify1 \ + xchacha20" + +readonly OUT_DIR=$PWD/libsodium/zig-out/bin +readonly REPORT=$PWD/report.txt +readonly IWASM_CMD=$PWD/../../../product-mini/platforms/linux/build/iwasm + +BENCH_NAME_MAX_LEN=20 + +rm -f $REPORT +touch $REPORT + +function print_bench_name() +{ + name=$1 + echo -en "$name" >> $REPORT + name_len=${#name} + if [ $name_len -lt $BENCH_NAME_MAX_LEN ] + then + spaces=$(( $BENCH_NAME_MAX_LEN - $name_len )) + for i in $(eval echo "{1..$spaces}"); do echo -n " " >> $REPORT; done + fi +} + +# run benchmarks +cd $OUT_DIR + +echo -en "\t\t\t\t\t\tnative\tiwasm-aot\n" >> $REPORT + +for t in $libsodium_CASES +do + print_bench_name $t + + echo "run $t with native..." + echo -en "\t" >> $REPORT + ./${t} | awk -F '-' 'BEGIN{FIELDWIDTHS="10"}{ORS=""; print $1 / 1000000.0}' >> $REPORT + + echo "run $t with iwasm aot..." + echo -en "\t \t" >> $REPORT + $IWASM_CMD ${t}.aot | awk -F '-' 'BEGIN{FIELDWIDTHS="10"}{ORS=""; print $1 / 1000000.0}' >> $REPORT + + echo -en "\n" >> $REPORT +done + diff --git a/tests/benchmarks/polybench/README.md b/tests/benchmarks/polybench/README.md index 191c6f9dc..7808e17d9 100644 --- a/tests/benchmarks/polybench/README.md +++ b/tests/benchmarks/polybench/README.md @@ -8,7 +8,7 @@ Please build iwasm and wamrc, refer to: - [Build iwasm on Linux](../../../doc/build_wamr.md#linux), or [Build iwasm on MacOS](../../../doc/build_wamr.md#macos) -- [build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) +- [Build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) And install WASI SDK, please download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`. diff --git a/tests/benchmarks/sightglass/README.md b/tests/benchmarks/sightglass/README.md index 8ffef0994..a446d80ea 100644 --- a/tests/benchmarks/sightglass/README.md +++ b/tests/benchmarks/sightglass/README.md @@ -8,7 +8,7 @@ Please build iwasm and wamrc, refer to: - [Build iwasm on Linux](../../../doc/build_wamr.md#linux), or [Build iwasm on MacOS](../../../doc/build_wamr.md#macos) -- [build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) +- [Build wamrc AOT compiler](../../../README.md#build-wamrc-aot-compiler) And install WASI SDK, please download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`. From 915b4d2a89ceb46df68630de31a099a7a5c4160d Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Wed, 15 Mar 2023 12:34:34 +0800 Subject: [PATCH 06/61] Fix few wasm-c-api python binding issues (#2029) How to python language binding test cases: ``` $ cd /language-bindings/python $ python -m pip install -e . $ cd wasm-c-api $ python -m unittest tests/test_basic.py $ python -m unittest tests/test_advanced.py ``` --- core/iwasm/common/wasm_c_api.c | 2 +- language-bindings/python/wasm-c-api/tests/test_basic.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 9f6ed1e5d..15eb9f011 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -1905,7 +1905,7 @@ wasm_trap_new_internal(wasm_store_t *store, } /* fill in message */ - if (strlen(error_info) > 0) { + if (error_info && strlen(error_info) > 0) { if (!(trap->message = malloc_internal(sizeof(wasm_byte_vec_t)))) { goto failed; } diff --git a/language-bindings/python/wasm-c-api/tests/test_basic.py b/language-bindings/python/wasm-c-api/tests/test_basic.py index 632ad512a..a2d3f2850 100644 --- a/language-bindings/python/wasm-c-api/tests/test_basic.py +++ b/language-bindings/python/wasm-c-api/tests/test_basic.py @@ -1183,9 +1183,10 @@ class BasicTestSuite(unittest.TestCase): self._wasm_store, module, imports, create_null_pointer(wasm_trap_t) ) - wasm_instance_delete(instance) wasm_module_delete(module) + self.assertIsNullPointer(instance) + def test_wasm_instance_new_pos(self): binary = load_module_file(MODULE_BINARY) module = wasm_module_new(self._wasm_store, binary) @@ -1227,9 +1228,10 @@ class BasicTestSuite(unittest.TestCase): create_null_pointer(wasm_trap_t), ) - wasm_instance_delete(instance) wasm_module_delete(module) + self.assertIsNullPointer(instance) + # test those APIs in advanced: # wasm_instance_delete # wasm_instance_exports From 23e9a356e50f157210c72bd7e19570474409edbd Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Thu, 16 Mar 2023 00:22:03 +0000 Subject: [PATCH 07/61] Enable to run wasi-thread tests with AOT (#2026) --- .../wasi-test-script/run_wasi_tests.sh | 69 ++++++++++++------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh index 30d32d5f8..eb6cf3f91 100755 --- a/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh +++ b/tests/wamr-test-suites/wasi-test-script/run_wasi_tests.sh @@ -13,6 +13,42 @@ readonly PLATFORM=$(uname -s | tr A-Z a-z) readonly WAMR_DIR="${WORK_DIR}/../../../.." readonly IWASM_CMD="${WORK_DIR}/../../../../product-mini/platforms/${PLATFORM}/build/iwasm" readonly WAMRC_CMD="${WORK_DIR}/../../../../wamr-compiler/build/wamrc" +readonly C_TESTS="tests/c/testsuite/" +readonly ASSEMBLYSCRIPT_TESTS="tests/assemblyscript/testsuite/" +readonly THREAD_PROPOSAL_TESTS="tests/proposals/wasi-threads/" +readonly THREAD_INTERNAL_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/test/" +readonly LIB_SOCKET_TESTS="${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/" + +run_aot_tests () { + local tests=("$@") + for test_wasm in ${tests[@]}; do + test_aot="${test_wasm%.wasm}.aot" + test_json="${test_wasm%.wasm}.json" + + if [ -f ${test_wasm} ]; then + expected=$(jq .exit_code ${test_json}) + fi + + echo "Compiling $test_wasm to $test_aot" + ${WAMRC_CMD} --enable-multi-thread ${target_option} \ + -o ${test_aot} ${test_wasm} + + echo "Running $test_aot" + expected=0 + if [ -f ${test_json} ]; then + expected=$(jq .exit_code ${test_json}) + fi + + ${IWASM_CMD} $test_aot + + ret=${PIPESTATUS[0]} + + echo "expected=$expected, actual=$ret" + if [[ $expected != "" ]] && [[ $expected != $ret ]];then + exit_code=1 + fi + done +} if [[ $MODE != "aot" ]];then python3 -m venv wasi-env && source wasi-env/bin/activate @@ -20,11 +56,11 @@ if [[ $MODE != "aot" ]];then TEST_RUNTIME_EXE="${IWASM_CMD}" python3 test-runner/wasi_test_runner.py \ -r adapters/wasm-micro-runtime.py \ -t \ - tests/c/testsuite/ \ - tests/assemblyscript/testsuite/ \ - tests/proposals/wasi-threads/ \ - ${WAMR_DIR}/core/iwasm/libraries/lib-wasi-threads/test/ \ - ${WAMR_DIR}/core/iwasm/libraries/lib-socket/test/ \ + ${C_TESTS} \ + ${ASSEMBLYSCRIPT_TESTS} \ + ${THREAD_PROPOSAL_TESTS} \ + ${THREAD_INTERNAL_TESTS} \ + ${LIB_SOCKET_TESTS} \ exit_code=${PIPESTATUS[0]} deactivate else @@ -33,26 +69,11 @@ else target_option="--target=i386" fi - # Run WASI thread proposal tests exit_code=0 - wasm_tests=$(ls tests/proposals/wasi-threads/*.wasm) - for test_wasm in ${wasm_tests}; do - test_aot="${test_wasm%.wasm}.aot" - test_json="${test_wasm%.wasm}.json" - - echo "Compiling $test_wasm to $test_aot" - ${WAMRC_CMD} --enable-multi-thread ${target_option} \ - -o $test_aot $test_wasm - - echo "Running $test_aot" - expected=$(jq .exit_code ${test_json}) - ${IWASM_CMD} $test_aot - ret=${PIPESTATUS[0]} - - echo "expected=$expected, actual=$ret" - if [[ $expected != "" ]] && [[ $expected != $ret ]];then - exit_code=1 - fi + for testsuite in ${THREAD_PROPOSAL_TESTS} ${THREAD_INTERNAL_TESTS}; do + tests=$(ls ${testsuite}*.wasm) + tests_array=($tests) + run_aot_tests "${tests_array[@]}" done fi From 83659fa42af73456d90667325292a187af7baba2 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Fri, 17 Mar 2023 13:02:03 +0100 Subject: [PATCH 08/61] Use wasi-sdk 20 pre-release for tests with threads (#2021) `wasi-sdk-20` pre-release can be used to avoid building `wasi-libc` to enable threads. It's not possible to use `wasi-sdk-20` pre-release on Ubuntu 20.04 because of incompatibility with the glibc version: ```bash /opt/wasi-sdk/bin/clang: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /opt/wasi-sdk/bin/clang) ``` --- .../compilation_on_android_ubuntu.yml | 53 +++++++++++++------ .github/workflows/compilation_on_macos.yml | 22 ++------ core/iwasm/libraries/lib-socket/test/build.sh | 5 +- .../libraries/lib-wasi-threads/test/build.sh | 4 +- samples/wasi-threads/CMakeLists.txt | 7 --- samples/wasi-threads/README.md | 12 +---- samples/wasi-threads/wasm-apps/CMakeLists.txt | 5 +- 7 files changed, 50 insertions(+), 58 deletions(-) diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 0cb961bc8..6654e1b31 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -337,9 +337,13 @@ jobs: - os: ubuntu-20.04 wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz" wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + wasi_sdk_folder_name: "wasi-sdk-19.0" + wasi_sysroot_option: "-DWASI_SYSROOT=`pwd`/../../../core/deps/wasi-libc/sysroot" - os: ubuntu-22.04 - wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz" + wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-linux.tar.gz" wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + wasi_sdk_folder_name: "wasi-sdk-20.0+threads" + wasi_sysroot_option: "" steps: - name: checkout uses: actions/checkout@v3 @@ -349,7 +353,7 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv wasi-sdk-19.0 wasi-sdk + sudo mv ${{ matrix.wasi_sdk_folder_name }} wasi-sdk - name: download and install wabt run: | @@ -359,6 +363,7 @@ jobs: sudo mv wabt-1.0.31 wabt - name: build wasi-libc (needed for wasi-threads) + if: matrix.os == 'ubuntu-20.04' run: | mkdir wasi-libc cd wasi-libc @@ -431,15 +436,22 @@ jobs: run: | cd samples/wasi-threads mkdir build && cd build - cmake -DWASI_SYSROOT=`pwd`/../../../core/deps/wasi-libc/sysroot .. + cmake ${{ matrix.wasi_sysroot_option }} .. cmake --build . --config Release --parallel 4 ./iwasm wasm-apps/no_pthread.wasm test: - needs: [build_iwasm, build_llvm_libraries_on_ubuntu_2004, build_wamrc] - runs-on: ubuntu-20.04 + needs: + [ + build_iwasm, + build_llvm_libraries_on_ubuntu_2004, + build_llvm_libraries_on_ubuntu_2204, + build_wamrc + ] + runs-on: ${{ matrix.os }} strategy: matrix: + os: [ubuntu-20.04, ubuntu-22.04] running_mode: [ "classic-interp", @@ -457,12 +469,21 @@ jobs: $THREADS_TEST_OPTIONS, $WASI_TEST_OPTIONS, ] - wasi_sdk_release: - [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz", - ] - llvm_cache_key: - ["${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}"] + include: + - os: ubuntu-20.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} + wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz" + wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + wasi_sdk_folder_name: "wasi-sdk-19.0" + wasi_sysroot_option: "WASI_SYSROOT_OPTION='--sysroot ../../../../../core/deps/wasi-libc/sysroot'" + ubuntu_version: "20.04" + - os: ubuntu-22.04 + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} + wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-linux.tar.gz" + wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + wasi_sdk_folder_name: "wasi-sdk-20.0+threads" + wasi_sysroot_option: "" + ubuntu_version: "22.04" exclude: # uncompatiable modes and features # classic-interp and fast-interp don't support simd @@ -503,10 +524,10 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv wasi-sdk-19.0 wasi-sdk + sudo mv ${{ matrix.wasi_sdk_folder_name }} wasi-sdk - name: build wasi-libc (needed for wasi-threads) - if: matrix.test_option == '$WASI_TEST_OPTIONS' + if: matrix.os == 'ubuntu-20.04' && matrix.test_option == '$WASI_TEST_OPTIONS' run: | mkdir wasi-libc cd wasi-libc @@ -557,12 +578,12 @@ jobs: - name: Build WASI thread tests if: matrix.test_option == '$WASI_TEST_OPTIONS' - run: WASI_SYSROOT=../../../../../core/deps/wasi-libc/sysroot bash build.sh + run: ${{ matrix.wasi_sysroot_option }} bash build.sh working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/ - name: build socket api tests if: matrix.test_option == '$WASI_TEST_OPTIONS' - run: WASI_SYSROOT=../../../../../core/deps/wasi-libc/sysroot bash build.sh + run: ${{ matrix.wasi_sysroot_option }} bash build.sh working-directory: ./core/iwasm/libraries/lib-socket/test/ - name: run tests @@ -577,7 +598,7 @@ jobs: # Add another apt repository as some packages cannot # be downloaded with the github default repository sudo curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc && - sudo apt-add-repository https://packages.microsoft.com/ubuntu/20.04/prod && + sudo apt-add-repository https://packages.microsoft.com/ubuntu/${{ matrix.ubuntu_version }}/prod && sudo apt-get update && sudo apt install -y g++-multilib lib32gcc-9-dev diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index 816e65ce9..5f3828406 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -249,7 +249,7 @@ jobs: os: [macos-latest] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-macos.tar.gz", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-macos.tar.gz", ] wabt_release: [ @@ -264,7 +264,7 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv wasi-sdk-19.0 wasi-sdk + sudo mv wasi-sdk-20.0+threads wasi-sdk - name: download and install wabt run: | @@ -273,22 +273,6 @@ jobs: sudo tar -xzf wabt-1.0.31-*.tar.gz sudo mv wabt-1.0.31 wabt - - name: build wasi-libc (needed for wasi-threads) - run: | - mkdir wasi-libc - cd wasi-libc - git init - # "Rename thread_spawn import" commit on main branch - git fetch https://github.com/WebAssembly/wasi-libc \ - 8f5275796a82f8ecfd0833a4f3f444fa37ed4546 - git checkout FETCH_HEAD - make \ - AR=/opt/wasi-sdk/bin/llvm-ar \ - NM=/opt/wasi-sdk/bin/llvm-nm \ - CC=/opt/wasi-sdk/bin/clang \ - THREAD_MODEL=posix - working-directory: core/deps - - name: Build Sample [basic] run: | cd samples/basic @@ -339,6 +323,6 @@ jobs: run: | cd samples/wasi-threads mkdir build && cd build - cmake -DWASI_SYSROOT=`pwd`/../../../core/deps/wasi-libc/sysroot .. + cmake .. cmake --build . --config Release --parallel 4 ./iwasm wasm-apps/no_pthread.wasm diff --git a/core/iwasm/libraries/lib-socket/test/build.sh b/core/iwasm/libraries/lib-socket/test/build.sh index ec8d6608c..5cdfbd8d6 100755 --- a/core/iwasm/libraries/lib-socket/test/build.sh +++ b/core/iwasm/libraries/lib-socket/test/build.sh @@ -3,18 +3,17 @@ # Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set -ueo pipefail +set -eo pipefail CC="${CC:=/opt/wasi-sdk/bin/clang}" files=("tcp_udp.c" "nslookup.c") -WASI_SYSROOT=${WASI_SYSROOT:=~/dev/wasi-libc/sysroot} for file in "${files[@]}" do echo $file $CC \ + $WASI_SYSROOT_OPTION \ --target=wasm32-wasi-threads \ -I../inc \ - --sysroot $WASI_SYSROOT \ ../src/wasi/wasi_socket_ext.c -pthread -ftls-model=local-exec \ -Wl,--allow-undefined \ -Wl,--strip-all,--no-entry \ diff --git a/core/iwasm/libraries/lib-wasi-threads/test/build.sh b/core/iwasm/libraries/lib-wasi-threads/test/build.sh index 58ff59481..c8431bb91 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/build.sh +++ b/core/iwasm/libraries/lib-wasi-threads/test/build.sh @@ -5,8 +5,8 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # +set -eo pipefail CC=${CC:=/opt/wasi-sdk/bin/clang} -WASI_SYSROOT=${WASI_SYSROOT:=~/dev/wasi-libc/sysroot} WAMR_DIR=../../../../.. for test_c in *.c; do @@ -14,7 +14,7 @@ for test_c in *.c; do echo "Compiling $test_c to $test_wasm" $CC \ - --sysroot $WASI_SYSROOT \ + $WASI_SYSROOT_OPTION \ -target wasm32-wasi-threads \ -pthread -ftls-model=local-exec \ -z stack-size=32768 \ diff --git a/samples/wasi-threads/CMakeLists.txt b/samples/wasi-threads/CMakeLists.txt index 93f6b3310..467f5fd1f 100644 --- a/samples/wasi-threads/CMakeLists.txt +++ b/samples/wasi-threads/CMakeLists.txt @@ -7,13 +7,6 @@ include(CheckPIESupported) project(wasi_threads_sample) -if (NOT DEFINED WASI_SYSROOT) - message (WARNING "Custom sysroot with threads enabled is required to build wasi threads samples. -Please note that current wasi-sdk doesn't ship with threads enabled. -Run cmake command with -DWASI_SYSROOT=/path/to/sysroot/with/threads to compile samples.") - return () -endif () - ################ runtime settings ################ string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM) if (APPLE) diff --git a/samples/wasi-threads/README.md b/samples/wasi-threads/README.md index ca8d166d2..a5e1aed3c 100644 --- a/samples/wasi-threads/README.md +++ b/samples/wasi-threads/README.md @@ -1,21 +1,13 @@ # "WASI threads" sample introduction -Currently, since the `wasi-sdk` does not have thread support in the latest release, make sure to have [wasi-libc](https://github.com/WebAssembly/wasi-libc) installed. Build it with threads enabled, e.g. - -```shell -make \ - AR=/opt/wasi-sdk/bin/llvm-ar \ - NM=/opt/wasi-sdk/bin/llvm-nm \ - CC=/opt/wasi-sdk/bin/clang \ - THREAD_MODEL=posix -``` +To run the sample, `wasi-sdk` >= 20 is required. ## Build and run the samples ```shell $ mkdir build $ cd build -$ cmake -DWASI_SYSROOT=/path/to/wasi-libc/sysroot .. +$ cmake .. $ make ... $ ./iwasm wasm-apps/no_pthread.wasm diff --git a/samples/wasi-threads/wasm-apps/CMakeLists.txt b/samples/wasi-threads/wasm-apps/CMakeLists.txt index e77e53304..a6b288449 100644 --- a/samples/wasi-threads/wasm-apps/CMakeLists.txt +++ b/samples/wasi-threads/wasm-apps/CMakeLists.txt @@ -11,7 +11,10 @@ if (NOT DEFINED WASI_SDK_DIR) set (WASI_SDK_DIR "/opt/wasi-sdk") endif () -set (CMAKE_SYSROOT "${WASI_SYSROOT}") +if (DEFINED WASI_SYSROOT) + set (CMAKE_SYSROOT "${WASI_SYSROOT}") +endif () + set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang") set (CMAKE_ASM_COMPILER "${WASI_SDK_DIR}/bin/clang") set (CMAKE_EXE_LINKER_FLAGS "-target wasm32-wasi-threads") From c2b73eabe2b1b301c2efc3b2944a251a338ac42e Mon Sep 17 00:00:00 2001 From: Wang Xin Date: Sun, 19 Mar 2023 08:05:57 +0800 Subject: [PATCH 09/61] Readme refactoring (#2038) --- README.md | 161 +++--------- core/app-framework/README.md | 31 +-- core/app-mgr/README.md | 8 +- doc/build_wamr.md | 470 +---------------------------------- doc/memory_tune.md | 7 +- doc/source_debugging.md | 4 + product-mini/README.md | 459 ++++++++++++++++++++++++++++++++++ samples/README.md | 15 ++ wamr-compiler/README.md | 23 ++ wamr-sdk/README.md | 7 + 10 files changed, 574 insertions(+), 611 deletions(-) create mode 100644 product-mini/README.md create mode 100644 samples/README.md create mode 100644 wamr-compiler/README.md diff --git a/README.md b/README.md index 99bcff0a1..fc31f927f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -WebAssembly Micro Runtime -========================= +# WebAssembly Micro Runtime + **A [Bytecode Alliance][BA] project** @@ -7,51 +7,35 @@ WebAssembly Micro Runtime **[Guide](https://wamr.gitbook.io/)**  **[Website](https://bytecodealliance.github.io/wamr.dev)**  **[Chat](https://bytecodealliance.zulipchat.com/#narrow/stream/290350-wamr)** -[Build WAMR](./doc/build_wamr.md) | [Build AOT Compiler](./README.md#build-wamrc-aot-compiler) | [Embed WAMR](./doc/embed_wamr.md) | [Export Native API](./doc/export_native_api.md) | [Build WASM Apps](./doc/build_wasm_app.md) | [Samples](./README.md#samples) +[Build WAMR](./doc/build_wamr.md) | [Build AOT Compiler](./README.md#build-wamrc-aot-compiler) | [Embed WAMR](./doc/embed_wamr.md) | [Export Native API](./doc/export_native_api.md) | [Build Wasm Apps](./doc/build_wasm_app.md) | [Samples](./README.md#samples) -WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (WASM) runtime with small footprint, high performance and highly configurable features for applications cross from embedded, IoT, edge to Trusted Execution Environment (TEE), smart contract, cloud native and so on. It includes a few parts as below: -- The [**"iwasm" VM core**](./README.md#iwasm-vm-core) to run WASM applications, supporting interpreter mode, AOT mode (Ahead-of-Time compilation) and JIT modes (Just-in-Time compilation, LLVM JIT and Fast JIT are supported) +WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm) runtime with small footprint, high performance and highly configurable features for applications cross from embedded, IoT, edge to Trusted Execution Environment (TEE), smart contract, cloud native and so on. It includes a few parts as below: +- [**VMcore**](./core/iwasm/): A set of runtime libraries for loading and running Wasm modules. It supports several execution modes including interpreter, Ahead-of-Time compilation(AoT) and Just-in-Time compilation (JIT). The WAMR supports two JIT tiers - Fast JIT, LLVM JIT, and dynamic tier-up from Fast JIT to LLVM JIT. +- [**iwasm**](./product-mini/): The executable binary built with WAMR VMcore supports WASI and command line interface. +- [**wamrc**](./wamr-compiler/): The AOT compiler to compile Wasm file into AOT file +- Useful components and tools for building real solutions with WAMR vmcore: + - [App-framework](./core/app-framework/README.md): A framework for supporting APIs for the Wasm applications + - [App-manager](./core/app-mgr/README.md): a framework for dynamical loading the Wasm module remotely + - [WAMR-IDE](./test-tools/wamr-ide): An experimental VSCode extension for developping WebAssembly applications with C/C++ -- The [**"wamrc" AOT compiler**](./README.md#build-wamrc-aot-compiler) to compile WASM file into AOT file for best performance and smaller runtime footprint, which is run by "iwasm" VM Core - -- The [**application framework**](./README.md#application-framework) and the supporting APIs for the WASM applications - -- The [**dynamic management**](./README.md#remote-application-management) of the WASM applications - -Getting started -================== -- [Build iwasm VM core](./doc/build_wamr.md) on [Linux](./doc/build_wamr.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos) and [Windows](./doc/build_wamr.md#windows), and [Build wamrc AOT compiler](./README.md#build-wamrc-aot-compiler) -- [Embed WAMR into host applications](./doc/embed_wamr.md) - - [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go) - -- [Register native APIs for WASM applications](./doc/export_native_api.md) -- [Build WASM applications](./doc/build_wasm_app.md) -- [Port WAMR to a new platform](./doc/port_wamr.md) -- [Benchmarks](./tests/benchmarks) and [Samples](./samples) -- [VS Code development container](./doc/devcontainer.md) - -iwasm VM core -========================= ### Key features - -- Full compliant to the W3C WASM MVP +- Full compliant to the W3C Wasm MVP - Small runtime binary size (~85K for interpreter and ~50K for AOT) and low memory usage - Near to native speed by AOT and JIT - Self-implemented AOT module loader to enable AOT working on Linux, Windows, MacOS, Android, SGX and MCU systems -- Choices of WASM application libc support: the built-in libc subset for the embedded environment or [WASI](https://github.com/WebAssembly/WASI) for the standard libc +- Choices of Wasm application libc support: the built-in libc subset for the embedded environment or [WASI](https://github.com/WebAssembly/WASI) for the standard libc - [The simple C APIs to embed WAMR into host environment](./doc/embed_wamr.md), see [how to integrate WAMR](./doc/embed_wamr.md) and the [API list](./core/iwasm/include/wasm_export.h) -- [The mechanism to export native APIs to WASM applications](./doc/export_native_api.md), see [how to register native APIs](./doc/export_native_api.md) +- [The mechanism to export native APIs to Wasm applications](./doc/export_native_api.md), see [how to register native APIs](./doc/export_native_api.md) - [Multiple modules as dependencies](./doc/multi_module.md), ref to [document](./doc/multi_module.md) and [sample](samples/multi-module) - [Multi-thread, pthread APIs and thread management](./doc/pthread_library.md), ref to [document](./doc/pthread_library.md) and [sample](samples/multi-thread) - [Linux SGX (Intel Software Guard Extension) support](./doc/linux_sgx.md), ref to [document](./doc/linux_sgx.md) - [Source debugging support](./doc/source_debugging.md), ref to [document](./doc/source_debugging.md) -- [WAMR-IDE (Experimental)](./test-tools/wamr-ide) to develop WebAssembly applications with build, run and debug support, ref to [document](./test-tools/wamr-ide) - [XIP (Execution In Place) support](./doc/xip.md), ref to [document](./doc/xip.md) - [Berkeley/Posix Socket support](./doc/socket_api.md), ref to [document](./doc/socket_api.md) and [sample](./samples/socket-api) - Language bindings: [Go](./language-bindings/go/README.md), [Python](./language-bindings/python/README.md) -### WASM post-MVP features +### Wasm post-MVP features - [wasm-c-api](https://github.com/WebAssembly/wasm-c-api), ref to [document](doc/wasm_c_api.md) and [sample](samples/wasm-c-api) - [128-bit SIMD](https://github.com/WebAssembly/simd), ref to [samples/workload](samples/workload) - [Reference Types](https://github.com/WebAssembly/reference-types), ref to [document](doc/ref_types.md) and [sample](samples/ref-types) @@ -60,111 +44,40 @@ iwasm VM core - [Multi-value](https://github.com/WebAssembly/multi-value), [Tail-call](https://github.com/WebAssembly/tail-call), [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory) ### Supported architectures and platforms - -The iwasm supports the following architectures: - +The WAMR VMcore supports the following architectures: - X86-64, X86-32 - ARM, THUMB (ARMV7 Cortex-M7 and Cortex-A15 are tested) - AArch64 (Cortex-A57 and Cortex-A53 are tested) - RISCV64, RISCV32 (RISC-V LP64 and RISC-V LP64D are tested) - XTENSA, MIPS, ARC -The following platforms are supported, click each link below for how to build iwasm on that platform. Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform. - +The following platforms are supported, click each link below for how to build iwasm on that platform. Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform. - [Linux](./doc/build_wamr.md#linux), [Linux SGX (Intel Software Guard Extension)](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos), [Android](./doc/build_wamr.md#android), [Windows](./doc/build_wamr.md#windows), [Windows (MinGW)](./doc/build_wamr.md#mingw) - [Zephyr](./doc/build_wamr.md#zephyr), [AliOS-Things](./doc/build_wamr.md#alios-things), [VxWorks](./doc/build_wamr.md#vxworks), [NuttX](./doc/build_wamr.md#nuttx), [RT-Thread](./doc/build_wamr.md#RT-Thread), [ESP-IDF](./doc/build_wamr.md#esp-idf) -### Build iwasm VM core (mini product) -WAMR supports building the iwasm VM core only (no app framework) to the mini product. The WAMR mini product takes the WASM application file name or AOT file name as input and then executes it. For the detailed procedure, please see **[build WAMR VM core](./doc/build_wamr.md)** and **[build and run WASM application](./doc/build_wasm_app.md)**. Also we can click the link of each platform above to see how to build iwasm on it. +## Getting started +- [Build iwasm VM core](./doc/build_wamr.md) on [Linux](./doc/build_wamr.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos) and [Windows](./doc/build_wamr.md#windows), and [Build wamrc AOT compiler](./README.md#build-wamrc-aot-compiler) +- [Build iwasm (mini product)](./product-mini/README.md) +- [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go) +- [Register native APIs for Wasm applications](./doc/export_native_api.md) +- [Build wamrc AOT compiler](./wamr-compiler/README.md) +- [Build Wasm applications](./doc/build_wasm_app.md) +- [Port WAMR to a new platform](./doc/port_wamr.md) +- [VS Code development container](./doc/devcontainer.md) +- [Samples](./samples) and [Benchmarks](./tests/benchmarks) -### Build wamrc AOT compiler -Both wasm binary file and AOT file are supported by iwasm. The wamrc AOT compiler is to compile wasm binary file to AOT file which can also be run by iwasm. Execute following commands to build **wamrc** compiler for Linux: -```shell -cd wamr-compiler -./build_llvm.sh (or "./build_llvm_xtensa.sh" to support xtensa target) -mkdir build && cd build -cmake .. (or "cmake .. -DWAMR_BUILD_PLATFORM=darwin" for MacOS) -make -# wamrc is generated under current directory -``` - -For **Windows**: -```shell -cd wamr-compiler -python build_llvm.py -mkdir build && cd build -cmake .. -cmake --build . --config Release -# wamrc.exe is generated under .\Release directory -``` - -### Performance and Footprint - -- [Performance and footprint data](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance): checkout [here](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance) for the performance and footprint data -- [Memory usage tunning](./doc/memory_tune.md): checkout [here](./doc/memory_tune.md) for the memory model and how to tune the memory usage -- [Memory usage profiling](./doc/build_wamr.md#enable-memory-profiling-experiment): checkout [here](./doc/build_wamr.md#enable-memory-profiling-experiment) for how to profile the memory usage +### Performance and memory +- [Blog: Understand WAMR heap](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heap/) +- [Blog: Understand WAMR stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/) +- [Blog: Introduction to WAMR running modes](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/) +- [Memory usage tunning](./doc/memory_tune.md): the memory model and how to tune the memory usage +- [Memory usage profiling](./doc/build_wamr.md#enable-memory-profiling-experiment): how to profile the memory usage - [Benchmarks](./tests/benchmarks): checkout these links for how to run the benchmarks: [PolyBench](./tests/benchmarks/polybench), [CoreMark](./tests/benchmarks/coremark), [Sightglass](./tests/benchmarks/sightglass), [JetStream2](./tests/benchmarks/jetstream) +- [Performance and footprint data](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Performance): the performance and footprint data -### User cases - -WAMR is widely used in a lot areas, here are some cases: -- [Hyperledger Private Data Objects](https://github.com/hyperledger-labs/private-data-objects/blob/main/common/interpreter/wawaka_wasm/README.md) -- [Inclavare Containers](https://github.com/alibaba/inclavare-containers) -- [Fassm](https://github.com/faasm/faasm) -- [Waft](https://developer.aliyun.com/article/787582) -- [Envoy Proxy](https://github.com/envoyproxy/envoy) -- [Apache Teaclave](https://teaclave.apache.org/docs/executing-wasm) - -Application framework -=================================== - -By using the iwasm VM core, we are flexible to build different application frameworks for the specific domains, although it would take quite some effort. - -The WAMR has offered a comprehensive framework for programming WASM applications for device and IoT usages. The framework supports running multiple applications, that are based on the event driven programming model. Here are the supporting API sets by the [WAMR application framework library](./doc/wamr_api.md) : - -- Timer, Inter-app communication (request/response and pub/sub), Sensor, Connectivity and data transmission, 2D graphic UI - -Browse the folder [core/app-framework](./core/app-framework) for how to extend the application framework. - -# Remote application management - -The WAMR application manager supports [remote application management](./core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes. - -The tool [host_tool](./test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](./test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud. - - -WAMR SDK -========== - -Usually there are two tasks for integrating the WAMR into a particular project: - -- Select what WAMR components (vmcore, libc, app-mgr, app-framework components) to be integrated, and get the associated source files added into the project building configuration -- Generate the APP SDK for developing the WASM apps on the selected libc and framework components - -The **[WAMR SDK](./wamr-sdk)** tools is helpful to finish the two tasks quickly. It supports menu configuration for selecting WAMR components and builds the WAMR to a SDK package that includes **runtime SDK** and **APP SDK**. The runtime SDK is used for building the native application and the APP SDK should be shipped to WASM application developers. - - -Samples -================= - -The WAMR [samples](./samples) integrate the iwasm VM core, application manager and selected application framework components. - -- [**basic**](./samples/basic): Demonstrating how to use runtime exposed API's to call WASM functions, how to register native functions and call them, and how to call WASM function from native function. -- **[simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default. -- **[file](./samples/file/README.md)**: Demonstrating the supported file interaction API of WASI. This sample can also demonstrate the SGX IPFS (Intel Protected File System), enabling an enclave to seal and unseal data at rest. -- **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LVGL](https://github.com/lvgl/lvgl) 2D user graphic library and the UI application are built into WASM application. It uses **WASI libc** and executes apps in **AOT mode** by default. -- **[gui](./samples/gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default. -- **[multi-thread](./samples/multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's. -- **[spawn-thread](./samples/spawn-thread)**: Demonstrating how to execute wasm functions of the same wasm application concurrently, in threads created by host embedder or runtime, but not the wasm application itself. -- **[multi-module](./samples/multi-module)**: Demonstrating the [multiple modules as dependencies](./doc/multi_module.md) feature which implements the [load-time dynamic linking](https://webassembly.org/docs/dynamic-linking/). -- **[ref-types](./samples/ref-types)**: Demonstrating how to call wasm functions with argument of externref type introduced by [reference types proposal](https://github.com/WebAssembly/reference-types). -- **[wasm-c-api](./samples/wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's. -- **[socket-api](./samples/socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other. -- **[workload](./samples/workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa. -- **[sgx-ra](./samples/sgx-ra/README.md)**: Demonstrating how to execute Remote Attestation on SGX with [librats](https://github.com/inclavare-containers/librats), which enables mutual attestation with other runtimes or other entities that support librats to ensure that each is running within the TEE. Project Technical Steering Committee @@ -192,10 +105,8 @@ Any contributions you make will be under the same license. # More resources -Check out the [Wiki documents ](https://github.com/bytecodealliance/wasm-micro-runtime/wiki) for more resources: - +- [WAMR Blogs](https://bytecodealliance.github.io/wamr.dev/blog/) - [Community news and events](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Events) - [Roadmap](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Roadmap) -- [WAMR TSC meetings](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/TSC-meeting) -- Technical documents +- [WAMR TSC meetings](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/TSC-meeting-notes) diff --git a/core/app-framework/README.md b/core/app-framework/README.md index 34f0e27eb..d1476fd8b 100644 --- a/core/app-framework/README.md +++ b/core/app-framework/README.md @@ -1,28 +1,27 @@ -Application framework -======= +# Application framework + +By using the WAMR VM core, we are flexible to build different application frameworks for the specific domains, although it would take quite some effort. + +The WAMR has offered a comprehensive framework for programming WASM applications for device and IoT usages. The framework supports running multiple applications, that are based on the event driven programming model. Here are the supporting API sets by the [WAMR application framework library](../doc/wamr_api.md) : + +- Timer, Inter-app communication (request/response and pub/sub), Sensor, Connectivity and data transmission, 2D graphic UI + +Browse the folder [core/app-framework](./app-framework) for how to extend the application framework. + ## Directory structure - - - -This folder "app-native-shared" is for the source files shared by both WASM APP and native runtime +This folder "app-native-shared" is for the source files shared by both WASM APP and native runtime - The c files in this directory are compiled into both the WASM APP and runtime. - The header files for distributing to SDK are placed in the "bi-inc" folder. +This folder "template" contains a pre-defined directory structure for a framework component. The developers can copy the template folder to create new components to the application framework. - -This folder "template" contains a pre-defined directory structure for a framework component. The developers can copy the template folder to create new components to the application framework. - - - -Every other subfolder is framework component. Each component contains two library parts: **app and native**. +Every other subfolder is framework component. Each component contains two library parts: **app and native**. - The "base" component provide timer API and inter-app communication support. It must be enabled if other components are selected. - Under the "app" folder of a component, the subfolder "wa_inc" holds all header files that should be included by the WASM applications - - ## Application framework basic model The app framework is built on top of two fundamental operations: @@ -116,10 +115,6 @@ Generally you should follow following steps to create a new component: ``` - ## Sensor component working flow - - - ![](../../doc/pics/sensor_callflow.PNG) diff --git a/core/app-mgr/README.md b/core/app-mgr/README.md index d5e058815..31c705e1f 100644 --- a/core/app-mgr/README.md +++ b/core/app-mgr/README.md @@ -1,10 +1,8 @@ -WASM application management -======= - -## structure - +# Remote application management +The WAMR application manager supports [remote application management](../core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes. +The tool [host_tool](../test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](../test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud. diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 27bea9550..69a284129 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -1,11 +1,16 @@ -Build WAMR vmcore (iwasm) -========================= -It is recommended to use the [WAMR SDK](../wamr-sdk) tools to build a project that integrates the WAMR. This document introduces how to build the WAMR minimal product which is vmcore only (no app-framework and app-mgr) for multiple platforms. +# Build WAMR vmcore + +WAMR vmcore is a set of runtime libraries for loading and running Wasm modules. This document introduces how to build the WAMR vmcore. + +References: +- [how to build iwasm](../product-mini/README.md): building different target platforms such as Linux, Windows, Mac etc +- [Blog: Introduction to WAMR running modes](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/) + ## WAMR vmcore cmake building configurations -By including the script `runtime_lib.cmake` under folder [build-scripts](../build-scripts) in CMakeList.txt, it is easy to build minimal product with cmake. +By including the script `runtime_lib.cmake` under folder [build-scripts](../build-scripts) in CMakeList.txt, it is easy to use vmcore to build host software with cmake. ```cmake # add this into your CMakeList.txt @@ -195,460 +200,3 @@ Or if we want to enable interpreter, disable AOT and WASI, and build as X86_32, ``` Bash cmake .. -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_AOT=0 -DWAMR_BUILD_LIBC_WASI=0 -DWAMR_BUILD_TARGET=X86_32 ``` - -## Cross compilation - -If you are building for ARM architecture on a X86 development machine, you can use the `CMAKE_TOOLCHAIN_FILE` to set the toolchain file for cross compling. - -``` -cmake .. -DCMAKE_TOOLCHAIN_FILE=$TOOL_CHAIN_FILE \ - -DWAMR_BUILD_PLATFORM=linux \ - -DWAMR_BUILD_TARGET=ARM -``` - -Refer to toolchain sample file [`samples/simple/profiles/arm-interp/toolchain.cmake`](../samples/simple/profiles/arm-interp/toolchain.cmake) for how to build mini product for ARM target architecture. - -If you compile for ESP-IDF, make sure to set the right toolchain file for the chip you're using (e.g. `$IDF_PATH/tools/cmake/toolchain-esp32c3.cmake`). -Note that all ESP-IDF toolchain files live under `$IDF_PATH/tools/cmake/`. - -Linux -------------------------- -First of all please install the dependent packages. -Run command below in Ubuntu-18.04: - -``` Bash -sudo apt install build-essential cmake g++-multilib libgcc-8-dev lib32gcc-8-dev -``` -Or in Ubuntu-16.04: -``` Bash -sudo apt install build-essential cmake g++-multilib libgcc-5-dev lib32gcc-5-dev -``` -Or in Fedora: -``` Bash -sudo dnf install glibc-devel.i686 -``` - -After installing dependencies, build the source code: -``` Bash -cd product-mini/platforms/linux/ -mkdir build && cd build -cmake .. -make -# iwasm is generated under current directory -``` - -By default in Linux, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. -And the build target is set to X86_64 or X86_32 depending on the platform's bitwidth. - -There are total 6 running modes supported: fast interpreter, classi interpreter, AOT, LLVM JIT, Fast JIT and Multi-tier JIT. - -(1) To run a wasm file with `fast interpreter` mode - build iwasm with default build and then: -```Bash -iwasm -``` -Or -```Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_INTERP=1 -make -``` - -(2) To disable `fast interpreter` and enable `classic interpreter` instead: -``` Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_FAST_INTERP=0 -make -``` - -(3) To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../README.md#build-wamrc-aot-compiler) to build wamrc, and then: -```Bash -wamrc -o -iwasm -``` - -(4) To enable the `LLVM JIT` mode, firstly we should build the LLVM library: -``` Bash -cd product-mini/platforms/linux/ -./build_llvm.sh (The llvm source code is cloned under /core/deps/llvm and auto built) -``` - -Then pass argument `-DWAMR_BUILD_JIT=1` to cmake to enable LLVM JIT: -``` Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_JIT=1 -make -``` - -Note: -By default, the LLVM Orc JIT with Lazy compilation is enabled to speedup the lanuching process and reduce -the JIT compilation time by creating backend threads to compile the WASM functions parallely, and for the -main thread, the functions in the module will not be compiled until they are firstly called and haven't been -compiled by the compilation threads. - -If developer wants to disable the Lazy compilation, we can: -``` Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0 -make -``` -In which all the WASM functions will be previously compiled before main thread starts to run the wasm module. - -(5) To enable the `Fast JIT` mode: -``` Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_FAST_JIT=1 -make -``` -The Fast JIT is a lightweight JIT engine with quick startup, small footprint and good portability, and gains ~50% performance of AOT. - -(6) To enable the `Multi-tier JIT` mode: -``` Bash -mkdir build && cd build -cmake .. -DWAMR_BUILD_FAST_JTI=1 -DWAMR_BUILD_JIT=1 -make -``` -The Multi-tier JIT is a two level JIT tier-up engine, which launchs Fast JIT to run the wasm module as soon as possible and creates backend threads to compile the LLVM JIT functions at the same time, and when the LLVM JIT functions are compiled, the runtime will switch the extecution from the Fast JIT jitted code to LLVM JIT jitted code gradually, so as to gain the best performance. - -Linux SGX (Intel Software Guard Extension) -------------------------- - -Please see [Build and Port WAMR vmcore for Linux SGX](./linux_sgx.md) for the details. - -MacOS -------------------------- - -Make sure to install Xcode from App Store firstly, and install cmake. - -If you use Homebrew, install cmake from the command line: -``` Bash -brew install cmake -``` - -Then build the source codes: -``` Bash -cd product-mini/platforms/darwin/ -mkdir build -cd build -cmake .. -make -# iwasm is generated under current directory -``` -By default in MacOS, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. -And the build target is set to X86_64 or X86_32 depending on the platform's bitwidth. - -To run a wasm file with interpreter mode: -```Bash -iwasm -``` -To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../README.md#build-wamrc-aot-compiler) to build wamrc, and then: -```Bash -wamrc -o -iwasm -``` -Note: -For how to build the `JIT` mode and `classic interpreter` mode, please refer to [Build iwasm on Linux](./build_wamr.md#linux). - -WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](./build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in MacOS, interpreter, AOT, and builtin libc are enabled by default. - -Windows -------------------------- - -Make sure `MSVC` and `cmake` are installed and available in the command line environment - -Then build the source codes: -``` Bash -cd product-mini/platforms/windows/ -mkdir build -cd build -cmake .. -cmake --build . --config Release -# ./Release/iwasm.exe is generated -``` - -By default in Windows, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. - -To run a wasm file with interpreter mode: -```Bash -iwasm.exe -``` -To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../README.md#build-wamrc-aot-compiler) to build wamrc, and then: -```Bash -wamrc.exe -o -iwasm.exe -``` -Note: -For how to build the `JIT` mode and `classic interpreter` mode, please refer to [Build iwasm on Linux](./build_wamr.md#linux). - -WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](./build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in Windows, interpreter, AOT, and builtin libc are enabled by default. - -MinGW -------------------------- - -First make sure the correct CMake package is installed; the following commands -are valid for the MSYS2 build environment: - -```Bash -pacman -R cmake -pacman -S mingw-w64-x86_64-cmake -pacman -S mingw-w64-x86_64-gcc -pacman -S make git -``` - -Then follow the build instructions for Windows above, and add the following -arguments for cmake: - -```Bash -cmake .. -G"Unix Makefiles" \ - -DWAMR_DISABLE_HW_BOUND_CHECK=1 -```` - -Note that WASI will be disabled until further work is done towards full MinGW support. - -- Since memory access boundary check with hardware trap feature is disabled, when generating the AOT file with `wamrc`, the `--bounds-checks=1` flag should be added to generate the memory access boundary check instructions to ensure the sandbox security: -```bash -wamrc --bounds-checks=1 -o -``` -- Compiler complaining about missing `UnwindInfoAddress` field in `RUNTIME_FUNCTION` -struct (winnt.h). - - -VxWorks -------------------------- -VxWorks 7 SR0620 release is validated. - -First you need to build a VSB. Make sure *UTILS_UNIX* layer is added in the VSB. -After the VSB is built, export the VxWorks toolchain path by: -```bash -export /host/vx-compiler/bin:$PATH -``` -Now switch to iwasm source tree to build the source code: -```bash -cd product-mini/platforms/vxworks/ -mkdir build -cd build -cmake .. -make -``` -Create a VIP based on the VSB. Make sure the following components are added: -* INCLUDE_POSIX_PTHREADS -* INCLUDE_POSIX_PTHREAD_SCHEDULER -* INCLUDE_SHARED_DATA -* INCLUDE_SHL - -Copy the generated iwasm executable, the test WASM binary as well as the needed -shared libraries (libc.so.1, libllvm.so.1 or libgnu.so.1 depending on the VSB, -libunix.so.1) to a supported file system (eg: romfs). - -Note: -WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](./build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in VxWorks, interpreter and builtin libc are enabled by default. - -Zephyr -------------------------- -You need to prepare Zephyr first as described here https://docs.zephyrproject.org/latest/getting_started/index.html#get-zephyr-and-install-python-dependencies. - -After that you need to point the `ZEPHYR_BASE` variable to e.g. `~/zephyrproject/zephyr`. Also, it is important that you have `west` available for subsequent actions. - -``` Bash -cd /product-mini/platforms/zephyr/simple -# Execute the ./build_and_run.sh script with board name as parameter. Here take x86 as example: -./build_and_run.sh x86 -``` - -If you want to use the Espressif toolchain (esp32 or esp32c3), you can most conveniently install it with `west`: - -``` Bash -cd $ZEPHYR_BASE -west espressif install -``` - -After that set `ESPRESSIF_TOOLCHAIN_PATH` according to the output, for example `~/.espressif/tools/zephyr`. - -Note: -WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](./build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in Zephyr, interpreter, AOT and builtin libc are enabled by default. - - -AliOS-Things -------------------------- -1. a developerkit board id needed for testing -2. download the AliOS-Things code - ``` Bash - git clone https://github.com/alibaba/AliOS-Things.git - ``` -3. copy /product-mini/platforms/alios-things directory to AliOS-Things/middleware, and rename it as iwasm - ``` Bash - cp -a /product-mini/platforms/alios-things middleware/iwasm - ``` -4. create a link to in middleware/iwasm/ and rename it to wamr - ``` Bash - ln -s middleware/iwasm/wamr - ``` -5. modify file app/example/helloworld/helloworld.c, patch as: - ``` C - #include - #include - extern bool iwasm_init(); - int application_start(int argc, char *argv[]) - { - int count = 0; - iwasm_init(); - ... - } - ``` -6. modify file app/example/helloworld/aos.mk - ``` C - $(NAME)_COMPONENTS := osal_aos iwasm - ``` -7. build source code and run - For linux host: - - ``` Bash - aos make helloworld@linuxhost -c config - aos make - ./out/helloworld@linuxhost/binary/helloworld@linuxhost.elf - ``` - - For developerkit: - Modify file middleware/iwasm/aos.mk, patch as: - - ``` C - WAMR_BUILD_TARGET := THUMBV7M - ``` - - ``` Bash - aos make helloworld@developerkit -c config - aos make - ``` - download the binary to developerkit board, check the output from serial port - -RT-Thread -------------------------- - -1. Get rt-thread [system codes](https://github.com/RT-Thread/rt-thread). - -2. Enable WAMR software package with menuconfig tool which provided by RT-Thread. - - * Environment in Linux, run command below: - - ```bash - scons --menuconfig - ``` - - * Environment in Windows ConEmu, run command below: - - ```bash - menuconfig - ``` - - Select and enable `WAMR` in: - - * RT-Thread online packages - * tools packages - * WebAssembly Micro Runtime (WAMR) - -3. Configure `WAMR` with menuconfig tool. - - you can choice features of iwasm below: - - * Enable testing parameters of iwasm - * Enable interpreter Mode / Fast interpreter Mode - * Use built-libc - * Enable AOT - -4. Exit menuconfig tool and save configure, update and download package. - - ```bash - pkgs --update - ``` - -5. build project and download the binary to boards. - - ```bash - scons - ``` - - or build project with 8-thread by using command below: - - ```bash - scons -j8 - ``` - - after project building, you can got an binary file named `rtthread.bin`, then you can download this file to the MCU board. - -Android -------------------------- -able to generate a shared library support Android platform. -- need an [android SDK](https://developer.android.com/studio). Go and get the "Command line tools only" -- look for a command named *sdkmanager* and download below components. version numbers might need to check and pick others - - "build-tools;29.0.3" - - "cmake;3.10.2.4988404" - - "ndk;latest" - - "patcher;v4" - - "platform-tools" - - "platforms;android-29" -- add bin/ of the downloaded cmake to $PATH -- export ANDROID_HOME=/the/path/of/downloaded/sdk/ -- export ANDROID_NDK_LATEST_HOME=/the/path/of/downloaded/sdk/ndk/2x.xxx/ -- ready to go - -Use such commands, you are able to compile with default configurations. Any compiling requirement should be satisfied by modifying product-mini/platforms/android/CMakeList.txt. For example, chaning ${WAMR_BUILD_TARGET} in CMakeList could get different libraries support different ABIs. - -``` shell -$ cd product-mini/platforms/android/ -$ mkdir build -$ cd build -$ cmake .. -$ make -$ # check output in distribution/wasm -$ # include/ includes all necesary head files -$ # lib includes libiwasm.so -``` - -NuttX -------------------------- -WAMR is intergrated with NuttX, just enable the WAMR in Kconfig option (Application Configuration/Interpreters). - -ESP-IDF -------------------------- -WAMR integrates with ESP-IDF both for the XTENSA and RISC-V chips (esp32x and esp32c3 respectively). - -In order to use this, you need at least version 4.3.1 of ESP-IDF. -If you don't have it installed, follow the instructions [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/#get-started-get-prerequisites). -ESP-IDF also installs the toolchains needed for compiling WAMR and ESP-IDF. -A small demonstration of how to use WAMR and ESP-IDF can be found under [product_mini](/product-mini/platforms/esp-idf). -The demo builds WAMR for ESP-IDF and runs a small wasm program. -In order to run it for your specific Espressif chip, edit the [build_and_run.sh](/product-mini/platforms/esp-idf/build_and_run.sh) file and put the correct toolchain file (see #Cross-compilation) and `IDF_TARGET`. -Before compiling it is also necessary to call ESP-IDF's `export.sh` script to bring all compile time relevant information in scope. - -Docker -------------------------- -[Docker](https://www.docker.com/) will download all the dependencies and build WAMR Core on your behalf. - -Make sure you have Docker installed on your machine: [macOS](https://docs.docker.com/docker-for-mac/install/), [Windows](https://docs.docker.com/docker-for-windows/install/) or [Linux](https://docs.docker.com/install/linux/docker-ce/ubuntu/). - -Build *iwasm* with the Docker image: - -``` Bash -$ cd ci -$ ./build_wamr.sh -$ ls ../build_out/ -``` - -*build_wamr.sh* will generate *linux* compatible libraries ( libiwasm.so and -libvmlib.a ) and an executable binary (*iwasm*) and copy *iwasm* to -*build_out*. All original generated files are still under -*product-mini/platforms/linux/build*. - -FreeBSD -------------------------- -First, install the dependent packages: -```shell -sudo pkg install gcc cmake wget -``` - -Then you can run the following commands to build iwasm with default configurations: -```shell -cd product-mini/platforms/freebsd -mkdir build && cd build -cmake .. -make -``` diff --git a/doc/memory_tune.md b/doc/memory_tune.md index c3703390e..8159aaac8 100644 --- a/doc/memory_tune.md +++ b/doc/memory_tune.md @@ -1,5 +1,8 @@ -Memory model and memory usage tunning -===================================== +# Memory model and memory usage tunning + +References: +- [Blog: Understand WAMR heap](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heap/) +- [Blog: Understand WAMR stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/) ## The memory model diff --git a/doc/source_debugging.md b/doc/source_debugging.md index c18c61267..0c219efd3 100644 --- a/doc/source_debugging.md +++ b/doc/source_debugging.md @@ -1,5 +1,9 @@ # WAMR source debugging +References: +- [Blog: WAMR source debugging basic](https://bytecodealliance.github.io/wamr.dev/blog/wamr-source-debugging-basic/) +- [Blog: Debugging wasm with VSCode](https://bytecodealliance.github.io/wamr.dev/blog/debugging-wasm-with-vscode/) + WAMR supports source level debugging based on DWARF (normally used in C/C++/Rust), source map (normally used in AssemblyScript) is not supported. **The lldb's ability to debug wasm application is based on the patch [Add class WasmProcess for WebAssembly debugging](https://reviews.llvm.org/D78801). Thanks very much to the author @paolosev for such a great work!** diff --git a/product-mini/README.md b/product-mini/README.md new file mode 100644 index 000000000..736b35b0a --- /dev/null +++ b/product-mini/README.md @@ -0,0 +1,459 @@ +# Build iwasm + +iwasm is the executable binary built with WAMR VMcore supports WASI and command line interface. Refer to [**how to build wamr vmcore**](../doc/build_wamr.md) for all the supported CMAKE compilation variables. + +If you are building for ARM architecture on a X86 development machine, you can use the `CMAKE_TOOLCHAIN_FILE` to set the toolchain file for cross compling. + +``` +cmake .. -DCMAKE_TOOLCHAIN_FILE=$TOOL_CHAIN_FILE \ + -DWAMR_BUILD_PLATFORM=linux \ + -DWAMR_BUILD_TARGET=ARM +``` + +Refer to toolchain sample file [`samples/simple/profiles/arm-interp/toolchain.cmake`](../samples/simple/profiles/arm-interp/toolchain.cmake) for how to build mini product for ARM target architecture. + +If you compile for ESP-IDF, make sure to set the right toolchain file for the chip you're using (e.g. `$IDF_PATH/tools/cmake/toolchain-esp32c3.cmake`). +Note that all ESP-IDF toolchain files live under `$IDF_PATH/tools/cmake/`. + +## Linux + +First of all please install the dependent packages. +Run command below in Ubuntu-18.04: + +``` Bash +sudo apt install build-essential cmake g++-multilib libgcc-8-dev lib32gcc-8-dev +``` +Or in Ubuntu-16.04: +``` Bash +sudo apt install build-essential cmake g++-multilib libgcc-5-dev lib32gcc-5-dev +``` +Or in Fedora: +``` Bash +sudo dnf install glibc-devel.i686 +``` + +After installing dependencies, build the source code: +``` Bash +cd product-mini/platforms/linux/ +mkdir build && cd build +cmake .. +make +# iwasm is generated under current directory +``` + +By default in Linux, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. +And the build target is set to X86_64 or X86_32 depending on the platform's bitwidth. + +There are total 6 running modes supported: fast interpreter, classi interpreter, AOT, LLVM JIT, Fast JIT and Multi-tier JIT. + +(1) To run a wasm file with `fast interpreter` mode - build iwasm with default build and then: +```Bash +iwasm +``` +Or +```Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_INTERP=1 +make +``` + +(2) To disable `fast interpreter` and enable `classic interpreter` instead: +``` Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_FAST_INTERP=0 +make +``` + +(3) To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../wamr-compiler/README.md) to build wamrc, and then: +```Bash +wamrc -o +iwasm +``` + +(4) To enable the `LLVM JIT` mode, firstly we should build the LLVM library: +``` Bash +cd product-mini/platforms/linux/ +./build_llvm.sh (The llvm source code is cloned under /core/deps/llvm and auto built) +``` + +Then pass argument `-DWAMR_BUILD_JIT=1` to cmake to enable LLVM JIT: +``` Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_JIT=1 +make +``` + +Note: +By default, the LLVM Orc JIT with Lazy compilation is enabled to speedup the lanuching process and reduce +the JIT compilation time by creating backend threads to compile the WASM functions parallely, and for the +main thread, the functions in the module will not be compiled until they are firstly called and haven't been +compiled by the compilation threads. + +If developer wants to disable the Lazy compilation, we can: +``` Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_JIT=1 -DWAMR_BUILD_LAZY_JIT=0 +make +``` +In which all the WASM functions will be previously compiled before main thread starts to run the wasm module. + +(5) To enable the `Fast JIT` mode: +``` Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_FAST_JIT=1 +make +``` +The Fast JIT is a lightweight JIT engine with quick startup, small footprint and good portability, and gains ~50% performance of AOT. + +(6) To enable the `Multi-tier JIT` mode: +``` Bash +mkdir build && cd build +cmake .. -DWAMR_BUILD_FAST_JTI=1 -DWAMR_BUILD_JIT=1 +make +``` +The Multi-tier JIT is a two level JIT tier-up engine, which launchs Fast JIT to run the wasm module as soon as possible and creates backend threads to compile the LLVM JIT functions at the same time, and when the LLVM JIT functions are compiled, the runtime will switch the extecution from the Fast JIT jitted code to LLVM JIT jitted code gradually, so as to gain the best performance. + +## Linux SGX (Intel Software Guard Extension) + + +Please see [Build and Port WAMR vmcore for Linux SGX](../doc/linux_sgx.md) for the details. + +## MacOS + + +Make sure to install Xcode from App Store firstly, and install cmake. + +If you use Homebrew, install cmake from the command line: +``` Bash +brew install cmake +``` + +Then build the source codes: +``` Bash +cd product-mini/platforms/darwin/ +mkdir build +cd build +cmake .. +make +# iwasm is generated under current directory +``` +By default in MacOS, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. +And the build target is set to X86_64 or X86_32 depending on the platform's bitwidth. + +To run a wasm file with interpreter mode: +```Bash +iwasm +``` +To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../wamr-compiler/README.md) to build wamrc, and then: +```Bash +wamrc -o +iwasm +``` +Note: +For how to build the `JIT` mode and `classic interpreter` mode, please refer to [Build iwasm on Linux](../doc/build_wamr.md#linux). + +WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](../doc/build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in MacOS, interpreter, AOT, and builtin libc are enabled by default. + +## Windows + + +Make sure `MSVC` and `cmake` are installed and available in the command line environment + +Then build the source codes: +``` Bash +cd product-mini/platforms/windows/ +mkdir build +cd build +cmake .. +cmake --build . --config Release +# ./Release/iwasm.exe is generated +``` + +By default in Windows, the `fast interpreter`, `AOT` and `Libc WASI` are enabled, and JIT is disabled. + +To run a wasm file with interpreter mode: +```Bash +iwasm.exe +``` +To run an AOT file, firstly please refer to [Build wamrc AOT compiler](../wamr-compiler/README.md) to build wamrc, and then: +```Bash +wamrc.exe -o +iwasm.exe +``` +Note: +For how to build the `JIT` mode and `classic interpreter` mode, please refer to [Build iwasm on Linux](../doc/build_wamr.md#linux). + +WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](../doc/build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in Windows, interpreter, AOT, and builtin libc are enabled by default. + +## MinGW + + +First make sure the correct CMake package is installed; the following commands +are valid for the MSYS2 build environment: + +```Bash +pacman -R cmake +pacman -S mingw-w64-x86_64-cmake +pacman -S mingw-w64-x86_64-gcc +pacman -S make git +``` + +Then follow the build instructions for Windows above, and add the following +arguments for cmake: + +```Bash +cmake .. -G"Unix Makefiles" \ + -DWAMR_DISABLE_HW_BOUND_CHECK=1 +```` + +Note that WASI will be disabled until further work is done towards full MinGW support. + +- Since memory access boundary check with hardware trap feature is disabled, when generating the AOT file with `wamrc`, the `--bounds-checks=1` flag should be added to generate the memory access boundary check instructions to ensure the sandbox security: +```bash +wamrc --bounds-checks=1 -o +``` +- Compiler complaining about missing `UnwindInfoAddress` field in `RUNTIME_FUNCTION` +struct (winnt.h). + + +## VxWorks + +VxWorks 7 SR0620 release is validated. + +First you need to build a VSB. Make sure *UTILS_UNIX* layer is added in the VSB. +After the VSB is built, export the VxWorks toolchain path by: +```bash +export /host/vx-compiler/bin:$PATH +``` +Now switch to iwasm source tree to build the source code: +```bash +cd product-mini/platforms/vxworks/ +mkdir build +cd build +cmake .. +make +``` +Create a VIP based on the VSB. Make sure the following components are added: +* INCLUDE_POSIX_PTHREADS +* INCLUDE_POSIX_PTHREAD_SCHEDULER +* INCLUDE_SHARED_DATA +* INCLUDE_SHL + +Copy the generated iwasm executable, the test WASM binary as well as the needed +shared libraries (libc.so.1, libllvm.so.1 or libgnu.so.1 depending on the VSB, +libunix.so.1) to a supported file system (eg: romfs). + +Note: +WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](../doc/build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in VxWorks, interpreter and builtin libc are enabled by default. + +## Zephyr + +You need to prepare Zephyr first as described here https://docs.zephyrproject.org/latest/getting_started/index.html#get-zephyr-and-install-python-dependencies. + +After that you need to point the `ZEPHYR_BASE` variable to e.g. `~/zephyrproject/zephyr`. Also, it is important that you have `west` available for subsequent actions. + +``` Bash +cd /product-mini/platforms/zephyr/simple +# Execute the ./build_and_run.sh script with board name as parameter. Here take x86 as example: +./build_and_run.sh x86 +``` + +If you want to use the Espressif toolchain (esp32 or esp32c3), you can most conveniently install it with `west`: + +``` Bash +cd $ZEPHYR_BASE +west espressif install +``` + +After that set `ESPRESSIF_TOOLCHAIN_PATH` according to the output, for example `~/.espressif/tools/zephyr`. + +Note: +WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](../doc/build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in Zephyr, interpreter, AOT and builtin libc are enabled by default. + + +## RT-Thread + + +1. Get rt-thread [system codes](https://github.com/RT-Thread/rt-thread). + +2. Enable WAMR software package with menuconfig tool which provided by RT-Thread. + + * Environment in Linux, run command below: + + ```bash + scons --menuconfig + ``` + + * Environment in Windows ConEmu, run command below: + + ```bash + menuconfig + ``` + + Select and enable `WAMR` in: + + * RT-Thread online packages + * tools packages + * WebAssembly Micro Runtime (WAMR) + +3. Configure `WAMR` with menuconfig tool. + + you can choice features of iwasm below: + + * Enable testing parameters of iwasm + * Enable interpreter Mode / Fast interpreter Mode + * Use built-libc + * Enable AOT + +4. Exit menuconfig tool and save configure, update and download package. + + ```bash + pkgs --update + ``` + +5. build project and download the binary to boards. + + ```bash + scons + ``` + + or build project with 8-thread by using command below: + + ```bash + scons -j8 + ``` + + after project building, you can got an binary file named `rtthread.bin`, then you can download this file to the MCU board. + +## Android + +able to generate a shared library support Android platform. +- need an [android SDK](https://developer.android.com/studio). Go and get the "Command line tools only" +- look for a command named *sdkmanager* and download below components. version numbers might need to check and pick others + - "build-tools;29.0.3" + - "cmake;3.10.2.4988404" + - "ndk;latest" + - "patcher;v4" + - "platform-tools" + - "platforms;android-29" +- add bin/ of the downloaded cmake to $PATH +- export ANDROID_HOME=/the/path/of/downloaded/sdk/ +- export ANDROID_NDK_LATEST_HOME=/the/path/of/downloaded/sdk/ndk/2x.xxx/ +- ready to go + +Use such commands, you are able to compile with default configurations. Any compiling requirement should be satisfied by modifying product-mini/platforms/android/CMakeList.txt. For example, chaning ${WAMR_BUILD_TARGET} in CMakeList could get different libraries support different ABIs. + +``` shell +$ cd product-mini/platforms/android/ +$ mkdir build +$ cd build +$ cmake .. +$ make +$ # check output in distribution/wasm +$ # include/ includes all necesary head files +$ # lib includes libiwasm.so +``` + +## NuttX + +WAMR is intergrated with NuttX, just enable the WAMR in Kconfig option (Application Configuration/Interpreters). + +## ESP-IDF + +WAMR integrates with ESP-IDF both for the XTENSA and RISC-V chips (esp32x and esp32c3 respectively). + +In order to use this, you need at least version 4.3.1 of ESP-IDF. +If you don't have it installed, follow the instructions [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/#get-started-get-prerequisites). +ESP-IDF also installs the toolchains needed for compiling WAMR and ESP-IDF. +A small demonstration of how to use WAMR and ESP-IDF can be found under [product_mini](./platforms/esp-idf). +The demo builds WAMR for ESP-IDF and runs a small wasm program. +In order to run it for your specific Espressif chip, edit the [build_and_run.sh](./platforms/esp-idf/build_and_run.sh) file and put the correct toolchain file (see #Cross-compilation) and `IDF_TARGET`. +Before compiling it is also necessary to call ESP-IDF's `export.sh` script to bring all compile time relevant information in scope. + +## Docker + +[Docker](https://www.docker.com/) will download all the dependencies and build WAMR Core on your behalf. + +Make sure you have Docker installed on your machine: [macOS](https://docs.docker.com/docker-for-mac/install/), [Windows](https://docs.docker.com/docker-for-windows/install/) or [Linux](https://docs.docker.com/install/linux/docker-ce/ubuntu/). + +Build *iwasm* with the Docker image: + +``` Bash +$ cd ci +$ ./build_wamr.sh +$ ls ../build_out/ +``` + +*build_wamr.sh* will generate *linux* compatible libraries ( libiwasm.so and +libvmlib.a ) and an executable binary (*iwasm*) and copy *iwasm* to +*build_out*. All original generated files are still under +*product-mini/platforms/linux/build*. + +## FreeBSD + +First, install the dependent packages: +```shell +sudo pkg install gcc cmake wget +``` + +Then you can run the following commands to build iwasm with default configurations: +```shell +cd product-mini/platforms/freebsd +mkdir build && cd build +cmake .. +make +``` + + +## AliOS-Things + +1. a developerkit board id needed for testing +2. download the AliOS-Things code + ``` Bash + git clone https://github.com/alibaba/AliOS-Things.git + ``` +3. copy /product-mini/platforms/alios-things directory to AliOS-Things/middleware, and rename it as iwasm + ``` Bash + cp -a /product-mini/platforms/alios-things middleware/iwasm + ``` +4. create a link to in middleware/iwasm/ and rename it to wamr + ``` Bash + ln -s middleware/iwasm/wamr + ``` +5. modify file app/example/helloworld/helloworld.c, patch as: + ``` C + #include + #include + extern bool iwasm_init(); + int application_start(int argc, char *argv[]) + { + int count = 0; + iwasm_init(); + ... + } + ``` +6. modify file app/example/helloworld/aos.mk + ``` C + $(NAME)_COMPONENTS := osal_aos iwasm + ``` +7. build source code and run + For linux host: + + ``` Bash + aos make helloworld@linuxhost -c config + aos make + ./out/helloworld@linuxhost/binary/helloworld@linuxhost.elf + ``` + + For developerkit: + Modify file middleware/iwasm/aos.mk, patch as: + + ``` C + WAMR_BUILD_TARGET := THUMBV7M + ``` + + ``` Bash + aos make helloworld@developerkit -c config + aos make + ``` + download the binary to developerkit board, check the output from serial port diff --git a/samples/README.md b/samples/README.md new file mode 100644 index 000000000..6690c07f3 --- /dev/null +++ b/samples/README.md @@ -0,0 +1,15 @@ + +# Samples +- [**basic**](./basic): Demonstrating how to use runtime exposed API's to call WASM functions, how to register native functions and call them, and how to call WASM function from native function. +- **[simple](./simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default. +- **[file](./file/README.md)**: Demonstrating the supported file interaction API of WASI. This sample can also demonstrate the SGX IPFS (Intel Protected File System), enabling an enclave to seal and unseal data at rest. +- **[littlevgl](./littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LVGL](https://github.com/lvgl/lvgl) 2D user graphic library and the UI application are built into WASM application. It uses **WASI libc** and executes apps in **AOT mode** by default. +- **[gui](./gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default. +- **[multi-thread](./multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's. +- **[spawn-thread](./spawn-thread)**: Demonstrating how to execute wasm functions of the same wasm application concurrently, in threads created by host embedder or runtime, but not the wasm application itself. +- **[multi-module](./multi-module)**: Demonstrating the [multiple modules as dependencies](./doc/multi_module.md) feature which implements the [load-time dynamic linking](https://webassembly.org/docs/dynamic-linking/). +- **[ref-types](./ref-types)**: Demonstrating how to call wasm functions with argument of externref type introduced by [reference types proposal](https://github.com/WebAssembly/reference-types). +- **[wasm-c-api](./wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's. +- **[socket-api](./socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other. +- **[workload](./workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa. +- **[sgx-ra](./sgx-ra/README.md)**: Demonstrating how to execute Remote Attestation on SGX with [librats](https://github.com/inclavare-containers/librats), which enables mutual attestation with other runtimes or other entities that support librats to ensure that each is running within the TEE. diff --git a/wamr-compiler/README.md b/wamr-compiler/README.md new file mode 100644 index 000000000..a3a791f99 --- /dev/null +++ b/wamr-compiler/README.md @@ -0,0 +1,23 @@ + +### Build wamrc AOT compiler + +Both wasm binary file and AOT file are supported by iwasm. The wamrc AOT compiler is to compile wasm binary file to AOT file which can also be run by iwasm. Execute following commands to build **wamrc** compiler for Linux: + +```shell +cd wamr-compiler +./build_llvm.sh (or "./build_llvm_xtensa.sh" to support xtensa target) +mkdir build && cd build +cmake .. (or "cmake .. -DWAMR_BUILD_PLATFORM=darwin" for MacOS) +make +# wamrc is generated under current directory +``` + +For **Windows**: +```shell +cd wamr-compiler +python build_llvm.py +mkdir build && cd build +cmake .. +cmake --build . --config Release +# wamrc.exe is generated under .\Release directory +``` \ No newline at end of file diff --git a/wamr-sdk/README.md b/wamr-sdk/README.md index c161a69a4..14b172e02 100644 --- a/wamr-sdk/README.md +++ b/wamr-sdk/README.md @@ -1,5 +1,12 @@ # WebAssembly Micro Runtime SDK +Usually there are two tasks for integrating the WAMR into a particular project: + +- Select what WAMR components (vmcore, libc, app-mgr, app-framework components) to be integrated, and get the associated source files added into the project building configuration +- Generate the APP SDK for developing the WASM apps on the selected libc and framework components + +The **[WAMR SDK](./wamr-sdk)** tools is helpful to finish the two tasks quickly. It supports menu configuration for selecting WAMR components and builds the WAMR to a SDK package that includes **runtime SDK** and **APP SDK**. The runtime SDK is used for building the native application and the APP SDK should be shipped to WASM application developers. + **Note**: [WASI-SDK](https://github.com/CraneStation/wasi-sdk/releases) version 7 and above should be installed before building the WAMR SDK. From 5c37ddfbca2350d82ff71d60cc71974fb7ef55c6 Mon Sep 17 00:00:00 2001 From: Wang Xin Date: Sun, 19 Mar 2023 08:40:51 +0800 Subject: [PATCH 10/61] fix readme broken links (#2039) --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fc31f927f..bb09a279b 100644 --- a/README.md +++ b/README.md @@ -52,13 +52,13 @@ The WAMR VMcore supports the following architectures: - XTENSA, MIPS, ARC The following platforms are supported, click each link below for how to build iwasm on that platform. Refer to [WAMR porting guide](./doc/port_wamr.md) for how to port WAMR to a new platform. -- [Linux](./doc/build_wamr.md#linux), [Linux SGX (Intel Software Guard Extension)](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos), [Android](./doc/build_wamr.md#android), [Windows](./doc/build_wamr.md#windows), [Windows (MinGW)](./doc/build_wamr.md#mingw) -- [Zephyr](./doc/build_wamr.md#zephyr), [AliOS-Things](./doc/build_wamr.md#alios-things), [VxWorks](./doc/build_wamr.md#vxworks), [NuttX](./doc/build_wamr.md#nuttx), [RT-Thread](./doc/build_wamr.md#RT-Thread), [ESP-IDF](./doc/build_wamr.md#esp-idf) +- [Linux](./product-mini/README.md#linux), [Linux SGX (Intel Software Guard Extension)](./doc/linux_sgx.md), [MacOS](./product-mini/README.md#macos), [Android](./product-mini/README.md#android), [Windows](./product-mini/README.md#windows), [Windows (MinGW)](./product-mini/README.md#mingw) +- [Zephyr](./product-mini/README.md#zephyr), [AliOS-Things](./product-mini/README.md#alios-things), [VxWorks](./product-mini/README.md#vxworks), [NuttX](./product-mini/README.md#nuttx), [RT-Thread](./product-mini/README.md#RT-Thread), [ESP-IDF](./product-mini/README.md#esp-idf) ## Getting started -- [Build iwasm VM core](./doc/build_wamr.md) on [Linux](./doc/build_wamr.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./doc/build_wamr.md#macos) and [Windows](./doc/build_wamr.md#windows), and [Build wamrc AOT compiler](./README.md#build-wamrc-aot-compiler) -- [Build iwasm (mini product)](./product-mini/README.md) +- [Build VM core](./doc/build_wamr.md) and [Build wamrc AOT compiler](./wamr-compiler/README.md) +- [Build iwasm (mini product)](./product-mini/README.md): [Linux](./product-mini/README.md#linux), [SGX](./doc/linux_sgx.md), [MacOS](./product-mini/README.md#macos) and [Windows](./product-mini/README.md#windows) - [Embed into C/C++](./doc/embed_wamr.md), [Embed into Python](./language-bindings/python), [Embed into Go](./language-bindings/go) - [Register native APIs for Wasm applications](./doc/export_native_api.md) - [Build wamrc AOT compiler](./wamr-compiler/README.md) @@ -104,9 +104,8 @@ use, modify, distribute and sell your own products based on WAMR. Any contributions you make will be under the same license. # More resources - +- [Who use WAMR?](https://github.com/bytecodealliance/wasm-micro-runtime/wiki) - [WAMR Blogs](https://bytecodealliance.github.io/wamr.dev/blog/) -- [Community news and events](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Events) -- [Roadmap](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/Roadmap) +- [Community news and events](https://bytecodealliance.github.io/wamr.dev/events/) - [WAMR TSC meetings](https://github.com/bytecodealliance/wasm-micro-runtime/wiki/TSC-meeting-notes) From d75cb3224f7c8a6565937a6389936a1a2160fc59 Mon Sep 17 00:00:00 2001 From: Xu Jun Date: Mon, 20 Mar 2023 08:17:22 +0800 Subject: [PATCH 11/61] Fix dead lock in source debugger (#2040) --- core/iwasm/interpreter/wasm_interp_classic.c | 4 ++++ core/iwasm/libraries/thread-mgr/thread_manager.c | 6 ------ core/iwasm/libraries/thread-mgr/thread_manager.h | 3 +++ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index dd45865ba..fd115fb81 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1079,12 +1079,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, /* Record the current frame_ip, so when exception occurs, \ debugger can know the exact opcode who caused the exception */ \ frame_ip_orig = frame_ip; \ + os_mutex_lock(&exec_env->wait_lock); \ while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \ && exec_env->current_status->step_count++ == 1) { \ exec_env->current_status->step_count = 0; \ SYNC_ALL_TO_FRAME(); \ wasm_cluster_thread_waiting_run(exec_env); \ } \ + os_mutex_unlock(&exec_env->wait_lock); \ goto *handle_table[*frame_ip++]; \ } while (0) #else @@ -1095,12 +1097,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst, #define HANDLE_OP(opcode) case opcode: #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0 #define HANDLE_OP_END() \ + os_mutex_lock(&exec_env->wait_lock); \ if (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \ && exec_env->current_status->step_count++ == 2) { \ exec_env->current_status->step_count = 0; \ SYNC_ALL_TO_FRAME(); \ wasm_cluster_thread_waiting_run(exec_env); \ } \ + os_mutex_unlock(&exec_env->wait_lock); \ continue #else #define HANDLE_OP_END() continue diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index bfb7d0a48..5e2acdbcd 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -793,18 +793,12 @@ notify_debug_instance_exit(WASMExecEnv *exec_env) void wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env) { - os_mutex_lock(&exec_env->wait_lock); - - /* Wake up debugger thread after we get the lock, otherwise we may miss the - * signal from debugger thread, see - * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */ exec_env->current_status->running_status = STATUS_STOP; notify_debug_instance(exec_env); while (!wasm_cluster_thread_is_running(exec_env)) { os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock); } - os_mutex_unlock(&exec_env->wait_lock); } void diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.h b/core/iwasm/libraries/thread-mgr/thread_manager.h index 38ca167fb..899a4cc21 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.h +++ b/core/iwasm/libraries/thread-mgr/thread_manager.h @@ -180,6 +180,9 @@ wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status); void wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo); +/* This function must be called with exec_env->wait_lock locked, otherwise we + * may miss the signal from debugger thread, see + * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */ void wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env); From 0ee6e18a06cee7ab3da94c68eefbc09d8c1f0d0d Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Wed, 22 Mar 2023 17:39:08 +0800 Subject: [PATCH 12/61] Rename parameter names in wasm_runtime_instantiate (#2045) --- core/iwasm/common/wasm_runtime_common.h | 4 ++-- core/iwasm/include/wasm_export.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index b20e12ecf..58db29e3e 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -508,8 +508,8 @@ wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst, /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * -wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size, - uint32 heap_size, char *error_buf, +wasm_runtime_instantiate(WASMModuleCommon *module, uint32 default_stack_size, + uint32 host_managed_heap_size, char *error_buf, uint32 error_buf_size); /* See wasm_export.h for description */ diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 7f82b6de5..f6c0107b9 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -467,14 +467,14 @@ wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module, const char *ns_lookup * Instantiate a WASM module. * * @param module the WASM module to instantiate - * @param stack_size the default stack size of the module instance when the + * @param default_stack_size the default stack size of the module instance when the * exec env's operation stack isn't created by user, e.g. API * wasm_application_execute_main() and wasm_application_execute_func() * create the operation stack internally with the stack size specified * here. And API wasm_runtime_create_exec_env() creates the operation * stack with stack size specified by its parameter, the stack size * specified here is ignored. - * @param heap_size the default heap size of the module instance, a heap will + * @param host_managed_heap_size the default heap size of the module instance, a heap will * be created besides the app memory space. Both wasm app and native * function can allocate memory from the heap. * @param error_buf buffer to output the error info if failed @@ -484,7 +484,7 @@ wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module, const char *ns_lookup */ WASM_RUNTIME_API_EXTERN wasm_module_inst_t wasm_runtime_instantiate(const wasm_module_t module, - uint32_t stack_size, uint32_t heap_size, + uint32_t default_stack_size, uint32_t host_managed_heap_size, char *error_buf, uint32_t error_buf_size); /** From ea50bd2acaf572be4ae0fb3e62ad93474abb5804 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Wed, 22 Mar 2023 18:11:53 +0800 Subject: [PATCH 13/61] Support dump call stack on exception and dump call stack on nuttx (#2042) --- core/iwasm/common/wasm_application.c | 13 +++++++++++-- product-mini/platforms/nuttx/wamr.mk | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 1bb9f29b6..05e53c451 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -195,6 +195,7 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) if (argv_buf_offset) wasm_runtime_module_free(module_inst, argv_buf_offset); + return ret; } @@ -203,7 +204,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[]) { bool ret; -#if WASM_ENABLE_MEMORY_PROFILING != 0 +#if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_DUMP_CALL_STACK != 0) WASMExecEnv *exec_env; #endif @@ -220,7 +221,15 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, wasm_runtime_dump_perf_profiling(module_inst); #endif - return (ret && !wasm_runtime_get_exception(module_inst)) ? true : false; + if (ret) + ret = wasm_runtime_get_exception(module_inst) == NULL; + +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (!ret) + wasm_runtime_dump_call_stack(exec_env); +#endif + + return ret; } /** diff --git a/product-mini/platforms/nuttx/wamr.mk b/product-mini/platforms/nuttx/wamr.mk index 7c9b546ff..78cf3eea1 100644 --- a/product-mini/platforms/nuttx/wamr.mk +++ b/product-mini/platforms/nuttx/wamr.mk @@ -216,6 +216,12 @@ else CFLAGS += -DWASM_ENABLE_MEMORY_TRACING=0 endif +ifeq ($(CONFIG_INTERPRETERS_WAMR_DUMP_CALL_STACK),y) +CFLAGS += -DWASM_ENABLE_DUMP_CALL_STACK=1 +else +CFLAGS += -DWASM_ENABLE_DUMP_CALL_STACK=0 +endif + ifeq ($(CONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN),y) CFLAGS += -DWASM_ENABLE_LIBC_BUILTIN=1 CSRCS += libc_builtin_wrapper.c From 49d439a3bc0bfeb4122e1ffe00d4656c0c21e26a Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 23 Mar 2023 09:21:16 +0800 Subject: [PATCH 14/61] Fix/Simplify the atomic.wait/nofity implementations (#2044) Use the shared memory's shared_mem_lock to lock the whole atomic.wait and atomic.notify processes, and use it for os_cond_reltimedwait and os_cond_notify, so as to make the whole processes actual atomic operations: the original implementation accesses the wait address with shared_mem_lock and uses wait_node->wait_lock for os_cond_reltimedwait, which is not an atomic operation. And remove the unnecessary wait_map_lock and wait_lock, since the whole processes are already locked by shared_mem_lock. --- core/iwasm/common/wasm_shared_memory.c | 246 +++++++----------- core/iwasm/interpreter/wasm_interp_classic.c | 13 +- core/iwasm/interpreter/wasm_interp_fast.c | 8 +- .../platform/include/platform_api_extension.h | 2 + .../platform/linux-sgx/platform_internal.h | 2 + 5 files changed, 107 insertions(+), 164 deletions(-) diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 3b896d9b4..778d6e576 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -21,28 +21,20 @@ enum { /* clang-format on */ typedef struct AtomicWaitInfo { - korp_mutex wait_list_lock; bh_list wait_list_head; bh_list *wait_list; /* WARNING: insert to the list allowed only in acquire_wait_info - otherwise there will be data race as described in PR #2016 */ + otherwise there will be data race as described in PR #2016 */ } AtomicWaitInfo; typedef struct AtomicWaitNode { bh_list_link l; uint8 status; - korp_mutex wait_lock; korp_cond wait_cond; } AtomicWaitNode; -typedef struct AtomicWaitAddressArgs { - uint32 index; - void **addr; -} AtomicWaitAddressArgs; - /* Atomic wait map */ static HashMap *wait_map; -static korp_mutex wait_map_lock; static uint32 wait_address_hash(void *address); @@ -59,17 +51,11 @@ wasm_shared_memory_init() if (os_mutex_init(&shared_memory_list_lock) != 0) return false; - if (os_mutex_init(&wait_map_lock) != 0) { - os_mutex_destroy(&shared_memory_list_lock); - return false; - } - /* wait map not exists, create new map */ if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash, (KeyEqualFunc)wait_address_equal, NULL, destroy_wait_info))) { os_mutex_destroy(&shared_memory_list_lock); - os_mutex_destroy(&wait_map_lock); return false; } @@ -79,11 +65,8 @@ wasm_shared_memory_init() void wasm_shared_memory_destroy() { + bh_hash_map_destroy(wait_map); os_mutex_destroy(&shared_memory_list_lock); - os_mutex_destroy(&wait_map_lock); - if (wait_map) { - bh_hash_map_destroy(wait_map); - } } static WASMSharedMemNode * @@ -224,7 +207,7 @@ notify_wait_list(bh_list *wait_list, uint32 count) AtomicWaitNode *node, *next; uint32 i, notify_count = count; - if ((count == UINT32_MAX) || (count > wait_list->len)) + if (count > wait_list->len) notify_count = wait_list->len; node = bh_list_first_elem(wait_list); @@ -235,11 +218,9 @@ notify_wait_list(bh_list *wait_list, uint32 count) bh_assert(node); next = bh_list_elem_next(node); - os_mutex_lock(&node->wait_lock); node->status = S_NOTIFIED; /* wakeup */ os_cond_signal(&node->wait_cond); - os_mutex_unlock(&node->wait_lock); node = next; } @@ -253,13 +234,10 @@ acquire_wait_info(void *address, AtomicWaitNode *wait_node) AtomicWaitInfo *wait_info = NULL; bh_list_status ret; - os_mutex_lock(&wait_map_lock); /* Make find + insert atomic */ - if (address) wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address); if (!wait_node) { - os_mutex_unlock(&wait_map_lock); return wait_info; } @@ -267,7 +245,7 @@ acquire_wait_info(void *address, AtomicWaitNode *wait_node) if (!wait_info) { if (!(wait_info = (AtomicWaitInfo *)wasm_runtime_malloc( sizeof(AtomicWaitInfo)))) { - goto fail1; + return NULL; } memset(wait_info, 0, sizeof(AtomicWaitInfo)); @@ -276,38 +254,17 @@ acquire_wait_info(void *address, AtomicWaitNode *wait_node) ret = bh_list_init(wait_info->wait_list); bh_assert(ret == BH_LIST_SUCCESS); - /* init wait list lock */ - if (0 != os_mutex_init(&wait_info->wait_list_lock)) { - goto fail2; - } - if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) { - goto fail3; + wasm_runtime_free(wait_info); + return NULL; } } - os_mutex_lock(&wait_info->wait_list_lock); ret = bh_list_insert(wait_info->wait_list, wait_node); - os_mutex_unlock(&wait_info->wait_list_lock); bh_assert(ret == BH_LIST_SUCCESS); (void)ret; - os_mutex_unlock(&wait_map_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(&wait_map_lock); - - return NULL; } static void @@ -321,13 +278,11 @@ destroy_wait_info(void *wait_info) while (node) { next = bh_list_elem_next(node); - os_mutex_destroy(&node->wait_lock); os_cond_destroy(&node->wait_cond); wasm_runtime_free(node); node = next; } - os_mutex_destroy(&((AtomicWaitInfo *)wait_info)->wait_list_lock); wasm_runtime_free(wait_info); } } @@ -336,17 +291,11 @@ static void map_try_release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address) { - os_mutex_lock(&wait_map_lock); - os_mutex_lock(&wait_info->wait_list_lock); if (wait_info->wait_list->len > 0) { - os_mutex_unlock(&wait_info->wait_list_lock); - os_mutex_unlock(&wait_map_lock); return; } - os_mutex_unlock(&wait_info->wait_list_lock); bh_hash_map_remove(wait_map_, address, NULL, NULL); - os_mutex_unlock(&wait_map_lock); destroy_wait_info(wait_info); } @@ -361,6 +310,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, #if WASM_ENABLE_THREAD_MGR != 0 WASMExecEnv *exec_env; #endif + uint64 timeout_left, timeout_wait, timeout_1sec; bool check_ret, is_timeout, no_wait; bh_assert(module->module_type == Wasm_Module_Bytecode @@ -383,124 +333,108 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address, return -1; } - node = search_module((WASMModuleCommon *)module_inst->module); - os_mutex_lock(&node->shared_mem_lock); - no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) - || (wait64 && *(uint64 *)address != expect); - os_mutex_unlock(&node->shared_mem_lock); - - if (no_wait) { - return 1; - } - - if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { - wasm_runtime_set_exception(module, "failed to create wait node"); - return -1; - } - memset(wait_node, 0, sizeof(AtomicWaitNode)); - - if (0 != os_mutex_init(&wait_node->wait_lock)) { - wasm_runtime_free(wait_node); - return -1; - } - - if (0 != os_cond_init(&wait_node->wait_cond)) { - os_mutex_destroy(&wait_node->wait_lock); - wasm_runtime_free(wait_node); - return -1; - } - - wait_node->status = S_WAITING; - - /* acquire the wait info, create new one if not exists */ - wait_info = acquire_wait_info(address, wait_node); - - if (!wait_info) { - os_mutex_destroy(&wait_node->wait_lock); - wasm_runtime_free(wait_node); - wasm_runtime_set_exception(module, "failed to acquire wait_info"); - return -1; - } - #if WASM_ENABLE_THREAD_MGR != 0 exec_env = wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); bh_assert(exec_env); #endif + node = search_module((WASMModuleCommon *)module_inst->module); + bh_assert(node); + + /* Lock the shared_mem_lock for the whole atomic wait process, + and use it to os_cond_reltimedwait */ os_mutex_lock(&node->shared_mem_lock); + no_wait = (!wait64 && *(uint32 *)address != (uint32)expect) || (wait64 && *(uint64 *)address != expect); - os_mutex_unlock(&node->shared_mem_lock); - /* condition wait start */ - os_mutex_lock(&wait_node->wait_lock); + if (no_wait) { + os_mutex_unlock(&node->shared_mem_lock); + return 1; + } - if (!no_wait) { - /* unit of timeout is nsec, convert it to usec */ - uint64 timeout_left = (uint64)timeout / 1000, timeout_wait; - uint64 timeout_1sec = 1e6; + if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) { + os_mutex_unlock(&node->shared_mem_lock); + wasm_runtime_set_exception(module, "failed to create wait node"); + return -1; + } + memset(wait_node, 0, sizeof(AtomicWaitNode)); - while (1) { - if (timeout < 0) { - /* wait forever until it is notified or terminatied - here we keep waiting and checking every second */ - os_cond_reltimedwait(&wait_node->wait_cond, - &wait_node->wait_lock, - (uint64)timeout_1sec); - if (wait_node->status - == S_NOTIFIED /* notified by atomic.notify */ + if (0 != os_cond_init(&wait_node->wait_cond)) { + os_mutex_unlock(&node->shared_mem_lock); + wasm_runtime_free(wait_node); + wasm_runtime_set_exception(module, "failed to init wait cond"); + return -1; + } + + wait_node->status = S_WAITING; + + /* Acquire the wait info, create new one if not exists */ + wait_info = acquire_wait_info(address, wait_node); + + if (!wait_info) { + os_mutex_unlock(&node->shared_mem_lock); + os_cond_destroy(&wait_node->wait_cond); + wasm_runtime_free(wait_node); + wasm_runtime_set_exception(module, "failed to acquire wait_info"); + return -1; + } + + /* unit of timeout is nsec, convert it to usec */ + timeout_left = (uint64)timeout / 1000; + timeout_1sec = 1e6; + + while (1) { + if (timeout < 0) { + /* wait forever until it is notified or terminatied + here we keep waiting and checking every second */ + os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock, + (uint64)timeout_1sec); + if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */ #if WASM_ENABLE_THREAD_MGR != 0 - /* terminated by other thread */ - || wasm_cluster_is_thread_terminated(exec_env) + /* terminated by other thread */ + || wasm_cluster_is_thread_terminated(exec_env) #endif - ) { - break; - } - /* continue to wait */ + ) { + break; } - else { - timeout_wait = - timeout_left < timeout_1sec ? timeout_left : timeout_1sec; - os_cond_reltimedwait(&wait_node->wait_cond, - &wait_node->wait_lock, timeout_wait); - if (wait_node->status - == S_NOTIFIED /* notified by atomic.notify */ - || timeout_left <= timeout_wait /* time out */ + } + else { + timeout_wait = + timeout_left < timeout_1sec ? timeout_left : timeout_1sec; + os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock, + timeout_wait); + if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */ + || timeout_left <= timeout_wait /* time out */ #if WASM_ENABLE_THREAD_MGR != 0 - /* terminated by other thread */ - || wasm_cluster_is_thread_terminated(exec_env) + /* terminated by other thread */ + || wasm_cluster_is_thread_terminated(exec_env) #endif - ) { - break; - } - timeout_left -= timeout_wait; + ) { + break; } + timeout_left -= timeout_wait; } } is_timeout = wait_node->status == S_WAITING ? true : false; - os_mutex_unlock(&wait_node->wait_lock); - - os_mutex_lock(&node->shared_mem_lock); - os_mutex_lock(&wait_info->wait_list_lock); check_ret = is_wait_node_exists(wait_info->wait_list, wait_node); bh_assert(check_ret); + (void)check_ret; - /* Remove wait node */ + /* Remove wait node from wait list */ bh_list_remove(wait_info->wait_list, wait_node); - os_mutex_destroy(&wait_node->wait_lock); os_cond_destroy(&wait_node->wait_cond); wasm_runtime_free(wait_node); - /* Release wait info if no wait nodes attached */ - os_mutex_unlock(&wait_info->wait_list_lock); + /* Release wait info if no wait nodes are attached */ map_try_release_wait_info(wait_map, wait_info, address); + os_mutex_unlock(&node->shared_mem_lock); - (void)check_ret; - return no_wait ? 1 : is_timeout ? 2 : 0; + return is_timeout ? 2 : 0; } uint32 @@ -516,35 +450,41 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address, bh_assert(module->module_type == Wasm_Module_Bytecode || module->module_type == Wasm_Module_AoT); - node = search_module((WASMModuleCommon *)module_inst->module); - if (node) - os_mutex_lock(&node->shared_mem_lock); out_of_bounds = ((uint8 *)address < module_inst->memories[0]->memory_data || (uint8 *)address + 4 > module_inst->memories[0]->memory_data_end); if (out_of_bounds) { - if (node) - os_mutex_unlock(&node->shared_mem_lock); wasm_runtime_set_exception(module, "out of bounds memory access"); return -1; } + /* Currently we have only one memory instance */ + if (!module_inst->memories[0]->is_shared) { + /* Always return 0 for ushared linear memory since there is + no way to create a waiter on it */ + return 0; + } + + node = search_module((WASMModuleCommon *)module_inst->module); + bh_assert(node); + + /* Lock the shared_mem_lock for the whole atomic notify process, + and use it to os_cond_signal */ + os_mutex_lock(&node->shared_mem_lock); + wait_info = acquire_wait_info(address, NULL); /* Nobody wait on this address */ if (!wait_info) { - if (node) - os_mutex_unlock(&node->shared_mem_lock); + os_mutex_unlock(&node->shared_mem_lock); return 0; } - os_mutex_lock(&wait_info->wait_list_lock); + /* Notify each wait node in the wait list */ notify_result = notify_wait_list(wait_info->wait_list, count); - os_mutex_unlock(&wait_info->wait_list_lock); - if (node) - os_mutex_unlock(&node->shared_mem_lock); + os_mutex_unlock(&node->shared_mem_lock); return notify_result; } diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index fd115fb81..a94dc1769 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -3414,7 +3414,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, ret = wasm_runtime_atomic_notify( (WASMModuleInstanceCommon *)module, maddr, notify_count); - bh_assert((int32)ret >= 0); + if (ret == (uint32)-1) + goto got_exception; PUSH_I32(ret); break; @@ -3471,7 +3472,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, { /* Skip the memory index */ frame_ip++; - os_atomic_thread_fence(os_memory_order_release); + os_atomic_thread_fence(os_memory_order_seq_cst); break; } @@ -3578,7 +3579,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); os_mutex_lock(&node->shared_mem_lock); - STORE_U32(maddr, frame_sp[1]); + STORE_U32(maddr, sval); os_mutex_unlock(&node->shared_mem_lock); } break; @@ -3619,8 +3620,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); os_mutex_lock(&node->shared_mem_lock); - PUT_I64_TO_ADDR((uint32 *)maddr, - GET_I64_FROM_ADDR(frame_sp + 1)); + PUT_I64_TO_ADDR((uint32 *)maddr, sval); os_mutex_unlock(&node->shared_mem_lock); } break; @@ -3721,9 +3721,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_I64(maddr); - if (readv == expect) { + if (readv == expect) STORE_I64(maddr, sval); - } os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 628f4d065..b4bab4605 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -3252,7 +3252,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, ret = wasm_runtime_atomic_notify( (WASMModuleInstanceCommon *)module, maddr, notify_count); - bh_assert((int32)ret >= 0); + if (ret == (uint32)-1) + goto got_exception; PUSH_I32(ret); break; @@ -3307,7 +3308,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, } case WASM_OP_ATOMIC_FENCE: { - os_atomic_thread_fence(os_memory_order_release); + os_atomic_thread_fence(os_memory_order_seq_cst); break; } @@ -3555,9 +3556,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_I64(maddr); - if (readv == expect) { + if (readv == expect) STORE_I64(maddr, sval); - } os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 7640e12c2..938530a4e 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -121,7 +121,9 @@ os_thread_exit(void *retval); #if defined(BH_HAS_STD_ATOMIC) && !defined(__cplusplus) #include +#define os_memory_order_acquire memory_order_acquire #define os_memory_order_release memory_order_release +#define os_memory_order_seq_cst memory_order_seq_cst #define os_atomic_thread_fence atomic_thread_fence #endif diff --git a/core/shared/platform/linux-sgx/platform_internal.h b/core/shared/platform/linux-sgx/platform_internal.h index 04babaf94..d18f015ee 100644 --- a/core/shared/platform/linux-sgx/platform_internal.h +++ b/core/shared/platform/linux-sgx/platform_internal.h @@ -63,7 +63,9 @@ os_set_print_function(os_print_function_t pf); char * strcpy(char *dest, const char *src); +#define os_memory_order_acquire __ATOMIC_ACQUIRE #define os_memory_order_release __ATOMIC_RELEASE +#define os_memory_order_seq_cst __ATOMIC_SEQ_CST #define os_atomic_thread_fence __atomic_thread_fence #ifdef __cplusplus From d06d2d375458affb5f6ee85b4f8b2097a99a4e99 Mon Sep 17 00:00:00 2001 From: Wang Xin Date: Thu, 23 Mar 2023 10:37:38 +0800 Subject: [PATCH 15/61] Add architecture diagram for wasm function (#2046) --- core/iwasm/README.md | 6 + .../iwasm/doc/images/wasm_function.excalidraw | 7754 +++++++++++++++++ core/iwasm/doc/images/wasm_function.svg | 16 + core/iwasm/doc/wasm_function.MD | 5 + 4 files changed, 7781 insertions(+) create mode 100644 core/iwasm/doc/images/wasm_function.excalidraw create mode 100644 core/iwasm/doc/images/wasm_function.svg create mode 100644 core/iwasm/doc/wasm_function.MD diff --git a/core/iwasm/README.md b/core/iwasm/README.md index e69de29bb..55e864990 100644 --- a/core/iwasm/README.md +++ b/core/iwasm/README.md @@ -0,0 +1,6 @@ +# vmcore architecture +- [WAMR memory model overview](https://bytecodealliance.github.io/wamr.dev/blog/the-wamr-memory-model/) + +## Wasm function +- [Wasm function architecture](./doc/wasm_function.MD) + diff --git a/core/iwasm/doc/images/wasm_function.excalidraw b/core/iwasm/doc/images/wasm_function.excalidraw new file mode 100644 index 000000000..8c59bdbca --- /dev/null +++ b/core/iwasm/doc/images/wasm_function.excalidraw @@ -0,0 +1,7754 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "type": "rectangle", + "version": 215, + "versionNonce": 1880133867, + "isDeleted": false, + "id": "4o9JHPgrKQSqK-ibc0qs_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2254.5001678466797, + "y": 1663.1666412353516, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 150.66668701171875, + "height": 43.000030517578125, + "seed": 4270136, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "PsNatrhOR918YjbmvyT9x", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 230, + "versionNonce": 1135445829, + "isDeleted": false, + "id": "94gfo2BctxYsRP6cuuIbI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1297.1946105957031, + "y": 1755.6666768391929, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 214.33333333333348, + "height": 122.66668701171875, + "seed": 305330883, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "9vnyulmvSUCDWXvSKKyJ6", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 162, + "versionNonce": 1027947403, + "isDeleted": false, + "id": "JWlL3nHzTP4pxrEVYolFx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2226.416498184204, + "y": 1001.3333435058594, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 278.6666259765625, + "height": 244.00003051757812, + "seed": 1502608995, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "70jp9eV1jV2_kUBbN055m", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 115, + "versionNonce": 291919525, + "isDeleted": false, + "id": "Cc8lshSSJ7lAY4RPjzS5A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1289.1666717529297, + "y": 1285.8333587646484, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 20, + "seed": 411108936, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunctionInstance", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunctionInstance" + }, + { + "type": "rectangle", + "version": 100, + "versionNonce": 1607176747, + "isDeleted": false, + "id": "onh-wm6wgKrkH94fakl6O", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1291.1666107177734, + "y": 1309.1666717529297, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 259.33331298828125, + "height": 210.3333435058593, + "seed": 2073695304, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "fltFoJAyfls8KPkBw6X_P", + "type": "arrow" + }, + { + "id": "MLVyGZQLa4jU554J6bsmJ", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 113, + "versionNonce": 34486789, + "isDeleted": false, + "id": "eAtZfC7P3ZafizTDITzz-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1363.1666717529297, + "y": 1335.500015258789, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 136923720, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 139, + "versionNonce": 411964619, + "isDeleted": false, + "id": "GmBiArFp8A3Q9NaPWxp3Q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1395.8332977294922, + "y": 1332.8333587646484, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 94, + "height": 20, + "seed": 258177848, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "nUF7GyfmAGZN3iZvBfYtq", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_import", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_import" + }, + { + "type": "text", + "version": 239, + "versionNonce": 245543269, + "isDeleted": false, + "id": "YdCXv7DFgrOOU2wowasgm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1748.499984741211, + "y": 1142.4999237060547, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 164, + "height": 20, + "seed": 1678600520, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunctionImport:", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunctionImport:" + }, + { + "type": "rectangle", + "version": 254, + "versionNonce": 656884587, + "isDeleted": false, + "id": "1Oi1iFkA8pBbaQpvduCq1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1738.499984741211, + "y": 1161.1666717529297, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 176, + "height": 200.33340454101554, + "seed": 1244990536, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "nUF7GyfmAGZN3iZvBfYtq", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 701, + "versionNonce": 879836357, + "isDeleted": false, + "id": "nUF7GyfmAGZN3iZvBfYtq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1502.280048689805, + "y": 1332.5712493918486, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 234.84228393034437, + "height": 170.17912641351631, + "seed": 213606712, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "startBinding": { + "elementId": "GmBiArFp8A3Q9NaPWxp3Q", + "focus": 0.8789861743715494, + "gap": 14.558826765976846 + }, + "endBinding": { + "elementId": "w7-3leJjFtbtDhwDpkUjF", + "focus": 0.9853865103923569, + "gap": 6.774518257019281 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 157.46964422706515, + -143.2377075217314 + ], + [ + 234.84228393034437, + -170.17912641351631 + ] + ] + }, + { + "type": "text", + "version": 197, + "versionNonce": 1944165899, + "isDeleted": false, + "id": "bM6INpWVFBvURve3zdbdf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1396.1666717529297, + "y": 1355.5000457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 34, + "height": 20, + "seed": 379599688, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func" + }, + { + "type": "diamond", + "version": 140, + "versionNonce": 1796693029, + "isDeleted": false, + "id": "3cBYbIbQEyvFuXBMoyida", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1364.8332977294922, + "y": 1360.3333435058594, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 1837623096, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 310, + "versionNonce": 2042078379, + "isDeleted": false, + "id": "9KTm6XzaqX3iZ90_AL3RN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1900.8332977294922, + "y": 1530.166732788086, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 211, + "height": 20, + "seed": 1970637640, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Bnf72M4RGMZjNgBlzk90B", + "type": "arrow" + }, + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + }, + { + "id": "S1cN82-5SoSu4e4SWfAUw", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunction (per module)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction (per module)" + }, + { + "type": "rectangle", + "version": 261, + "versionNonce": 1518505861, + "isDeleted": false, + "id": "0kWlc6iPzGzhrfIVEPeOM", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1902.1667938232422, + "y": 1559.6667175292969, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 225.33337402343744, + "height": 200.9999389648438, + "seed": 2020723016, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + }, + { + "id": "Bnf72M4RGMZjNgBlzk90B", + "type": "arrow" + }, + { + "id": "uC3ZSm-IltHDllxDGLJ9v", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 675, + "versionNonce": 1884542795, + "isDeleted": false, + "id": "zzj3BPEivUiaW1sqpfx7J", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2266.8334197998047, + "y": 1673.8333282470703, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 129, + "height": 20, + "seed": 26708536, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + }, + { + "id": "PsNatrhOR918YjbmvyT9x", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "internal function", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "internal function" + }, + { + "type": "arrow", + "version": 666, + "versionNonce": 1357928165, + "isDeleted": false, + "id": "78xSb96N8EcRm2LhdCNjJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1434.5331571443298, + "y": 1377.528759465866, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 458.6267427864543, + "height": 186.82387510648414, + "seed": 535299656, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "startBinding": { + "elementId": "evHonaxVjRvjwFP08UX9x", + "focus": -0.827785929496437, + "gap": 16.471286310501227 + }, + "endBinding": { + "elementId": "9KTm6XzaqX3iZ90_AL3RN", + "focus": -1.317866862333605, + "gap": 14.985901784264229 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 184.63351460859985, + 58.63791228706373 + ], + [ + 458.6267427864543, + 186.82387510648414 + ] + ] + }, + { + "type": "rectangle", + "version": 145, + "versionNonce": 907064811, + "isDeleted": false, + "id": "WfHCEtd4eDaOU42FFn9wo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1341.1666717529297, + "y": 1321.500015258789, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 186.00006103515625, + "height": 65, + "seed": 663703880, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 166, + "versionNonce": 2028876357, + "isDeleted": false, + "id": "QbAKq7kA_EZo7yxdpqj6F", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1742.499984741211, + "y": 1166.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 158.66668701171872, + "height": 45.33337402343752, + "seed": 757681480, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 170, + "versionNonce": 2046345355, + "isDeleted": false, + "id": "w7-3leJjFtbtDhwDpkUjF", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1715.499984741211, + "y": 1169.1666412353516, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 187, + "height": 40, + "seed": 1177365064, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "nUF7GyfmAGZN3iZvBfYtq", + "type": "arrow" + }, + { + "id": "70jp9eV1jV2_kUBbN055m", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": " char *module_name;\n char *field_name;", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " char *module_name;\n char *field_name;" + }, + { + "type": "rectangle", + "version": 190, + "versionNonce": 1331274149, + "isDeleted": false, + "id": "m6kQPfRjltByoJapP3m-h", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1744.499984741211, + "y": 1234.499984741211, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 155.33337402343747, + "height": 35.666656494140625, + "seed": 613948728, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 184, + "versionNonce": 633763627, + "isDeleted": false, + "id": "IXwlC5RgaF1iJPCtg6-Er", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1768.4999237060547, + "y": 1243.499984741211, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 125, + "height": 20, + "seed": 664043080, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "l4S1IXvHmVx_wl8DPQXk3", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_ptr_linked", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_ptr_linked" + }, + { + "type": "rectangle", + "version": 230, + "versionNonce": 1499473157, + "isDeleted": false, + "id": "o1vzUOCoilIzaDJdTpt35", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1735.8333587646484, + "y": 932.4999542236328, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 155.33331298828125, + "height": 90.33334350585938, + "seed": 1170302520, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "l4S1IXvHmVx_wl8DPQXk3", + "type": "arrow" + }, + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 211, + "versionNonce": 132405707, + "isDeleted": false, + "id": "Kpjtivj-7LYLq1nuvC4KS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1742.5000457763672, + "y": 940.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 123, + "height": 20, + "seed": 1541878344, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "l4S1IXvHmVx_wl8DPQXk3", + "type": "arrow" + }, + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "native function:", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "native function:" + }, + { + "type": "arrow", + "version": 755, + "versionNonce": 444546149, + "isDeleted": false, + "id": "l4S1IXvHmVx_wl8DPQXk3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1751.6334408235434, + "y": 1247.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 121.88354763506686, + "height": 307.57912212433075, + "seed": 203809096, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "startBinding": { + "elementId": "OpV38MM8YOexWG_e-5_hX", + "focus": -0.4013706262952343, + "gap": 1.943772417380456 + }, + "endBinding": { + "elementId": "Kpjtivj-7LYLq1nuvC4KS", + "focus": 1.1040701980735919, + "gap": 6.6751580517609455 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -121.88354763506686, + -191.16677856445312 + ], + [ + -15.808553098937182, + -307.57912212433075 + ] + ] + }, + { + "type": "rectangle", + "version": 185, + "versionNonce": 1030547563, + "isDeleted": false, + "id": "5EDlNHzjVbZ3Rx8ny3SUe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1742.6665802001953, + "y": 1279.1666412353516, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 165.16677856445304, + "height": 73.666748046875, + "seed": 202955336, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 241, + "versionNonce": 1250191301, + "isDeleted": false, + "id": "wc-s6ecXMbmh2ViGrkOa4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1757.8332977294922, + "y": 1289.5000457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 152, + "height": 40, + "seed": 1536408648, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "S1cN82-5SoSu4e4SWfAUw", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "import_module;\nimport_func_linked;", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "import_module;\nimport_func_linked;" + }, + { + "type": "arrow", + "version": 788, + "versionNonce": 1546298123, + "isDeleted": false, + "id": "S1cN82-5SoSu4e4SWfAUw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1741.963485458681, + "y": 1322.4954523286892, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 248.14874440629774, + "height": 238.16542426722026, + "seed": 1657735240, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "startBinding": { + "elementId": "-vw33v9u2Ko2ayilI0CXG", + "focus": 2.0635763351494516, + "gap": 4.200185998866319 + }, + "endBinding": { + "elementId": "9KTm6XzaqX3iZ90_AL3RN", + "focus": -1.1514950968199016, + "gap": 11.294143807823616 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -88.79684422332912, + 88.33793695353734 + ], + [ + 159.35190018296862, + 238.16542426722026 + ] + ] + }, + { + "type": "text", + "version": 234, + "versionNonce": 1267541797, + "isDeleted": false, + "id": "jF8UBxFom2hco1NronB-_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1639.2142922537669, + "y": 1510.404782976423, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 137, + "height": 20, + "seed": 548488008, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(WASMFunction *)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(WASMFunction *)" + }, + { + "type": "diamond", + "version": 76, + "versionNonce": 1553467819, + "isDeleted": false, + "id": "jJOCFAslIe3JYgWsRnIKx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1915.8334197998047, + "y": 1577.1667022705078, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 17.33331298828125, + "height": 15.666656494140625, + "seed": 1470386504, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "PsNatrhOR918YjbmvyT9x", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 88, + "versionNonce": 1611070085, + "isDeleted": false, + "id": "V1RSJPoudlOhc-GaAxPSa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1947.8334197998047, + "y": 1577.500015258789, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 37, + "height": 20, + "seed": 1209849672, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "PsNatrhOR918YjbmvyT9x", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "code", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "code" + }, + { + "type": "rectangle", + "version": 217, + "versionNonce": 1138728011, + "isDeleted": false, + "id": "tXHmR9TBkCnxMdo_pd0XG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2255.833480834961, + "y": 1603.1666412353516, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 149.3333740234375, + "height": 114.33340454101562, + "seed": 321892664, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 182, + "versionNonce": 548364773, + "isDeleted": false, + "id": "Zsg-OsrfZ2doJiTuOOpPu", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2277.166793823242, + "y": 1576.1666107177734, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70, + "height": 20, + "seed": 40194872, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "bytecode", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "bytecode" + }, + { + "type": "arrow", + "version": 545, + "versionNonce": 232512235, + "isDeleted": false, + "id": "PsNatrhOR918YjbmvyT9x", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1990.5000762939453, + "y": 1589.1666717529297, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 264.9616597351928, + "height": 70.73153780068333, + "seed": 1716226360, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "startBinding": { + "elementId": "V1RSJPoudlOhc-GaAxPSa", + "focus": -0.13746287298855567, + "gap": 7.9146728515625 + }, + "endBinding": { + "elementId": "4o9JHPgrKQSqK-ibc0qs_", + "focus": 0.060950944035830956, + "gap": 3.268431681738548 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 149.9165802001953, + 22.1666259765625 + ], + [ + 191.24952507019043, + 48.83355712890625 + ], + [ + 264.9616597351928, + 70.73153780068333 + ] + ] + }, + { + "type": "diamond", + "version": 79, + "versionNonce": 848551237, + "isDeleted": false, + "id": "sWaZg1Dcn3g0Qfdc7onW_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1916.5001068115234, + "y": 1629.8333892822266, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 18.6666259765625, + "height": 15, + "seed": 238700600, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 84, + "versionNonce": 1461142923, + "isDeleted": false, + "id": "U5NUD0rdNNDuY14J1ZRMu", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1954.8333587646484, + "y": 1628.8333892822266, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 110, + "height": 20, + "seed": 744475464, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "code_compiled", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "code_compiled" + }, + { + "type": "rectangle", + "version": 431, + "versionNonce": 1024584869, + "isDeleted": false, + "id": "gk39IBXF-F8MrwhzL35C6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2462.5001068115234, + "y": 1639.5001373291016, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 114.66674804687503, + "height": 119.33334350585936, + "seed": 201839672, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 444, + "versionNonce": 1187798059, + "isDeleted": false, + "id": "ZRckuyHrC8P5etlpd8MWT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2443.166793823242, + "y": 1616.833480834961, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 161, + "height": 20, + "seed": 2016979784, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "precompiled-bytecode", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "precompiled-bytecode" + }, + { + "type": "rectangle", + "version": 437, + "versionNonce": 534188037, + "isDeleted": false, + "id": "qGjmy62MZbL7zALsNU2dL", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2463.166793823242, + "y": 1699.5001373291016, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 114.00006103515625, + "height": 43.000030517578125, + "seed": 1165004088, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "iqe6U9xOE6ECb18moJnw-", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 68, + "versionNonce": 954572491, + "isDeleted": false, + "id": "SiZHwNA9YKd93iwc74wxB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1942.4999542236328, + "y": 1667.833480834961, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 175, + "height": 20, + "seed": 1708294472, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "HCvGV6j45DG_BGeI3J7ut", + "type": "arrow" + } + ], + "updated": 1679533929331, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "fast_jit_jitted_code", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "fast_jit_jitted_code" + }, + { + "type": "diamond", + "version": 85, + "versionNonce": 1759561573, + "isDeleted": false, + "id": "ODI38iO5_5uu6RobQgkVa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1912.499984741211, + "y": 1672.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 18.6666259765625, + "height": 15, + "seed": 297387080, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 93, + "versionNonce": 670928235, + "isDeleted": false, + "id": "gNxfqnpn5KEfZX8dL5GX3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1913.499984741211, + "y": 1717.666732788086, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 18.6666259765625, + "height": 15, + "seed": 1391035448, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 99, + "versionNonce": 175936197, + "isDeleted": false, + "id": "sYSDwbrpZl0692xpkcG4z", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1946.499984741211, + "y": 1713.166763305664, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 143, + "height": 20, + "seed": 1305637176, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "RckpORzYftIA2k4VSkTaW", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "llvm_jit_func_ptr", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "llvm_jit_func_ptr" + }, + { + "type": "text", + "version": 450, + "versionNonce": 1465821195, + "isDeleted": false, + "id": "1iUf8pP_YoM8qCPpSEahX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2383.0000762939453, + "y": 1788.8333129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 142, + "height": 20, + "seed": 68451128, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "fast jitted coode", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "fast jitted coode" + }, + { + "type": "rectangle", + "version": 501, + "versionNonce": 1363669541, + "isDeleted": false, + "id": "qVsRlSPxTl9a8XrnRMl2a", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2405.6665802001953, + "y": 1827.4999389648438, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 103.33337402343747, + "height": 29.2, + "seed": 1374549064, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "HCvGV6j45DG_BGeI3J7ut", + "type": "arrow" + }, + { + "id": "BF2h7Ub5gAf2yYxLfQSFh", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 447, + "versionNonce": 1023635115, + "isDeleted": false, + "id": "bu6GnR96DeCSFWu3DhMIJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2419.499954223633, + "y": 1890.1666870117188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 133, + "height": 20, + "seed": 713214264, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "RckpORzYftIA2k4VSkTaW", + "type": "arrow" + }, + { + "id": "kjpM2qWJqDrV-jr9XK8QR", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "llvm jitted coode", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "llvm jitted coode" + }, + { + "type": "rectangle", + "version": 395, + "versionNonce": 439379333, + "isDeleted": false, + "id": "Z9cJSNSjDvW2uPNthdOW9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2406.1666412353516, + "y": 1916.1666870117188, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 150.66668701171875, + "height": 43.000030517578125, + "seed": 1255376456, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4E9MghnYo6hn8E82pmPMe", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 266, + "versionNonce": 731275595, + "isDeleted": false, + "id": "evHonaxVjRvjwFP08UX9x", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1335.1666259765625, + "y": 1394.0000457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 187.33343505859372, + "height": 73.666748046875, + "seed": 873572680, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "78xSb96N8EcRm2LhdCNjJ", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 258, + "versionNonce": 1215524069, + "isDeleted": false, + "id": "4R5zAaFl-qG-PwNUPfyXq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1360.4999389648438, + "y": 1404.6667022705078, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 157, + "height": 40, + "seed": 237924152, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "import_module_inst;\nimport_func_inst;", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "import_module_inst;\nimport_func_inst;" + }, + { + "type": "diamond", + "version": 132, + "versionNonce": 1014104043, + "isDeleted": false, + "id": "-cXxAxf0DBRaXH85Wn82G", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1341.4998168945312, + "y": 1408.6666564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 1993562680, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "MLVyGZQLa4jU554J6bsmJ", + "type": "arrow" + }, + { + "id": "9vnyulmvSUCDWXvSKKyJ6", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 136, + "versionNonce": 2073987141, + "isDeleted": false, + "id": "V3cEII-BWPnk8MmO8v9Hw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1342.8331909179688, + "y": 1431.6666564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 374375752, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "MLVyGZQLa4jU554J6bsmJ", + "type": "arrow" + }, + { + "id": "9vnyulmvSUCDWXvSKKyJ6", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 196, + "versionNonce": 2040580747, + "isDeleted": false, + "id": "jccHI4GP5zADwZpJ6_F0e", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1020.4999542236328, + "y": 1294.5002899169922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 132.66668701171866, + "height": 34.3333740234375, + "seed": 1209325128, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "eyNKBEqdZDGI0jikxT-7-" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 28, + "versionNonce": 1577034445, + "isDeleted": false, + "id": "eyNKBEqdZDGI0jikxT-7-", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1050.8332977294922, + "y": 1302.066976928711, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 72, + "height": 20, + "seed": 13177699, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247195, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "functions", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "jccHI4GP5zADwZpJ6_F0e", + "originalText": "functions" + }, + { + "type": "diamond", + "version": 157, + "versionNonce": 1205682475, + "isDeleted": false, + "id": "DpQKmgYqIbva-oudQDKVA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1029.8332977294922, + "y": 1302.8336334228516, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1787304760, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 460, + "versionNonce": 544406277, + "isDeleted": false, + "id": "fltFoJAyfls8KPkBw6X_P", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1152.0382824623548, + "y": 1307.393701716202, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 140.3213191272912, + "height": 0.8215748529805751, + "seed": 1890946120, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "onh-wm6wgKrkH94fakl6O", + "focus": 1.0244280280971265, + "gap": 2.5945448897082315 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 140.3213191272912, + -0.8215748529805751 + ] + ] + }, + { + "type": "rectangle", + "version": 245, + "versionNonce": 277996491, + "isDeleted": false, + "id": "BpsyACMObLF20Fkti2Uqq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1020.8332061767578, + "y": 1339.000228881836, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 130.00000000000009, + "height": 31, + "seed": 1664170040, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "22kjCR2ZOQmZQXYgnarEF" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 50, + "versionNonce": 1029340291, + "isDeleted": false, + "id": "22kjCR2ZOQmZQXYgnarEF", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1058.3332061767578, + "y": 1344.900228881836, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 55, + "height": 20, + "seed": 1753405955, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247196, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "globals", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "BpsyACMObLF20Fkti2Uqq", + "originalText": "globals" + }, + { + "type": "diamond", + "version": 201, + "versionNonce": 735654507, + "isDeleted": false, + "id": "66O-4o40vS3pLIeBqwFBW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1030.1665802001953, + "y": 1344.000228881836, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 231180104, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 336, + "versionNonce": 2136587717, + "isDeleted": false, + "id": "l2Sz8ohFcHQT7gWys1M9D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 751.1665802001953, + "y": 1311.6668853759766, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 158, + "height": 32, + "seed": 1571295288, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "o-cON41NQVHvHqkgeW_6m" + }, + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 115, + "versionNonce": 956023085, + "isDeleted": false, + "id": "o-cON41NQVHvHqkgeW_6m", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 824.6665802001953, + "y": 1317.1668853759766, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 11, + "height": 20, + "seed": 1939939267, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247196, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "e", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "l2Sz8ohFcHQT7gWys1M9D", + "originalText": "e" + }, + { + "type": "diamond", + "version": 340, + "versionNonce": 659012901, + "isDeleted": false, + "id": "_eiwTSAQSXB8P2k-PDhNa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 769.8332061767578, + "y": 1323.6668548583984, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1019883336, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 238, + "versionNonce": 536466347, + "isDeleted": false, + "id": "OLHiYmF0KqdbZBgecyb7T", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1017.1665802001953, + "y": 1430.6669158935547, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 131.33337402343759, + "height": 32.33331298828125, + "seed": 1564507192, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 172, + "versionNonce": 1409208453, + "isDeleted": false, + "id": "qUAVJJGhHiEU00yvj5Xwy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1041.1665802001953, + "y": 1438.3335723876953, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1916699464, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 170, + "versionNonce": 209200715, + "isDeleted": false, + "id": "ZzKApm4TYPqV3EGJbMuQ3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1001.6664886474609, + "y": 1253.9168853759766, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 214, + "height": 20, + "seed": 1061991496, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstanceExtra", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstanceExtra" + }, + { + "type": "rectangle", + "version": 195, + "versionNonce": 859600869, + "isDeleted": false, + "id": "SWgPVXvgjtN7AVlTfBUDR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1009.2498474121094, + "y": 1279.9169082641602, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 155, + "height": 200.41667938232422, + "seed": 1419979080, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 389, + "versionNonce": 114500843, + "isDeleted": false, + "id": "3rcvtpnHrIvCrE__yw5GU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1339.5831756591797, + "y": 1031.000186920166, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 174, + "height": 40, + "seed": 1610110792, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "AuwWYqGK5XChc2C2ZDCOd", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstance::\nimport_func_ptrs", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance::\nimport_func_ptrs" + }, + { + "type": "rectangle", + "version": 137, + "versionNonce": 1594766149, + "isDeleted": false, + "id": "IK-a-uPI373j3VM1YHdKy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1390.1666870117188, + "y": 1107.625286102295, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1938455864, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "dA4sHNYw9NqC0yRSl1ByC", + "type": "arrow" + }, + { + "id": "AuwWYqGK5XChc2C2ZDCOd", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 123, + "versionNonce": 110448523, + "isDeleted": false, + "id": "xEmeSz_qg3vcIV0Kjo_4r", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1414.1666870117188, + "y": 1115.2919425964355, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1045500488, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "AuwWYqGK5XChc2C2ZDCOd", + "type": "arrow" + }, + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 158, + "versionNonce": 1406239397, + "isDeleted": false, + "id": "u6aTea5vKrjtv4E0SAr_D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1389.8333129882812, + "y": 1140.7919120788574, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1488328248, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 144, + "versionNonce": 771302955, + "isDeleted": false, + "id": "6petv8iQ_6W4RCCyGVs86", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1413.8333129882812, + "y": 1148.458568572998, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1174899016, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 146, + "versionNonce": 640935429, + "isDeleted": false, + "id": "HWwjwJX9MC7vOni7CdfwU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1389.5, + "y": 1174.1252555847168, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 654741304, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 158, + "versionNonce": 1944660171, + "isDeleted": false, + "id": "3V6VqEBHUeHRXm4rtMN9P", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1388.1666259765625, + "y": 1201.7919120788574, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 652208184, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 138, + "versionNonce": 2033376613, + "isDeleted": false, + "id": "s3LweJMlqb3u8zFFOtRWC", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1410.8333129882812, + "y": 1210.1252555847168, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 630970184, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 748, + "versionNonce": 234870635, + "isDeleted": false, + "id": "j_Tg3JOansfDRNxNBUMfi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1423.3266279235036, + "y": 1116.6584335466105, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 310.5923414580757, + "height": 177.73696684706545, + "seed": 561180216, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "startBinding": { + "elementId": "xEmeSz_qg3vcIV0Kjo_4r", + "focus": -0.6524247058306003, + "gap": 2.5695135809208747 + }, + "endBinding": { + "elementId": "Kpjtivj-7LYLq1nuvC4KS", + "focus": 1.1530360747961412, + "gap": 8.581076394787942 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 125.75645618294175, + -55.99185334641493 + ], + [ + 310.5923414580757, + -177.73696684706545 + ] + ] + }, + { + "type": "diamond", + "version": 115, + "versionNonce": 874244293, + "isDeleted": false, + "id": "SosCUEMFvN64e8eYhtj4S", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1748.0836486816406, + "y": 1289.8335762023926, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 8.333282470703125, + "height": 13.75, + "seed": 1668126536, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "S1cN82-5SoSu4e4SWfAUw", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 119, + "versionNonce": 445100555, + "isDeleted": false, + "id": "-vw33v9u2Ko2ayilI0CXG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1745.5836486816406, + "y": 1319.8335762023926, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10.833282470703125, + "height": 9.583320617675781, + "seed": 2012578120, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "S1cN82-5SoSu4e4SWfAUw", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 648, + "versionNonce": 2022475813, + "isDeleted": false, + "id": "MLVyGZQLa4jU554J6bsmJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1347.8331909179688, + "y": 1415.2017225151058, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 179.41659545898438, + "height": 304.1667256414903, + "seed": 1591654456, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "startBinding": { + "elementId": "V3cEII-BWPnk8MmO8v9Hw", + "focus": 3.669987091693772, + "gap": 10.369642504898593 + }, + "endBinding": { + "elementId": "Rcref7JZ-AhlcXLLdwY5D", + "focus": -0.4568695235814372, + "gap": 6.321478788304148 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -179.41659545898438, + 169.4649187202458 + ], + [ + -89.48586426600582, + 304.1667256414903 + ] + ] + }, + { + "type": "text", + "version": 807, + "versionNonce": 175847595, + "isDeleted": false, + "id": "tUs9waDW6sL0AbyoZYJ5Q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 867.8295186360679, + "y": 823.9724260965983, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 672, + "height": 160, + "seed": 709576760, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "this is the one actually referred during executing opcode\n\nduring model load, if import can be solved through the native api registeration,\nthe pointer of native function will be filled.\n\nc-api could change the pointer later, then it will point to a different native function\n\nNULL: means multi-module import, go to \"import_func_inst\" field for target function", + "baseline": 154, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "this is the one actually referred during executing opcode\n\nduring model load, if import can be solved through the native api registeration,\nthe pointer of native function will be filled.\n\nc-api could change the pointer later, then it will point to a different native function\n\nNULL: means multi-module import, go to \"import_func_inst\" field for target function" + }, + { + "type": "rectangle", + "version": 410, + "versionNonce": 1483881349, + "isDeleted": false, + "id": "kARKLR5va5hDwe-2JCl7d", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 855.623291015625, + "y": 824.4128579639253, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 691.1904471261159, + "height": 170.05954742431626, + "seed": 1355113288, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "AuwWYqGK5XChc2C2ZDCOd", + "type": "arrow" + }, + { + "id": "j_Tg3JOansfDRNxNBUMfi", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 1427, + "versionNonce": 1267002187, + "isDeleted": false, + "id": "AuwWYqGK5XChc2C2ZDCOd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1132.2583561737392, + "y": 997.6315427986297, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188.93306844281233, + "height": 54.67370578283135, + "seed": 1524992312, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "startBinding": { + "elementId": "kARKLR5va5hDwe-2JCl7d", + "gap": 3.1591374103880994, + "focus": 0.5842950344963632 + }, + "endBinding": { + "elementId": "3rcvtpnHrIvCrE__yw5GU", + "gap": 18.39175104262814, + "focus": -0.7039875993615579 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 188.93306844281233, + 54.67370578283135 + ] + ] + }, + { + "type": "text", + "version": 363, + "versionNonce": 1275757285, + "isDeleted": false, + "id": "_pYmb7H1lxRLE4Qw_MajA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1034.3336715698242, + "y": 1680.4170036315918, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 176, + "height": 20, + "seed": 764509256, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstance*", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance*" + }, + { + "type": "text", + "version": 314, + "versionNonce": 838814187, + "isDeleted": false, + "id": "GBXnnFKM_76tjt1WAlYnV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1250.0279070536296, + "y": 1605.2504641215007, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 198, + "height": 20, + "seed": 1630119496, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "9vnyulmvSUCDWXvSKKyJ6", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(WASMFunctionInstance*)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(WASMFunctionInstance*)" + }, + { + "type": "arrow", + "version": 881, + "versionNonce": 1742921285, + "isDeleted": false, + "id": "9vnyulmvSUCDWXvSKKyJ6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1347.3662637658592, + "y": 1437.871212796838, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 109.83801974730454, + "height": 307.7636946939249, + "seed": 422577480, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "startBinding": { + "elementId": "-cXxAxf0DBRaXH85Wn82G", + "focus": -3.9115852992052806, + "gap": 11.29853538112821 + }, + "endBinding": { + "elementId": "94gfo2BctxYsRP6cuuIbI", + "gap": 10.033975741878294, + "focus": -0.6520703073991437 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -109.83801974730454, + 135.3790961936404 + ], + [ + -51.493209521376, + 307.7636946939249 + ] + ] + }, + { + "type": "diamond", + "version": 207, + "versionNonce": 2116029227, + "isDeleted": false, + "id": "kliwot061_yUhDMDbVbQe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1354.3614679972331, + "y": 1779.417065938314, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 82951992, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 233, + "versionNonce": 2082066693, + "isDeleted": false, + "id": "mvfNSPpLgMxaEaQuXYPrl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1387.0280939737956, + "y": 1776.7504094441733, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 94, + "height": 20, + "seed": 1266085960, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_import", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_import" + }, + { + "type": "text", + "version": 265, + "versionNonce": 1206611403, + "isDeleted": false, + "id": "Oe13Ts1dEazuz8ilwnZiL", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1398.6947809855144, + "y": 1806.7504094441733, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 34, + "height": 20, + "seed": 2145720376, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func" + }, + { + "type": "diamond", + "version": 230, + "versionNonce": 287533157, + "isDeleted": false, + "id": "nyquujDKZGyYvDs-a_GQ-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1356.0280939737956, + "y": 1811.5837071736655, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 10, + "height": 12.333343505859375, + "seed": 784443208, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 252, + "versionNonce": 326204523, + "isDeleted": false, + "id": "cGQYK5rXelrtuGolytFol", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1332.3614679972331, + "y": 1765.417065938314, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 154.00006103515616, + "height": 79, + "seed": 1426411832, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "9vnyulmvSUCDWXvSKKyJ6", + "type": "arrow" + } + ], + "updated": 1679533929332, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 521, + "versionNonce": 868422597, + "isDeleted": false, + "id": "VRweEUgFB9qqzjdTwpHnK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1323.694574991862, + "y": 1739.194897969564, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 20, + "seed": 155802936, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929332, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunction ", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction " + }, + { + "type": "arrow", + "version": 621, + "versionNonce": 746370827, + "isDeleted": false, + "id": "CUEfVWpVIuIHc_5h3VskN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1459.8716446745273, + "y": 1829.1380187988277, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 394.2706533635544, + "height": 82.19527893066447, + "seed": 1854588984, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "epVvbDyPF40MaERFnDDJy", + "focus": 0.2506598246466399, + "gap": 9.849883651733307 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 153.21163779617586, + 82.19527893066447 + ], + [ + 394.2706533635544, + 27.990782200797412 + ] + ] + }, + { + "type": "text", + "version": 309, + "versionNonce": 1880511269, + "isDeleted": false, + "id": "OTP338ttAjF_rIJwNKA1S", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1298.416748046875, + "y": 1343.3333587646484, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 38, + "height": 20, + "seed": 1994699981, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "union", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "union" + }, + { + "type": "rectangle", + "version": 62, + "versionNonce": 25664939, + "isDeleted": false, + "id": "7kmKkWcfD2eeTgLmci_TA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1289.75, + "y": 1517.3333282470703, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 260.66668701171875, + "height": 61.333343505859375, + "seed": 1810842211, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "fr9-3bNKWz24759an1jPs" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 13, + "versionNonce": 914224163, + "isDeleted": false, + "id": "fr9-3bNKWz24759an1jPs", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1404.5833435058594, + "y": 1538.4, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 20, + "seed": 1884299875, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247200, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "7kmKkWcfD2eeTgLmci_TA", + "originalText": "[...]" + }, + { + "type": "line", + "version": 176, + "versionNonce": 1373083019, + "isDeleted": false, + "id": "pYd8BNqe32DQ1BK15gl1X", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1607.7500610351565, + "y": 911.2331604003898, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 2.2737367544323206e-13, + "height": 1207.7780151367188, + "seed": 1889947117, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533932559, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + -2.2737367544323206e-13, + 1207.7780151367188 + ] + ] + }, + { + "type": "text", + "version": 58, + "versionNonce": 2111671781, + "isDeleted": false, + "id": "-EA8TtLR5unZFdjT-k9mq", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1404.4167785644531, + "y": 1492.6665802001953, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 1174452173, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "text", + "version": 225, + "versionNonce": 49704683, + "isDeleted": false, + "id": "al3s0Ce-XZ_FiU84jmv0f", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 729.2799504597981, + "y": 1209.9554656982423, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 171, + "height": 19, + "seed": 1330045933, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModuleInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance" + }, + { + "type": "rectangle", + "version": 102, + "versionNonce": 555518277, + "isDeleted": false, + "id": "TxSoCCktw7hU7jU0cN2he", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 723.0834655761719, + "y": 1240.9998931884766, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 210.66668701171875, + "height": 305.33334350585943, + "seed": 598232163, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 113, + "versionNonce": 1941920139, + "isDeleted": false, + "id": "uyhu5MiXRFgQansSAKgbz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1858.638671875, + "y": 1857.11110941569, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 229.3333740234375, + "height": 71.33331298828125, + "seed": 1064313101, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "4W7-B8UsG2Kp0-6eEN0-h" + }, + { + "id": "CUEfVWpVIuIHc_5h3VskN", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 67, + "versionNonce": 1873089421, + "isDeleted": false, + "id": "4W7-B8UsG2Kp0-6eEN0-h", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1959.8053588867188, + "y": 1883.1777659098307, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 27, + "height": 20, + "seed": 1206387267, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247203, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[..]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "uyhu5MiXRFgQansSAKgbz", + "originalText": "[..]" + }, + { + "type": "arrow", + "version": 335, + "versionNonce": 1028780075, + "isDeleted": false, + "id": "0dTwoTnwCJUbyz3e0bm1O", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 780.7038274166374, + "y": 1329.8562414550568, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 227.1615634556406, + "height": 49.895659740248675, + "seed": 1282951939, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "startBinding": { + "elementId": "_eiwTSAQSXB8P2k-PDhNa", + "focus": -0.16162303890895813, + "gap": 1.5411549516792498 + }, + "endBinding": { + "elementId": "SWgPVXvgjtN7AVlTfBUDR", + "focus": 1.0022214255263049, + "gap": 1.3844565398313762 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 227.1615634556406, + -49.895659740248675 + ] + ] + }, + { + "type": "rectangle", + "version": 380, + "versionNonce": 1831123973, + "isDeleted": false, + "id": "EjfvS52mTJV_ntE7FAmqi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 749.41650390625, + "y": 1265.500015258789, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 163, + "height": 38.333343505859375, + "seed": 908455875, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 372, + "versionNonce": 395899749, + "isDeleted": false, + "id": "0n8DknkuWXlRynFJmYm-N", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 760.0831298828125, + "y": 1276.500015258789, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1140391779, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "dA4sHNYw9NqC0yRSl1ByC", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 131, + "versionNonce": 169804459, + "isDeleted": false, + "id": "xwVumJFL4-d-8BM7nSKzG", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1406.5276896158855, + "y": 1849.9999745686848, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 25, + "height": 20, + "seed": 813534477, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[n]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[n]" + }, + { + "type": "arrow", + "version": 164, + "versionNonce": 1833439621, + "isDeleted": false, + "id": "dA4sHNYw9NqC0yRSl1ByC", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 767.0830841064453, + "y": 1278.6665496826172, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 617.3333435058594, + "height": 168.00003051757812, + "seed": 1360269091, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "startBinding": { + "elementId": "0n8DknkuWXlRynFJmYm-N", + "focus": -0.6970200254594874, + "gap": 1 + }, + "endBinding": { + "elementId": "IK-a-uPI373j3VM1YHdKy", + "focus": 0.91934006004951, + "gap": 5.7502593994140625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 283.33331298828125, + -86.66671752929688 + ], + [ + 617.3333435058594, + -168.00003051757812 + ] + ] + }, + { + "type": "text", + "version": 370, + "versionNonce": 2015327563, + "isDeleted": false, + "id": "1uhr4l-w9t4eVo0gQ06SH", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1628.0831146240234, + "y": 1047.333236694336, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 60, + "height": 20, + "seed": 2127932547, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "70jp9eV1jV2_kUBbN055m", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(void *)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(void *)" + }, + { + "type": "diamond", + "version": 110, + "versionNonce": 867539173, + "isDeleted": false, + "id": "OpV38MM8YOexWG_e-5_hX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1751.5831604003906, + "y": 1244.7915496826172, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 8.333282470703125, + "height": 13.75, + "seed": 1876974509, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "l4S1IXvHmVx_wl8DPQXk3", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 201, + "versionNonce": 1052283883, + "isDeleted": false, + "id": "0VYDhNUTpNaSbemsP54Zy", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 982.6778793334961, + "y": 1174.3998931884767, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 68, + "height": 20, + "seed": 2080172771, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(void **)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(void **)" + }, + { + "type": "text", + "version": 52, + "versionNonce": 364590149, + "isDeleted": false, + "id": "mEKNbQ7XuwA2N2CRqO86h", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1395.7501068115234, + "y": 1178.6665954589844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 43, + "height": 20, + "seed": 95270211, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "NULL", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "NULL" + }, + { + "type": "rectangle", + "version": 348, + "versionNonce": 306207333, + "isDeleted": false, + "id": "FKonkUbaqKFXKyt5VSiGE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 743.0831654866537, + "y": 1476.5000508626301, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 31.666625976562507, + "seed": 710825357, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "0dTwoTnwCJUbyz3e0bm1O", + "type": "arrow" + } + ], + "updated": 1679533956228, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 376, + "versionNonce": 1951705707, + "isDeleted": false, + "id": "xNodTFHQFtS6jmRfbZDpo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 748.4164784749349, + "y": 1484.1667073567708, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1417026541, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533956228, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 82, + "versionNonce": 678544837, + "isDeleted": false, + "id": "8i8vmtgsTLeEQt_E_hLrk", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 768.4165089925131, + "y": 1481.0000508626301, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 149, + "height": 20, + "seed": 1944091203, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "yu3un9i0kAGrZ8bAnVMa3", + "type": "arrow" + } + ], + "updated": 1679533956228, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_type_indexes", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_type_indexes" + }, + { + "type": "rectangle", + "version": 210, + "versionNonce": 1441855435, + "isDeleted": false, + "id": "IwrJYgHbhcHGM-MPt77v3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 907.3989664713541, + "y": 1609.9723409016926, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 919532995, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 230, + "versionNonce": 2006154853, + "isDeleted": false, + "id": "XRMQmYFkm-FtbS8PBuF_X", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 907.0655924479166, + "y": 1643.1389668782551, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 361842019, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 218, + "versionNonce": 473286251, + "isDeleted": false, + "id": "nsMfEXFd6IeqB7fL4ngUa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 906.7322794596354, + "y": 1676.4723103841145, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1923653891, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 227, + "versionNonce": 1069574597, + "isDeleted": false, + "id": "R5ioSAhKEdUlCurXbrHuN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 905.3989054361979, + "y": 1704.1389668782551, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1469286563, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 323, + "versionNonce": 617227531, + "isDeleted": false, + "id": "yu3un9i0kAGrZ8bAnVMa3", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 753.0831654866537, + "y": 1487.6672379829788, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 200.16657758128372, + "height": 153.3329247774377, + "seed": 1439562723, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533956229, + "link": null, + "locked": false, + "startBinding": { + "elementId": "8i8vmtgsTLeEQt_E_hLrk", + "focus": 1.0014597510870404, + "gap": 15.333343505859375 + }, + "endBinding": { + "elementId": "p5TPteQC3PraRMJtt4XsT", + "focus": 0.36261877029011863, + "gap": 3.9746450546211918 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -60.000050862630246, + 26.332884087333696 + ], + [ + -40.88889567057288, + 105.11070594605758 + ], + [ + 62.88881429036462, + 153.3329247774377 + ], + [ + 140.16652671865347, + 150.58490939994954 + ] + ] + }, + { + "type": "text", + "version": 99, + "versionNonce": 2113464613, + "isDeleted": false, + "id": "a8gv4R6T3PYjKJhay9vMv", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 802.4165191650391, + "y": 1604.7780354817708, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70, + "height": 20, + "seed": 453646061, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint32 *", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "uint32 *" + }, + { + "type": "text", + "version": 97, + "versionNonce": 692152235, + "isDeleted": false, + "id": "eNJLe1mhF_AWRUyt9lO6k", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2227.083185195923, + "y": 955.9999694824219, + "strokeColor": "#1864ab", + "backgroundColor": "transparent", + "width": 96, + "height": 19, + "seed": 1711184323, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModule", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule" + }, + { + "type": "rectangle", + "version": 247, + "versionNonce": 329940101, + "isDeleted": false, + "id": "25KRboddeZem953trnn-R", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2216.416498184204, + "y": 985.9999389648438, + "strokeColor": "#1864ab", + "backgroundColor": "transparent", + "width": 308, + "height": 568, + "seed": 847170787, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 135, + "versionNonce": 799881803, + "isDeleted": false, + "id": "NnvrV9DcfaaiOCGPUdP78", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2229.083246231079, + "y": 1003.3333129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 263, + "height": 224, + "seed": 2117157197, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": " WASMImport *import_tables;\n WASMImport *import_memories;\n WASMImport *import_globals;\n\n WASMType **types;\n WASMImport *imports;\n WASMTable *tables;\n WASMMemory *memories;\n WASMGlobal *globals;\n WASMExport *exports;\n WASMTableSeg *table_segments;\n WASMDataSeg **data_segments;", + "baseline": 220, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " WASMImport *import_tables;\n WASMImport *import_memories;\n WASMImport *import_globals;\n\n WASMType **types;\n WASMImport *imports;\n WASMTable *tables;\n WASMMemory *memories;\n WASMGlobal *globals;\n WASMExport *exports;\n WASMTableSeg *table_segments;\n WASMDataSeg **data_segments;" + }, + { + "type": "rectangle", + "version": 123, + "versionNonce": 1486005221, + "isDeleted": false, + "id": "O5y5oOsgUB5ue4vWSQB0i", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2232.4165592193604, + "y": 1301.3332824707031, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 273.3333740234375, + "height": 44, + "seed": 1988414157, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 145, + "versionNonce": 709212395, + "isDeleted": false, + "id": "6xufIeHeKpvDChXCTeKSb", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2294.4165592193604, + "y": 1314.6665954589844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 198, + "height": 19, + "seed": 2026661485, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMFunction **functions;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction **functions;" + }, + { + "type": "diamond", + "version": 108, + "versionNonce": 1354686277, + "isDeleted": false, + "id": "s4lQvHIN1eAAubp7DkNrk", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2245.083246231079, + "y": 1318, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 26.6666259765625, + "height": 19.333343505859375, + "seed": 1489582509, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Bnf72M4RGMZjNgBlzk90B", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 354, + "versionNonce": 1184195467, + "isDeleted": false, + "id": "Bnf72M4RGMZjNgBlzk90B", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2250.416437149048, + "y": 1332.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 163.1120623945253, + "height": 15.460472501937602, + "seed": 1550987139, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "startBinding": { + "elementId": "s4lQvHIN1eAAubp7DkNrk", + "focus": -0.36983487209914556, + "gap": 1 + }, + "endBinding": { + "elementId": "swt6lb3ztkUJAvM41XHBK", + "focus": -0.7544161254824635, + "gap": 5.555002272222737 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -163.1120623945253, + 15.460472501937602 + ] + ] + }, + { + "type": "text", + "version": 138, + "versionNonce": 579645093, + "isDeleted": false, + "id": "TfktbM2ODt0uHXCbkJtbX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2277.4166202545166, + "y": 1269.3333435058594, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 229, + "height": 19, + "seed": 2140950979, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMImport *import_functions;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMImport *import_functions;" + }, + { + "type": "rectangle", + "version": 99, + "versionNonce": 483834411, + "isDeleted": false, + "id": "sIxEmRk_EPaTumCGaxM6t", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2231.749994277954, + "y": 1254.6667175292969, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 276, + "height": 42.6666259765625, + "seed": 2140310499, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 86, + "versionNonce": 1286181381, + "isDeleted": false, + "id": "_er3JaiUwljITdxfog0w_", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2246.416742324829, + "y": 1265.3334045410156, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 15.33331298828125, + "height": 22.66668701171875, + "seed": 568056877, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 453, + "versionNonce": 1509178571, + "isDeleted": false, + "id": "70jp9eV1jV2_kUBbN055m", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2253.0103282895525, + "y": 1275.9391811320388, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 323.49287390894006, + "height": 187.53914675447618, + "seed": 638625069, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "startBinding": { + "elementId": "JWlL3nHzTP4pxrEVYolFx", + "focus": -1.0762119763220488, + "gap": 30.60580710860131 + }, + "endBinding": { + "elementId": "1rZk-xFL82XSp5Mpcqy4f", + "focus": -1.2708836305762516, + "gap": 14.434116596798958 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -146.59352492956714, + -83.93927268477319 + ], + [ + -323.49287390894006, + -187.53914675447618 + ] + ] + }, + { + "type": "rectangle", + "version": 145, + "versionNonce": 471009637, + "isDeleted": false, + "id": "4BwxH9WndrjsXga95YTvm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1705.7500858306885, + "y": 1086.6665954589844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 222.6666259765625, + "height": 303.33331298828125, + "seed": 803769283, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "70jp9eV1jV2_kUBbN055m", + "type": "arrow" + }, + { + "id": "nUF7GyfmAGZN3iZvBfYtq", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 270, + "versionNonce": 696806251, + "isDeleted": false, + "id": "RR6mIlX4wkxcfcv6RQ8Wa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1708.416711807251, + "y": 1062.6665954589844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 97, + "height": 19, + "seed": 2042686211, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMImport", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMImport" + }, + { + "type": "rectangle", + "version": 191, + "versionNonce": 1645647045, + "isDeleted": false, + "id": "1rZk-xFL82XSp5Mpcqy4f", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1745.749963760376, + "y": 1097.3333129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 169.3333740234375, + "height": 31, + "seed": 176484109, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "qkiSeaixB8ivmpNxhvY6l" + }, + { + "id": "70jp9eV1jV2_kUBbN055m", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 162, + "versionNonce": 395409347, + "isDeleted": false, + "id": "qkiSeaixB8ivmpNxhvY6l", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1750.749963760376, + "y": 1102.3333129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 79, + "height": 20, + "seed": 2146735565, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247208, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint8 kind", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "middle", + "containerId": "1rZk-xFL82XSp5Mpcqy4f", + "originalText": "uint8 kind" + }, + { + "type": "rectangle", + "version": 175, + "versionNonce": 1783739429, + "isDeleted": false, + "id": "R_f4RWhd20C8JXmaJofMm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1706.7500247955322, + "y": 1390.6665954589844, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 221, + "height": 31, + "seed": 691699363, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "jXOu2RGl7KTvcY3-hwIj2" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 56, + "versionNonce": 2117409261, + "isDeleted": false, + "id": "jXOu2RGl7KTvcY3-hwIj2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1806.2500247955322, + "y": 1396.0665954589845, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 20, + "seed": 776900557, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247209, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "R_f4RWhd20C8JXmaJofMm", + "originalText": "[1]" + }, + { + "type": "text", + "version": 51, + "versionNonce": 816965509, + "isDeleted": false, + "id": "JvLqnDwgx42bo19rINn18", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1807.083490371704, + "y": 1371.9998474121094, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 2020174093, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 185, + "versionNonce": 1499856715, + "isDeleted": false, + "id": "Xj5n84LklLY7rIUbMpV30", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1708.2501163482666, + "y": 1422.3332061767578, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 221, + "height": 31, + "seed": 1499618403, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "LOWTAqc1KaVYNxnLkXHB4" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 61, + "versionNonce": 2125694819, + "isDeleted": false, + "id": "LOWTAqc1KaVYNxnLkXHB4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1803.2501163482666, + "y": 1427.733206176758, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 20, + "seed": 701124429, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247210, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Xj5n84LklLY7rIUbMpV30", + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 50, + "versionNonce": 178118123, + "isDeleted": false, + "id": "qd-T97QOO_xa4SGTgkrAj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1363.083200454712, + "y": 1076.0001373291016, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 96, + "height": 170.66668701171875, + "seed": 215655011, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "AuwWYqGK5XChc2C2ZDCOd", + "type": "arrow" + } + ], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 169, + "versionNonce": 1562872389, + "isDeleted": false, + "id": "EAEAQzFaB6T9-rCB0X-61", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2303.749662399292, + "y": 1418.0001983642578, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 160, + "height": 20, + "seed": 1651418499, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "fast_jit_func_ptrs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "fast_jit_func_ptrs" + }, + { + "type": "rectangle", + "version": 195, + "versionNonce": 312535179, + "isDeleted": false, + "id": "n3LUTZSRU6GJ4nfF98WsH", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2233.7496013641357, + "y": 1409.6669158935547, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 273.3333740234375, + "height": 44, + "seed": 1123016931, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 173, + "versionNonce": 312998309, + "isDeleted": false, + "id": "SOlRVdTv-nHYKomLm0-Lr", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2246.749662399292, + "y": 1421.000244140625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 26.6666259765625, + "height": 19.333343505859375, + "seed": 381478531, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929333, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 61, + "versionNonce": 1193910059, + "isDeleted": false, + "id": "RckpORzYftIA2k4VSkTaW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2093.082914352417, + "y": 1731.3334503173828, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 314.6666564941406, + "height": 191.3333740234375, + "seed": 1221862445, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": { + "elementId": "sYSDwbrpZl0692xpkcG4z", + "focus": -0.8132904069013918, + "gap": 6.05506706237793 + }, + "endBinding": { + "elementId": "bu6GnR96DeCSFWu3DhMIJ", + "focus": -1.5131314965155, + "gap": 13.30013732910163 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 150.66665649414062, + 128.66668701171875 + ], + [ + 314.6666564941406, + 191.3333740234375 + ] + ] + }, + { + "type": "arrow", + "version": 66, + "versionNonce": 1361280261, + "isDeleted": false, + "id": "HCvGV6j45DG_BGeI3J7ut", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2116.4162578582764, + "y": 1692.6667938232422, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 288.25032234191895, + "height": 141.39862277829707, + "seed": 298119629, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": { + "elementId": "SiZHwNA9YKd93iwc74wxB", + "focus": -0.7153529191190878, + "gap": 5.633312988281318 + }, + "endBinding": { + "elementId": "qVsRlSPxTl9a8XrnRMl2a", + "focus": -0.10195339456743455, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 125.33331298828125, + 108.66665649414062 + ], + [ + 288.25032234191895, + 141.39862277829707 + ] + ] + }, + { + "type": "arrow", + "version": 81, + "versionNonce": 1654817227, + "isDeleted": false, + "id": "iqe6U9xOE6ECb18moJnw-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2083.0828227996826, + "y": 1640.0001068115234, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 380, + "height": 114.66668701171875, + "seed": 1655019469, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "qGjmy62MZbL7zALsNU2dL", + "focus": 0.8815432234830397, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 202.66668701171875, + 114.66668701171875 + ], + [ + 380, + 64 + ] + ] + }, + { + "type": "rectangle", + "version": 196, + "versionNonce": 1880593509, + "isDeleted": false, + "id": "pWu_lwlXIT6mrZDyT6QkK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2690.0828075408936, + "y": 1522.750244140625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 162247299, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "NSz4yfxdToa5c5At8YYeR", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 181, + "versionNonce": 1847988331, + "isDeleted": false, + "id": "rBPIesLQ3_hwRCCEZDo_K", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2714.0828075408936, + "y": 1530.4169006347656, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 2113989421, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 216, + "versionNonce": 2068955077, + "isDeleted": false, + "id": "1nU3Tx2BdlitDqcIjhR6O", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2689.749433517456, + "y": 1555.9168701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 255355427, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 202, + "versionNonce": 1803471627, + "isDeleted": false, + "id": "qPuFVkGJxscoxDIlxjxO7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2713.749433517456, + "y": 1563.5835266113281, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1853160845, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 205, + "versionNonce": 686784293, + "isDeleted": false, + "id": "ijtdWkKxrTh4Pnlp14iE0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2689.416120529175, + "y": 1589.2502136230469, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 495791555, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "BF2h7Ub5gAf2yYxLfQSFh", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 215, + "versionNonce": 1059533227, + "isDeleted": false, + "id": "jFcNDR-eUAEW7pedWkAdo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2688.0827465057373, + "y": 1616.9168701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 796378093, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 196, + "versionNonce": 257839749, + "isDeleted": false, + "id": "q4AkedYi9svz1WOMHGyiP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2710.749433517456, + "y": 1625.2502136230469, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 2009628003, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 195, + "versionNonce": 1514783819, + "isDeleted": false, + "id": "NSz4yfxdToa5c5At8YYeR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2491.7495250701904, + "y": 1437.3335571289062, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 199.43811857564833, + "height": 81.5190719332436, + "seed": 909964067, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "pWu_lwlXIT6mrZDyT6QkK", + "focus": 0.37183947794184286, + "gap": 3.8976150784751553 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 199.43811857564833, + 81.5190719332436 + ] + ] + }, + { + "type": "arrow", + "version": 222, + "versionNonce": 458996197, + "isDeleted": false, + "id": "BF2h7Ub5gAf2yYxLfQSFh", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2718.826031777619, + "y": 1626.7287320369785, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 207.0765067074285, + "height": 202.09118637438291, + "seed": 358411853, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": { + "elementId": "D0065Oo1uIjEqNG6iDJjn", + "focus": -2.935287320516118, + "gap": 14.961736017351072 + }, + "endBinding": { + "elementId": "qVsRlSPxTl9a8XrnRMl2a", + "focus": 0.3455990175110858, + "gap": 2.749570846557617 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -84.40981969570976, + 140.60479457434963 + ], + [ + -207.0765067074285, + 202.09118637438291 + ] + ] + }, + { + "type": "diamond", + "version": 207, + "versionNonce": 616628971, + "isDeleted": false, + "id": "D0065Oo1uIjEqNG6iDJjn", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2712.0828075408936, + "y": 1594.1669158935547, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1454945635, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "BF2h7Ub5gAf2yYxLfQSFh", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 61, + "versionNonce": 1173697861, + "isDeleted": false, + "id": "OI5mleCPF3WYtCzvosMk1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2661.7495861053467, + "y": 1495.3336181640625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 177.33334350585938, + "seed": 617283619, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 81, + "versionNonce": 655846795, + "isDeleted": false, + "id": "4Q_PdspTfAcKBYqfwEOrl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2534.4162731170654, + "y": 1478.0003051757812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 68, + "height": 20, + "seed": 468048995, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(void **)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(void **)" + }, + { + "type": "text", + "version": 215, + "versionNonce": 176702629, + "isDeleted": false, + "id": "zEBN6RuZylHRtnzhMAsfm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2302.082899093628, + "y": 1367.6669006347656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 20, + "seed": 1726260589, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_ptrs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_ptrs" + }, + { + "type": "rectangle", + "version": 240, + "versionNonce": 1955038251, + "isDeleted": false, + "id": "Q1RbJ8FG5PuoKZ0jGW-AG", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2232.0828380584717, + "y": 1359.3336181640625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 273.3333740234375, + "height": 44, + "seed": 1664381923, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 218, + "versionNonce": 482502661, + "isDeleted": false, + "id": "lKOq2jf5D0WXwfNx9mwVb", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2245.082899093628, + "y": 1370.6669464111328, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 26.6666259765625, + "height": 19.333343505859375, + "seed": 1869049805, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 197, + "versionNonce": 1425786571, + "isDeleted": false, + "id": "5_VLE0dE94H4gwxL9iUpC", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2851.4160289764404, + "y": 1432.750228881836, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1330766563, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "8jHbZMq4zvKK9AxPUw9Qf", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 181, + "versionNonce": 1587617637, + "isDeleted": false, + "id": "k1p6Nabm5uz-_RQk8vKUy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2875.4160289764404, + "y": 1440.4168853759766, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1901883597, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 216, + "versionNonce": 789493099, + "isDeleted": false, + "id": "BH3ZK-RnoIcnosroWZ9_J", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2851.082654953003, + "y": 1465.9168548583984, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 897158787, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 202, + "versionNonce": 376564421, + "isDeleted": false, + "id": "cAmZfC7YbkEqrmByhjjHI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2875.082654953003, + "y": 1473.583511352539, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 596561709, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 205, + "versionNonce": 839569419, + "isDeleted": false, + "id": "yAeZ1rNDP97dzjt5edJvJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2850.7493419647217, + "y": 1499.2501983642578, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1022019107, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 215, + "versionNonce": 1691503141, + "isDeleted": false, + "id": "h_AbFbWb_N0KfOV68sJf6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2849.415967941284, + "y": 1526.9168548583984, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1889952141, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 196, + "versionNonce": 1072338603, + "isDeleted": false, + "id": "OKOuC260x6EDIVInqBKer", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2872.082654953003, + "y": 1535.2501983642578, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 479463875, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 208, + "versionNonce": 2058337669, + "isDeleted": false, + "id": "zQXps3l6_CULfrKz0sxFV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2873.4160289764404, + "y": 1504.1669006347656, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 769435629, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4E9MghnYo6hn8E82pmPMe", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 61, + "versionNonce": 391678283, + "isDeleted": false, + "id": "4EdLS1fcNDOsz52Mf7ATN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2823.0828075408936, + "y": 1405.3336029052734, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 177.33334350585938, + "seed": 697555299, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 108, + "versionNonce": 256361701, + "isDeleted": false, + "id": "8jHbZMq4zvKK9AxPUw9Qf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2495.082899093628, + "y": 1376.0003051757812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 355.3333740234375, + "height": 55.999969482421875, + "seed": 424364771, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "5_VLE0dE94H4gwxL9iUpC", + "focus": 0.6186308498480104, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 355.3333740234375, + 55.999969482421875 + ] + ] + }, + { + "type": "text", + "version": 44, + "versionNonce": 1034889195, + "isDeleted": false, + "id": "PamsTN-BPmxTRCvWvz1kZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2636.5496044158936, + "y": 1377.7335876464845, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 68, + "height": 20, + "seed": 508079075, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(void **)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(void **)" + }, + { + "type": "arrow", + "version": 101, + "versionNonce": 371712069, + "isDeleted": false, + "id": "4E9MghnYo6hn8E82pmPMe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2877.7495250701904, + "y": 1546.6669921875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 317.33331298828125, + "height": 370, + "seed": 625293229, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": { + "elementId": "zQXps3l6_CULfrKz0sxFV", + "focus": -3.2298254921305025, + "gap": 13.691591814926234 + }, + "endBinding": { + "elementId": "Z9cJSNSjDvW2uPNthdOW9", + "focus": 0.3950527937625778, + "gap": 3.582883834838867 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -144, + 266 + ], + [ + -317.33331298828125, + 370 + ] + ] + }, + { + "type": "rectangle", + "version": 219, + "versionNonce": 687403659, + "isDeleted": false, + "id": "swt6lb3ztkUJAvM41XHBK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2033.7493724822998, + "y": 1348.4170532226562, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 177857187, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Bnf72M4RGMZjNgBlzk90B", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 203, + "versionNonce": 892178341, + "isDeleted": false, + "id": "MlaoCVMw-5S2Yi8P1HjDR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2057.7493724823, + "y": 1356.0837097167969, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1852132621, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 238, + "versionNonce": 703621419, + "isDeleted": false, + "id": "TiGonLf-juzwJEoH9VSZD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2033.4159984588623, + "y": 1381.5836791992188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 254514755, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 224, + "versionNonce": 2055623429, + "isDeleted": false, + "id": "3YRJV9k9ywr0i4pEZkHkN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2057.4159984588623, + "y": 1389.2503356933594, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 2075272045, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 227, + "versionNonce": 369101771, + "isDeleted": false, + "id": "33dfOgt2KTLk3Q5NBImFr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2033.082685470581, + "y": 1414.9170227050781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1787155939, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 237, + "versionNonce": 1387244133, + "isDeleted": false, + "id": "92FFROdmhjPmxEpXFFQ5M", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2031.7493114471436, + "y": 1442.5836791992188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1238707661, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 218, + "versionNonce": 826432107, + "isDeleted": false, + "id": "QULGDwKUKXLejiOFZCB88", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2054.4159984588623, + "y": 1450.9170227050781, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1270292867, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 230, + "versionNonce": 1047991749, + "isDeleted": false, + "id": "-dLa28cPs8d1YMU273D-q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2055.7493724823, + "y": 1419.833724975586, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1206381613, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "uC3ZSm-IltHDllxDGLJ9v", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 83, + "versionNonce": 1484903691, + "isDeleted": false, + "id": "diotVPud8Nk4qCzgu2hJi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2005.416151046753, + "y": 1321.0004272460938, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 177.33334350585938, + "seed": 2080241955, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 89, + "versionNonce": 1224348965, + "isDeleted": false, + "id": "uC3ZSm-IltHDllxDGLJ9v", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2061.749616622925, + "y": 1459.3337860107422, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 103.33331298828125, + "height": 104.66668701171875, + "seed": 687885357, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": { + "elementId": "-dLa28cPs8d1YMU273D-q", + "focus": 3.424460294999428, + "gap": 11.855942213284369 + }, + "endBinding": { + "elementId": "0kWlc6iPzGzhrfIVEPeOM", + "focus": 0.1363752482649436, + "gap": 1.5828227996826172 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 103.33331298828125, + 64.66668701171875 + ], + [ + 67.3333740234375, + 104.66668701171875 + ] + ] + }, + { + "type": "text", + "version": 107, + "versionNonce": 1798896555, + "isDeleted": false, + "id": "Ba0bmo-eQQnhNNi6zcCzg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2259.0828075408936, + "y": 1502.6670684814453, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 177, + "height": 40, + "seed": 1174246765, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": " uint8 *load_addr;\n uint64 load_size;", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " uint8 *load_addr;\n uint64 load_size;" + }, + { + "type": "rectangle", + "version": 43, + "versionNonce": 1034299525, + "isDeleted": false, + "id": "SOEOh6pxx-gC9L5EGGFZb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2247.082929611206, + "y": 1502.6670684814453, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 256, + "height": 38, + "seed": 1478394307, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 17, + "versionNonce": 1972522571, + "isDeleted": false, + "id": "KcLwCwuZF-_XQTvbSOePf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2267.7495555877686, + "y": 1506.6670684814453, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 17.3333740234375, + "height": 13.333343505859375, + "seed": 1278561005, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 58, + "versionNonce": 507039717, + "isDeleted": false, + "id": "f7JIg_N3m3yBHDkQvlpUn", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2275.7495555877686, + "y": 1510.6670684814453, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 63.33331298828125, + "height": 94.00003051757812, + "seed": 646153155, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -63.33331298828125, + 70 + ], + [ + -19.33331298828125, + 94.00003051757812 + ] + ] + }, + { + "type": "text", + "version": 331, + "versionNonce": 443043051, + "isDeleted": false, + "id": "epVvbDyPF40MaERFnDDJy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1858.9132976531982, + "y": 1828.5115061442057, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 238, + "height": 20, + "seed": 2133258755, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "CUEfVWpVIuIHc_5h3VskN", + "type": "arrow" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunction (second module)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction (second module)" + }, + { + "type": "text", + "version": 36, + "versionNonce": 1488948037, + "isDeleted": false, + "id": "iSNS4LqcpEqsBWT3JrhTG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1985.4163494110107, + "y": 1302.0003509521484, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 176, + "height": 20, + "seed": 895067437, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::functions", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::functions" + }, + { + "type": "text", + "version": 58, + "versionNonce": 1027962763, + "isDeleted": false, + "id": "zzptLpjImiiG1vPCDIGPS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2788.5657176971436, + "y": 1386.4003204345704, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 185, + "height": 20, + "seed": 510558371, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::func_ptrs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::func_ptrs" + }, + { + "type": "text", + "version": 84, + "versionNonce": 1033362085, + "isDeleted": false, + "id": "QPiZaCnPYGIz7ApGqrktI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2629.160482406616, + "y": 1451.7336334228517, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 160, + "height": 40, + "seed": 1301033645, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::\nfast_jit_func_ptrs", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::\nfast_jit_func_ptrs" + }, + { + "type": "rectangle", + "version": 444, + "versionNonce": 1818512939, + "isDeleted": false, + "id": "bGS26pMiud1SV_QZasA4k", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 753.6687545776367, + "y": 1354.399984741211, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 140.66668701171875, + "height": 32.33331298828126, + "seed": 1104978987, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "E9Lf0GGwiMXE7OEKmLBD0" + } + ], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 223, + "versionNonce": 498422861, + "isDeleted": false, + "id": "E9Lf0GGwiMXE7OEKmLBD0", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 784.0020980834961, + "y": 1360.0666412353517, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 20, + "seed": 1389316101, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679537247214, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_ptrs", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bGS26pMiud1SV_QZasA4k", + "originalText": "func_ptrs" + }, + { + "type": "diamond", + "version": 480, + "versionNonce": 179261643, + "isDeleted": false, + "id": "3V5jOnV9GBHrydrWDjdlN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 764.3353805541992, + "y": 1366.7332977294923, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 2058151627, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 64, + "versionNonce": 927151461, + "isDeleted": false, + "id": "Ej1XTEhuVY9wBpKERi-1L", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 772.668815612793, + "y": 1274.0665191650392, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 140, + "height": 20, + "seed": 1144833349, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "import_func_ptrs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "import_func_ptrs" + }, + { + "type": "rectangle", + "version": 521, + "versionNonce": 50715531, + "isDeleted": false, + "id": "OFyAqRR6a69cDApnQUNYF", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 735.2243474324545, + "y": 1412.3998321533204, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 185.3334045410156, + "height": 34.99996948242188, + "seed": 1243189643, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533960843, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 511, + "versionNonce": 2105521829, + "isDeleted": false, + "id": "Nv_mYV9MitkgQQoVIZJ9H", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 737.8910039265951, + "y": 1424.3998321533204, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1000679467, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533960843, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 85, + "versionNonce": 1685598763, + "isDeleted": false, + "id": "sB-lDN4LgjZtFuvGEHopU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 753.8910039265951, + "y": 1421.2331756591798, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 160, + "height": 20, + "seed": 967892165, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "WmAyzG_eOk5gu9ag2e4NN", + "type": "arrow" + } + ], + "updated": 1679533960843, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "fast_jit_func_ptrs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "fast_jit_func_ptrs" + }, + { + "type": "rectangle", + "version": 247, + "versionNonce": 1175609515, + "isDeleted": false, + "id": "bEyCLX9k_ShKiQzS-ZFKc", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 871.6685104370117, + "y": 1862.1498245239259, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1755598347, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929334, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 231, + "versionNonce": 591500165, + "isDeleted": false, + "id": "mz6MyUFqd-cTtlX0HmAqX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 895.6685104370117, + "y": 1869.8164810180665, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 488090661, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 266, + "versionNonce": 1509364555, + "isDeleted": false, + "id": "i6UWgN6SrSs9asopho9X_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 871.3351364135742, + "y": 1895.3164505004884, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 581194923, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 252, + "versionNonce": 858708709, + "isDeleted": false, + "id": "OxO-Lw3MtI3B3_yxI_9BQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 895.3351364135742, + "y": 1902.983106994629, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 133750661, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 255, + "versionNonce": 2146202091, + "isDeleted": false, + "id": "Av0IXtuoDwPzsT4d4ZD9r", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 871.001823425293, + "y": 1928.6497940063477, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 942311243, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 265, + "versionNonce": 414987845, + "isDeleted": false, + "id": "zsHPiP1O3kL8Jo_YTK1SB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 869.6684494018555, + "y": 1956.3164505004884, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 454862565, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 246, + "versionNonce": 150797451, + "isDeleted": false, + "id": "QkKoENHz9noDS00xsmwGp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 892.3351364135742, + "y": 1964.6497940063477, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 798057963, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 258, + "versionNonce": 1321674149, + "isDeleted": false, + "id": "8h3LnYKSejC6NlmCDjN_T", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 893.6685104370117, + "y": 1933.5664962768556, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1494254149, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 127, + "versionNonce": 1469009605, + "isDeleted": false, + "id": "8FJ9nE4COwUuKYB0Fjze2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 843.3352890014648, + "y": 1851.0666336059571, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 160.99990844726562, + "seed": 1608741003, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "WmAyzG_eOk5gu9ag2e4NN", + "type": "arrow" + }, + { + "id": "Xr0h90XMpFNQFRcVNp-Qb", + "type": "arrow" + } + ], + "updated": 1679534054366, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 103, + "versionNonce": 410855685, + "isDeleted": false, + "id": "xkXUNjzkhjNlrNaWU9GPX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 826.6688613891602, + "y": 1811.3999618530274, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174, + "height": 40, + "seed": 380760485, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstance::\nfast_jit_func_ptrs", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance::\nfast_jit_func_ptrs" + }, + { + "type": "arrow", + "version": 98, + "versionNonce": 1677433349, + "isDeleted": false, + "id": "WmAyzG_eOk5gu9ag2e4NN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 742.8910344441732, + "y": 1433.2344728128833, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 187.33331298828125, + "height": 431.9987943990309, + "seed": 471597803, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533960844, + "link": null, + "locked": false, + "startBinding": { + "elementId": "sB-lDN4LgjZtFuvGEHopU", + "focus": 1.017117824752581, + "gap": 10.999969482421875 + }, + "endBinding": { + "elementId": "8FJ9nE4COwUuKYB0Fjze2", + "focus": 0.09986159259017957, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -87.5555318196615, + 110.66535934043713 + ], + [ + -41.555531819661496, + 281.99876388145276 + ], + [ + 99.77778116861975, + 431.9987943990309 + ] + ] + }, + { + "type": "rectangle", + "version": 261, + "versionNonce": 227189867, + "isDeleted": false, + "id": "AXS2auzqFNZS35F2ixu8Z", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1039.001808166504, + "y": 1963.98309173584, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1019623493, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 245, + "versionNonce": 1630563269, + "isDeleted": false, + "id": "cjLfuQX8dFdgByjdkn0sY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1063.001808166504, + "y": 1971.6497482299806, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 67902091, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 280, + "versionNonce": 1496375051, + "isDeleted": false, + "id": "O8ko0NdUbnEnqQSXbDcTn", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1038.6684341430664, + "y": 1997.1497177124024, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 641787813, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 266, + "versionNonce": 907586341, + "isDeleted": false, + "id": "MK_yFDygTjEm7c4A1RI_A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1062.6684341430664, + "y": 2004.816374206543, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 140415275, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 269, + "versionNonce": 1433847211, + "isDeleted": false, + "id": "IpQhaQLL8LX1JsLCZTqHR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1038.3351211547852, + "y": 2030.4830612182618, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 527346437, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 279, + "versionNonce": 1988230789, + "isDeleted": false, + "id": "G_B8CuUKKojKnmDg-blQS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1037.0017471313477, + "y": 2058.1497177124024, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1416180683, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 261, + "versionNonce": 696703051, + "isDeleted": false, + "id": "bubXHX2zzv6QsRGmmBlvp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1059.6684341430664, + "y": 2066.483061218262, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1758265957, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "kjpM2qWJqDrV-jr9XK8QR", + "type": "arrow" + } + ], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 272, + "versionNonce": 959047141, + "isDeleted": false, + "id": "p2Ps7ouZR4NFea5dxTpPY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1061.001808166504, + "y": 2035.3997634887696, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 407274091, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 142, + "versionNonce": 161780453, + "isDeleted": false, + "id": "PZQU4Sc5stYlZLaGSiYZg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1010.668586730957, + "y": 1952.8999008178712, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 160.99990844726562, + "seed": 1462332869, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "eXEUtswyqJzZHgjz8P_J5", + "type": "arrow" + }, + { + "id": "BcRoQEkrTOTzUxX-Uw8S8", + "type": "arrow" + } + ], + "updated": 1679534050516, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 119, + "versionNonce": 1629348165, + "isDeleted": false, + "id": "RolknO7AhmdfdQTNiXJ8F", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 994.0021591186523, + "y": 1913.2332290649415, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174, + "height": 40, + "seed": 482409739, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "eXEUtswyqJzZHgjz8P_J5", + "type": "arrow" + } + ], + "updated": 1679533929335, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstance::\nfunc_ptrs", + "baseline": 34, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance::\nfunc_ptrs" + }, + { + "type": "rectangle", + "version": 222, + "versionNonce": 824148363, + "isDeleted": false, + "id": "p5TPteQC3PraRMJtt4XsT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 897.2243372599283, + "y": 1585.9554707845052, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 74.666748046875, + "height": 160.99990844726562, + "seed": 727269189, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "yu3un9i0kAGrZ8bAnVMa3", + "type": "arrow" + } + ], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 444, + "versionNonce": 841297547, + "isDeleted": false, + "id": "eXEUtswyqJzZHgjz8P_J5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 771.3355026245117, + "y": 1374.8998474121095, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 384.88897705078125, + "height": 633.6667022705078, + "seed": 539008875, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533948630, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "PZQU4Sc5stYlZLaGSiYZg", + "focus": 0.2318272147781851, + "gap": 3.3330230712890625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -148.888916015625, + 184.1111602783203 + ], + [ + 15.555613199869754, + 612.4444732666016 + ], + [ + 236.00006103515625, + 633.6667022705078 + ] + ] + }, + { + "type": "arrow", + "version": 83, + "versionNonce": 745347115, + "isDeleted": false, + "id": "kjpM2qWJqDrV-jr9XK8QR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1063.3354822794595, + "y": 2044.0108703613284, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 1343.333333333333, + "height": 143.33333333333326, + "seed": 738327429, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false, + "startBinding": { + "elementId": "bubXHX2zzv6QsRGmmBlvp", + "focus": -3.5383188444895577, + "gap": 13.041657453315548 + }, + "endBinding": { + "elementId": "bu6GnR96DeCSFWu3DhMIJ", + "focus": -0.1414139865892621, + "gap": 14.399755859375318 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 790, + 23.888905843098883 + ], + [ + 1343.333333333333, + -119.44442749023438 + ] + ] + }, + { + "type": "text", + "version": 258, + "versionNonce": 1857033221, + "isDeleted": false, + "id": "VCjoZw1mwV4c94ES2JChm", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 708.2243372599285, + "y": 1804.0109212239581, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 68, + "height": 20, + "seed": 1329151115, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(void **)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(void **)" + }, + { + "type": "text", + "version": 317, + "versionNonce": 588176075, + "isDeleted": false, + "id": "8pDOO3W9GlOqpH8OfM3H_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1274.502098083496, + "y": 1674.5109720865876, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 246, + "height": 19, + "seed": 73971563, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679533929335, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModuleInstance(second)", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance(second)" + }, + { + "type": "rectangle", + "version": 271, + "versionNonce": 2113489765, + "isDeleted": false, + "id": "Rcref7JZ-AhlcXLLdwY5D", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1264.668805440267, + "y": 1697.4554453531891, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 270.66663614908845, + "height": 194.22224934895837, + "seed": 635278027, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "MLVyGZQLa4jU554J6bsmJ", + "type": "arrow" + } + ], + "updated": 1679533929335, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 226, + "versionNonce": 1289066309, + "isDeleted": false, + "id": "CZNopRssr82fjSim4TRBD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 601.1133956909175, + "y": 2080.3445597330715, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 335, + "height": 20, + "seed": 556524395, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679534038146, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "function pointer arrays for faster access", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "function pointer arrays for faster access" + }, + { + "type": "rectangle", + "version": 45, + "versionNonce": 815465317, + "isDeleted": false, + "id": "J2L3EeElp1XhI1X3IbanK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 578.8910547892249, + "y": 2055.122269694009, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 364.4444274902344, + "height": 58.33338419596339, + "seed": 1181100939, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "BcRoQEkrTOTzUxX-Uw8S8", + "type": "arrow" + }, + { + "id": "Xr0h90XMpFNQFRcVNp-Qb", + "type": "arrow" + } + ], + "updated": 1679534054366, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 33, + "versionNonce": 57793355, + "isDeleted": false, + "id": "BcRoQEkrTOTzUxX-Uw8S8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 944.4466272989905, + "y": 2095.1223205566394, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 63.33333333333326, + "height": 19.444478352864735, + "seed": 132937093, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679534050516, + "link": null, + "locked": false, + "startBinding": { + "elementId": "J2L3EeElp1XhI1X3IbanK", + "focus": 0.788606211312463, + "gap": 1.11114501953125 + }, + "endBinding": { + "elementId": "PZQU4Sc5stYlZLaGSiYZg", + "focus": -0.2743956700481259, + "gap": 2.8886260986332672 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 63.33333333333326, + -19.444478352864735 + ] + ] + }, + { + "type": "arrow", + "version": 24, + "versionNonce": 2098532715, + "isDeleted": false, + "id": "Xr0h90XMpFNQFRcVNp-Qb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 786.6688156127926, + "y": 2054.011175537108, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 55.555572509765625, + "height": 45.00000000000023, + "seed": 1053702635, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679534054366, + "link": null, + "locked": false, + "startBinding": { + "elementId": "J2L3EeElp1XhI1X3IbanK", + "focus": -0.054183297415777855, + "gap": 1.1110941569011175 + }, + "endBinding": { + "elementId": "8FJ9nE4COwUuKYB0Fjze2", + "focus": -0.3037089268567984, + "gap": 1.110900878906591 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 55.555572509765625, + -45.00000000000023 + ] + ] + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/core/iwasm/doc/images/wasm_function.svg b/core/iwasm/doc/images/wasm_function.svg new file mode 100644 index 000000000..86fdf78ad --- /dev/null +++ b/core/iwasm/doc/images/wasm_function.svg @@ -0,0 +1,16 @@ + + + + + + + WASMFunctionInstancefunc_importWASMFunctionImport:funcWASMFunction (per module)internal function char *module_name; char *field_name;func_ptr_linkednative function:import_module;import_func_linked;(WASMFunction *)codebytecodecode_compiledprecompiled-bytecodefast_jit_jitted_codellvm_jit_func_ptrfast jitted coodellvm jitted coodeimport_module_inst;import_func_inst;functionsglobalseWASMModuleInstanceExtraWASMModuleInstance::import_func_ptrsthis is the one actually referred during executing opcodeduring model load, if import can be solved through the native api registeration,the pointer of native function will be filled.c-api could change the pointer later, then it will point to a different native functionNULL: means multi-module import, go to "import_func_inst" field for target functionWASMModuleInstance*(WASMFunctionInstance*)func_importfuncWASMFunction union[...][0]WASMModuleInstance[..][n](void *)(void **)NULLfunc_type_indexesuint32 *WASMModule WASMImport *import_tables; WASMImport *import_memories; WASMImport *import_globals; WASMType **types; WASMImport *imports; WASMTable *tables; WASMMemory *memories; WASMGlobal *globals; WASMExport *exports; WASMTableSeg *table_segments; WASMDataSeg **data_segments;WASMFunction **functions;WASMImport *import_functions;WASMImportuint8 kind[1][0][...]fast_jit_func_ptrs(void **)func_ptrs(void **) uint8 *load_addr; uint64 load_size;WASMFunction (second module)WASMModule::functionsWASMModule::func_ptrsWASMModule::fast_jit_func_ptrsfunc_ptrsimport_func_ptrsfast_jit_func_ptrsWASMModuleInstance::fast_jit_func_ptrsWASMModuleInstance::func_ptrs(void **)WASMModuleInstance(second)function pointer arrays for faster access \ No newline at end of file diff --git a/core/iwasm/doc/wasm_function.MD b/core/iwasm/doc/wasm_function.MD new file mode 100644 index 000000000..7655ffbfe --- /dev/null +++ b/core/iwasm/doc/wasm_function.MD @@ -0,0 +1,5 @@ +# Wasm Function + +## Internal data structure + +![](./images/wasm_function.svg) From bfbe51e1b379a233963d0101145b4728181ed77b Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Thu, 23 Mar 2023 07:10:47 +0100 Subject: [PATCH 16/61] fix debugger: Set termination flags also when in debug mode (#2048) When using multiple threads, termination flags are checked to stop the thread if a `proc_exit` or trap occurs. They have to be set also in debug mode. Tested using [WASI thread tests](https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/core/iwasm/libraries/lib-wasi-threads/test). --- core/iwasm/libraries/thread-mgr/thread_manager.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 5e2acdbcd..2bcdba3bd 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -988,12 +988,12 @@ static void set_thread_cancel_flags(WASMExecEnv *exec_env) { os_mutex_lock(&exec_env->wait_lock); - /* Set the termination flag */ + #if WASM_ENABLE_DEBUG_INTERP != 0 wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); -#else - exec_env->suspend_flags.flags |= 0x01; #endif + exec_env->suspend_flags.flags |= 0x01; + os_mutex_unlock(&exec_env->wait_lock); } From db2a4104b3fb4af18d55eb2ca23290734ba876f8 Mon Sep 17 00:00:00 2001 From: Wang Xin Date: Thu, 23 Mar 2023 17:13:17 +0800 Subject: [PATCH 17/61] Add architecture document for wasm export (#2049) --- core/iwasm/README.md | 2 + .../doc/images/export_function.excalidraw | 5695 +++++++++++++++++ core/iwasm/doc/images/wasm_exports.svg | 16 + core/iwasm/doc/wasm_exports.MD | 22 + 4 files changed, 5735 insertions(+) create mode 100644 core/iwasm/doc/images/export_function.excalidraw create mode 100644 core/iwasm/doc/images/wasm_exports.svg create mode 100644 core/iwasm/doc/wasm_exports.MD diff --git a/core/iwasm/README.md b/core/iwasm/README.md index 55e864990..31253c6ed 100644 --- a/core/iwasm/README.md +++ b/core/iwasm/README.md @@ -4,3 +4,5 @@ ## Wasm function - [Wasm function architecture](./doc/wasm_function.MD) +## Exports +- [Wasm export architecture](./doc/wasm_exports.MD) diff --git a/core/iwasm/doc/images/export_function.excalidraw b/core/iwasm/doc/images/export_function.excalidraw new file mode 100644 index 000000000..b983af05b --- /dev/null +++ b/core/iwasm/doc/images/export_function.excalidraw @@ -0,0 +1,5695 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "type": "rectangle", + "version": 469, + "versionNonce": 587617691, + "isDeleted": false, + "id": "YQFdEhDm9LI_5UD2YjLU-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 238.99996948242188, + "y": 207.16673278808577, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 221.3333740234375, + "height": 94.629648844401, + "seed": 1964509979, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 318, + "versionNonce": 929539477, + "isDeleted": false, + "id": "pDkkkqvgrizIP6AYdFbkj", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 239.66665649414062, + "y": 161.83335876464827, + "strokeColor": "#1864ab", + "backgroundColor": "transparent", + "width": 96, + "height": 19, + "seed": 278267925, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModule", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule" + }, + { + "type": "rectangle", + "version": 592, + "versionNonce": 276752955, + "isDeleted": false, + "id": "awCpIZpFN-gQRBgh6iG1X", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 228.33334350585938, + "y": 191.50007629394514, + "strokeColor": "#1864ab", + "backgroundColor": "transparent", + "width": 247.11109754774304, + "height": 265.6667175292969, + "seed": 1908273083, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 411, + "versionNonce": 1793600245, + "isDeleted": false, + "id": "TOmX9MwwNOgbfjNJ8V8j7", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 239.4444953070747, + "y": 233.9815283881292, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 211, + "height": 56, + "seed": 86392181, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "2NQmRBF_NE2Myp3-jqLfT", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": " WASMTable *tables;\n WASMMemory *memories;\n WASMGlobal *globals;", + "baseline": 52, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": " WASMTable *tables;\n WASMMemory *memories;\n WASMGlobal *globals;" + }, + { + "type": "text", + "version": 390, + "versionNonce": 1283272731, + "isDeleted": false, + "id": "FPUGB-iP7ep91gfoTuV2d", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 289.3334045410156, + "y": 374.1667327880857, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 165, + "height": 19, + "seed": 504570933, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "OdDm5a5O_NIoZbF3u0c0H", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExport *exports;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExport *exports;" + }, + { + "type": "rectangle", + "version": 371, + "versionNonce": 692171541, + "isDeleted": false, + "id": "iP-OL8X-L4CE8z9CTp9qG", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 243.66677856445312, + "y": 359.5001068115232, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 216, + "height": 42.6666259765625, + "seed": 1531454875, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 336, + "versionNonce": 1261860027, + "isDeleted": false, + "id": "jkgMB1VHPK6x-xD6Wuey7", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 258.3335266113281, + "y": 370.16679382324196, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 15.33331298828125, + "height": 22.66668701171875, + "seed": 2028656021, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 286, + "versionNonce": 1775181787, + "isDeleted": false, + "id": "v4paccURicZAp-WeQNnlQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 585.7036675347218, + "y": 278.944342719184, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 156, + "height": 128.33334350585938, + "seed": 766182741, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 176, + "versionNonce": 907517781, + "isDeleted": false, + "id": "blxQLl_yf7DMD76qHC5rc", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 587.9629041883677, + "y": 256.3147176106771, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 97, + "height": 19, + "seed": 1409110677, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "OdDm5a5O_NIoZbF3u0c0H", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExport", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExport" + }, + { + "type": "text", + "version": 216, + "versionNonce": 271871099, + "isDeleted": false, + "id": "xQPYBI_XdfyZkh2-U_YQB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 617.3703240288627, + "y": 289.2776862250434, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 88, + "height": 19, + "seed": 1776880725, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "char *name;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "char *name;" + }, + { + "type": "text", + "version": 241, + "versionNonce": 217246901, + "isDeleted": false, + "id": "lB_sRHE0gMYdFdpT2Dvja", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 614.7036370171439, + "y": 321.6110602484809, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 75, + "height": 19, + "seed": 1312575355, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "uint8 kind;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "uint8 kind;" + }, + { + "type": "text", + "version": 230, + "versionNonce": 562504987, + "isDeleted": false, + "id": "SQI7khDAbJL0pLh0deiej", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 610.0369805230033, + "y": 354.944342719184, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 93, + "height": 19, + "seed": 2114894261, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "C_HvFqwDiW4wGe01QNKFg", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "uint32 index;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "uint32 index;" + }, + { + "type": "rectangle", + "version": 188, + "versionNonce": 2042465813, + "isDeleted": false, + "id": "sqBZGoR4vKErEsSE7jSJk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 601.0370110405812, + "y": 284.9443579779731, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 120.66668701171875, + "height": 29.666671752929688, + "seed": 1817827573, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 255, + "versionNonce": 892979643, + "isDeleted": false, + "id": "xy3rvXCHxwYSjuQZAaa0Y", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 601.7036675347218, + "y": 320.6110602484809, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 26.33331298828125, + "seed": 1394813013, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 190, + "versionNonce": 728564597, + "isDeleted": false, + "id": "noIblgsWe1zKM-bENF8Ev", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 599.0370110405812, + "y": 351.61102973090277, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 126, + "height": 29.666656494140625, + "seed": 410891355, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 174, + "versionNonce": 1447480533, + "isDeleted": false, + "id": "q8XZjMjkc5oaR7KNqOcGF", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 654.3703545464408, + "y": 385.7777167426215, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 20, + "height": 19, + "seed": 1931744507, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "[0]", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 177, + "versionNonce": 804837115, + "isDeleted": false, + "id": "cywWwhg521rh-6jpDBbTE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 586.3703240288625, + "y": 407.94437323676215, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 158, + "height": 42, + "seed": 19921979, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "8dd-iKzlb9Z4V1eqnx9a-" + } + ], + "updated": 1679555887720, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 152, + "versionNonce": 165702197, + "isDeleted": false, + "id": "8dd-iKzlb9Z4V1eqnx9a-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 655.3703240288627, + "y": 419.44437323676215, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 20, + "height": 19, + "seed": 1593993467, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887720, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "[1]", + "baseline": 15, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cywWwhg521rh-6jpDBbTE", + "originalText": "[1]" + }, + { + "type": "rectangle", + "version": 191, + "versionNonce": 1381646235, + "isDeleted": false, + "id": "SsP3zaE3LuSyRa2Ma4ffB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 587.3703240288625, + "y": 450.94437323676215, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 158, + "height": 42, + "seed": 1216947029, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "Ux1Agae75_DS0veGHXMuH" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 169, + "versionNonce": 1193237397, + "isDeleted": false, + "id": "Ux1Agae75_DS0veGHXMuH", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 654.3703240288627, + "y": 462.44437323676215, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 24, + "height": 19, + "seed": 982329467, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "[...]", + "baseline": 15, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "SsP3zaE3LuSyRa2Ma4ffB", + "originalText": "[...]" + }, + { + "type": "text", + "version": 248, + "versionNonce": 1555249749, + "isDeleted": false, + "id": "o7FaW1SjzOKpt86xZNbly", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -71.58126068115234, + "y": 146.11661834716801, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 171, + "height": 19, + "seed": 1768482683, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModuleInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance" + }, + { + "type": "rectangle", + "version": 131, + "versionNonce": 1297489444, + "isDeleted": false, + "id": "MC9rQuxIk7iVRtsas7ICs", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -73.99992370605469, + "y": 180.9666107177734, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 210.66668701171875, + "height": 314.33334350585943, + "seed": 1805099445, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558426546, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 473, + "versionNonce": 1484728732, + "isDeleted": false, + "id": "6pGqkyRY8AHL4k5LTJ0Yl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -51.000274658203125, + "y": 425.4667785644531, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 31.666625976562507, + "seed": 957429083, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558303924, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 499, + "versionNonce": 1368837668, + "isDeleted": false, + "id": "cDohxEkx3HhhoX-zcCc9Q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -45.666961669921875, + "y": 433.1334350585937, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 63676885, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558303924, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 208, + "versionNonce": 1386190364, + "isDeleted": false, + "id": "kOP_SYX2hDGyTbKOLrSY7", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -25.66693115234375, + "y": 429.9667785644531, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 115, + "height": 20, + "seed": 697815547, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "xGVX08X1n0JU0OA60_t9A", + "type": "arrow" + } + ], + "updated": 1679558303924, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_tables", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_tables" + }, + { + "type": "rectangle", + "version": 534, + "versionNonce": 1960518965, + "isDeleted": false, + "id": "FnISIa4MPRb3okZ9nUHSQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -58.66651916503906, + "y": 359.8333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 31.666625976562507, + "seed": 1723426171, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 562, + "versionNonce": 901559451, + "isDeleted": false, + "id": "KPco9Nm_8Olmg0Uq3NVQ1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -53.33320617675781, + "y": 367.5000305175781, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 135660469, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 260, + "versionNonce": 420132501, + "isDeleted": false, + "id": "8KE83CX20gDJQwJueCKwN", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -39.33323669433594, + "y": 365.66668701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 131, + "height": 20, + "seed": 788856347, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "v2uiV8UbBxa6_yEOLAehf", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_memories", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_memories" + }, + { + "type": "rectangle", + "version": 477, + "versionNonce": 1527867707, + "isDeleted": false, + "id": "_CbJcjswexYEsNuWct5mC", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -51.99998474121094, + "y": 189.83334350585938, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 31.666625976562507, + "seed": 1344002453, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 505, + "versionNonce": 671161333, + "isDeleted": false, + "id": "hGw4Pp4LnIpkfSfU4PeRb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -46.66667175292969, + "y": 197.5, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 861402683, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 213, + "versionNonce": 690391515, + "isDeleted": false, + "id": "67MrbK1oKDTBrmUzIQlr1", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -26.666641235351562, + "y": 194.33334350585938, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 20, + "seed": 1190518517, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_globals", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_globals" + }, + { + "type": "rectangle", + "version": 400, + "versionNonce": 1237570901, + "isDeleted": false, + "id": "eMcaE0yc0BCbsQ4MrLuGP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -51.33323669433594, + "y": 271.8333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 31.666625976562507, + "seed": 1337283029, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 429, + "versionNonce": 84842107, + "isDeleted": false, + "id": "rW76UbdBzelN0CWuqQjTc", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -45.99992370605469, + "y": 279.5000305175781, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 778117627, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4eMPasZehGc58H7vVusCf", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 136, + "versionNonce": 162030261, + "isDeleted": false, + "id": "NfPonNQyhbRCCPh50Ed7I", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -25.999893188476562, + "y": 276.3333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 136, + "height": 20, + "seed": 1026969397, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4eMPasZehGc58H7vVusCf", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_functions", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_functions" + }, + { + "type": "text", + "version": 121, + "versionNonce": 227282715, + "isDeleted": false, + "id": "ILDnCNxtBv4qdrhMb3QoZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -365.33335876464844, + "y": 193.1666259765625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 193, + "height": 19, + "seed": 282525979, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExportFuncInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExportFuncInstance" + }, + { + "type": "rectangle", + "version": 201, + "versionNonce": 1817461781, + "isDeleted": false, + "id": "2agHBzF-91Fb2ws0hYObd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -354.33335876464844, + "y": 223.83334350585938, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 177.33331298828122, + "height": 121.00006103515625, + "seed": 1290367509, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4eMPasZehGc58H7vVusCf", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 176, + "versionNonce": 1961256348, + "isDeleted": false, + "id": "aZL7IU5LEszDJmyyWcmtp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -340.6666717529297, + "y": 239.83328247070312, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 31, + "seed": 1714300347, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "P3_9LebxO4r1Nud8xISGk" + }, + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + } + ], + "updated": 1679558297714, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 194, + "versionNonce": 2136035876, + "isDeleted": false, + "id": "P3_9LebxO4r1Nud8xISGk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -334.6666717529297, + "y": 244.83328247070312, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 21, + "seed": 2004641653, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297727, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "char* name ", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "aZL7IU5LEszDJmyyWcmtp", + "originalText": "char* name " + }, + { + "type": "diamond", + "version": 159, + "versionNonce": 1002521691, + "isDeleted": false, + "id": "qdga26-o2AGoXkwH2yP4N", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -323.00001525878906, + "y": 284.1666259765625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 14.666656494140625, + "height": 17.666656494140625, + "seed": 444053083, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 216, + "versionNonce": 1328022229, + "isDeleted": false, + "id": "2onXRIpW3Znosk6O46QtY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -338.33335876464844, + "y": 276.49993896484375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 38, + "seed": 852078805, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "Zrwh0TsrNxBSNhpJZIqbu" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 183, + "versionNonce": 1455378972, + "isDeleted": false, + "id": "Zrwh0TsrNxBSNhpJZIqbu", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -305.83335876464844, + "y": 285.49993896484375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 63, + "height": 21, + "seed": 2089169659, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297728, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "function", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "2onXRIpW3Znosk6O46QtY", + "originalText": "function" + }, + { + "type": "arrow", + "version": 505, + "versionNonce": 2099961909, + "isDeleted": false, + "id": "nG4vs8WttuFFZPXDKIdNr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -320.33335876464844, + "y": 293.49993896484375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 111.00001525878906, + "height": 184.2470495648475, + "seed": 476499509, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "7JcYtZ-KQ0WF1SDFDwvcV", + "gap": 1.2531640581994319, + "focus": -0.8059388021902064 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -111.00001525878906, + 33.166717529296875 + ], + [ + -35.26115412319115, + 184.2470495648475 + ] + ] + }, + { + "type": "text", + "version": 531, + "versionNonce": 363532693, + "isDeleted": false, + "id": "7MNv-pmgV4-8yJ5lIFY1U", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 496.5186225043402, + "y": 71.31480577256946, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 235, + "height": 149, + "seed": 2074251419, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + }, + { + "id": "2NQmRBF_NE2Myp3-jqLfT", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "name: shown to external\nindex: refer to item idx for export \n in current kind\nkind: total 4 export kinds:\n- function\n- globals\n- memory\n- table", + "baseline": 145, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "name: shown to external\nindex: refer to item idx for export \n in current kind\nkind: total 4 export kinds:\n- function\n- globals\n- memory\n- table" + }, + { + "type": "rectangle", + "version": 81, + "versionNonce": 997735995, + "isDeleted": false, + "id": "orpW0tFerpELyreVDruzO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -353.3333740234375, + "y": 343.99998474121094, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 940489147, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "KlcGzdua5BpLa_-0RGeFO" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 53, + "versionNonce": 1965780388, + "isDeleted": false, + "id": "KlcGzdua5BpLa_-0RGeFO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -274.3333740234375, + "y": 350.1666564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 21, + "seed": 1399452699, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297729, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "orpW0tFerpELyreVDruzO", + "originalText": "[1]" + }, + { + "type": "text", + "version": 71, + "versionNonce": 1609219803, + "isDeleted": false, + "id": "da0XYl9R6gkV-BQ4X1JdF", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -278.166748046875, + "y": 324.33338928222656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 848835675, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 109, + "versionNonce": 528755579, + "isDeleted": false, + "id": "oVhH9XqC6rs2uaPMH4x2B", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -353.0001220703125, + "y": 377.50006103515625, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 1099143605, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "wu6BDVXXPWLo-Z-l7TYGW" + }, + { + "id": "Eda9W8eaZom6PATRAm5EX", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 83, + "versionNonce": 1472638620, + "isDeleted": false, + "id": "wu6BDVXXPWLo-Z-l7TYGW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -278.5001220703125, + "y": 383.66673278808594, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 21, + "seed": 1029949467, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297730, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "oVhH9XqC6rs2uaPMH4x2B", + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 134, + "versionNonce": 1882593572, + "isDeleted": false, + "id": "t8xOhAVyJcx51xJsmWC6j", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -352.33331298828125, + "y": 408.5001220703125, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 31, + "seed": 883564757, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "F09zazRYIO_G3oM7DmBbr" + }, + { + "id": "Eda9W8eaZom6PATRAm5EX", + "type": "arrow" + } + ], + "updated": 1679558297730, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 111, + "versionNonce": 1756265244, + "isDeleted": false, + "id": "F09zazRYIO_G3oM7DmBbr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -274.83331298828125, + "y": 418.5001220703125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 25, + "height": 21, + "seed": 1529135867, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297738, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[n]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "t8xOhAVyJcx51xJsmWC6j", + "originalText": "[n]" + }, + { + "type": "line", + "version": 284, + "versionNonce": 350603451, + "isDeleted": false, + "id": "XphCtXmoQONIDWT15UPmf", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 169.00015258789057, + "y": 21.389623853895444, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 1.66656494140625, + "height": 838.3330154418943, + "seed": 395797243, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 1.66656494140625, + 838.3330154418943 + ] + ] + }, + { + "type": "arrow", + "version": 156, + "versionNonce": 1808036981, + "isDeleted": false, + "id": "4eMPasZehGc58H7vVusCf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -40.66667175292969, + "y": 278.5517677558588, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 133.01236173861167, + "height": 54.587889349881976, + "seed": 526956341, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "startBinding": { + "elementId": "NfPonNQyhbRCCPh50Ed7I", + "focus": -0.6897037086038879, + "gap": 14.666778564453125 + }, + "endBinding": { + "elementId": "2agHBzF-91Fb2ws0hYObd", + "focus": -1.0127197558064842, + "gap": 3.3210122848258408 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -133.01236173861167, + -54.587889349881976 + ] + ] + }, + { + "type": "rectangle", + "version": 227, + "versionNonce": 2017655131, + "isDeleted": false, + "id": "7JcYtZ-KQ0WF1SDFDwvcV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -362, + "y": 478.3334655761719, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 223.3334655761719, + "height": 33.00015258789055, + "seed": 857261429, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "nG4vs8WttuFFZPXDKIdNr", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 351, + "versionNonce": 1552424405, + "isDeleted": false, + "id": "QLOWRmBSKHUu_NrX66JPt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -355.3333740234375, + "y": 486.00006103515625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 208, + "height": 20, + "seed": 513338651, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "nG4vs8WttuFFZPXDKIdNr", + "type": "arrow" + }, + { + "id": "Vhva2LNBhtrohj4Y3bGV9", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(refer to function diagam)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(refer to function diagam)" + }, + { + "type": "text", + "version": 94, + "versionNonce": 636556795, + "isDeleted": false, + "id": "R3bNKi3-D-UlbcoafRHR5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -40.6666259765625, + "y": 316.9998779296875, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 154, + "height": 20, + "seed": 1038062939, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Eda9W8eaZom6PATRAm5EX", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_func_count", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_func_count" + }, + { + "type": "arrow", + "version": 162, + "versionNonce": 1037015861, + "isDeleted": false, + "id": "Eda9W8eaZom6PATRAm5EX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -51.354154838890395, + "y": 333.9999084472656, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 192.10502044691845, + "height": 89.91317165306509, + "seed": 518031893, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "startBinding": { + "elementId": "mZobbVjOOfzbAK_1alOcK", + "focus": 0.6974503894293331, + "gap": 1 + }, + "endBinding": { + "elementId": "oVhH9XqC6rs2uaPMH4x2B", + "focus": 0.8116332021918504, + "gap": 14.079675559315092 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -81.97918866696898, + 54.666717529296875 + ], + [ + -192.10502044691845, + 89.91317165306509 + ] + ] + }, + { + "type": "rectangle", + "version": 71, + "versionNonce": 2013293717, + "isDeleted": false, + "id": "mZobbVjOOfzbAK_1alOcK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -50.66668701171875, + "y": 311.333251953125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 172.666748046875, + "height": 31.66668701171875, + "seed": 1172380085, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Eda9W8eaZom6PATRAm5EX", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 417, + "versionNonce": 1255150069, + "isDeleted": false, + "id": "YyGWHpfM0OE4uzGAFwZ12", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 484.1481289333766, + "y": 65.53704833984384, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 287.70376925998266, + "height": 162.29637824164502, + "seed": 274906523, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 1048, + "versionNonce": 392819675, + "isDeleted": false, + "id": "YidAloK-3ikBBzvuu-S22", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 743.579402430669, + "y": 225.04108862166348, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 21.48420572561895, + "height": 53.29342358325337, + "seed": 1380550619, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "startBinding": { + "elementId": "7MNv-pmgV4-8yJ5lIFY1U", + "focus": -0.6782971803849929, + "gap": 12.953770184814061 + }, + "endBinding": { + "elementId": "sqBZGoR4vKErEsSE7jSJk", + "focus": 0.7448990456524555, + "gap": 10.515841746169144 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 10.124343093419043, + 26.347898601643806 + ], + [ + -11.359862632199906, + 53.29342358325337 + ] + ] + }, + { + "type": "text", + "version": 264, + "versionNonce": 1665403733, + "isDeleted": false, + "id": "sRzZXOvjblsPsAM89sUXa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -705.3333892822266, + "y": 113.58320617675781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 192, + "height": 19, + "seed": 700308213, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExportGlobInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExportGlobInstance" + }, + { + "type": "rectangle", + "version": 348, + "versionNonce": 1800716411, + "isDeleted": false, + "id": "xWPtNuyAqazMMUyouKnhf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -694.3333892822266, + "y": 144.2499237060547, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 177.33331298828122, + "height": 121.00006103515625, + "seed": 1037646555, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "RxhU0Qr-hmqzklRZdxsvn", + "type": "arrow" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 323, + "versionNonce": 467621028, + "isDeleted": false, + "id": "7uYVutqCDMjhS1LtgrSpl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -680.6667022705078, + "y": 160.24986267089844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 31, + "seed": 328250453, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "PlRFeDiD1tywOAk_rJgHg" + } + ], + "updated": 1679558297741, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 337, + "versionNonce": 334018460, + "isDeleted": false, + "id": "PlRFeDiD1tywOAk_rJgHg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -674.6667022705078, + "y": 165.24986267089844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 21, + "seed": 843261819, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297749, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "char* name ", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "7uYVutqCDMjhS1LtgrSpl", + "originalText": "char* name " + }, + { + "type": "diamond", + "version": 301, + "versionNonce": 2143222293, + "isDeleted": false, + "id": "01IysLeEkWSJyxI9NbVb8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -663.0000457763672, + "y": 204.5832061767578, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 14.666656494140625, + "height": 17.666656494140625, + "seed": 1686200757, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 360, + "versionNonce": 458563003, + "isDeleted": false, + "id": "lWjh1xjt4eB1XKwJJx59D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -678.3333892822266, + "y": 196.91651916503906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 38, + "seed": 671514651, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "VQ0ymOLfMpjFiupR01ZFb" + } + ], + "updated": 1679555887721, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 327, + "versionNonce": 97853476, + "isDeleted": false, + "id": "VQ0ymOLfMpjFiupR01ZFb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -637.3333892822266, + "y": 205.91651916503906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 46, + "height": 21, + "seed": 565535509, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297750, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "global", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lWjh1xjt4eB1XKwJJx59D", + "originalText": "global" + }, + { + "type": "arrow", + "version": 624, + "versionNonce": 2147462747, + "isDeleted": false, + "id": "E_RGDiJbGUf1aNH6jDnvz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -660.3333892822266, + "y": 213.91651916503906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 111.00001525878906, + "height": 176.67764729852638, + "seed": 152421563, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "KWKN5CpCB6zVtYZd6txj9", + "focus": -0.8240578974308156, + "gap": 7.457318223231596 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -111.00001525878906, + 33.166717529296875 + ], + [ + -17.790676987880033, + 176.67764729852638 + ] + ] + }, + { + "type": "rectangle", + "version": 225, + "versionNonce": 1372149301, + "isDeleted": false, + "id": "uLMWTXI90CGAIKI4zHJML", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -693.3334045410156, + "y": 264.41656494140625, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 1208836565, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "AGXBiW0dSLHn3nGEzduCY" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 196, + "versionNonce": 1168598044, + "isDeleted": false, + "id": "AGXBiW0dSLHn3nGEzduCY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -614.3334045410156, + "y": 270.58323669433594, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 21, + "seed": 324145659, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297750, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "uLMWTXI90CGAIKI4zHJML", + "originalText": "[1]" + }, + { + "type": "text", + "version": 213, + "versionNonce": 2064304021, + "isDeleted": false, + "id": "QvT_bIR-th1HBXIOu8j7Y", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -618.1667785644531, + "y": 244.74996948242188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 269246261, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 253, + "versionNonce": 630646843, + "isDeleted": false, + "id": "zom5ZNn_gBWzVI1PMMYQo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -693.0001525878906, + "y": 297.91664123535156, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 215227035, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "U2e2lWVjWzkRt9x6FkfeD" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 226, + "versionNonce": 1443199908, + "isDeleted": false, + "id": "U2e2lWVjWzkRt9x6FkfeD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -618.5001525878906, + "y": 304.08331298828125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 21, + "seed": 1845801109, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297751, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "zom5ZNn_gBWzVI1PMMYQo", + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 278, + "versionNonce": 333217948, + "isDeleted": false, + "id": "IbfRch-fWorg9yld9Wih5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -692.3333435058594, + "y": 328.9167022705078, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 31, + "seed": 1716260667, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "So5vnnPiQUj6m6ZH6HSMP" + } + ], + "updated": 1679558297752, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 254, + "versionNonce": 111044388, + "isDeleted": false, + "id": "So5vnnPiQUj6m6ZH6HSMP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -614.8333435058594, + "y": 338.9167022705078, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 25, + "height": 21, + "seed": 2141967861, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297758, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[n]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "IbfRch-fWorg9yld9Wih5", + "originalText": "[n]" + }, + { + "type": "rectangle", + "version": 257, + "versionNonce": 494949755, + "isDeleted": false, + "id": "KWKN5CpCB6zVtYZd6txj9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -670.666748046875, + "y": 392.7500457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 196.00015258789062, + "height": 39.33346557617187, + "seed": 35418075, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "E_RGDiJbGUf1aNH6jDnvz", + "type": "arrow" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 415, + "versionNonce": 964039605, + "isDeleted": false, + "id": "uEz53YqVhDB8JRuE5hMcU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -659.3334655761719, + "y": 402.41664123535156, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 164, + "height": 20, + "seed": 268914517, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMGlobalInstance", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMGlobalInstance" + }, + { + "type": "text", + "version": 236, + "versionNonce": 2005417979, + "isDeleted": false, + "id": "FiGf5f4dzHNrO5L3NMiwT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -604.5001068115234, + "y": 504.4166564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 193, + "height": 19, + "seed": 1644818613, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "v2uiV8UbBxa6_yEOLAehf", + "type": "arrow" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExportMemInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExportMemInstance" + }, + { + "type": "rectangle", + "version": 316, + "versionNonce": 1410863413, + "isDeleted": false, + "id": "tgz_9er4fEh_TbaYDZF6u", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -593.5001068115234, + "y": 535.0833740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 177.33331298828122, + "height": 121.00006103515625, + "seed": 273834267, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 295, + "versionNonce": 104467740, + "isDeleted": false, + "id": "fZ94UaMm9ypc37Hwvn9SX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -579.8334197998047, + "y": 551.0833129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 31, + "seed": 492048917, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "QBs13zYnt2LZX4M9cdFuH" + } + ], + "updated": 1679558297759, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 308, + "versionNonce": 470672036, + "isDeleted": false, + "id": "QBs13zYnt2LZX4M9cdFuH", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -573.8334197998047, + "y": 556.0833129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 21, + "seed": 524125627, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297764, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "char* name ", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "fZ94UaMm9ypc37Hwvn9SX", + "originalText": "char* name " + }, + { + "type": "diamond", + "version": 271, + "versionNonce": 424590651, + "isDeleted": false, + "id": "nqJwiZ18KG3vCMfANM8aQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -562.1667633056641, + "y": 595.4166564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 14.666656494140625, + "height": 17.666656494140625, + "seed": 563283829, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 332, + "versionNonce": 1978861557, + "isDeleted": false, + "id": "HEJvi8QjWRiMWcoZPLHIl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -577.5001068115234, + "y": 587.7499694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 38, + "seed": 983242331, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "HU6nOicEloKkqYD55hBWR" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 304, + "versionNonce": 1580337564, + "isDeleted": false, + "id": "HU6nOicEloKkqYD55hBWR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -540.5001068115234, + "y": 596.7499694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 54, + "height": 21, + "seed": 554455253, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297765, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "memory", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "HEJvi8QjWRiMWcoZPLHIl", + "originalText": "memory" + }, + { + "type": "arrow", + "version": 546, + "versionNonce": 1519927637, + "isDeleted": false, + "id": "O2ixOO7WSexT4tbgcUDGA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -559.5001068115234, + "y": 604.7499694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 111.00001525878906, + "height": 176.67764729852638, + "seed": 20812539, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "Sn4zW4Qj5F8AgPuajBnRy", + "focus": -0.8240578974308156, + "gap": 7.457318223231596 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -111.00001525878906, + 33.166717529296875 + ], + [ + -17.790676987880033, + 176.67764729852638 + ] + ] + }, + { + "type": "text", + "version": 371, + "versionNonce": 1795615355, + "isDeleted": false, + "id": "XjbCYdp81z8HsAXal748C", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -794.1667785644531, + "y": 589.7500152587891, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 190, + "height": 20, + "seed": 1767206453, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(WASMMemoryInstance*)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(WASMMemoryInstance*)" + }, + { + "type": "rectangle", + "version": 197, + "versionNonce": 1561284277, + "isDeleted": false, + "id": "8-N4VCgO26s4M3_joLoAg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -592.5001220703125, + "y": 655.2500152587891, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 329743259, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "_zHc4H95qdMAwSfBAe4ji" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 167, + "versionNonce": 1560407588, + "isDeleted": false, + "id": "_zHc4H95qdMAwSfBAe4ji", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -513.5001220703125, + "y": 661.4166870117188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 21, + "seed": 2035539861, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297766, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "8-N4VCgO26s4M3_joLoAg", + "originalText": "[1]" + }, + { + "type": "text", + "version": 183, + "versionNonce": 201175061, + "isDeleted": false, + "id": "8MK4DV6gTxwniJIipRt0r", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -517.33349609375, + "y": 635.5834197998047, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 1577799739, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 225, + "versionNonce": 313275, + "isDeleted": false, + "id": "tIAX2kAFoZpVqZ5qUAx0Z", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -592.1668701171875, + "y": 688.7500915527344, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 1463624949, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "2puZDaevwGxRcBgZ-ptc6" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 197, + "versionNonce": 1593210396, + "isDeleted": false, + "id": "2puZDaevwGxRcBgZ-ptc6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -517.6668701171875, + "y": 694.9167633056641, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 21, + "seed": 575377627, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297767, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tIAX2kAFoZpVqZ5qUAx0Z", + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 250, + "versionNonce": 174623140, + "isDeleted": false, + "id": "N0OFLsAea9yT6OuliaHBO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -591.5000610351562, + "y": 719.7501525878906, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 31, + "seed": 647413333, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "q7ppugt7g7qcpJ5yt5OdE" + } + ], + "updated": 1679558297767, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 225, + "versionNonce": 360272540, + "isDeleted": false, + "id": "q7ppugt7g7qcpJ5yt5OdE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -514.0000610351562, + "y": 729.7501525878906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 25, + "height": 21, + "seed": 1106951547, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297771, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[n]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "N0OFLsAea9yT6OuliaHBO", + "originalText": "[n]" + }, + { + "type": "rectangle", + "version": 228, + "versionNonce": 647779579, + "isDeleted": false, + "id": "Sn4zW4Qj5F8AgPuajBnRy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -569.8334655761719, + "y": 783.58349609375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 196.00015258789062, + "height": 39.33346557617187, + "seed": 2117479349, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "O2ixOO7WSexT4tbgcUDGA", + "type": "arrow" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 386, + "versionNonce": 1606143029, + "isDeleted": false, + "id": "ADaMm1yoqbZuEu8DJV90L", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -558.5001831054688, + "y": 793.2500915527344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 170, + "height": 20, + "seed": 1213945371, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMMemoryInstance", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMMemoryInstance" + }, + { + "type": "arrow", + "version": 134, + "versionNonce": 1991153820, + "isDeleted": false, + "id": "RxhU0Qr-hmqzklRZdxsvn", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -42.66673278808594, + "y": 209.66668701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 470.2476914752049, + "height": 74.33332824707031, + "seed": 1569902293, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679558440686, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "xWPtNuyAqazMMUyouKnhf", + "focus": -0.7987290948340221, + "gap": 4.085652030654501 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -274, + -74.33332824707031 + ], + [ + -470.2476914752049, + -62.82886586813058 + ] + ] + }, + { + "type": "arrow", + "version": 214, + "versionNonce": 1329495445, + "isDeleted": false, + "id": "v2uiV8UbBxa6_yEOLAehf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -54.615555578359704, + "y": 386.91916605443436, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 362.7179252566011, + "height": 185.08100179224533, + "seed": 1266609179, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "startBinding": { + "elementId": "8KE83CX20gDJQwJueCKwN", + "focus": 1.000586020261827, + "gap": 15.33355712890625 + }, + "endBinding": { + "elementId": "FiGf5f4dzHNrO5L3NMiwT", + "focus": 0.2798025099622999, + "gap": 11.916763305664062 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -132.71792525660123, + 185.08100179224533 + ], + [ + -362.7179252566011, + 148.41425374537033 + ] + ] + }, + { + "type": "text", + "version": 48, + "versionNonce": 304349941, + "isDeleted": false, + "id": "VoO6IQkaaomgHGzvmdk9L", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -107.00004577636719, + "y": 551.3334197998047, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 184, + "height": 19, + "seed": 2114679797, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMExportTabInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMExportTabInstance" + }, + { + "type": "rectangle", + "version": 353, + "versionNonce": 340366043, + "isDeleted": false, + "id": "cfV2B-j5UbmISEWVZNm_5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -108.33344268798828, + "y": 571.0000915527344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 177.33331298828122, + "height": 121.00006103515625, + "seed": 2095295067, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 335, + "versionNonce": 393196836, + "isDeleted": false, + "id": "DJ8H7VUIn868NKonqg5gA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -94.66675567626953, + "y": 587.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 31, + "seed": 1950809301, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "kVEW0vY1bUiCqI5IpX5ML" + }, + { + "id": "xGVX08X1n0JU0OA60_t9A", + "type": "arrow" + } + ], + "updated": 1679558297772, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 346, + "versionNonce": 543989532, + "isDeleted": false, + "id": "kVEW0vY1bUiCqI5IpX5ML", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -88.66675567626953, + "y": 592.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 21, + "seed": 357803771, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297776, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "char* name ", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "DJ8H7VUIn868NKonqg5gA", + "originalText": "char* name " + }, + { + "type": "diamond", + "version": 308, + "versionNonce": 930974133, + "isDeleted": false, + "id": "gUolYbJIMeIJ_CDZqZFxE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -77.0000991821289, + "y": 631.3333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 14.666656494140625, + "height": 17.666656494140625, + "seed": 1482332725, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 371, + "versionNonce": 809555995, + "isDeleted": false, + "id": "KIe-ngH8dNcYj_TNLGGa1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -92.33344268798828, + "y": 623.6666870117188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 38, + "seed": 1675300763, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "NtF7gKcUrgH2P2tIg7Y1I" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 343, + "versionNonce": 1636135076, + "isDeleted": false, + "id": "NtF7gKcUrgH2P2tIg7Y1I", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -49.83344268798828, + "y": 632.6666870117188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 43, + "height": 21, + "seed": 651398037, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297777, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "table", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "KIe-ngH8dNcYj_TNLGGa1", + "originalText": "table" + }, + { + "type": "rectangle", + "version": 236, + "versionNonce": 1212488891, + "isDeleted": false, + "id": "1vaZwH7ZrMW37Kus4v6s8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -107.33345794677734, + "y": 691.1667327880859, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 179070011, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "EcHCtg-lwToZUzRwQtRqU" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 205, + "versionNonce": 2017614748, + "isDeleted": false, + "id": "EcHCtg-lwToZUzRwQtRqU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -28.333457946777344, + "y": 697.3334045410156, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 21, + "seed": 266817781, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297777, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1vaZwH7ZrMW37Kus4v6s8", + "originalText": "[1]" + }, + { + "type": "text", + "version": 220, + "versionNonce": 748146011, + "isDeleted": false, + "id": "xnv1ofRPmnyf7Y75joBRd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -32.166831970214844, + "y": 671.5001373291016, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 1101669595, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 264, + "versionNonce": 1671072213, + "isDeleted": false, + "id": "WhKSAa-6xEaKbFn82X5ru", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -107.00020599365234, + "y": 724.6668090820312, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 32.333343505859375, + "seed": 555444821, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "-gxwjWzmqS5WDjuFaNKFD" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 235, + "versionNonce": 1750580260, + "isDeleted": false, + "id": "-gxwjWzmqS5WDjuFaNKFD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -32.500205993652344, + "y": 730.8334808349609, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 21, + "seed": 543609211, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297778, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "WhKSAa-6xEaKbFn82X5ru", + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 289, + "versionNonce": 925665308, + "isDeleted": false, + "id": "10EyNsT35ULiP_xM9qv8Y", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -106.3333969116211, + "y": 755.6668701171875, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 180, + "height": 31, + "seed": 457529269, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "x2msRpv4tJnWtZ_hp50wB" + } + ], + "updated": 1679558297778, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 263, + "versionNonce": 97818532, + "isDeleted": false, + "id": "x2msRpv4tJnWtZ_hp50wB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -28.833396911621094, + "y": 765.6668701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 25, + "height": 21, + "seed": 673507867, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297782, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[n]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "10EyNsT35ULiP_xM9qv8Y", + "originalText": "[n]" + }, + { + "type": "text", + "version": 76, + "versionNonce": 375904405, + "isDeleted": false, + "id": "0XlRzavkxOV0TYo3Cru6q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -307.66673278808594, + "y": 651.0002899169922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 171, + "height": 19, + "seed": 1584858171, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "GXMgwVG5yviwCuQz9-Jdx", + "type": "arrow" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "(WASMTableInstance *)", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "(WASMTableInstance *)" + }, + { + "type": "arrow", + "version": 29, + "versionNonce": 1192191803, + "isDeleted": false, + "id": "GXMgwVG5yviwCuQz9-Jdx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -67.33335876464844, + "y": 639.0001068115234, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 69.3333740234375, + "height": 18.333343505859375, + "seed": 1221178005, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "0XlRzavkxOV0TYo3Cru6q", + "focus": 0.6054948422392628, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -69.3333740234375, + 18.333343505859375 + ] + ] + }, + { + "type": "arrow", + "version": 104, + "versionNonce": 1499556260, + "isDeleted": false, + "id": "xGVX08X1n0JU0OA60_t9A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -41.0000457763672, + "y": 446.7786348431563, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 81.66662597656249, + "height": 127.22147196836715, + "seed": 1672312955, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679558303924, + "link": null, + "locked": false, + "startBinding": { + "elementId": "kOP_SYX2hDGyTbKOLrSY7", + "focus": 1.0138390872785434, + "gap": 15.333114624023438 + }, + "endBinding": { + "elementId": "DJ8H7VUIn868NKonqg5gA", + "focus": -0.9738124716848731, + "gap": 15.333290100097656 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -81.66662597656249, + 95.22147196836715 + ], + [ + -68.99999999999999, + 127.22147196836715 + ] + ] + }, + { + "type": "text", + "version": 42, + "versionNonce": 548718555, + "isDeleted": false, + "id": "HULjVKYZds5RYxESw_kpb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -343.66673278808594, + "y": 454.3334197998047, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 173, + "height": 19, + "seed": 2051995003, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887722, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMFunctionInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunctionInstance" + }, + { + "type": "rectangle", + "version": 116, + "versionNonce": 130053973, + "isDeleted": false, + "id": "kgRAri5TBI6AVeJYwZ0aO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 291.8626718521118, + "y": 615.9665649414064, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 229.3333740234375, + "height": 71.33331298828125, + "seed": 1363010869, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "GHvOda4nqju-pWyZr-_zS" + } + ], + "updated": 1679555887722, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 70, + "versionNonce": 1629299868, + "isDeleted": false, + "id": "GHvOda4nqju-pWyZr-_zS", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 393.02935886383057, + "y": 642.0332214355467, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 27, + "height": 21, + "seed": 1441133723, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679558297783, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[..]", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "kgRAri5TBI6AVeJYwZ0aO", + "originalText": "[..]" + }, + { + "type": "text", + "version": 339, + "versionNonce": 1673577653, + "isDeleted": false, + "id": "oxCwJMeoYhRvkKNPtKeha", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 292.13729763031006, + "y": 587.3669616699217, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 211, + "height": 20, + "seed": 1528133269, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Vhva2LNBhtrohj4Y3bGV9", + "type": "arrow" + }, + { + "id": "tV8skfel8ww2IgWRNSntj", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMFunction (per module)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction (per module)" + }, + { + "type": "arrow", + "version": 77, + "versionNonce": 1227017499, + "isDeleted": false, + "id": "Vhva2LNBhtrohj4Y3bGV9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -140.00001525878906, + "y": 499.6667022705078, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 435.3333740234375, + "height": 121, + "seed": 975356629, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": { + "elementId": "QLOWRmBSKHUu_NrX66JPt", + "focus": -0.5172589859849054, + "gap": 7.3333587646484375 + }, + "endBinding": { + "elementId": "oxCwJMeoYhRvkKNPtKeha", + "focus": -1.2215352226224219, + "gap": 13.29974060058612 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 230, + 35.33331298828125 + ], + [ + 435.3333740234375, + 121 + ] + ] + }, + { + "type": "rectangle", + "version": 220, + "versionNonce": 1520753525, + "isDeleted": false, + "id": "kby0LOGKuGuYeMzR0L7Pt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 602.3332366943359, + "y": 559.4166564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 47414645, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 241, + "versionNonce": 12821717, + "isDeleted": false, + "id": "J-wnUXeWDAfVNvwQHeW06", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 601.9998626708984, + "y": 592.5832824707031, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 785254101, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 226, + "versionNonce": 441810683, + "isDeleted": false, + "id": "qpSAJ6K0S6TvU6i2Uflep", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 625.9998626708984, + "y": 600.2499389648438, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1914322171, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "euj5CRuv6EoS2abVhp14P", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 229, + "versionNonce": 2130854453, + "isDeleted": false, + "id": "yCRds2HRNFQhi2l_NRv1E", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 601.6665496826172, + "y": 625.9166259765625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 24142901, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "tV8skfel8ww2IgWRNSntj", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 238, + "versionNonce": 451012507, + "isDeleted": false, + "id": "XQ_n6PzQRK1pjOIbTF09C", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 600.3331756591797, + "y": 653.5832824707031, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 48, + "height": 29, + "seed": 1465836955, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 219, + "versionNonce": 1782985621, + "isDeleted": false, + "id": "dQpthmaEJfLeEUR4UsOsg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 622.9998626708984, + "y": 661.9166259765625, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 2124420501, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 231, + "versionNonce": 1796750395, + "isDeleted": false, + "id": "lRGlqO5nnxQXGumLJpnO9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 624.3332366943359, + "y": 630.8333282470703, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 10.66668701171875, + "height": 17.666656494140625, + "seed": 1262844475, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 90, + "versionNonce": 516225269, + "isDeleted": false, + "id": "bCPa9rRVzubIpa31jwl73", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 574.0000152587891, + "y": 532.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 177.33334350585938, + "seed": 294820597, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "6EZFlJGbMoYN4RDYkSEYP", + "type": "arrow" + }, + { + "id": "euj5CRuv6EoS2abVhp14P", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 534, + "versionNonce": 1457192155, + "isDeleted": false, + "id": "C_HvFqwDiW4wGe01QNKFg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 715.7036827935111, + "y": 367.61115180121527, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00552481453781, + "height": 1.0071746818260863, + "seed": 1379035003, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": { + "elementId": "SQI7khDAbJL0pLh0deiej", + "focus": 0.39512687910745115, + "gap": 12.666702270507812 + }, + "endBinding": { + "elementId": "2jRIgxhs5VlnfeDeDJXss", + "focus": 0.24394927767367422, + "gap": 2.171731894901793 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 70.00552481453781, + -1.0071746818260863 + ] + ] + }, + { + "type": "arrow", + "version": 48, + "versionNonce": 163359099, + "isDeleted": false, + "id": "tV8skfel8ww2IgWRNSntj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 622.6667327880859, + "y": 610.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105.3333740234375, + "height": 3.666656494140625, + "seed": 1040768149, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": { + "elementId": "yCRds2HRNFQhi2l_NRv1E", + "focus": 1.968489954492859, + "gap": 15.583236694335938 + }, + "endBinding": { + "elementId": "oxCwJMeoYhRvkKNPtKeha", + "focus": 1.5212851912013483, + "gap": 14.196061134338379 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -105.3333740234375, + 3.666656494140625 + ] + ] + }, + { + "type": "rectangle", + "version": 138, + "versionNonce": 2094596021, + "isDeleted": false, + "id": "lbEH3IbUKE-BUvPaOCKOp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 705.7037133110892, + "y": 358.277838812934, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 13.33331298828125, + "height": 11.666671752929688, + "seed": 638517691, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 133, + "versionNonce": 419414555, + "isDeleted": false, + "id": "dTPwE9k9B6K3ksCQBb5OL", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 535.0371958414713, + "y": 506.51877678765186, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 176, + "height": 20, + "seed": 121765525, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::functions", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::functions" + }, + { + "type": "rectangle", + "version": 456, + "versionNonce": 1301726907, + "isDeleted": false, + "id": "2J2sR-bPrGrF9OxiUqIF0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 868.2591145833333, + "y": 158.1759851243761, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1128772501, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "hFcIrFVFFLvSiAWOYE-xZ", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 284, + "versionNonce": 154931515, + "isDeleted": false, + "id": "ZZLxhvBfAsVbp2PY6VOfR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 851.2592061360676, + "y": 129.7593591478136, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 153.00003051757812, + "seed": 1437253909, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "hFcIrFVFFLvSiAWOYE-xZ", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 356, + "versionNonce": 1161098229, + "isDeleted": false, + "id": "FdRdG15cLuW_kygoS9kFB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 862.5927598741318, + "y": 332.1297662523058, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 159, + "height": 20, + "seed": 1076709051, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::globals", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::globals" + }, + { + "type": "rectangle", + "version": 458, + "versionNonce": 196882907, + "isDeleted": false, + "id": "ev_sIxuEomRo18wQcVOAi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 863.5926411946614, + "y": 195.926084306505, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1597294293, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "hFcIrFVFFLvSiAWOYE-xZ", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 469, + "versionNonce": 1119661397, + "isDeleted": false, + "id": "2AbM31Y4eYzNJdn6ccO7X", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 870.2593892415364, + "y": 231.25939729478625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1887403259, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "6EZFlJGbMoYN4RDYkSEYP", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "ellipse", + "version": 193, + "versionNonce": 499530421, + "isDeleted": false, + "id": "2jRIgxhs5VlnfeDeDJXss", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 787.7037285698783, + "y": 359.277838812934, + "strokeColor": "#000000", + "backgroundColor": "#7950f2", + "width": 16, + "height": 19.000091552734375, + "seed": 1552112411, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "C_HvFqwDiW4wGe01QNKFg", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 445, + "versionNonce": 1861688341, + "isDeleted": false, + "id": "hFcIrFVFFLvSiAWOYE-xZ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 797.8519422743055, + "y": 365.2778930664062, + "strokeColor": "#000000", + "backgroundColor": "#7950f2", + "width": 60.463513970850386, + "height": 155.0348750393585, + "seed": 1134283957, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "ev_sIxuEomRo18wQcVOAi", + "focus": 0.8021785743382612, + "gap": 5.277184949505454 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 26.18546210394959, + -121.94443088107656 + ], + [ + 60.463513970850386, + -155.0348750393585 + ] + ] + }, + { + "type": "rectangle", + "version": 485, + "versionNonce": 1957174203, + "isDeleted": false, + "id": "qGE55eCk3NIsUQpSP-g6Y", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 888.4441562228732, + "y": 390.84254328409827, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 983648475, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 316, + "versionNonce": 507826549, + "isDeleted": false, + "id": "c3AswZE8rY-ZsD8gGAzgg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 871.4442477756076, + "y": 362.42591730753577, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 153.00003051757812, + "seed": 832079445, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 343, + "versionNonce": 1916988507, + "isDeleted": false, + "id": "6YL2S8HdLuD8PaiWGA-vU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 829.5925801595051, + "y": 102.42615678575305, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 156, + "height": 20, + "seed": 920221051, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::tables", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::tables" + }, + { + "type": "rectangle", + "version": 542, + "versionNonce": 2029312725, + "isDeleted": false, + "id": "50mTV_vbZA4UToji5TAhb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 882.0739339192708, + "y": 431.5186000400119, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1438577589, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "OjoiFuv7ZOtNkq4SpgOL-", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 553, + "versionNonce": 1635428603, + "isDeleted": false, + "id": "Aa3QPT7Ps924J0klBEGMw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 888.7406819661458, + "y": 466.85191302829315, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 547556891, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 424, + "versionNonce": 1473368475, + "isDeleted": false, + "id": "WMOLdrP9c0TFV1JLcmfzK", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 233.66656494140625, + "y": 236.33336639404277, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 17.3333740234375, + "height": 13.000015258789062, + "seed": 1272865237, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 442, + "versionNonce": 606202261, + "isDeleted": false, + "id": "XVo2iBeciuaFiIrP3DUw5", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 235.66656494140625, + "y": 252.66669464111305, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 17.3333740234375, + "height": 13.000015258789062, + "seed": 823202299, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "6EZFlJGbMoYN4RDYkSEYP", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 427, + "versionNonce": 377153083, + "isDeleted": false, + "id": "InatpictpQQa0Op1qByFJ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 235.66656494140625, + "y": 268.33336639404274, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 17.3333740234375, + "height": 13.000015258789062, + "seed": 682826293, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "6EZFlJGbMoYN4RDYkSEYP", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 609, + "versionNonce": 1207751547, + "isDeleted": false, + "id": "6EZFlJGbMoYN4RDYkSEYP", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 257.1755919962603, + "y": 432.4837343704476, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 350.4818452518821, + "height": 113.7944575139108, + "seed": 1046151995, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "bCPa9rRVzubIpa31jwl73", + "focus": 0.6467798007705062, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -33.87912050646, + 40.47938005012526 + ], + [ + 316.60272474542205, + 113.7944575139108 + ] + ] + }, + { + "type": "text", + "version": 380, + "versionNonce": 1636332981, + "isDeleted": false, + "id": "qUXi_zQbiA8lmV5c_r8ta", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 875.0742831759982, + "y": 534.6482721964519, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 172, + "height": 20, + "seed": 2104268027, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModule::memories", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModule::memories" + }, + { + "type": "rectangle", + "version": 511, + "versionNonce": 833268763, + "isDeleted": false, + "id": "rfTE9QxqtEjzOzoCNZT01", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 900.9256795247394, + "y": 593.3610492282444, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1292864565, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "4NjPz6Olqru3m83OxGXGX", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 342, + "versionNonce": 347731733, + "isDeleted": false, + "id": "RzznX4k1tfSt8AyuJuF2D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 883.9257710774738, + "y": 564.9444232516819, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.66668701171875, + "height": 153.00003051757812, + "seed": 1990606235, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "4NjPz6Olqru3m83OxGXGX", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 566, + "versionNonce": 626290875, + "isDeleted": false, + "id": "GEQFwoUvMYOSit62JGwLM", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 894.5554572211371, + "y": 634.037105984158, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 1545223573, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 578, + "versionNonce": 1559514229, + "isDeleted": false, + "id": "IvFYTMyYUBhJe6Ob5YAGg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 901.2222052680121, + "y": 669.3704189724392, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 70.00006103515625, + "height": 25.66668701171874, + "seed": 937546299, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 43, + "versionNonce": 1419551067, + "isDeleted": false, + "id": "ZMwf8VnKqa7gp45PnuQWi", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 780.3335876464843, + "y": 45.92599826388881, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 286.66666666666686, + "height": 707.0370313856337, + "seed": 876902971, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "YidAloK-3ikBBzvuu-S22", + "type": "arrow" + } + ], + "updated": 1679555887723, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 138, + "versionNonce": 1241314773, + "isDeleted": false, + "id": "2NQmRBF_NE2Myp3-jqLfT", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 418.1839375016565, + "y": 222.9630296495223, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 351.7376685654755, + "height": 202.59258694118918, + "seed": 1011740277, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": { + "elementId": "TOmX9MwwNOgbfjNJ8V8j7", + "focus": 0.48971428325717553, + "gap": 11.018498738606851 + }, + "endBinding": { + "elementId": "7MNv-pmgV4-8yJ5lIFY1U", + "focus": 1.3268339026620566, + "gap": 13.16658528645857 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 82.8903795827618, + -202.59258694118918 + ], + [ + 351.7376685654755, + -175.99734962527606 + ] + ] + }, + { + "type": "arrow", + "version": 58, + "versionNonce": 416660987, + "isDeleted": false, + "id": "OjoiFuv7ZOtNkq4SpgOL-", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 796.6298048231338, + "y": 366.6667785644529, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 82.96305338541652, + "height": 65.92593722873261, + "seed": 275987509, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "50mTV_vbZA4UToji5TAhb", + "focus": -0.4434608130384178, + "gap": 2.481075710720461 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 82.96305338541652, + 65.92593722873261 + ] + ] + }, + { + "type": "arrow", + "version": 131, + "versionNonce": 1458139957, + "isDeleted": false, + "id": "4NjPz6Olqru3m83OxGXGX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 796.6298726399739, + "y": 372.96306355794246, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98.51854112413207, + "height": 227.77777777777777, + "seed": 1888354747, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "rfTE9QxqtEjzOzoCNZT01", + "focus": -0.6184957089704255, + "gap": 5.7772657606334406 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 46.66673448350696, + 191.48159450954864 + ], + [ + 98.51854112413207, + 227.77777777777777 + ] + ] + }, + { + "type": "arrow", + "version": 105, + "versionNonce": 2097301147, + "isDeleted": false, + "id": "euj5CRuv6EoS2abVhp14P", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 792.9261237250435, + "y": 375.55566745334175, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 140, + "height": 233.33346896701386, + "seed": 856817851, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887723, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "qpSAJ6K0S6TvU6i2Uflep", + "focus": 1.8857122566967692, + "gap": 14.01957438916057 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -30.37034776475707, + 147.77781168619794 + ], + [ + -140, + 233.33346896701386 + ] + ] + }, + { + "type": "text", + "version": 404, + "versionNonce": 2049173, + "isDeleted": false, + "id": "0836mka_gP8EntAw7Pvzh", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 285.4076097276477, + "y": 424.0742221408418, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 198, + "height": 19, + "seed": 1302236763, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 2, + "text": "WASMFunction **functions;", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMFunction **functions;" + }, + { + "type": "rectangle", + "version": 385, + "versionNonce": 131382075, + "isDeleted": false, + "id": "Fv3xwjCOvQ9-pJ5ui2sV2", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 239.7409837510852, + "y": 409.4075961642793, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 216, + "height": 42.6666259765625, + "seed": 1276926165, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 350, + "versionNonce": 424929781, + "isDeleted": false, + "id": "IibWA_jM89ndxmrceQLmE", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 254.4077317979602, + "y": 420.07428317599806, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 15.33331298828125, + "height": 22.66668701171875, + "seed": 1427245819, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 133, + "versionNonce": 1169136603, + "isDeleted": false, + "id": "OdDm5a5O_NIoZbF3u0c0H", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 442.5558098687066, + "y": 370.37052747938344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 138.34606629993374, + "height": 88.15863628949046, + "seed": 967352763, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false, + "startBinding": { + "elementId": "FPUGB-iP7ep91gfoTuV2d", + "focus": 0.6557614629211577, + "gap": 3.7962053087022696 + }, + "endBinding": { + "elementId": "blxQLl_yf7DMD76qHC5rc", + "focus": -0.24942508137542688, + "gap": 9.870619032117872 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 61.48149278428815, + -72.22222222222217 + ], + [ + 138.34606629993374, + -88.15863628949046 + ] + ] + }, + { + "type": "text", + "version": 35, + "versionNonce": 1670177621, + "isDeleted": false, + "id": "armvxVMuT0bX77T30wPV4", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -39.66648017035561, + "y": 230.37051052517361, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 165, + "height": 20, + "seed": 587722005, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "export_global_count", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "export_global_count" + }, + { + "type": "rectangle", + "version": 502, + "versionNonce": 312830075, + "isDeleted": false, + "id": "nUlAmf5jmsJoZ2lStTbBw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -52.18503146701369, + "y": 226.01867336697043, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174.66668701171875, + "height": 25.37032402886292, + "seed": 1476753525, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679555887724, + "link": null, + "locked": false + }, + { + "id": "Mznw_08SMS746JVePQe3h", + "type": "text", + "x": -55.747947692871094, + "y": 396.450114440918, + "width": 174, + "height": 20, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 1392475036, + "version": 62, + "versionNonce": 452856732, + "isDeleted": false, + "boundElements": null, + "updated": 1679558398355, + "link": null, + "locked": false, + "text": "export_memory_count", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 14, + "containerId": null, + "originalText": "export_memory_count" + }, + { + "id": "wyGG1OIhy3X499IvtJM3Z", + "type": "rectangle", + "x": -58.081260681152344, + "y": 394.9499618530274, + "width": 182.33331298828125, + "height": 25, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 611257380, + "version": 32, + "versionNonce": 1973769116, + "isDeleted": false, + "boundElements": null, + "updated": 1679558406221, + "link": null, + "locked": false + }, + { + "id": "Gk4JYjHayAFkRDbQWId6b", + "type": "text", + "x": -42.081260681152344, + "y": 463.28327484130864, + "width": 162, + "height": 20, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 804003748, + "version": 47, + "versionNonce": 591391772, + "isDeleted": false, + "boundElements": null, + "updated": 1679558418472, + "link": null, + "locked": false, + "text": "export_table_count", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 14, + "containerId": null, + "originalText": "export_table_count" + }, + { + "id": "Xb-aggFXlG4Dh_LtxGJ7l", + "type": "rectangle", + "x": -49.414573669433594, + "y": 462.28330535888676, + "width": 174.33331298828125, + "height": 24.33343505859375, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 572093348, + "version": 30, + "versionNonce": 1840351132, + "isDeleted": false, + "boundElements": null, + "updated": 1679558423043, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/core/iwasm/doc/images/wasm_exports.svg b/core/iwasm/doc/images/wasm_exports.svg new file mode 100644 index 000000000..573f11c35 --- /dev/null +++ b/core/iwasm/doc/images/wasm_exports.svg @@ -0,0 +1,16 @@ + + + + + + + WASMModule WASMTable *tables; WASMMemory *memories; WASMGlobal *globals;WASMExport *exports;WASMExportchar *name;uint8 kind;uint32 index;[0][1][...]WASMModuleInstanceexport_tablesexport_memoriesexport_globalsexport_functionsWASMExportFuncInstancechar* name functionname: shown to externalindex: refer to item idx for export in current kindkind: total 4 export kinds:- function- globals- memory- table[1][0][...][n](refer to function diagam)export_func_countWASMExportGlobInstancechar* name global[1][0][...][n]WASMGlobalInstanceWASMExportMemInstancechar* name memory(WASMMemoryInstance*)[1][0][...][n]WASMMemoryInstanceWASMExportTabInstancechar* name table[1][0][...][n](WASMTableInstance *)WASMFunctionInstance[..]WASMFunction (per module)WASMModule::functionsWASMModule::globalsWASMModule::tablesWASMModule::memoriesWASMFunction **functions;export_global_countexport_memory_countexport_table_count \ No newline at end of file diff --git a/core/iwasm/doc/wasm_exports.MD b/core/iwasm/doc/wasm_exports.MD new file mode 100644 index 000000000..70708cde3 --- /dev/null +++ b/core/iwasm/doc/wasm_exports.MD @@ -0,0 +1,22 @@ +# Wasm exports +The internal data structure for Wasm exports: +![](./images/wasm_exports.svg) + +## Setup exports for Module +The array data structure pointed by `WASMModule::exports` is setup during loading a module. Basically the runtime will load the exports sections from the module file content, and construct an array of C struct `WASMExport`. + +A `WASMExport` item contains three elements that map the Wasm file exports section structure: +- name: the name shown to external +- kind: total 4 export types: function, globals, memory, table +- index: As all the 4 export types are organized in array, this refers to index in target export type + +## Function exports +### use function exports +function exports are often used in two situations: + 1. **call by host**: runtime API `wasm_runtime_lookup_function` will walk through the array of `WASMModuleInstance::export_functions` and compare the exported name with given target symbol name in the function parameter. If any array item matches the name, it then returns the value of field `function` which points to associated function instance (WASMFunctionInstance) + 2. **import by another module**: During linking multiple modules, the runtime saves the pointer of exported WASMFunctionInstance in the local WASMFunctionInstance of importing module. + +### setup for instance +The data structure pointed by `WASMModuleInstance::export_functions` is set up during instantiating module instance. + +The runtime will walk through the `WASMModule::exports` array and find all the item with kind equal to "function". Create a node of `WASMExportFuncInstance` for each matching, find the associated `WASMFunctionInstance` object and save its address in the field `function`. From d975a1a82c5001d77fd73a74bc039f51112db145 Mon Sep 17 00:00:00 2001 From: dongheng <930490596@qq.com> Date: Thu, 23 Mar 2023 17:29:57 +0800 Subject: [PATCH 18/61] Enable platform support for esp-idf v5.0.1 (#2050) --- build-scripts/esp-idf/wamr/CMakeLists.txt | 2 +- core/iwasm/aot/arch/aot_reloc_xtensa.c | 2 +- core/shared/platform/esp-idf/espidf_platform.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build-scripts/esp-idf/wamr/CMakeLists.txt b/build-scripts/esp-idf/wamr/CMakeLists.txt index c7b6100ec..5ac04ddc9 100644 --- a/build-scripts/esp-idf/wamr/CMakeLists.txt +++ b/build-scripts/esp-idf/wamr/CMakeLists.txt @@ -51,7 +51,7 @@ endif() idf_component_register(SRCS ${WAMR_RUNTIME_LIB_SOURCE} ${PLATFORM_SHARED_SOURCE} INCLUDE_DIRS ${IWASM_DIR}/include ${UTILS_SHARED_DIR} ${PLATFORM_SHARED_DIR} ${PLATFORM_SHARED_DIR}/../include - REQUIRES pthread + REQUIRES pthread lwip esp_timer ) diff --git a/core/iwasm/aot/arch/aot_reloc_xtensa.c b/core/iwasm/aot/arch/aot_reloc_xtensa.c index 731ae6395..3327c396f 100644 --- a/core/iwasm/aot/arch/aot_reloc_xtensa.c +++ b/core/iwasm/aot/arch/aot_reloc_xtensa.c @@ -294,7 +294,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr, snprintf(error_buf, error_buf_size, "Load relocation section failed: " "invalid relocation type %d.", - reloc_type); + (int)reloc_type); return false; } diff --git a/core/shared/platform/esp-idf/espidf_platform.c b/core/shared/platform/esp-idf/espidf_platform.c index d05b19f50..35b893d81 100644 --- a/core/shared/platform/esp-idf/espidf_platform.c +++ b/core/shared/platform/esp-idf/espidf_platform.c @@ -215,7 +215,7 @@ unlinkat(int fd, const char *path, int flag) } int -utimensat(int fd, const char *path, const struct timespec ts[2], int flag) +utimensat(int fd, const char *path, const struct timespec *ts, int flag) { errno = ENOSYS; return -1; @@ -238,7 +238,7 @@ ftruncate(int fd, off_t length) #endif int -futimens(int fd, const struct timespec times[2]) +futimens(int fd, const struct timespec *times) { errno = ENOSYS; return -1; From 4c2d3589806104eee9520b706feb7bd919a7a51b Mon Sep 17 00:00:00 2001 From: Xu Jun Date: Thu, 23 Mar 2023 19:16:56 +0800 Subject: [PATCH 19/61] Update document for source debugging (#2051) --- doc/source_debugging.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/doc/source_debugging.md b/doc/source_debugging.md index 0c219efd3..a9fa09307 100644 --- a/doc/source_debugging.md +++ b/doc/source_debugging.md @@ -40,16 +40,29 @@ iwasm -g=127.0.0.1:1234 test.wasm # Use port = 0 to allow a random assigned debug port ``` -4. Build customized lldb (assume you have already cloned llvm) +4. Build customized lldb ``` bash -cd ${WAMR_ROOT}/core/deps/llvm -git apply ../../../build-scripts/lldb-wasm.patch -mkdir build-lldb && cd build-lldb -cmake -DCMAKE_BUILD_TYPE:STRING="Release" -DLLVM_ENABLE_PROJECTS="clang;lldb" -DLLVM_TARGETS_TO_BUILD:STRING="X86;WebAssembly" -DLLVM_ENABLE_LIBXML2:BOOL=ON ../llvm -make -j $(nproc) +git clone --branch release/13.x --depth=1 https://github.com/llvm/llvm-project +cd llvm-project +git apply ${WAMR_ROOT}/build-scripts/lldb-wasm.patch +mkdir build-lldb +cmake -S ./llvm -B build-lldb \ + -G Ninja \ + -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;lldb" \ + -DLLVM_TARGETS_TO_BUILD:STRING="X86;WebAssembly" \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_BUILD_BENCHMARKS:BOOL=OFF \ + -DLLVM_BUILD_DOCS:BOOL=OFF -DLLVM_BUILD_EXAMPLES:BOOL=OFF \ + -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF -DLLVM_BUILD_TESTS:BOOL=OFF \ + -DLLVM_ENABLE_BINDINGS:BOOL=OFF -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \ + -DLLVM_INCLUDE_DOCS:BOOL=OFF -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ + -DLLVM_INCLUDE_TESTS:BOOL=OFF -DLLVM_ENABLE_LIBXML2:BOOL=ON +cmake --build build-lldb --target lldb --parallel $(nproc) +# The lldb is generated under build-lldb/bin/lldb ``` > Note: If using `CommandLineTools` on MacOS, make sure only one SDK is present in `/Library/Developer/CommandLineTools/SDKs`. +> You can download pre-built `wamr-lldb` binaries from [here](https://github.com/bytecodealliance/wasm-micro-runtime/releases). + 5. Launch customized lldb and connect to iwasm ``` bash lldb @@ -57,8 +70,6 @@ lldb ``` Then you can use lldb commands to debug your applications. Please refer to [lldb document](https://lldb.llvm.org/use/tutorial.html) for command usage. -> Known issue: `step over` on some function may be treated as `step in`, it will be fixed later. - ## Debugging with AOT > Note: AOT debugging is experimental and only a few debugging capabilities are supported. From 3977f0b22a4b71770ad30bfe8e96757466e962e4 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 23 Mar 2023 19:19:47 +0800 Subject: [PATCH 20/61] Use pre-created exec_env for instantiation and module_malloc/free (#2047) Use pre-created exec_env for instantiation and module_malloc/free, use the same exec_env of the current thread to avoid potential unexpected behavior. And remove unnecessary shared_mem_lock in wasm_module_free, which may cause dead lock. --- core/iwasm/aot/aot_runtime.c | 198 ++++++++--------- core/iwasm/aot/aot_runtime.h | 22 +- core/iwasm/common/wasm_application.c | 7 +- core/iwasm/common/wasm_runtime_common.c | 71 +++++- core/iwasm/common/wasm_runtime_common.h | 22 +- core/iwasm/interpreter/wasm_runtime.c | 208 +++++++++--------- core/iwasm/interpreter/wasm_runtime.h | 22 +- .../lib-pthread/lib_pthread_wrapper.c | 2 +- .../lib_wasi_threads_wrapper.c | 2 +- .../libraries/thread-mgr/thread_manager.c | 9 +- 10 files changed, 327 insertions(+), 236 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index c0fc23746..b96e04edd 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -922,14 +922,14 @@ lookup_post_instantiate_func(AOTModuleInstance *module_inst, static bool execute_post_instantiate_functions(AOTModuleInstance *module_inst, - bool is_sub_inst) + bool is_sub_inst, WASMExecEnv *exec_env_main) { AOTModule *module = (AOTModule *)module_inst->module; AOTFunctionInstance *initialize_func = NULL; AOTFunctionInstance *post_inst_func = NULL; AOTFunctionInstance *call_ctors_func = NULL; -#ifdef OS_ENABLE_HW_BOUND_CHECK WASMModuleInstanceCommon *module_inst_main = NULL; +#ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = NULL; #endif WASMExecEnv *exec_env = NULL; @@ -973,25 +973,29 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, return true; } -#ifdef OS_ENABLE_HW_BOUND_CHECK if (is_sub_inst) { - exec_env = exec_env_tls = wasm_runtime_get_exec_env_tls(); - if (exec_env_tls) { - /* Temporarily replace exec_env_tls's module inst to current - module inst to avoid checking failure when calling the - wasm functions, and ensure that the exec_env's module inst - is the correct one. */ - module_inst_main = exec_env_tls->module_inst; - exec_env_tls->module_inst = (WASMModuleInstanceCommon *)module_inst; - } - } + bh_assert(exec_env_main); +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env_tls = wasm_runtime_get_exec_env_tls(); + bh_assert(exec_env_tls == exec_env_main); + (void)exec_env_tls; #endif - if (!exec_env - && !(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - aot_set_exception(module_inst, "allocate memory failed"); - return false; + exec_env = exec_env_main; + + /* Temporarily replace parent exec_env's module inst to current + module inst to avoid checking failure when calling the + wasm functions, and ensure that the exec_env's module inst + is the correct one. */ + module_inst_main = exec_env_main->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; + } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + aot_set_exception(module_inst, "allocate memory failed"); + return false; + } } /* Execute start function for both main insance and sub instance */ @@ -1029,17 +1033,11 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, ret = true; fail: -#ifdef OS_ENABLE_HW_BOUND_CHECK - if (is_sub_inst && exec_env_tls) { - bh_assert(exec_env == exec_env_tls); - /* Restore the exec_env_tls's module inst */ - exec_env_tls->module_inst = module_inst_main; - } + if (is_sub_inst) + /* Restore the parent exec_env's module inst */ + exec_env_main->module_inst = module_inst_main; else wasm_exec_env_destroy(exec_env); -#else - wasm_exec_env_destroy(exec_env); -#endif return ret; } @@ -1065,8 +1063,9 @@ check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size) } AOTModuleInstance * -aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size, - uint32 heap_size, char *error_buf, uint32 error_buf_size) +aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main, + uint32 stack_size, uint32 heap_size, char *error_buf, + uint32 error_buf_size) { AOTModuleInstance *module_inst; const uint32 module_inst_struct_size = @@ -1206,7 +1205,8 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size, } #endif - if (!execute_post_instantiate_functions(module_inst, is_sub_inst)) { + if (!execute_post_instantiate_functions(module_inst, is_sub_inst, + exec_env_main)) { set_error_buf(error_buf, error_buf_size, module_inst->cur_exception); goto fail; } @@ -1557,39 +1557,6 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, } } -bool -aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst, - AOTFunctionInstance *func, unsigned argc, - uint32 argv[]) -{ - WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL; - bool ret; - -#if defined(OS_ENABLE_HW_BOUND_CHECK) - existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls(); -#elif WASM_ENABLE_THREAD_MGR != 0 - existing_exec_env = exec_env = - wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); -#endif - - if (!existing_exec_env) { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - aot_set_exception(module_inst, "allocate memory failed"); - return false; - } - } - - ret = wasm_runtime_call_wasm(exec_env, func, argc, argv); - - /* don't destroy the exec_env if it isn't created in this function */ - if (!existing_exec_env) - wasm_exec_env_destroy(exec_env); - - return ret; -} - void aot_set_exception(AOTModuleInstance *module_inst, const char *exception) { @@ -1621,7 +1588,7 @@ aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf) } static bool -execute_malloc_function(AOTModuleInstance *module_inst, +execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, AOTFunctionInstance *malloc_func, AOTFunctionInstance *retain_func, uint32 size, uint32 *p_result) @@ -1639,26 +1606,28 @@ execute_malloc_function(AOTModuleInstance *module_inst, argc = 2; } + if (exec_env) { #ifdef OS_ENABLE_HW_BOUND_CHECK - if (exec_env_tls != NULL) { - bh_assert(exec_env_tls->module_inst + if (exec_env_tls) { + bh_assert(exec_env_tls == exec_env); + } +#endif + bh_assert(exec_env->module_inst == (WASMModuleInstanceCommon *)module_inst); - ret = aot_call_function(exec_env_tls, malloc_func, argc, argv); - - if (retain_func && ret) { - ret = aot_call_function(exec_env_tls, retain_func, 1, argv); + } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; } } - else -#endif - { - ret = aot_create_exec_env_and_call_function(module_inst, malloc_func, - argc, argv); - if (retain_func && ret) { - ret = aot_create_exec_env_and_call_function(module_inst, - retain_func, 1, argv); - } + ret = aot_call_function(exec_env, malloc_func, argc, argv); + + if (retain_func && ret) { + ret = aot_call_function(exec_env, retain_func, 1, argv); } if (ret) @@ -1667,7 +1636,7 @@ execute_malloc_function(AOTModuleInstance *module_inst, } static bool -execute_free_function(AOTModuleInstance *module_inst, +execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, AOTFunctionInstance *free_func, uint32 offset) { #ifdef OS_ENABLE_HW_BOUND_CHECK @@ -1676,23 +1645,32 @@ execute_free_function(AOTModuleInstance *module_inst, uint32 argv[2]; argv[0] = offset; + + if (exec_env) { #ifdef OS_ENABLE_HW_BOUND_CHECK - if (exec_env_tls != NULL) { - bh_assert(exec_env_tls->module_inst - == (WASMModuleInstanceCommon *)module_inst); - return aot_call_function(exec_env_tls, free_func, 1, argv); - } - else + if (exec_env_tls) { + bh_assert(exec_env_tls == exec_env); + } #endif - { - return aot_create_exec_env_and_call_function(module_inst, free_func, 1, - argv); + bh_assert(exec_env->module_inst + == (WASMModuleInstanceCommon *)module_inst); } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + + return aot_call_function(exec_env, free_func, 1, argv); } uint32 -aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, - void **p_native_addr) +aot_module_malloc_internal(AOTModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 size, + void **p_native_addr) { AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst); AOTModule *module = (AOTModule *)module_inst->module; @@ -1729,8 +1707,8 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig); if (!malloc_func - || !execute_malloc_function(module_inst, malloc_func, retain_func, - size, &offset)) { + || !execute_malloc_function(module_inst, exec_env, malloc_func, + retain_func, size, &offset)) { return 0; } addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL; @@ -1753,8 +1731,9 @@ aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, } uint32 -aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size, - void **p_native_addr) +aot_module_realloc_internal(AOTModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 ptr, uint32 size, + void **p_native_addr) { AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst); uint8 *addr = NULL; @@ -1771,6 +1750,7 @@ aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size, } /* Only support realloc in WAMR's app heap */ + (void)exec_env; if (!addr) { if (memory_inst->heap_handle @@ -1789,7 +1769,8 @@ aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size, } void -aot_module_free(AOTModuleInstance *module_inst, uint32 ptr) +aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, + uint32 ptr) { AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst); AOTModule *module = (AOTModule *)module_inst->module; @@ -1823,11 +1804,32 @@ aot_module_free(AOTModuleInstance *module_inst, uint32 ptr) free_func = aot_lookup_function(module_inst, "__unpin", "(i)i"); if (free_func) - execute_free_function(module_inst, free_func, ptr); + execute_free_function(module_inst, exec_env, free_func, ptr); } } } +uint32 +aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, + void **p_native_addr) +{ + return aot_module_malloc_internal(module_inst, NULL, size, p_native_addr); +} + +uint32 +aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size, + void **p_native_addr) +{ + return aot_module_realloc_internal(module_inst, NULL, ptr, size, + p_native_addr); +} + +void +aot_module_free(AOTModuleInstance *module_inst, uint32 ptr) +{ + aot_module_free_internal(module_inst, NULL, ptr); +} + uint32 aot_module_dup_data(AOTModuleInstance *module_inst, const char *src, uint32 size) diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 35a1ccb4b..bcd06534e 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -343,8 +343,9 @@ aot_unload(AOTModule *module); * @return return the instantiated AOT module instance, NULL if failed */ AOTModuleInstance * -aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size, - uint32 heap_size, char *error_buf, uint32 error_buf_size); +aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main, + uint32 stack_size, uint32 heap_size, char *error_buf, + uint32 error_buf_size); /** * Deinstantiate a AOT module instance, destroy the resources. @@ -387,11 +388,6 @@ bool aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function, unsigned argc, uint32 argv[]); -bool -aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst, - AOTFunctionInstance *function, - unsigned argc, uint32 argv[]); - /** * Set AOT module instance exception with exception string * @@ -424,6 +420,18 @@ aot_get_exception(AOTModuleInstance *module_inst); bool aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf); +uint32 +aot_module_malloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env, + uint32 size, void **p_native_addr); + +uint32 +aot_module_realloc_internal(AOTModuleInstance *module_inst, WASMExecEnv *env, + uint32 ptr, uint32 size, void **p_native_addr); + +void +aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *env, + uint32 ptr); + uint32 aot_module_malloc(AOTModuleInstance *module_inst, uint32 size, void **p_native_addr); diff --git a/core/iwasm/common/wasm_application.c b/core/iwasm/common/wasm_application.c index 05e53c451..2ed217e7a 100644 --- a/core/iwasm/common/wasm_application.c +++ b/core/iwasm/common/wasm_application.c @@ -225,8 +225,11 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, ret = wasm_runtime_get_exception(module_inst) == NULL; #if WASM_ENABLE_DUMP_CALL_STACK != 0 - if (!ret) - wasm_runtime_dump_call_stack(exec_env); + if (!ret) { + exec_env = wasm_runtime_get_exec_env_singleton(module_inst); + if (exec_env) + wasm_runtime_dump_call_stack(exec_env); + } #endif return ret; diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 99e04ee98..452a2661b 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1196,20 +1196,21 @@ wasm_runtime_unload(WASMModuleCommon *module) WASMModuleInstanceCommon * wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, - uint32 stack_size, uint32 heap_size, - char *error_buf, uint32 error_buf_size) + WASMExecEnv *exec_env_main, uint32 stack_size, + uint32 heap_size, char *error_buf, + uint32 error_buf_size) { #if WASM_ENABLE_INTERP != 0 if (module->module_type == Wasm_Module_Bytecode) return (WASMModuleInstanceCommon *)wasm_instantiate( - (WASMModule *)module, is_sub_inst, stack_size, heap_size, error_buf, - error_buf_size); + (WASMModule *)module, is_sub_inst, exec_env_main, stack_size, + heap_size, error_buf, error_buf_size); #endif #if WASM_ENABLE_AOT != 0 if (module->module_type == Wasm_Module_AoT) return (WASMModuleInstanceCommon *)aot_instantiate( - (AOTModule *)module, is_sub_inst, stack_size, heap_size, error_buf, - error_buf_size); + (AOTModule *)module, is_sub_inst, exec_env_main, stack_size, + heap_size, error_buf, error_buf_size); #endif set_error_buf(error_buf, error_buf_size, "Instantiate module failed, invalid module type"); @@ -1222,7 +1223,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size, uint32 error_buf_size) { return wasm_runtime_instantiate_internal( - module, false, stack_size, heap_size, error_buf, error_buf_size); + module, false, NULL, stack_size, heap_size, error_buf, error_buf_size); } void @@ -2480,6 +2481,62 @@ wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm) return module_inst->custom_data; } +uint32 +wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 size, + void **p_native_addr) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) + return wasm_module_malloc_internal((WASMModuleInstance *)module_inst, + exec_env, size, p_native_addr); +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) + return aot_module_malloc_internal((AOTModuleInstance *)module_inst, + exec_env, size, p_native_addr); +#endif + return 0; +} + +uint32 +wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 ptr, + uint32 size, void **p_native_addr) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) + return wasm_module_realloc_internal((WASMModuleInstance *)module_inst, + exec_env, ptr, size, p_native_addr); +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) + return aot_module_realloc_internal((AOTModuleInstance *)module_inst, + exec_env, ptr, size, p_native_addr); +#endif + return 0; +} + +void +wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 ptr) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + wasm_module_free_internal((WASMModuleInstance *)module_inst, exec_env, + ptr); + return; + } +#endif +#if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + aot_module_free_internal((AOTModuleInstance *)module_inst, exec_env, + ptr); + return; + } +#endif +} + uint32 wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size, void **p_native_addr) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 58db29e3e..00d5ba237 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -498,8 +498,9 @@ wasm_runtime_unload(WASMModuleCommon *module); /* Internal API */ WASMModuleInstanceCommon * wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst, - uint32 stack_size, uint32 heap_size, - char *error_buf, uint32 error_buf_size); + WASMExecEnv *exec_env_main, uint32 stack_size, + uint32 heap_size, char *error_buf, + uint32 error_buf_size); /* Internal API */ void @@ -675,6 +676,23 @@ wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst); +/* Internal API */ +uint32 +wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 size, + void **p_native_addr); + +/* Internal API */ +uint32 +wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 ptr, + uint32 size, void **p_native_addr); + +/* Internal API */ +void +wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst, + WASMExecEnv *exec_env, uint32 ptr); + /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN uint32 wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size, diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 9f08a484d..5548fad5a 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1003,7 +1003,7 @@ lookup_post_instantiate_func(WASMModuleInstance *module_inst, static bool execute_post_instantiate_functions(WASMModuleInstance *module_inst, - bool is_sub_inst) + bool is_sub_inst, WASMExecEnv *exec_env_main) { WASMFunctionInstance *start_func = module_inst->e->start_function; WASMFunctionInstance *initialize_func = NULL; @@ -1012,8 +1012,8 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, #if WASM_ENABLE_LIBC_WASI != 0 WASMModule *module = module_inst->module; #endif -#ifdef OS_ENABLE_HW_BOUND_CHECK WASMModuleInstanceCommon *module_inst_main = NULL; +#ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = NULL; #endif WASMExecEnv *exec_env = NULL; @@ -1057,25 +1057,29 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, return true; } -#ifdef OS_ENABLE_HW_BOUND_CHECK if (is_sub_inst) { - exec_env = exec_env_tls = wasm_runtime_get_exec_env_tls(); - if (exec_env_tls) { - /* Temporarily replace exec_env_tls's module inst to current - module inst to avoid checking failure when calling the - wasm functions, and ensure that the exec_env's module inst - is the correct one. */ - module_inst_main = exec_env_tls->module_inst; - exec_env_tls->module_inst = (WASMModuleInstanceCommon *)module_inst; - } - } + bh_assert(exec_env_main); +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env_tls = wasm_runtime_get_exec_env_tls(); + bh_assert(exec_env_tls == exec_env_main); + (void)exec_env_tls; #endif - if (!exec_env - && !(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + exec_env = exec_env_main; + + /* Temporarily replace parent exec_env's module inst to current + module inst to avoid checking failure when calling the + wasm functions, and ensure that the exec_env's module inst + is the correct one. */ + module_inst_main = exec_env_main->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; + } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } } /* Execute start function for both main insance and sub instance */ @@ -1101,23 +1105,17 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, ret = true; fail: -#ifdef OS_ENABLE_HW_BOUND_CHECK - if (is_sub_inst && exec_env_tls) { - bh_assert(exec_env == exec_env_tls); - /* Restore the exec_env_tls's module inst */ - exec_env_tls->module_inst = module_inst_main; - } + if (is_sub_inst) + /* Restore the parent exec_env's module inst */ + exec_env_main->module_inst = module_inst_main; else wasm_exec_env_destroy(exec_env); -#else - wasm_exec_env_destroy(exec_env); -#endif return ret; } static bool -execute_malloc_function(WASMModuleInstance *module_inst, +execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, WASMFunctionInstance *malloc_func, WASMFunctionInstance *retain_func, uint32 size, uint32 *p_result) @@ -1143,26 +1141,28 @@ execute_malloc_function(WASMModuleInstance *module_inst, argc = 2; } + if (exec_env) { #ifdef OS_ENABLE_HW_BOUND_CHECK - if (exec_env_tls != NULL) { - bh_assert(exec_env_tls->module_inst + if (exec_env_tls) { + bh_assert(exec_env_tls == exec_env); + } +#endif + bh_assert(exec_env->module_inst == (WASMModuleInstanceCommon *)module_inst); - ret = wasm_call_function(exec_env_tls, malloc_func, argc, argv); - - if (retain_func && ret) { - ret = wasm_call_function(exec_env_tls, retain_func, 1, argv); + } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; } } - else -#endif - { - ret = wasm_create_exec_env_and_call_function(module_inst, malloc_func, - argc, argv); - if (retain_func && ret) { - ret = wasm_create_exec_env_and_call_function(module_inst, - retain_func, 1, argv); - } + ret = wasm_call_function(exec_env, malloc_func, argc, argv); + + if (retain_func && ret) { + ret = wasm_call_function(exec_env, retain_func, 1, argv); } if (ret) @@ -1171,7 +1171,7 @@ execute_malloc_function(WASMModuleInstance *module_inst, } static bool -execute_free_function(WASMModuleInstance *module_inst, +execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, WASMFunctionInstance *free_func, uint32 offset) { #ifdef OS_ENABLE_HW_BOUND_CHECK @@ -1180,18 +1180,26 @@ execute_free_function(WASMModuleInstance *module_inst, uint32 argv[2]; argv[0] = offset; + + if (exec_env) { #ifdef OS_ENABLE_HW_BOUND_CHECK - if (exec_env_tls != NULL) { - bh_assert(exec_env_tls->module_inst - == (WASMModuleInstanceCommon *)module_inst); - return wasm_call_function(exec_env_tls, free_func, 1, argv); - } - else + if (exec_env_tls) { + bh_assert(exec_env_tls == exec_env); + } #endif - { - return wasm_create_exec_env_and_call_function(module_inst, free_func, 1, - argv); + bh_assert(exec_env->module_inst + == (WASMModuleInstanceCommon *)module_inst); } + else { + if (!(exec_env = + wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + + return wasm_call_function(exec_env, free_func, 1, argv); } #if WASM_ENABLE_MULTI_MODULE != 0 @@ -1210,7 +1218,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst, WASMModuleInstance *sub_module_inst = NULL; sub_module_inst = - wasm_instantiate(sub_module, false, stack_size, heap_size, + wasm_instantiate(sub_module, false, NULL, stack_size, heap_size, error_buf, error_buf_size); if (!sub_module_inst) { LOG_DEBUG("instantiate %s failed", @@ -1555,7 +1563,8 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode) * Instantiate module */ WASMModuleInstance * -wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, +wasm_instantiate(WASMModule *module, bool is_sub_inst, + WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size, char *error_buf, uint32 error_buf_size) { WASMModuleInstance *module_inst; @@ -2049,7 +2058,8 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, &module_inst->e->functions[module->start_function]; } - if (!execute_post_instantiate_functions(module_inst, is_sub_inst)) { + if (!execute_post_instantiate_functions(module_inst, is_sub_inst, + exec_env_main)) { set_error_buf(error_buf, error_buf_size, module_inst->cur_exception); goto fail; } @@ -2346,39 +2356,6 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function, return !wasm_copy_exception(module_inst, NULL); } -bool -wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst, - WASMFunctionInstance *func, - unsigned argc, uint32 argv[]) -{ - WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL; - bool ret; - -#if defined(OS_ENABLE_HW_BOUND_CHECK) - existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls(); -#elif WASM_ENABLE_THREAD_MGR != 0 - existing_exec_env = exec_env = - wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst); -#endif - - if (!existing_exec_env) { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; - } - } - - ret = wasm_runtime_call_wasm(exec_env, func, argc, argv); - - /* don't destroy the exec_env if it isn't created in this function */ - if (!existing_exec_env) - wasm_exec_env_destroy(exec_env); - - return ret; -} - #if WASM_ENABLE_PERF_PROFILING != 0 void wasm_dump_perf_profiling(const WASMModuleInstance *module_inst) @@ -2426,8 +2403,9 @@ wasm_dump_perf_profiling(const WASMModuleInstance *module_inst) #endif uint32 -wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, - void **p_native_addr) +wasm_module_malloc_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 size, + void **p_native_addr) { WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); uint8 *addr = NULL; @@ -2443,7 +2421,7 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, } else if (module_inst->e->malloc_function && module_inst->e->free_function) { if (!execute_malloc_function( - module_inst, module_inst->e->malloc_function, + module_inst, exec_env, module_inst->e->malloc_function, module_inst->e->retain_function, size, &offset)) { return 0; } @@ -2471,8 +2449,9 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, } uint32 -wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size, - void **p_native_addr) +wasm_module_realloc_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 ptr, uint32 size, + void **p_native_addr) { WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); uint8 *addr = NULL; @@ -2488,6 +2467,7 @@ wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size, } /* Only support realloc in WAMR's app heap */ + (void)exec_env; if (!addr) { if (memory->heap_handle @@ -2506,7 +2486,8 @@ wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size, } void -wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr) +wasm_module_free_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 ptr) { if (ptr) { WASMMemoryInstance *memory = wasm_get_default_memory(module_inst); @@ -2516,12 +2497,6 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr) return; } -#if WASM_ENABLE_SHARED_MEMORY != 0 - WASMSharedMemNode *node = wasm_module_get_shared_memory( - (WASMModuleCommon *)module_inst->module); - if (node) - os_mutex_lock(&node->shared_mem_lock); -#endif addr = memory->memory_data + ptr; if (memory->heap_handle && memory->heap_data <= addr @@ -2531,16 +2506,33 @@ wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr) else if (module_inst->e->malloc_function && module_inst->e->free_function && memory->memory_data <= addr && addr < memory->memory_data_end) { - execute_free_function(module_inst, module_inst->e->free_function, - ptr); + execute_free_function(module_inst, exec_env, + module_inst->e->free_function, ptr); } -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (node) - os_mutex_unlock(&node->shared_mem_lock); -#endif } } +uint32 +wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, + void **p_native_addr) +{ + return wasm_module_malloc_internal(module_inst, NULL, size, p_native_addr); +} + +uint32 +wasm_module_realloc(WASMModuleInstance *module_inst, uint32 ptr, uint32 size, + void **p_native_addr) +{ + return wasm_module_realloc_internal(module_inst, NULL, ptr, size, + p_native_addr); +} + +void +wasm_module_free(WASMModuleInstance *module_inst, uint32 ptr) +{ + wasm_module_free_internal(module_inst, NULL, ptr); +} + uint32 wasm_module_dup_data(WASMModuleInstance *module_inst, const char *src, uint32 size) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 1767c540a..15169433e 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -400,7 +400,8 @@ void wasm_unload(WASMModule *module); WASMModuleInstance * -wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, +wasm_instantiate(WASMModule *module, bool is_sub_inst, + WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size, char *error_buf, uint32 error_buf_size); void @@ -432,11 +433,6 @@ bool wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function, unsigned argc, uint32 argv[]); -bool -wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst, - WASMFunctionInstance *function, - unsigned argc, uint32 argv[]); - void wasm_set_exception(WASMModuleInstance *module, const char *exception); @@ -455,6 +451,20 @@ wasm_get_exception(WASMModuleInstance *module); bool wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf); +uint32 +wasm_module_malloc_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 size, + void **p_native_addr); + +uint32 +wasm_module_realloc_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 ptr, uint32 size, + void **p_native_addr); + +void +wasm_module_free_internal(WASMModuleInstance *module_inst, + WASMExecEnv *exec_env, uint32 ptr); + uint32 wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size, void **p_native_addr); diff --git a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c index d2ca601d9..fc82e969e 100644 --- a/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c +++ b/core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c @@ -581,7 +581,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env, #endif if (!(new_module_inst = wasm_runtime_instantiate_internal( - module, true, stack_size, 0, NULL, 0))) + module, true, exec_env, stack_size, 0, NULL, 0))) return -1; /* Set custom_data to new module instance */ diff --git a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c index db96898db..30d66076d 100644 --- a/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c +++ b/core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c @@ -90,7 +90,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg) stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size; if (!(new_module_inst = wasm_runtime_instantiate_internal( - module, true, stack_size, 0, NULL, 0))) + module, true, exec_env, stack_size, 0, NULL, 0))) return -1; wasm_runtime_set_custom_data_internal( diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 2bcdba3bd..107186ed2 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -143,8 +143,8 @@ allocate_aux_stack(WASMExecEnv *exec_env, uint32 *start, uint32 *size) wasm_exec_env_get_module_inst(exec_env); uint32 stack_end; - stack_end = - wasm_runtime_module_malloc(module_inst, cluster->stack_size, NULL); + stack_end = wasm_runtime_module_malloc_internal(module_inst, exec_env, + cluster->stack_size, NULL); *start = stack_end + cluster->stack_size; *size = cluster->stack_size; @@ -188,7 +188,8 @@ free_aux_stack(WASMExecEnv *exec_env, uint32 start) bh_assert(start >= cluster->stack_size); - wasm_runtime_module_free(module_inst, start - cluster->stack_size); + wasm_runtime_module_free_internal(module_inst, exec_env, + start - cluster->stack_size); return true; #else @@ -495,7 +496,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env) #endif if (!(new_module_inst = wasm_runtime_instantiate_internal( - module, true, stack_size, 0, NULL, 0))) { + module, true, exec_env, stack_size, 0, NULL, 0))) { goto fail1; } From c7cdb78394ae73026dc0bccc27ac0e9314b5b61e Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 24 Mar 2023 14:05:17 +0800 Subject: [PATCH 21/61] Fix issues reported by Coverity (#2053) Fix the potential dead lock issue reported by Coverity code analysis tool. --- core/iwasm/common/wasm_shared_memory.c | 1 + .../libraries/thread-mgr/thread_manager.c | 33 +++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 778d6e576..c5e78e43c 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -253,6 +253,7 @@ acquire_wait_info(void *address, AtomicWaitNode *wait_node) wait_info->wait_list = &wait_info->wait_list_head; ret = bh_list_init(wait_info->wait_list); bh_assert(ret == BH_LIST_SUCCESS); + (void)ret; if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) { wasm_runtime_free(wait_info); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 107186ed2..bfb89c089 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -382,9 +382,9 @@ wasm_cluster_add_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) return ret; } -/* The caller should lock cluster->lock for thread safety */ -bool -wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) +static bool +wasm_cluster_del_exec_env_internal(WASMCluster *cluster, WASMExecEnv *exec_env, + bool can_destroy_cluster) { bool ret = true; bh_assert(exec_env->cluster == cluster); @@ -407,13 +407,26 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) if (bh_list_remove(&cluster->exec_env_list, exec_env) != 0) ret = false; - if (cluster->exec_env_list.len == 0) { - /* exec_env_list empty, destroy the cluster */ - wasm_cluster_destroy(cluster); + if (can_destroy_cluster) { + if (cluster->exec_env_list.len == 0) { + /* exec_env_list empty, destroy the cluster */ + wasm_cluster_destroy(cluster); + } } + else { + /* Don't destroy cluster as cluster->lock is being used */ + } + return ret; } +/* The caller should lock cluster->lock for thread safety */ +bool +wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) +{ + return wasm_cluster_del_exec_env_internal(cluster, exec_env, true); +} + static WASMExecEnv * wasm_cluster_search_exec_env(WASMCluster *cluster, WASMModuleInstanceCommon *module_inst) @@ -561,7 +574,7 @@ wasm_cluster_destroy_spawned_exec_env(WASMExecEnv *exec_env) /* Free aux stack space */ free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom); /* Remove exec_env */ - wasm_cluster_del_exec_env(cluster, exec_env); + wasm_cluster_del_exec_env_internal(cluster, exec_env, false); /* Destroy exec_env */ wasm_exec_env_destroy_internal(exec_env); /* Routine exit, destroy instance */ @@ -621,7 +634,7 @@ thread_manager_start_routine(void *arg) /* Free aux stack space */ free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom); /* Remove exec_env */ - wasm_cluster_del_exec_env(cluster, exec_env); + wasm_cluster_del_exec_env_internal(cluster, exec_env, false); /* Destroy exec_env */ wasm_exec_env_destroy_internal(exec_env); /* Routine exit, destroy instance */ @@ -707,7 +720,7 @@ wasm_cluster_create_thread(WASMExecEnv *exec_env, return 0; fail4: - wasm_cluster_del_exec_env(cluster, new_exec_env); + wasm_cluster_del_exec_env_internal(cluster, new_exec_env, false); fail3: /* free the allocated aux stack space */ if (alloc_aux_stack) @@ -972,7 +985,7 @@ wasm_cluster_exit_thread(WASMExecEnv *exec_env, void *retval) /* Free aux stack space */ free_aux_stack(exec_env, exec_env->aux_stack_bottom.bottom); /* Remove exec_env */ - wasm_cluster_del_exec_env(cluster, exec_env); + wasm_cluster_del_exec_env_internal(cluster, exec_env, false); /* Destroy exec_env */ wasm_exec_env_destroy_internal(exec_env); /* Routine exit, destroy instance */ From 09a2698bba2658008bba13ccaac6b46606ee4b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A4mes=20M=C3=A9n=C3=A9trey?= Date: Fri, 24 Mar 2023 14:24:23 +0100 Subject: [PATCH 22/61] Remove a file test outside of the specs and improve CI reporting (#2057) Remove the test in the sample of file interaction that tries to extend the file at the end, because this is not supported by the specifications of fseek. The WASI exit code is now propagated by the runtime, so the CI will indicate when a test is failing. --- samples/file/src/main.c | 6 +++--- samples/file/wasm-app/main.c | 36 ++++++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/samples/file/src/main.c b/samples/file/src/main.c index 2fb99e255..3675ee057 100644 --- a/samples/file/src/main.c +++ b/samples/file/src/main.c @@ -20,7 +20,7 @@ main(int argc, char *argv_main[]) static char global_heap_buf[512 * 1024]; char *buffer, error_buf[128]; const char *wasm_path = NULL, *wasi_dir = NULL; - int opt; + int opt, main_result = 1; wasm_module_t module = NULL; wasm_module_inst_t module_inst = NULL; @@ -91,7 +91,7 @@ main(int argc, char *argv_main[]) } if (wasm_application_execute_main(module_inst, 0, NULL)) { - printf("Main wasm function successfully finished.\n"); + main_result = wasm_runtime_get_wasi_exit_code(module_inst); } else { printf("call wasm function main failed. error: %s\n", @@ -109,5 +109,5 @@ fail: if (buffer) BH_FREE(buffer); wasm_runtime_destroy(); - return 0; + return main_result; } diff --git a/samples/file/wasm-app/main.c b/samples/file/wasm-app/main.c index f4363475a..6e6204cca 100644 --- a/samples/file/wasm-app/main.c +++ b/samples/file/wasm-app/main.c @@ -99,8 +99,32 @@ main(int argc, char **argv) assert(ftell(file) == strlen(FILE_TEXT)); printf("[Test] Reading at specified offset passed.\n"); + // Test: moving at the start of the file (fseek) + printf("Move at the start of the file (fseek)..\n"); + printf("File current offset: %ld\n", ftell(file)); + fseek(file, 0, SEEK_SET); + printf("File current offset: %ld\n", ftell(file)); + assert(ftell(file) == 0); + + // Test: moving at the end of the file (fseek) + printf("Move at the end of the file (fseek)..\n"); + printf("File current offset: %ld\n", ftell(file)); + fseek(file, 0, SEEK_END); + printf("File current offset: %ld\n", ftell(file)); + assert(ftell(file) == strlen(FILE_TEXT)); + int end_position = ftell(file) / 2; + + // Test: moving at the middle of the file (fseek) + printf("Move at the middle of the file (fseek)..\n"); + printf("File current offset: %ld\n", ftell(file)); + fseek(file, 0, SEEK_SET); + fseek(file, end_position, SEEK_CUR); + printf("File current offset: %ld\n", ftell(file)); + assert(ftell(file) == end_position); + // Test: allocate more space to the file (posix_fallocate) printf("Allocate more space to the file (posix_fallocate)..\n"); + fseek(file, 0, SEEK_END); posix_fallocate(fileno(file), ftell(file), ADDITIONAL_SPACE); printf("File current offset: %ld\n", ftell(file)); printf("Moving to the end..\n"); @@ -120,7 +144,7 @@ main(int argc, char **argv) assert(ftell(file) == strlen(text) + 2 * ADDITIONAL_SPACE); printf("[Test] Extension of the file size passed.\n"); - // Test: allocate more space to the file (fseek) + // Test: allocate more space to the file (fseek, from the start) printf("Allocate more space to the file (fseek) from the start..\n"); printf("File current offset: %ld\n", ftell(file)); fseek(file, 3 * ADDITIONAL_SPACE, SEEK_SET); @@ -128,15 +152,7 @@ main(int argc, char **argv) assert(ftell(file) == 3 * ADDITIONAL_SPACE); printf("[Test] Extension of the file size passed.\n"); - // Test: allocate more space to the file (fseek) - printf("Allocate more space to the file (fseek) from the end..\n"); - printf("File current offset: %ld\n", ftell(file)); - fseek(file, ADDITIONAL_SPACE, SEEK_END); - printf("File current offset: %ld\n", ftell(file)); - assert(ftell(file) == 4 * ADDITIONAL_SPACE); - printf("[Test] Extension of the file size passed.\n"); - - // Test: allocate more space to the file (fseek) + // Test: allocate more space to the file (fseek, from the middle) printf("Allocate more space to the file (fseek) from the middle..\n"); fseek(file, 3 * ADDITIONAL_SPACE, SEEK_SET); printf("File current offset: %ld\n", ftell(file)); From b0f614d77ab8304888f37884193e7b9ee2ee781e Mon Sep 17 00:00:00 2001 From: Wang Xin Date: Sat, 25 Mar 2023 09:39:20 +0800 Subject: [PATCH 23/61] Add architecture diagram for wasm globals and classic-interp stack frame (#2058) --- README.md | 4 +- core/iwasm/README.md | 6 + core/iwasm/doc/classic_interpreter.MD | 5 + .../doc/images/stack_format_ci.excalidraw | 2643 +++++++++++++++++ core/iwasm/doc/images/stack_format_ci.svg | 16 + core/iwasm/doc/images/wasm_globals.excalidraw | 2313 +++++++++++++++ core/iwasm/doc/images/wasm_globals.svg | 16 + core/iwasm/doc/wasm_function.MD | 42 + core/iwasm/doc/wasm_globals.MD | 4 + doc/memory_tune.md | 2 +- 10 files changed, 5048 insertions(+), 3 deletions(-) create mode 100644 core/iwasm/doc/classic_interpreter.MD create mode 100644 core/iwasm/doc/images/stack_format_ci.excalidraw create mode 100644 core/iwasm/doc/images/stack_format_ci.svg create mode 100644 core/iwasm/doc/images/wasm_globals.excalidraw create mode 100644 core/iwasm/doc/images/wasm_globals.svg create mode 100644 core/iwasm/doc/wasm_globals.MD diff --git a/README.md b/README.md index bb09a279b..6b38195c1 100644 --- a/README.md +++ b/README.md @@ -70,8 +70,8 @@ The following platforms are supported, click each link below for how to build iw ### Performance and memory -- [Blog: Understand WAMR heap](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heap/) -- [Blog: Understand WAMR stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/) +- [Blog: The WAMR memory model](https://bytecodealliance.github.io/wamr.dev/blog/the-wamr-memory-model/) +- [Blog: Understand WAMR heaps](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heaps/) and [stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/) - [Blog: Introduction to WAMR running modes](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/) - [Memory usage tunning](./doc/memory_tune.md): the memory model and how to tune the memory usage - [Memory usage profiling](./doc/build_wamr.md#enable-memory-profiling-experiment): how to profile the memory usage diff --git a/core/iwasm/README.md b/core/iwasm/README.md index 31253c6ed..65ab78a49 100644 --- a/core/iwasm/README.md +++ b/core/iwasm/README.md @@ -6,3 +6,9 @@ ## Exports - [Wasm export architecture](./doc/wasm_exports.MD) + +## globals +- [Wasm globals architecture](./doc/wasm_globals.MD) + +## classic interpreter +- [classic interpreter](./doc/classic_interpreter.MD) \ No newline at end of file diff --git a/core/iwasm/doc/classic_interpreter.MD b/core/iwasm/doc/classic_interpreter.MD new file mode 100644 index 000000000..a607758e2 --- /dev/null +++ b/core/iwasm/doc/classic_interpreter.MD @@ -0,0 +1,5 @@ +# Classic interpreter + +## stack format + +![](./images/stack_format_ci.svg) \ No newline at end of file diff --git a/core/iwasm/doc/images/stack_format_ci.excalidraw b/core/iwasm/doc/images/stack_format_ci.excalidraw new file mode 100644 index 000000000..f2ade3b20 --- /dev/null +++ b/core/iwasm/doc/images/stack_format_ci.excalidraw @@ -0,0 +1,2643 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "type": "rectangle", + "version": 155, + "versionNonce": 1248561528, + "isDeleted": false, + "id": "fxSjNN3geJtdm-2MR7INN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 583.9999694824219, + "y": 276.33331298828114, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 427.66665649414057, + "height": 468.6667785644533, + "seed": 1226571556, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "zFlCnXyCuuvj85rH8yMcR", + "type": "arrow" + }, + { + "id": "KiC12zdfqG7zXRbctXGmT", + "type": "arrow" + } + ], + "updated": 1679706874848, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 31, + "versionNonce": 726044059, + "isDeleted": false, + "id": "kKMhPpSUI7zZU0hhfGfSr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 310.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 91, + "height": 20, + "seed": 1323166748, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "v8qOyuaPyJmHPHCk-V90A", + "type": "arrow" + } + ], + "updated": 1679639568750, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "prev_frame", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "prev_frame" + }, + { + "type": "text", + "version": 31, + "versionNonce": 213374372, + "isDeleted": false, + "id": "97vkuGwuf9dOgnbXL4nZW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 345.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 84, + "height": 20, + "seed": 123433892, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679617642914, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func_inst ", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func_inst " + }, + { + "type": "text", + "version": 31, + "versionNonce": 34601372, + "isDeleted": false, + "id": "IaZULBLAtP-VbIpB210WT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 380.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 13, + "height": 20, + "seed": 1157761180, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679617674900, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "ip", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ip" + }, + { + "type": "text", + "version": 37, + "versionNonce": 556583925, + "isDeleted": false, + "id": "H6AElOIjCOfKVDEzsEb8_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 648.3333435058594, + "y": 415.16668701171875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 160, + "height": 20, + "seed": 175464228, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + } + ], + "updated": 1679638914768, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "opnd_stack_bottom", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "opnd_stack_bottom" + }, + { + "type": "text", + "version": 31, + "versionNonce": 2114117339, + "isDeleted": false, + "id": "InrDJwTwyP1E7lpeGu0Tb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 450.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 275, + "height": 20, + "seed": 158242076, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + } + ], + "updated": 1679638694120, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "opnd_sp (point to opnd stack top)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "opnd_sp (point to opnd stack top)" + }, + { + "type": "text", + "version": 31, + "versionNonce": 1005029461, + "isDeleted": false, + "id": "04QcPfm0Sc1zQpYDxmPVl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 485.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 163, + "height": 20, + "seed": 2051398308, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679638792159, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "label_stack_bottom", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "label_stack_bottom" + }, + { + "type": "text", + "version": 31, + "versionNonce": 1565468827, + "isDeleted": false, + "id": "GD4urgWTuYKcn7FcwA5uj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 652, + "y": 520.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 280, + "height": 20, + "seed": 429232540, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "AhNgHym2Ox-2Je47FlwkG", + "type": "arrow" + } + ], + "updated": 1679638982669, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "label_sp (point to label stack top)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "label_sp (point to label stack top)" + }, + { + "type": "text", + "version": 123, + "versionNonce": 458495496, + "isDeleted": false, + "id": "9TW8AADnHJOkmP9yPw86T", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 626, + "y": 586.1666564941406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 125, + "height": 20, + "seed": 561702436, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706667761, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func arguments:", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func arguments:" + }, + { + "type": "text", + "version": 373, + "versionNonce": 180653176, + "isDeleted": false, + "id": "ZDnffzv8Hf65ecpMemz82", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 700.6666870117188, + "y": 669.1667785644531, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 131, + "height": 20, + "seed": 1157792164, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543900, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "" + }, + { + "type": "rectangle", + "version": 108, + "versionNonce": 628186232, + "isDeleted": false, + "id": "10UtZNhGhQIza4PqPLKs5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 622.6665954589844, + "y": 299.9999694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 378.3334655761719, + "height": 33.66670227050781, + "seed": 1281579428, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706899765, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 108, + "versionNonce": 1807107317, + "isDeleted": false, + "id": "lxiJENi5HY8EPwIeH7LA0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 621.9999389648438, + "y": 343.3332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 377.6668090820312, + "height": 28.33332824707031, + "seed": 523845788, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679639010923, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 104, + "versionNonce": 114288661, + "isDeleted": false, + "id": "iBGNXVvcsdhIuK4rSyr24", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 621.333251953125, + "y": 377.9999694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 380.3333129882813, + "height": 24.666656494140625, + "seed": 1117299228, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679639014926, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 141, + "versionNonce": 1756531061, + "isDeleted": false, + "id": "hwgrctAuxGaA-SGuwFgEd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 623.6665649414062, + "y": 413.66664123535156, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 190.33331298828125, + "height": 25.333358764648438, + "seed": 1885325596, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "2yVfQUtaAnW5BuEtoXRcA", + "type": "arrow" + } + ], + "updated": 1679638734395, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 135, + "versionNonce": 138906299, + "isDeleted": false, + "id": "V6DAmN9L5JPz2B1MGfa9C", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 624.6665954589844, + "y": 445.9999694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 377.6666564941406, + "height": 28.00003051757812, + "seed": 1058988452, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + } + ], + "updated": 1679638756269, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 171, + "versionNonce": 755362101, + "isDeleted": false, + "id": "0m59R0bqJv_x7GbZ6hfyg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 624.6665954589844, + "y": 485.33331298828125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 197.33340454101562, + "height": 23.33328247070314, + "seed": 1040920092, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + } + ], + "updated": 1679638908118, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 191, + "versionNonce": 944635675, + "isDeleted": false, + "id": "Itqs7rL1-S3eIrmvfrr6i", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 625.333251953125, + "y": 516.3333129882812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 349.66674804687506, + "height": 34.66665649414062, + "seed": 498379804, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679639029205, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 169, + "versionNonce": 1525847816, + "isDeleted": false, + "id": "Yx4QpHhmHHvf267ot4QcW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 623.333251953125, + "y": 582.6666259765625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 352.3333740234375, + "height": 31.666748046875, + "seed": 612410396, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543900, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 195, + "versionNonce": 335028795, + "isDeleted": false, + "id": "sWiDv3IP9Y4zn-pQPKT59", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 585.6668090820312, + "y": 203.99998474121094, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 424.3334045410156, + "height": 70.66668701171874, + "seed": 813710748, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "v8qOyuaPyJmHPHCk-V90A", + "type": "arrow" + } + ], + "updated": 1679639568750, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 255, + "versionNonce": 1953250680, + "isDeleted": false, + "id": "gS_VbgMS5NUoHmfxH0eEO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 752.0001525878906, + "y": 624.3333129882812, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 30.6666259765625, + "height": 19.000091552734375, + "seed": 2044515484, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543900, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 171, + "versionNonce": 227339384, + "isDeleted": false, + "id": "m89OexiP1cw5cN304gmQ-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 771.3336334228516, + "y": 587.8333282470703, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 37.999969482421875, + "height": 19.666748046875, + "seed": 2074557348, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706664521, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 174, + "versionNonce": 1205391112, + "isDeleted": false, + "id": "aAWksorEQDseQSDntTUKe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 824.6669464111328, + "y": 589.1665802001953, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 35.999969482421875, + "height": 15.666778564453123, + "seed": 1851711260, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706659367, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 213, + "versionNonce": 1798283016, + "isDeleted": false, + "id": "IH4D4tHy91CnkLlP3kKJT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 878.6669464111328, + "y": 588.8333892822266, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 35.999969482421875, + "height": 16.333435058593754, + "seed": 1835107492, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706677882, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 28, + "versionNonce": 1189712156, + "isDeleted": false, + "id": "OGXe0pARYj6FFaTw_LGLs", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 916.6667785644531, + "y": 348.3333435058594, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 13.33331298828125, + "height": 15.66668701171875, + "seed": 703955236, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "zFlCnXyCuuvj85rH8yMcR", + "type": "arrow" + } + ], + "updated": 1679617654572, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 90, + "versionNonce": 1752012152, + "isDeleted": false, + "id": "zFlCnXyCuuvj85rH8yMcR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 930.9664201728779, + "y": 355.9093759200581, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 97.70041942673151, + "height": 3.156306335738577, + "seed": 1652552228, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706533823, + "link": null, + "locked": false, + "startBinding": { + "elementId": "OGXe0pARYj6FFaTw_LGLs", + "gap": 1, + "focus": -0.05520408889747474 + }, + "endBinding": { + "elementId": "fxSjNN3geJtdm-2MR7INN", + "gap": 17.000213623046875, + "focus": 0.6588609578759657 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 97.70041942673151, + 3.156306335738577 + ] + ] + }, + { + "type": "rectangle", + "version": 39, + "versionNonce": 2081828900, + "isDeleted": false, + "id": "cN9omEMJtZq2pKK3nPqeK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1033.3334655761719, + "y": 339.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 218, + "height": 37, + "seed": 1716587932, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "w-Fx4nTROv9qvnPqLigxc" + } + ], + "updated": 1679617661526, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 4, + "versionNonce": 727129976, + "isDeleted": false, + "id": "w-Fx4nTROv9qvnPqLigxc", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1051.3334655761719, + "y": 347.5000305175781, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 182, + "height": 20, + "seed": 1245620124, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706461629, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "(current func instance)", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cN9omEMJtZq2pKK3nPqeK", + "originalText": "(current func instance)" + }, + { + "type": "diamond", + "version": 19, + "versionNonce": 1517445412, + "isDeleted": false, + "id": "YAWb1D32tq9r2NA9BjPC0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.3334655761719, + "y": 381.3333740234375, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 12.6666259765625, + "height": 17.666656494140625, + "seed": 831940124, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679617681098, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 103, + "versionNonce": 437077525, + "isDeleted": false, + "id": "EUw5VCdUqXWdPh2cmFgTu", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1048.0000915527344, + "y": 390.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 224, + "height": 52, + "seed": 122854564, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "sQUYAdB_aJemE8MbtfUXU" + }, + { + "id": "7cT6qctQMJuzVHVpt9gAe", + "type": "arrow" + } + ], + "updated": 1679643416466, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 89, + "versionNonce": 818328584, + "isDeleted": false, + "id": "sQUYAdB_aJemE8MbtfUXU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1066.0000915527344, + "y": 395.0000305175781, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 188, + "height": 40, + "seed": 1881253020, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706461630, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": " (next bytecode in code\nfor return)", + "baseline": 34, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "EUw5VCdUqXWdPh2cmFgTu", + "originalText": " (next bytecode in code\nfor return)" + }, + { + "type": "arrow", + "version": 86, + "versionNonce": 44769845, + "isDeleted": false, + "id": "7cT6qctQMJuzVHVpt9gAe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 928.0000915527344, + "y": 389.66668701171875, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 118.6890752940651, + "height": 18.605575795885613, + "seed": 2073584156, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643418552, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "EUw5VCdUqXWdPh2cmFgTu", + "gap": 1.3109247059348494, + "focus": -0.23038166167021662 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 118.6890752940651, + 18.605575795885613 + ] + ] + }, + { + "type": "rectangle", + "version": 2, + "versionNonce": 504035291, + "isDeleted": false, + "id": "6fkbi-hv-WF274Ggup6O2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1200.0001525878906, + "y": 619.8332824707031, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.333251953125, + "height": 0.333343505859375, + "seed": 1881722357, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1679638527376, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 237, + "versionNonce": 103104376, + "isDeleted": false, + "id": "TBY_IOcQ1nL2SbnoH6sFO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 627.0001373291016, + "y": 660.5000610351562, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 357.33331298828125, + "height": 30.33352661132812, + "seed": 1619080725, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + }, + { + "id": "2yVfQUtaAnW5BuEtoXRcA", + "type": "arrow" + } + ], + "updated": 1679706543900, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 304, + "versionNonce": 1231721480, + "isDeleted": false, + "id": "2yVfQUtaAnW5BuEtoXRcA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1001.4951265607561, + "y": 435.4648501924554, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 69.86595546390652, + "height": 230.92727975758817, + "seed": 554350997, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": { + "elementId": "Q10gr2u0Ozc3e0iafNjrU", + "focus": -0.9749635321679403, + "gap": 1 + }, + "endBinding": { + "elementId": "TBY_IOcQ1nL2SbnoH6sFO", + "gap": 11.467449077109102, + "focus": 0.9687666106437038 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 64.17172829764229, + 132.70180630168522 + ], + [ + -5.694227166264227, + 230.92727975758817 + ] + ] + }, + { + "type": "arrow", + "version": 579, + "versionNonce": 1040896776, + "isDeleted": false, + "id": "bzZuzwhAslOM0VOMpIFi4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 637.088614263612, + "y": 428.66374830753944, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 87.42185095794798, + "height": 243.67105886528202, + "seed": 1778263445, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": { + "elementId": "H6AElOIjCOfKVDEzsEb8_", + "focus": 1.022917371543073, + "gap": 11.244729242247331 + }, + "endBinding": { + "elementId": "zmGNXD3FjbK3cLzJQcTS7", + "focus": -0.9191849396644245, + "gap": 1.3880431063754486 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -87.42185095794798, + 127.50287766902306 + ], + [ + -10.80983302916718, + 243.67105886528202 + ] + ] + }, + { + "type": "rectangle", + "version": 146, + "versionNonce": 1195282552, + "isDeleted": false, + "id": "zmGNXD3FjbK3cLzJQcTS7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 627.6668243408203, + "y": 662.8332824707031, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 207.333251953125, + "height": 25.333343505859375, + "seed": 2075064181, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "bzZuzwhAslOM0VOMpIFi4", + "type": "arrow" + }, + { + "id": "PtPViQVeIOLGj_fGdcXae", + "type": "arrow" + } + ], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 252, + "versionNonce": 1380659720, + "isDeleted": false, + "id": "fdKDasbQmnSQhVWnuc6o0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 892.2284992953181, + "y": 676.9139215503409, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 46.77163803378346, + "height": 0.7472955737783877, + "seed": 2138378229, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 46.77163803378346, + -0.7472955737783877 + ] + ] + }, + { + "type": "text", + "version": 63, + "versionNonce": 2032367925, + "isDeleted": false, + "id": "ZwrESUGUwekFgJ8cot-D1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 821.6667327880859, + "y": 414.6666259765625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 174, + "height": 20, + "seed": 795089589, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "2yVfQUtaAnW5BuEtoXRcA", + "type": "arrow" + } + ], + "updated": 1679638757542, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "opnd_stack_boundary", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "opnd_stack_boundary" + }, + { + "type": "rectangle", + "version": 32, + "versionNonce": 132303029, + "isDeleted": false, + "id": "VOinNwnsGZVJt9RUbM5gI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 821.3334197998047, + "y": 409.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 184.3333740234375, + "height": 30.333328247070312, + "seed": 1069875285, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679638823023, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 255, + "versionNonce": 453362040, + "isDeleted": false, + "id": "PtPViQVeIOLGj_fGdcXae", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 979.6667327880859, + "y": 460.4999694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 140.89037965104183, + "height": 211.49970410546382, + "seed": 472939093, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "zmGNXD3FjbK3cLzJQcTS7", + "focus": 0.7843520090394333, + "gap": 6.109589831379935 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.33331298828125, + 145 + ], + [ + -138.55706666276058, + 211.49970410546382 + ] + ] + }, + { + "type": "diamond", + "version": 19, + "versionNonce": 987485307, + "isDeleted": false, + "id": "u7bglMSX07f5CN_SyFAmd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 967.0000457763672, + "y": 452.1666259765625, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 15, + "height": 15, + "seed": 764957403, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679638777911, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 43, + "versionNonce": 115610933, + "isDeleted": false, + "id": "shh1k5OswcF57jhAKAI6G", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 830.0000457763672, + "y": 486.8332824707031, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 176, + "height": 20, + "seed": 1994374395, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679638809874, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "label_stack_boundary", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "label_stack_boundary" + }, + { + "type": "rectangle", + "version": 33, + "versionNonce": 1511042715, + "isDeleted": false, + "id": "H4lcjS3aIarViIGAHsLBU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 827.6667327880859, + "y": 480.83331298828125, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 181, + "height": 29.666656494140625, + "seed": 1492829339, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679638816247, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 372, + "versionNonce": 1764776968, + "isDeleted": false, + "id": "B1eH_aNspf4OoiXnvWu1V", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 630.0000915527344, + "y": 705.1667175292969, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 356.66662597656256, + "height": 31.333404541015625, + "seed": 710054491, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "X76to9wjER3VzqXb7tCwb", + "type": "arrow" + }, + { + "id": "1Urs2i0MGQSQ9XbOVdbCH", + "type": "arrow" + }, + { + "id": "KiC12zdfqG7zXRbctXGmT", + "type": "arrow" + } + ], + "updated": 1679706706153, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 332, + "versionNonce": 1981566984, + "isDeleted": false, + "id": "Tu7mkiWTjNwFrOsUa35N1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 633.3333740234375, + "y": 704.8334045410156, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 250.33328247070318, + "height": 26.66656494140625, + "seed": 1201312981, + "groupIds": [], + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "AhNgHym2Ox-2Je47FlwkG", + "type": "arrow" + } + ], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 250, + "versionNonce": 1696927496, + "isDeleted": false, + "id": "xQf_fS4j5XD1gPYVmnyQi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 687, + "y": 709.8335876464844, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 108, + "height": 20, + "seed": 1671092892, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "" + }, + { + "type": "diamond", + "version": 19, + "versionNonce": 167262267, + "isDeleted": false, + "id": "T43dNIeAePPWy65vsVjRw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 629.0000457763672, + "y": 420.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 13.66668701171875, + "height": 9, + "seed": 1938681499, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679638923749, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 26, + "versionNonce": 1796989173, + "isDeleted": false, + "id": "Q10gr2u0Ozc3e0iafNjrU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 988.5000762939453, + "y": 431.9999542236328, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 13.66668701171875, + "height": 9, + "seed": 1339643477, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "2yVfQUtaAnW5BuEtoXRcA", + "type": "arrow" + } + ], + "updated": 1679639079224, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 160, + "versionNonce": 1562882312, + "isDeleted": false, + "id": "X76to9wjER3VzqXb7tCwb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 633.6667327880859, + "y": 498.1665954589844, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 95, + "height": 226.4773119076067, + "seed": 332801877, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "B1eH_aNspf4OoiXnvWu1V", + "gap": 3.7751266782821933, + "focus": -0.9692106196282059 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -95, + 119 + ], + [ + -7.441767913633839, + 226.4773119076067 + ] + ] + }, + { + "type": "arrow", + "version": 202, + "versionNonce": 791528312, + "isDeleted": false, + "id": "1Urs2i0MGQSQ9XbOVdbCH", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 993.6667327880859, + "y": 500.833251953125, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 55.58884147480535, + "height": 215.3311147859538, + "seed": 385950459, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": { + "elementId": "_1a_M2hRRjsccFJTYD-i0", + "focus": -0.27052637703325505, + "gap": 2.7105616084241397 + }, + "endBinding": { + "elementId": "B1eH_aNspf4OoiXnvWu1V", + "focus": 0.9207393546998478, + "gap": 3.0779218308585996 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 51.666748046875, + 153.66668701171875 + ], + [ + -3.922093427930349, + 215.3311147859538 + ] + ] + }, + { + "type": "arrow", + "version": 252, + "versionNonce": 1150719096, + "isDeleted": false, + "id": "AhNgHym2Ox-2Je47FlwkG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 941.0000457763672, + "y": 533.833251953125, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 73.73891815660659, + "height": 177.63880524698254, + "seed": 17032283, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": { + "elementId": "GD4urgWTuYKcn7FcwA5uj", + "focus": -1.0502037458670375, + "gap": 9.000045776367188 + }, + "endBinding": { + "elementId": "Tu7mkiWTjNwFrOsUa35N1", + "focus": 0.7914007600477917, + "gap": 2.5944100904637253 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 18.99993896484375, + 133.33340454101562 + ], + [ + -54.73897919176284, + 177.63880524698254 + ] + ] + }, + { + "type": "diamond", + "version": 19, + "versionNonce": 987485307, + "isDeleted": false, + "id": "C2JNNEQlhQ4cFy2h16E4l", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 630.5000457763672, + "y": 491.333251953125, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 15, + "height": 15, + "seed": 2047712475, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679638991963, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 19, + "versionNonce": 987485307, + "isDeleted": false, + "id": "xsWhegnNTDUvjVk1Hl20d", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 931.5000457763672, + "y": 523.333251953125, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 15, + "height": 15, + "seed": 751530581, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679638994246, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 20, + "versionNonce": 2123101557, + "isDeleted": false, + "id": "_1a_M2hRRjsccFJTYD-i0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 987.5000457763672, + "y": 503.333251953125, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 15, + "height": 15, + "seed": 1838893435, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [ + { + "id": "1Urs2i0MGQSQ9XbOVdbCH", + "type": "arrow" + } + ], + "updated": 1679639046142, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 122, + "versionNonce": 918373752, + "isDeleted": false, + "id": "_FzrYgawOp32aihqUkx8N", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 937.3333587646484, + "y": 722.4999084472656, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 31, + "height": 0.333343505859375, + "seed": 125027067, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 31, + 0.333343505859375 + ] + ] + }, + { + "type": "arrow", + "version": 58, + "versionNonce": 1791510299, + "isDeleted": false, + "id": "v8qOyuaPyJmHPHCk-V90A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 640.33349609375, + "y": 318.1665954589844, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 112.66668701171875, + "height": 114.41643468378521, + "seed": 1521072891, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679639586455, + "link": null, + "locked": false, + "startBinding": { + "elementId": "kKMhPpSUI7zZU0hhfGfSr", + "focus": -0.8312315870337287, + "gap": 11.66650390625 + }, + "endBinding": { + "elementId": "sWiDv3IP9Y4zn-pQPKT59", + "focus": 1.0049483520293248, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -112.66668701171875, + -61.99995422363281 + ], + [ + -55.63497828298284, + -114.41643468378521 + ] + ] + }, + { + "type": "diamond", + "version": 23, + "versionNonce": 1760592469, + "isDeleted": false, + "id": "rizowRaNCY3sscSKdUoZ_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 637.6668090820312, + "y": 307.49993896484375, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 11.66668701171875, + "height": 17, + "seed": 599455541, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679639578366, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 241, + "versionNonce": 1517501429, + "isDeleted": false, + "id": "Mv8lernCpH2jNrVrNfqm5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 585.8334503173828, + "y": 130.833251953125, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 424.3334045410156, + "height": 70.66668701171874, + "seed": 1040624571, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "cl6Duxg7hC4_1chb5YNau", + "type": "arrow" + } + ], + "updated": 1679639602774, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 41, + "versionNonce": 926996117, + "isDeleted": false, + "id": "eQrRfUHvRypTcFfQ80nK5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 647.0000610351562, + "y": 219.33328247070312, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 91, + "height": 20, + "seed": 1884598901, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "cl6Duxg7hC4_1chb5YNau", + "type": "arrow" + } + ], + "updated": 1679639602774, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "prev_frame", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "prev_frame" + }, + { + "type": "diamond", + "version": 32, + "versionNonce": 784602165, + "isDeleted": false, + "id": "w_RQs6dyVbTAM3iaX46G2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 632.6668701171875, + "y": 216.33322143554688, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 11.66668701171875, + "height": 17, + "seed": 1918737243, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679639598842, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 135, + "versionNonce": 1953671957, + "isDeleted": false, + "id": "cl6Duxg7hC4_1chb5YNau", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 639.0001525878906, + "y": 224.16659545898438, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 80.33334350585938, + "height": 95, + "seed": 509490587, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679639608498, + "link": null, + "locked": false, + "startBinding": { + "elementId": "eQrRfUHvRypTcFfQ80nK5", + "focus": -0.7568501325114791, + "gap": 7.999908447265625 + }, + "endBinding": { + "elementId": "Mv8lernCpH2jNrVrNfqm5", + "focus": 1.0067042515978792, + "gap": 1.666656494140625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -80.33334350585938, + -53.66668701171875 + ], + [ + -53.66668701171875, + -95 + ] + ] + }, + { + "type": "text", + "version": 196, + "versionNonce": 1763609493, + "isDeleted": false, + "id": "7pum3cjupgQ0Fz7eY_3xD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1026.33349609375, + "y": 123.83326721191406, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 109, + "height": 20, + "seed": 1300737371, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679640276534, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Stack bottom", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Stack bottom" + }, + { + "type": "text", + "version": 310, + "versionNonce": 1972102043, + "isDeleted": false, + "id": "Su_2hWwLvhW5W8cNMx6hT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1030.666748046875, + "y": 266.8333206176758, + "strokeColor": "#000000", + "backgroundColor": "#12b886", + "width": 110, + "height": 20, + "seed": 2131950293, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679640279741, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "current frame", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "current frame" + }, + { + "type": "rectangle", + "version": 181, + "versionNonce": 1099516792, + "isDeleted": false, + "id": "jCBotdnPaPF-NkuwgrLyd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 582.3333129882812, + "y": 744.8332977294922, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 429.666748046875, + "height": 48.333343505859396, + "seed": 1136750491, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706699607, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 167, + "versionNonce": 647398264, + "isDeleted": false, + "id": "BRMXHqjjvaWADtilYg0NV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 784.3333740234375, + "y": 775.8333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 57, + "height": 20, + "seed": 415943189, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "KiC12zdfqG7zXRbctXGmT", + "type": "arrow" + } + ], + "updated": 1679706708714, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Unused", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Unused" + }, + { + "type": "text", + "version": 179, + "versionNonce": 1210985736, + "isDeleted": false, + "id": "6YoFb1tMeQkuEDMy5H4FV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1018.6668090820312, + "y": 778.8333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 122, + "height": 20, + "seed": 1257872437, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706711595, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "stack boundary", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "stack boundary" + }, + { + "type": "text", + "version": 174, + "versionNonce": 314437128, + "isDeleted": false, + "id": "_e0Yy4p4UD9MNJUym2U_N", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1025.6666259765625, + "y": 732.8335113525391, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 20, + "seed": 521361589, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "stack top", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "stack top" + }, + { + "type": "rectangle", + "version": 126, + "versionNonce": 1927665272, + "isDeleted": false, + "id": "ATaMGJS9emfaD_vgxw4Wi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 625.5619915078412, + "y": 621.4944998254441, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 358.66670227050787, + "height": 25.999969482421875, + "seed": 1247140509, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 268, + "versionNonce": 1190911752, + "isDeleted": false, + "id": "qlKC-UwDGQErtLa5oG6C3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 625.3333740234375, + "y": 554.1666870117188, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 236, + "height": 20, + "seed": 1957232156, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706639231, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Wasm LOCALs (local.set/get):", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Wasm LOCALs (local.set/get):" + }, + { + "type": "rectangle", + "version": 264, + "versionNonce": 500451192, + "isDeleted": false, + "id": "CnBSoD9DNI5Himd9gJXwV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 787.8953006814252, + "y": 625.661102913823, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 30.6666259765625, + "height": 19.000091552734375, + "seed": 1737116886, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 259, + "versionNonce": 235932680, + "isDeleted": false, + "id": "z4Ye9_zQDUab5ewn2mujX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 827.5619876931439, + "y": 623.9944159021043, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 30.6666259765625, + "height": 19.000091552734375, + "seed": 1207868746, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 292, + "versionNonce": 600610936, + "isDeleted": false, + "id": "V3_r6rtZsp-pFDhmttdsh", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 865.5620487283002, + "y": 625.3277594079636, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 30.6666259765625, + "height": 19.000091552734375, + "seed": 974809482, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 266, + "versionNonce": 1061243656, + "isDeleted": false, + "id": "Tov8P7W3W8Zmma9a3S8gP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 904.5620487283002, + "y": 626.661102913823, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 30.6666259765625, + "height": 19.000091552734375, + "seed": 1423773654, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679706543901, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 148, + "versionNonce": 1167673464, + "isDeleted": false, + "id": "KiC12zdfqG7zXRbctXGmT", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 806.4613995527118, + "y": 748.8279119958543, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 2.161352857758061, + "height": 20.33328247070324, + "seed": 167487754, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679706706153, + "link": null, + "locked": false, + "startBinding": { + "elementId": "B1eH_aNspf4OoiXnvWu1V", + "focus": 0.026931962058821583, + "gap": 12.327789925541765 + }, + "endBinding": { + "elementId": "fxSjNN3geJtdm-2MR7INN", + "focus": -0.06989783256192499, + "gap": 24.16110291382313 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.161352857758061, + 20.33328247070324 + ] + ] + }, + { + "type": "text", + "version": 151, + "versionNonce": 1430888312, + "isDeleted": false, + "id": "wBnV18_fVimstqpfPY0KR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 631.4456683895414, + "y": 624.6666107177734, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 91, + "height": 20, + "seed": 1961347080, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1679706671751, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "func locals:", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "func locals:" + }, + { + "id": "8Y0Qz7jDPtVE84-d_UHu2", + "type": "rectangle", + "x": 613.2790118954008, + "y": 575.9999542236328, + "width": 384.0000305175781, + "height": 76.66668701171875, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": { + "type": 3 + }, + "seed": 743618568, + "version": 80, + "versionNonce": 129563000, + "isDeleted": false, + "boundElements": null, + "updated": 1679706644458, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/core/iwasm/doc/images/stack_format_ci.svg b/core/iwasm/doc/images/stack_format_ci.svg new file mode 100644 index 000000000..f054c4345 --- /dev/null +++ b/core/iwasm/doc/images/stack_format_ci.svg @@ -0,0 +1,16 @@ + + + + + + + prev_framefunc_inst ipopnd_stack_bottomopnd_sp (point to opnd stack top)label_stack_bottomlabel_sp (point to label stack top)func arguments:<operand stack>(current func instance) (next bytecode in codefor return)opnd_stack_boundarylabel_stack_boundary<lable stack>prev_frameStack bottomcurrent frameUnusedstack boundarystack topWasm LOCALs (local.set/get):func locals: \ No newline at end of file diff --git a/core/iwasm/doc/images/wasm_globals.excalidraw b/core/iwasm/doc/images/wasm_globals.excalidraw new file mode 100644 index 000000000..947153520 --- /dev/null +++ b/core/iwasm/doc/images/wasm_globals.excalidraw @@ -0,0 +1,2313 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "type": "rectangle", + "version": 381, + "versionNonce": 2068900405, + "isDeleted": false, + "id": "D5Ay5TxydaAe4f80l_79L", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 982.833251953125, + "y": 298.00006103515625, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 99.666748046875, + "height": 211.00007629394523, + "seed": 1123866381, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "5S0qe2-BjQRPwuEEQ_UsU", + "type": "arrow" + } + ], + "updated": 1679660991439, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 317, + "versionNonce": 1880855285, + "isDeleted": false, + "id": "4JTzPDASWmnx1PVSabO3A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 914.833251953125, + "y": 236.3333282470703, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 103, + "height": 20, + "seed": 422161475, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661135316, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "global_data:", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "global_data:" + }, + { + "type": "text", + "version": 183, + "versionNonce": 1437992789, + "isDeleted": false, + "id": "HQjUeFzLlihuH1Lf8XZQq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 528.1666870117188, + "y": 324.00001525878906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 274, + "height": 20, + "seed": 2018585571, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661163124, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstanceExtra::globals", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstanceExtra::globals" + }, + { + "type": "arrow", + "version": 453, + "versionNonce": 92905717, + "isDeleted": false, + "id": "I86Qg5wzdmE77J5SbA7HP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 759.0470523835444, + "y": 472.4753157819668, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 223.44867715016005, + "height": 152.25013181880155, + "seed": 661894701, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "Qm7oDN7yJzVFQrCa0EE1G" + } + ], + "updated": 1679660991440, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "Sd34CflTFN9Elv1dedCI1", + "focus": 0.9595350520837825, + "gap": 4.004209431139316 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 223.44867715016005, + -152.25013181880155 + ] + ] + }, + { + "type": "text", + "version": 4, + "versionNonce": 2089047221, + "isDeleted": false, + "id": "Qm7oDN7yJzVFQrCa0EE1G", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 844.2713909586244, + "y": 386.350249872566, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 53, + "height": 20, + "seed": 1720249052, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661201718, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "offset", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "I86Qg5wzdmE77J5SbA7HP", + "originalText": "offset" + }, + { + "type": "rectangle", + "version": 213, + "versionNonce": 1454183483, + "isDeleted": false, + "id": "Sd34CflTFN9Elv1dedCI1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 986.4999389648438, + "y": 315.6666564941406, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 91.66668701171875, + "height": 27.999999999999996, + "seed": 357984397, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "I86Qg5wzdmE77J5SbA7HP", + "type": "arrow" + } + ], + "updated": 1679660991440, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 192, + "versionNonce": 706008283, + "isDeleted": false, + "id": "X5nXXDxRcZputNDZp2WfW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 984.4998779296875, + "y": 350.83333587646484, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 94.3333740234375, + "height": 19.333358764648438, + "seed": 1611395779, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "PFkOKGbMOcdhcpcv4DutQ", + "type": "arrow" + } + ], + "updated": 1679660991442, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 369, + "versionNonce": 1307818581, + "isDeleted": false, + "id": "PFkOKGbMOcdhcpcv4DutQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 753.8716651262948, + "y": 690.3334503173828, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 220.3341412661283, + "height": 341.60985534904495, + "seed": 1747362403, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "MPb6tVMlSBtnXhUTpZvIC" + } + ], + "updated": 1679660991442, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "X5nXXDxRcZputNDZp2WfW", + "gap": 5.794568769140314, + "focus": 1.2182487723741706 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 220.3341412661283, + -341.60985534904495 + ] + ] + }, + { + "type": "text", + "version": 4, + "versionNonce": 1008745755, + "isDeleted": false, + "id": "MPb6tVMlSBtnXhUTpZvIC", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 837.538735759359, + "y": 509.52852264286037, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 53, + "height": 20, + "seed": 1880081892, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661201719, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "offset", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "PFkOKGbMOcdhcpcv4DutQ", + "originalText": "offset" + }, + { + "type": "text", + "version": 429, + "versionNonce": 147921333, + "isDeleted": false, + "id": "5GnY6Vq9qPDS0ntZW3UOE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.166748046875, + "y": 259.3333282470703, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 197, + "height": 20, + "seed": 1179957165, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661138960, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "hold values of GLOBALs", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "hold values of GLOBALs" + }, + { + "type": "rectangle", + "version": 234, + "versionNonce": 339097851, + "isDeleted": false, + "id": "FcG2LCAdKxw_z2SzLhPPr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 548.3333129882812, + "y": 351.666748046875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 228.66668701171866, + "height": 299.66668701171875, + "seed": 407083364, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "_acaSZ2N5FSiuPGQjH8RA", + "type": "arrow" + } + ], + "updated": 1679660870990, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 182, + "versionNonce": 1735336804, + "isDeleted": false, + "id": "OdBdX2K4Kcn9Hq7vInwKA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 571, + "y": 387.3333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 190, + "height": 30, + "seed": 175211612, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "OZDTfM4SDGXEVbxgCAbsx" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 135, + "versionNonce": 1695691996, + "isDeleted": false, + "id": "OZDTfM4SDGXEVbxgCAbsx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 621.5, + "y": 392.3333740234375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 89, + "height": 20, + "seed": 1994750564, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint8 type;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "OdBdX2K4Kcn9Hq7vInwKA", + "originalText": "uint8 type;" + }, + { + "type": "text", + "version": 174, + "versionNonce": 2063524661, + "isDeleted": false, + "id": "w5el7zqw5vcK9RGIcDlFZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 580.9999389648438, + "y": 357.8333435058594, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 171, + "height": 19, + "seed": 1831729636, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "_acaSZ2N5FSiuPGQjH8RA", + "type": "arrow" + } + ], + "updated": 1679660882880, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMGlobalInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMGlobalInstance" + }, + { + "type": "rectangle", + "version": 147, + "versionNonce": 1194277212, + "isDeleted": false, + "id": "gd9UxDYh5XZYBG_P0f0c2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 568.3333129882812, + "y": 424.666748046875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 195, + "height": 30, + "seed": 1018791012, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "YeoEjoPWRnxxyB2DjNi3g" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 104, + "versionNonce": 1904253540, + "isDeleted": false, + "id": "YeoEjoPWRnxxyB2DjNi3g", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 600.8333129882812, + "y": 429.666748046875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 130, + "height": 20, + "seed": 839439588, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "bool is_mutable;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "gd9UxDYh5XZYBG_P0f0c2", + "originalText": "bool is_mutable;" + }, + { + "type": "rectangle", + "version": 91, + "versionNonce": 1480043996, + "isDeleted": false, + "id": "MB23InQWKES3OnYie8bbP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 569.6666870117188, + "y": 460.666748046875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 195, + "height": 30, + "seed": 1468762332, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "--vP8lM62PEnMBhgFRqTM" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 63, + "versionNonce": 717729252, + "isDeleted": false, + "id": "--vP8lM62PEnMBhgFRqTM", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 582.6666870117188, + "y": 465.666748046875, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 169, + "height": 20, + "seed": 695551844, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint32 data_offset;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "MB23InQWKES3OnYie8bbP", + "originalText": "uint32 data_offset;" + }, + { + "type": "rectangle", + "version": 111, + "versionNonce": 155030108, + "isDeleted": false, + "id": "pUUma4amJviNKdfn5otpb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 577.6666870117188, + "y": 497.33338928222656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 180.33331298828125, + "height": 30, + "seed": 1550527844, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "JybtW1PyDYQa00JaSYsuo" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 63, + "versionNonce": 1625313636, + "isDeleted": false, + "id": "JybtW1PyDYQa00JaSYsuo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 618.8333435058594, + "y": 502.33338928222656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98, + "height": 20, + "seed": 1952693084, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "initial_value", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "pUUma4amJviNKdfn5otpb", + "originalText": "initial_value" + }, + { + "type": "rectangle", + "version": 91, + "versionNonce": 1494410972, + "isDeleted": false, + "id": "CewuQtNj0ZC6Ogsq68ite", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 569.6666870117188, + "y": 546.6667022705078, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 191, + "height": 30, + "seed": 10317668, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "4xSFF2vFZIoA0G7GTeC8-" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 63, + "versionNonce": 588809444, + "isDeleted": false, + "id": "4xSFF2vFZIoA0G7GTeC8-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 588.1666870117188, + "y": 551.6667022705078, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 154, + "height": 20, + "seed": 1109403492, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "import_module_inst", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "CewuQtNj0ZC6Ogsq68ite", + "originalText": "import_module_inst" + }, + { + "type": "rectangle", + "version": 123, + "versionNonce": 474590044, + "isDeleted": false, + "id": "AuHfz77U4KxNTCmKvW6bJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 573, + "y": 589.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 184, + "height": 30, + "seed": 2058570588, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "h7MfnIO2f08rV_U7840Zp" + } + ], + "updated": 1679643912221, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 75, + "versionNonce": 1727940708, + "isDeleted": false, + "id": "h7MfnIO2f08rV_U7840Zp", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 591, + "y": 594.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 148, + "height": 20, + "seed": 1917882340, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643912221, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "import_global_inst", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "AuHfz77U4KxNTCmKvW6bJ", + "originalText": "import_global_inst" + }, + { + "type": "text", + "version": 134, + "versionNonce": 1361481211, + "isDeleted": false, + "id": "Clf1NqZqRXJuRl-CQgx_u", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 232.6667175292969, + "y": 454.6668395996094, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 237, + "height": 20, + "seed": 1711793252, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "_acaSZ2N5FSiuPGQjH8RA", + "type": "arrow" + } + ], + "updated": 1679661000688, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMGlobalInstance *globals;", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMGlobalInstance *globals;" + }, + { + "type": "text", + "version": 30, + "versionNonce": 1504826724, + "isDeleted": false, + "id": "Mj7l2FOHQ7NNAkTiGq7T_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 641, + "y": 631.0001373291016, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 29, + "height": 20, + "seed": 1401608924, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643959727, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[0]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[0]" + }, + { + "type": "rectangle", + "version": 52, + "versionNonce": 894397020, + "isDeleted": false, + "id": "CGwcN3BpsJaehLlHjEn6l", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 548.6666259765625, + "y": 653.0000457763672, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 227, + "height": 87, + "seed": 253331684, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644065258, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 107, + "versionNonce": 1424372828, + "isDeleted": false, + "id": "YjTAPKLSA0k-ml5j0Ho59", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 565.1666259765625, + "y": 671.6667327880859, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 195, + "height": 30, + "seed": 192441436, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "jmlAM3nHo1CJVxGKppt1O" + } + ], + "updated": 1679643968867, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 78, + "versionNonce": 2064306020, + "isDeleted": false, + "id": "jmlAM3nHo1CJVxGKppt1O", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 578.1666259765625, + "y": 676.6667327880859, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 169, + "height": 20, + "seed": 1473779556, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643968868, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint32 data_offset;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "YjTAPKLSA0k-ml5j0Ho59", + "originalText": "uint32 data_offset;" + }, + { + "type": "text", + "version": 32, + "versionNonce": 1512962780, + "isDeleted": false, + "id": "QnLh-KZNv_MoD4Ak5RsLk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 636.1666259765625, + "y": 719.0000457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 22, + "height": 20, + "seed": 927449564, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679643979051, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[1]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[1]" + }, + { + "type": "rectangle", + "version": 62, + "versionNonce": 626330844, + "isDeleted": false, + "id": "F26JZDrwDBDSk5o5kcV_E", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 547.3333129882812, + "y": 739.6667327880859, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 227.666748046875, + "height": 60.666656494140625, + "seed": 725179740, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644057644, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 71, + "versionNonce": 1658992100, + "isDeleted": false, + "id": "H6cL4L0PUBLB5An3KDf-i", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 636.6666259765625, + "y": 784.0003204345703, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 31, + "height": 20, + "seed": 83711068, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644496025, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "[...]", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "[...]" + }, + { + "type": "rectangle", + "version": 158, + "versionNonce": 208125412, + "isDeleted": false, + "id": "M6cl8S-GRJkkRSQrUxzJV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 566.833251953125, + "y": 747.6667327880859, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 195, + "height": 30, + "seed": 997959652, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "DrpXGgZIT2RAhz4L6EM2n" + } + ], + "updated": 1679644019993, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 128, + "versionNonce": 493257308, + "isDeleted": false, + "id": "DrpXGgZIT2RAhz4L6EM2n", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 579.833251953125, + "y": 752.6667327880859, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 169, + "height": 20, + "seed": 157169756, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644019993, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint32 data_offset;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "M6cl8S-GRJkkRSQrUxzJV", + "originalText": "uint32 data_offset;" + }, + { + "type": "rectangle", + "version": 223, + "versionNonce": 680765365, + "isDeleted": false, + "id": "nPxM8HePICecTvRXbdEeU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 983.333251953125, + "y": 378.1666793823242, + "strokeColor": "#000000", + "backgroundColor": "#868e96", + "width": 97.66668701171875, + "height": 30.000015258789062, + "seed": 1516156124, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "Y_Dw9hCEvutA3MjjHfyJK", + "type": "arrow" + } + ], + "updated": 1679660991443, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 165, + "versionNonce": 430152219, + "isDeleted": false, + "id": "Y_Dw9hCEvutA3MjjHfyJK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 756.6666259765625, + "y": 766.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 217.14296385054604, + "height": 385.92617569738337, + "seed": 703298780, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "MraNxq38RWxCBOb3EhIue" + } + ], + "updated": 1679660991443, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "nPxM8HePICecTvRXbdEeU", + "gap": 9.523662126016394, + "focus": 1.1442737969660202 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 217.14296385054604, + -385.92617569738337 + ] + ] + }, + { + "type": "text", + "version": 4, + "versionNonce": 1122104853, + "isDeleted": false, + "id": "MraNxq38RWxCBOb3EhIue", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 838.7381079018355, + "y": 563.3703014335349, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 53, + "height": 20, + "seed": 1058889828, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661201730, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "offset", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Y_Dw9hCEvutA3MjjHfyJK", + "originalText": "offset" + }, + { + "type": "text", + "version": 239, + "versionNonce": 551950564, + "isDeleted": false, + "id": "O5mHltv55Fs4-vM6wNcf-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 226.99996948242188, + "y": 655.0000457763672, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 164, + "height": 20, + "seed": 352849508, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "1QAmzR8Zkk8scUA3tqI0k", + "type": "arrow" + } + ], + "updated": 1679644753215, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMGlobalInstance", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMGlobalInstance" + }, + { + "type": "rectangle", + "version": 104, + "versionNonce": 219644132, + "isDeleted": false, + "id": "CpOJESdMD1E9wBe2Gkkvf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 216.66665649414062, + "y": 681.6666412353516, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 180.33331298828125, + "height": 46.666778564453125, + "seed": 705788380, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644728661, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 153, + "versionNonce": 296383867, + "isDeleted": false, + "id": "1QAmzR8Zkk8scUA3tqI0k", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 583.9999694824219, + "y": 602.3333587646484, + "strokeColor": "#000000", + "backgroundColor": "#15aabf", + "width": 179.2173434297432, + "height": 75.12469349055664, + "seed": 869061340, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "N9fS0DKeDh1d_Ueyopb9v" + } + ], + "updated": 1679661068533, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "O5mHltv55Fs4-vM6wNcf-", + "focus": 1.1855962422681312, + "gap": 14.0001220703125 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -179.2173434297432, + 75.12469349055664 + ] + ] + }, + { + "id": "N9fS0DKeDh1d_Ueyopb9v", + "type": "text", + "x": 449.39129776755027, + "y": 629.8957055099268, + "width": 90, + "height": 20, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "roundness": null, + "seed": 339183189, + "version": 24, + "versionNonce": 270159573, + "isDeleted": false, + "boundElements": null, + "updated": 1679661092509, + "link": null, + "locked": false, + "text": "when import", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 14, + "containerId": "1QAmzR8Zkk8scUA3tqI0k", + "originalText": "when import" + }, + { + "type": "rectangle", + "version": 59, + "versionNonce": 96174172, + "isDeleted": false, + "id": "oDs6sXYd2cCCUTlDuFyfK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 199.66659545898438, + "y": 599.9999847412109, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 236.33343505859375, + "height": 196.3333740234375, + "seed": 1531972708, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644717838, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 72, + "versionNonce": 1711293284, + "isDeleted": false, + "id": "Gyz12ttmraGX-CaCTWl3h", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 191.99990844726562, + "y": 576.3333892822266, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 239, + "height": 20, + "seed": 683171044, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "957MNrV_zCOsf-ssBBkla", + "type": "arrow" + } + ], + "updated": 1679644717838, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "WASMModuleInstance (second)", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance (second)" + }, + { + "type": "text", + "version": 185, + "versionNonce": 1644000405, + "isDeleted": false, + "id": "7TYuQ_yCiwRN4oz8zkdGb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 38.33337402343753, + "y": 248.66676330566406, + "strokeColor": "#d9480f", + "backgroundColor": "transparent", + "width": 171, + "height": 19, + "seed": 1694546652, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModuleInstance", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstance" + }, + { + "type": "rectangle", + "version": 151, + "versionNonce": 1152705621, + "isDeleted": false, + "id": "DN3tWnhyoeDPQR_-BYeYI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 36.666656494140625, + "y": 269.00010681152344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 202.00003051757815, + "height": 124.66665649414062, + "seed": 693300324, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "-n6vwSfIOzGpAxjpRyuNZ", + "type": "arrow" + } + ], + "updated": 1679661004485, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 150, + "versionNonce": 458299605, + "isDeleted": false, + "id": "K0JMv-qZGU4i9Or0Xz4Gg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 246.33328247070315, + "y": 399.33343505859375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 218, + "height": 19, + "seed": 881476572, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661029361, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 3, + "text": "WASMModuleInstanceExtra", + "baseline": 15, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "WASMModuleInstanceExtra" + }, + { + "type": "rectangle", + "version": 169, + "versionNonce": 769392085, + "isDeleted": false, + "id": "CERoUCjzlaXjrdr4PSxtB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 225.33328247070312, + "y": 428.00010681152344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 256.3333740234375, + "height": 91.33331298828128, + "seed": 1750838620, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "-n6vwSfIOzGpAxjpRyuNZ", + "type": "arrow" + } + ], + "updated": 1679661027326, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 88, + "versionNonce": 1947089019, + "isDeleted": false, + "id": "H3BkjBVeDYM2F429PxOI9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 233.0000915527344, + "y": 447.00010681152344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 243.00006103515625, + "height": 31, + "seed": 258806116, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "-n6vwSfIOzGpAxjpRyuNZ", + "type": "arrow" + } + ], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 257, + "versionNonce": 314119835, + "isDeleted": false, + "id": "_acaSZ2N5FSiuPGQjH8RA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 463.97668298272777, + "y": 453.66683959960943, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80.59006409386518, + "height": 100.23285752369344, + "seed": 1866235612, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false, + "startBinding": { + "elementId": "Clf1NqZqRXJuRl-CQgx_u", + "focus": 0.8216444271084713, + "gap": 1 + }, + "endBinding": { + "elementId": "FcG2LCAdKxw_z2SzLhPPr", + "focus": 1.009989878742988, + "gap": 3.7665659116883603 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 80.59006409386518, + -100.23285752369344 + ] + ] + }, + { + "type": "rectangle", + "version": 63, + "versionNonce": 1164697781, + "isDeleted": false, + "id": "NIObCr2apYl6JLLzA37G2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 232.66665649414065, + "y": 486.66676330566406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 244.33331298828125, + "height": 30, + "seed": 1813909212, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "sYEF77zbpRw-pcdX1ass6" + } + ], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 24, + "versionNonce": 4682011, + "isDeleted": false, + "id": "sYEF77zbpRw-pcdX1ass6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 272.33331298828125, + "y": 491.66676330566406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 165, + "height": 20, + "seed": 382274908, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint32 global_count;", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "NIObCr2apYl6JLLzA37G2", + "originalText": "uint32 global_count;" + }, + { + "type": "rectangle", + "version": 142, + "versionNonce": 519569941, + "isDeleted": false, + "id": "7jX0wgP7v4HHkuITKOf89", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 94.3333435058594, + "y": 344.33351135253906, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 115, + "height": 30.333358764648438, + "seed": 1226666212, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "sK7ecOoz_3QIduVF0nHd7" + } + ], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 116, + "versionNonce": 1846580667, + "isDeleted": false, + "id": "sK7ecOoz_3QIduVF0nHd7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 146.3333435058594, + "y": 349.5001907348633, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 11, + "height": 20, + "seed": 1178170724, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "e", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "7jX0wgP7v4HHkuITKOf89", + "originalText": "e" + }, + { + "type": "diamond", + "version": 135, + "versionNonce": 691599221, + "isDeleted": false, + "id": "yTfoj623sdm1eh4Eusmvt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 174.66665649414065, + "y": 352.0001983642578, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 13.66668701171875, + "height": 12.333328247070312, + "seed": 559414236, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 324, + "versionNonce": 1197545819, + "isDeleted": false, + "id": "-n6vwSfIOzGpAxjpRyuNZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 182.00003051757815, + "y": 356.66676330566406, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 45.12566323463764, + "height": 69.66665649414062, + "seed": 1850539876, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661027326, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "CERoUCjzlaXjrdr4PSxtB", + "gap": 1, + "focus": -0.6072997775389923 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 45.12566323463764, + 69.66665649414062 + ] + ] + }, + { + "type": "arrow", + "version": 68, + "versionNonce": 732107996, + "isDeleted": false, + "id": "957MNrV_zCOsf-ssBBkla", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 578.0000305175781, + "y": 557.6666717529297, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 144.0692777412945, + "height": 39.30743410761045, + "seed": 1605267676, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644717838, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "Gyz12ttmraGX-CaCTWl3h", + "focus": 1.0338080600507247, + "gap": 3.00006103515625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -144.0692777412945, + 39.30743410761045 + ] + ] + }, + { + "type": "diamond", + "version": 20, + "versionNonce": 825681252, + "isDeleted": false, + "id": "pKw8fr7S6f80J93nrJtkQ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 575.8333129882812, + "y": 553.5000076293945, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 13.66668701171875, + "height": 12.333328247070312, + "seed": 222063588, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644481683, + "link": null, + "locked": false + }, + { + "type": "diamond", + "version": 20, + "versionNonce": 825681252, + "isDeleted": false, + "id": "XKwLDKrjsXcSogvJHSY-e", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 573.8333129882812, + "y": 597.5000076293945, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 13.66668701171875, + "height": 12.333328247070312, + "seed": 1140569180, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644483164, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 215, + "versionNonce": 510935253, + "isDeleted": false, + "id": "oPjebDyI5NP26BNK4PLtX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 50.33343505859378, + "y": 290.33338928222656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 180, + "height": 31, + "seed": 727213156, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "type": "text", + "id": "ZK3cjtpUxVpruHBkbgevo" + } + ], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 175, + "versionNonce": 1653383931, + "isDeleted": false, + "id": "ZK3cjtpUxVpruHBkbgevo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 58.33343505859378, + "y": 295.83338928222656, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 164, + "height": 20, + "seed": 1130592356, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "uint8 * global_data", + "baseline": 14, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "oPjebDyI5NP26BNK4PLtX", + "originalText": "uint8 * global_data" + }, + { + "type": "arrow", + "version": 159, + "versionNonce": 345149237, + "isDeleted": false, + "id": "5S0qe2-BjQRPwuEEQ_UsU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 228.00003051757812, + "y": 299.9999694824219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 754.7517447227082, + "height": 17.8331298828125, + "seed": 1256331620, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679661008047, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "D5Ay5TxydaAe4f80l_79L", + "focus": 0.9720307648275319, + "gap": 1 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 385.0834503173828, + -17.8331298828125 + ], + [ + 754.7517447227082, + -2.996583692902334 + ] + ] + }, + { + "type": "diamond", + "version": 89, + "versionNonce": 1413439029, + "isDeleted": false, + "id": "szV9RT3yAJ51dUnP5JYMS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 220.1667175292969, + "y": 294.50000762939453, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 13.66668701171875, + "height": 12.333328247070312, + "seed": 1642184284, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679661000688, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 160, + "versionNonce": 715957468, + "isDeleted": false, + "id": "DuwilIDd-fhNUxybFRKva", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 255.16659545898438, + "y": 750.6665496826172, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 99, + "height": 20, + "seed": 121250780, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644739787, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "global_data", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "global_data" + }, + { + "type": "rectangle", + "version": 143, + "versionNonce": 2046173532, + "isDeleted": false, + "id": "6CMun9I8IOX876t85IJ2X", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 215.83328247070312, + "y": 738.6664733886719, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 180.33331298828125, + "height": 46.666778564453125, + "seed": 2113088100, + "groupIds": [], + "roundness": null, + "boundElements": [ + { + "id": "igqxFPh3AgDb1kYMsORSZ", + "type": "arrow" + } + ], + "updated": 1679644784578, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 34, + "versionNonce": 1198703204, + "isDeleted": false, + "id": "cbSo4pUG_J3a4Pnk3ODCA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 276.6665954589844, + "y": 693.3332366943359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 55, + "height": 20, + "seed": 328242020, + "groupIds": [], + "roundness": null, + "boundElements": [], + "updated": 1679644771096, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "globals", + "baseline": 14, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "globals" + }, + { + "type": "arrow", + "version": 81, + "versionNonce": 311117156, + "isDeleted": false, + "id": "igqxFPh3AgDb1kYMsORSZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 247.33328247070312, + "y": 706.3332366943359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 71.66665649414062, + "height": 58.33343505859375, + "seed": 1345639908, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1679644787747, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": { + "elementId": "6CMun9I8IOX876t85IJ2X", + "focus": -0.8452179527426857, + "gap": 1.499908447265625 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -71.66665649414062, + 15.66668701171875 + ], + [ + -32.999908447265625, + 58.33343505859375 + ] + ] + }, + { + "type": "diamond", + "version": 135, + "versionNonce": 691599221, + "isDeleted": false, + "id": "koTtnTl85TIGelUbfKlR9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 459.58338928222656, + "y": 446.0001754760742, + "strokeColor": "#000000", + "backgroundColor": "#be4bdb", + "width": 13.66668701171875, + "height": 12.333328247070312, + "seed": 626707637, + "groupIds": [], + "roundness": null, + "boundElements": null, + "updated": 1679661018823, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/core/iwasm/doc/images/wasm_globals.svg b/core/iwasm/doc/images/wasm_globals.svg new file mode 100644 index 000000000..fa3461732 --- /dev/null +++ b/core/iwasm/doc/images/wasm_globals.svg @@ -0,0 +1,16 @@ + + + + + + + global_data:WASMModuleInstanceExtra::globalsoffsetoffsethold values of GLOBALsuint8 type;WASMGlobalInstancebool is_mutable;uint32 data_offset;initial_valueimport_module_instimport_global_instWASMGlobalInstance *globals;[0]uint32 data_offset;[1][...]uint32 data_offset;offsetWASMGlobalInstancewhen importWASMModuleInstance (second)WASMModuleInstanceWASMModuleInstanceExtrauint32 global_count;euint8 * global_dataglobal_dataglobals \ No newline at end of file diff --git a/core/iwasm/doc/wasm_function.MD b/core/iwasm/doc/wasm_function.MD index 7655ffbfe..da4dac239 100644 --- a/core/iwasm/doc/wasm_function.MD +++ b/core/iwasm/doc/wasm_function.MD @@ -3,3 +3,45 @@ ## Internal data structure ![](./images/wasm_function.svg) + +## Module level data (function) +**WASMModule**: Data structure created for loading a module. +- `WASMImport *import_functions`: initialized from the Wasm file function section +- `WASMImport *import_functions`: initialized from the Wasm file import section. The runtime will try to solve the imports from the native API registration, refer to [Export native API to WASM application](../../../doc/export_native_api.md). + +**WASMFunction**: represent a Wasm function located in Wasm file code section. Track the links to the compiled function body. +**WASMImport**: represent a imported Wasm function which can be a solved as a native function or another Wasm module exported function. + +## Instance level data (function) +**WASMModuleInstance**: Data structure created for instantiating a module +- `WASMModuleInstanceExtra::functions`: combined the imported and internal functions into single array of structure `WASMFunctionInstance` +- `WASMModuleInstance::import_func_ptrs`: pointer array for solved function imports. This array is referred during calling imported native function. Note it is initialzed with the module level solved imports, but may points to different native function later due to c-api calls. + +## Execution paths +**Interpreter**: +- Execute internal bytecode function: + ``` + WASMModuleInstance::e + -> WASMModuleInstanceExtra::functions[..] + -> WASMFunctionInstance::func + -> WASMFunction::code + ``` + +- Execute imported function from other module: + ``` + WASMModuleInstance::e + -> WASMModuleInstanceExtra::functions[..] + (WASMFunctionInstance flag indicates an import) + -> WASMFunctionInstance::import_func_inst + -> WASMModuleInstance(second)::func + -> WASMFunction (second module)::code + ``` + +- Execute imported native function: + ``` + WASMModuleInstance::e + -> WASMModuleInstanceExtra::functions[..] + (flag indicates imported native) + WASMModuleInstance::import_func_ptrs[..] + -> native function + ``` \ No newline at end of file diff --git a/core/iwasm/doc/wasm_globals.MD b/core/iwasm/doc/wasm_globals.MD new file mode 100644 index 000000000..e5019a9fc --- /dev/null +++ b/core/iwasm/doc/wasm_globals.MD @@ -0,0 +1,4 @@ +# Wasm globals + +![](./images/wasm_globals.svg) + diff --git a/doc/memory_tune.md b/doc/memory_tune.md index 8159aaac8..e14a1a164 100644 --- a/doc/memory_tune.md +++ b/doc/memory_tune.md @@ -1,7 +1,7 @@ # Memory model and memory usage tunning References: -- [Blog: Understand WAMR heap](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heap/) +- [Blog: Understand WAMR heap](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heaps/) - [Blog: Understand WAMR stacks](https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-stacks/) ## The memory model From 605c8b07dce6a097658a42edca1bf0e803af9399 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sat, 25 Mar 2023 11:15:05 +0800 Subject: [PATCH 24/61] Fix issue of Multi-tier JIT (#2056) --- core/iwasm/interpreter/wasm.h | 3 +++ core/iwasm/interpreter/wasm_loader.c | 11 +++++++++-- core/iwasm/interpreter/wasm_mini_loader.c | 11 +++++++++-- core/iwasm/interpreter/wasm_runtime.c | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index e6d02c3f1..0797a018b 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -602,6 +602,9 @@ struct WASMModule { since no need to enable llvm jit compilation for Mode_Interp and Mode_Fast_JIT, so as to improve performance for them */ bool enable_llvm_jit_compilation; + /* The count of groups which finish compiling the fast jit + functions in that group */ + uint32 fast_jit_ready_groups; #endif }; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 376152763..d3128dbd0 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -3182,6 +3182,11 @@ orcjit_thread_callback(void *arg) return NULL; } } +#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT != 0 + os_mutex_lock(&module->tierup_wait_lock); + module->fast_jit_ready_groups++; + os_mutex_unlock(&module->tierup_wait_lock); +#endif #endif #if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ @@ -3209,9 +3214,11 @@ orcjit_thread_callback(void *arg) } } - /* Wait until init_llvm_jit_functions_stage2 finishes */ + /* Wait until init_llvm_jit_functions_stage2 finishes and all + fast jit functions are compiled */ os_mutex_lock(&module->tierup_wait_lock); - while (!(module->llvm_jit_inited && module->enable_llvm_jit_compilation)) { + while (!(module->llvm_jit_inited && module->enable_llvm_jit_compilation + && module->fast_jit_ready_groups >= group_stride)) { os_cond_reltimedwait(&module->tierup_wait_cond, &module->tierup_wait_lock, 10000); if (module->orcjit_stop_compiling) { diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 92be851fa..3a983b293 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -2025,6 +2025,11 @@ orcjit_thread_callback(void *arg) return NULL; } } +#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT != 0 + os_mutex_lock(&module->tierup_wait_lock); + module->fast_jit_ready_groups++; + os_mutex_unlock(&module->tierup_wait_lock); +#endif #endif #if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ @@ -2052,9 +2057,11 @@ orcjit_thread_callback(void *arg) } } - /* Wait until init_llvm_jit_functions_stage2 finishes */ + /* Wait until init_llvm_jit_functions_stage2 finishes and all + fast jit functions are compiled */ os_mutex_lock(&module->tierup_wait_lock); - while (!(module->llvm_jit_inited && module->enable_llvm_jit_compilation)) { + while (!(module->llvm_jit_inited && module->enable_llvm_jit_compilation + && module->fast_jit_ready_groups >= group_stride)) { os_cond_reltimedwait(&module->tierup_wait_cond, &module->tierup_wait_lock, 10000); if (module->orcjit_stop_compiling) { diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 5548fad5a..2338f90bf 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1489,7 +1489,7 @@ set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode, os_mutex_lock(&module->tierup_wait_lock); while (!module->llvm_jit_inited) { os_cond_reltimedwait(&module->tierup_wait_cond, - &module->tierup_wait_lock, 10); + &module->tierup_wait_lock, 10000); if (module->orcjit_stop_compiling) { /* init_llvm_jit_functions_stage2 failed */ os_mutex_unlock(&module->tierup_wait_lock); From 0faec7c96cf63d1bf05a6a4d0021f4616600e37e Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Sat, 25 Mar 2023 20:25:54 +0800 Subject: [PATCH 25/61] Update version to 1.2.0 and update release notes (#2062) --- RELEASE_NOTES.md | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ core/version.h | 4 +-- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a0cfe7a82..003ee607d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,97 @@ +## WAMR-1.2.0 + +### Breaking Changes + + +### New Features +Implement two-level Multi-tier JIT engine: tier-up from Fast JIT to LLVM JIT to get quick cold startup and better performance +Enable running mode control for runtime, wasm module instance and iwasm +Implement wasi-threads feature +Upgrade toolkits: upgrade to llvm-15.0, wasi-sdk-19.0, emsdk-3.1.28 and so on +Port WAMR to the FreeBSD platform +Refactor wasi-nn to simplify the support for multiple frameworks +wasi-nn: Enable GPU support +wasi-nn: Support multiple TFLite models +Add WAMR API bindings in Python +Add libsodium benchmark + +### Bug Fixes +Fix wasm-c-api import func link issue in wasm_instance_new +Fix watchpoint segfault when using debug interp without server +libc-wasi: Fix spurious poll timeout +Fix typo verify_module in aot_compiler.c +Fix failure about preopen of reactor modules +Fix equal check in AOT XIP float cmp intrinsic +Fix issue of resolving func name in custom name section +Fix go language binding build on macos arm64 +Prevent undefined behavior from c_api_func_imports == NULL +Fix potential block issue in source debugger +SGX IPFS: Fix a segfault and support seeking beyond the end of files while using SEEK_CUR/SEEK_END +Fix undef error about WAMR_BUILD_MEMORY_PROFILING +Fix jit memory overwritten after instance deinstantiate +Fix stack alignment issue on ia32 +Fix explicit casts and types in espidf_socket.c +Fix potential integer overflow issue in wasm-c-api +Fix libc-wasi build failure when using clang +Fix wamrapi python binding for darwin +Fix getting port issue in posix os_socket_bind +Fix key error in build_llvm.py +nuttx: Add missing pthread.h header +Fix os_socket_addr_resolve() for IPv6 +Enhance/Fix sample socket-api and workload +Fix fast-jit build error +Fix dead lock in source debugger +fix debugger: Set termination flags also when in debug mode + +### Enhancements +Add WAMR-IDE vscode extension to the Visual Studio Marketplace +Refine Windows thread waiting list operations +Improve wasm-c-api instantiation-time linking +Enable platform support for esp-idf v5.0.1 +Readme refactoring +Add architecture diagram for wasm function +Add architecture document for wasm export +Add architecture diagram for wasm globals and classic-interp stack frame +Use boringssl instead of openssl to implement wasm cache loading +Implement i32.rem_s and i32.rem_u intrinsic +Perfect the codebase for wamr-ide +Remove unnecessary ret value control when spec test is enabled +Use float version library routine for XIP aot_intrinsic_xxx APIs +Register missing symbols for f32 to 64 bit integer conversion +Report error in instantiation when meeting unlinked import globals +Add more types and APIs for attr_container +Simplify fcmp intrinsic logic for AOT/XIP +Add some missing macros for int literals in wamr-sdk libc-builtin-sysroot stdint.h +nuttx: Mock socket APIs if NET is disabled +Main thread spread exception when thread-mgr is enabled +Implement opcode atomic.wait and atomic.notify for Fast JIT +Add docker images auto check and setup support for WAMR-IDE +Make memory profiling show native stack usage +Enable gcc-4.8 compilation +Enable specifying out-of-source platform configuration cmake file +Add gh api call for fetching llvm version (#1942) Fixes +Don't terminate other threads when create thread failed +Modify poll_oneoff in libc-wasi to make it interruptible +Expose wasm_runtime_call_indirect +Make a workaround for EGO when fstat returns NOT_SUPPORT +Re-org calling post instantiation functions +Enable custom llvm build flags +support SSH for git clone llvm +Support dump call stack on exception and dump call stack on nuttx +Update document for source debugging +Document some info about estimating memory usage + +### Others +Enable XIP in CI daily test +Integrate wasi test suite to wamr-test-suites and CI +Add CI for wasi-threads tests +Update CIs and documents to make naming of generated binaries consist +Enable CI wasi test suite for x86-32 classic/fast interpreter +CI: Enable libc-wasi compilation test on NuttX +CI: Enable Multi-tier JIT by default for released iwasm binary + +--- + ## WAMR-1.1.2 ### Breaking Changes diff --git a/core/version.h b/core/version.h index 9834dae1c..69df43d56 100644 --- a/core/version.h +++ b/core/version.h @@ -6,6 +6,6 @@ #ifndef _WAMR_VERSION_H_ #define _WAMR_VERSION_H_ #define WAMR_VERSION_MAJOR 1 -#define WAMR_VERSION_MINOR 1 -#define WAMR_VERSION_PATCH 2 +#define WAMR_VERSION_MINOR 2 +#define WAMR_VERSION_PATCH 0 #endif From 0f73ce107635a8128e314c49aab26cfb256f1000 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Sun, 26 Mar 2023 03:03:26 +0200 Subject: [PATCH 26/61] Update wasi-libc version in CI and implement custom sync primitives (#2028) Update wasi-libc version to resolve the hang issue when running wasi-threads cases. Implement custom sync primitives as a counterpart of `pthread_barrier_wait` to attempt to replace pthread sync primitives since they seem to cause data races when running with the thread sanitizer. --- .../compilation_on_android_ubuntu.yml | 8 +- .github/workflows/compilation_on_sgx.yml | 4 +- .../libraries/lib-wasi-threads/test/common.h | 7 +- .../lib-wasi-threads/test/global_lock.c | 5 + .../lib-wasi-threads/test/sync_primitives.h | 91 +++++++++++ samples/wasi-threads/README.md | 2 - samples/wasi-threads/wasm-apps/CMakeLists.txt | 3 +- .../wasm-apps/thread_termination.c | 142 ------------------ 8 files changed, 109 insertions(+), 153 deletions(-) create mode 100644 core/iwasm/libraries/lib-wasi-threads/test/sync_primitives.h delete mode 100644 samples/wasi-threads/wasm-apps/thread_termination.c diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 6654e1b31..062b17297 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -368,9 +368,9 @@ jobs: mkdir wasi-libc cd wasi-libc git init - # "Rename thread_spawn import" commit on main branch + # "Fix a_store operation in atomic.h" commit on main branch git fetch https://github.com/WebAssembly/wasi-libc \ - 8f5275796a82f8ecfd0833a4f3f444fa37ed4546 + 1dfe5c302d1c5ab621f7abf04620fae92700fd22 git checkout FETCH_HEAD make -j \ AR=/opt/wasi-sdk/bin/llvm-ar \ @@ -532,9 +532,9 @@ jobs: mkdir wasi-libc cd wasi-libc git init - # "Rename thread_spawn import" commit on main branch + # "Fix a_store operation in atomic.h" commit on main branch git fetch https://github.com/WebAssembly/wasi-libc \ - 8f5275796a82f8ecfd0833a4f3f444fa37ed4546 + 1dfe5c302d1c5ab621f7abf04620fae92700fd22 git checkout FETCH_HEAD make -j \ AR=/opt/wasi-sdk/bin/llvm-ar \ diff --git a/.github/workflows/compilation_on_sgx.yml b/.github/workflows/compilation_on_sgx.yml index 2988a6fe1..a26f27aaf 100644 --- a/.github/workflows/compilation_on_sgx.yml +++ b/.github/workflows/compilation_on_sgx.yml @@ -265,9 +265,9 @@ jobs: mkdir wasi-libc cd wasi-libc git init - # "Rename thread_spawn import" commit on main branch + # "Fix a_store operation in atomic.h" commit on main branch git fetch https://github.com/WebAssembly/wasi-libc \ - 8f5275796a82f8ecfd0833a4f3f444fa37ed4546 + 1dfe5c302d1c5ab621f7abf04620fae92700fd22 git checkout FETCH_HEAD make \ AR=/opt/wasi-sdk/bin/llvm-ar \ diff --git a/core/iwasm/libraries/lib-wasi-threads/test/common.h b/core/iwasm/libraries/lib-wasi-threads/test/common.h index d032f824c..01ca932c5 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/common.h +++ b/core/iwasm/libraries/lib-wasi-threads/test/common.h @@ -6,11 +6,16 @@ #include #include #include -#include #include #include #include +#if USE_CUSTOM_SYNC_PRIMITIVES != 0 +#include "sync_primitives.h" +#else +#include +#endif + #include "wasi_thread_start.h" typedef enum { diff --git a/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c b/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c index 282bec71c..f81fca49b 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c +++ b/core/iwasm/libraries/lib-wasi-threads/test/global_lock.c @@ -11,7 +11,12 @@ #include #include #include + +#if USE_CUSTOM_SYNC_PRIMITIVES != 0 +#include "sync_primitives.h" +#else #include +#endif #include "wasi_thread_start.h" diff --git a/core/iwasm/libraries/lib-wasi-threads/test/sync_primitives.h b/core/iwasm/libraries/lib-wasi-threads/test/sync_primitives.h new file mode 100644 index 000000000..4b7dac8ec --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/test/sync_primitives.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include + +/* Mutex */ + +typedef int pthread_mutex_t; + +int +pthread_mutex_init(pthread_mutex_t *mutex, void *unused) +{ + *mutex = 0; + return 0; +} + +int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return 0; +} + +static bool +try_pthread_mutex_lock(pthread_mutex_t *mutex) +{ + int expected = 0; + return __atomic_compare_exchange_n(mutex, &expected, 1, false, + __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} + +int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + while (!try_pthread_mutex_lock(mutex)) + __builtin_wasm_memory_atomic_wait32(mutex, 1, -1); + return 0; +} + +int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + __atomic_store_n(mutex, 0, __ATOMIC_SEQ_CST); + __builtin_wasm_memory_atomic_notify(mutex, 1); + return 0; +} + +/* Barrier */ + +typedef struct { + int count; + int num_threads; + int mutex; + int ready; +} pthread_barrier_t; + +int +pthread_barrier_init(pthread_barrier_t *barrier, void *unused, int num_threads) +{ + barrier->count = 0; + barrier->num_threads = num_threads; + barrier->ready = 0; + pthread_mutex_init(&barrier->mutex, NULL); + + return 0; +} + +int +pthread_barrier_wait(pthread_barrier_t *barrier) +{ + bool no_wait = false; + int count; + + pthread_mutex_lock(&barrier->mutex); + count = barrier->count++; + if (barrier->count >= barrier->num_threads) { + no_wait = true; + barrier->count = 0; + } + pthread_mutex_unlock(&barrier->mutex); + + if (no_wait) { + __atomic_store_n(&barrier->ready, 1, __ATOMIC_SEQ_CST); + __builtin_wasm_memory_atomic_notify(&barrier->ready, count); + return 0; + } + + __builtin_wasm_memory_atomic_wait32(&barrier->ready, 0, -1); + return 0; +} \ No newline at end of file diff --git a/samples/wasi-threads/README.md b/samples/wasi-threads/README.md index a5e1aed3c..a79a3cd6a 100644 --- a/samples/wasi-threads/README.md +++ b/samples/wasi-threads/README.md @@ -11,8 +11,6 @@ $ cmake .. $ make ... $ ./iwasm wasm-apps/no_pthread.wasm -... -$ ./iwasm wasm-apps/exception_propagation.wasm ``` ## Run samples in AOT mode diff --git a/samples/wasi-threads/wasm-apps/CMakeLists.txt b/samples/wasi-threads/wasm-apps/CMakeLists.txt index a6b288449..87f21e9fd 100644 --- a/samples/wasi-threads/wasm-apps/CMakeLists.txt +++ b/samples/wasi-threads/wasm-apps/CMakeLists.txt @@ -43,5 +43,4 @@ function (compile_sample SOURCE_FILE) ) endfunction () -compile_sample(no_pthread.c wasi_thread_start.S) -compile_sample(thread_termination.c wasi_thread_start.S) +compile_sample(no_pthread.c wasi_thread_start.S) \ No newline at end of file diff --git a/samples/wasi-threads/wasm-apps/thread_termination.c b/samples/wasi-threads/wasm-apps/thread_termination.c deleted file mode 100644 index 9f5cf1fe8..000000000 --- a/samples/wasi-threads/wasm-apps/thread_termination.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ -#ifndef __wasi__ -#error This example only compiles to WASM/WASI target -#endif - -#include -#include -#include -#include -#include -#include - -#include "wasi_thread_start.h" - -#define BUSY_WAIT 0 -#define ATOMIC_WAIT 1 -#define POLL_ONEOFF 2 - -/* Change parameters here to modify the sample behavior */ -#define TEST_TERMINATION_BY_TRAP 0 /* Otherwise `proc_exit` termination */ -#define TEST_TERMINATION_IN_MAIN_THREAD 1 /* Otherwise in spawn thread */ -#define LONG_TASK_IMPL ATOMIC_WAIT - -#define TIMEOUT_SECONDS 10 -#define NUM_THREADS 3 -static pthread_barrier_t barrier; - -typedef struct { - start_args_t base; - bool throw_exception; -} shared_t; - -void -run_long_task() -{ -#if LONG_TASK_IMPL == BUSY_WAIT - for (int i = 0; i < TIMEOUT_SECONDS; i++) - sleep(1); -#elif LONG_TASK_IMPL == ATOMIC_WAIT - __builtin_wasm_memory_atomic_wait32(0, 0, -1); -#else - sleep(TIMEOUT_SECONDS); -#endif -} - -void -start_job() -{ - /* Wait for all threads (including the main thread) to be ready */ - pthread_barrier_wait(&barrier); - run_long_task(); /* Task to be interrupted */ - assert(false && "Thread termination test failed"); -} - -void -terminate_process() -{ - /* Wait for all other threads (including main thread) to be ready */ - printf("Waiting before terminating\n"); - pthread_barrier_wait(&barrier); - - printf("Force termination\n"); -#if TEST_TERMINATION_BY_TRAP == 1 - __builtin_trap(); -#else - __wasi_proc_exit(33); -#endif -} - -void -__wasi_thread_start_C(int thread_id, int *start_arg) -{ - shared_t *data = (shared_t *)start_arg; - - if (data->throw_exception) { - terminate_process(); - } - else { - printf("Thread running\n"); - - start_job(); - } -} - -int -main(int argc, char **argv) -{ - int thread_id = -1, i; - shared_t data[NUM_THREADS] = { 0 }; - - if (pthread_barrier_init(&barrier, NULL, NUM_THREADS + 1) != 0) { - printf("Failed to init barrier\n"); - return EXIT_FAILURE; - } - - for (i = 0; i < NUM_THREADS; i++) { - /* No graceful memory free to simplify the example */ - if (!start_args_init(&data[i].base)) { - printf("Failed to allocate thread's stack\n"); - return EXIT_FAILURE; - } - } - - /* Create a thread that forces termination through trap or `proc_exit` */ -#if TEST_TERMINATION_IN_MAIN_THREAD == 1 - data[0].throw_exception = false; -#else - data[0].throw_exception = true; -#endif - thread_id = __wasi_thread_spawn(&data[0]); - if (thread_id < 0) { - printf("Failed to create thread: %d\n", thread_id); - return EXIT_FAILURE; - } - - /* Create two additional threads to test exception propagation */ - data[1].throw_exception = false; - thread_id = __wasi_thread_spawn(&data[1]); - if (thread_id < 0) { - printf("Failed to create thread: %d\n", thread_id); - return EXIT_FAILURE; - } - data[2].throw_exception = false; - thread_id = __wasi_thread_spawn(&data[2]); - if (thread_id < 0) { - printf("Failed to create thread: %d\n", thread_id); - return EXIT_FAILURE; - } - -#if TEST_TERMINATION_IN_MAIN_THREAD == 1 - printf("Force termination (main thread)\n"); - terminate_process(); -#else /* TEST_TERMINATION_IN_MAIN_THREAD */ - printf("Main thread running\n"); - - start_job(); -#endif /* TEST_TERMINATION_IN_MAIN_THREAD */ - return EXIT_SUCCESS; -} From d0fb2716b61b54ac490ead7543f172cac9ed762b Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Sun, 26 Mar 2023 12:19:45 +0800 Subject: [PATCH 27/61] Fix several issues in CI binary releasing (#2064) --- .github/workflows/build_iwasm_release.yml | 20 ++++++++ .github/workflows/build_wamr_vscode_ext.yml | 11 +++-- .github/workflows/build_wamrc.yml | 9 ++-- .github/workflows/release_process.yml | 47 ++++++++++++++----- product-mini/platforms/android/build_llvm.sh | 1 + product-mini/platforms/darwin/build_llvm.sh | 1 + product-mini/platforms/freebsd/build_llvm.sh | 1 + product-mini/platforms/linux/build_llvm.sh | 1 + .../wamr-ide/WASM-Toolchain/Docker/Dockerfile | 8 +++- wamr-compiler/build_llvm.sh | 1 + wamr-compiler/build_llvm_arc.sh | 1 + wamr-compiler/build_llvm_xtensa.sh | 1 + 12 files changed, 79 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build_iwasm_release.yml b/.github/workflows/build_iwasm_release.yml index 557a81fc4..ae1f6140b 100644 --- a/.github/workflows/build_iwasm_release.yml +++ b/.github/workflows/build_iwasm_release.yml @@ -14,6 +14,10 @@ on: description: workfing directory type: string required: true + llvm_cache_key: + description: the cache key of llvm libraries + type: string + required: true runner: description: OS of compilation type: string @@ -33,6 +37,22 @@ jobs: steps: - uses: actions/checkout@v3 + - name: get cached LLVM libraries + id: retrieve_llvm_libs + uses: actions/cache@v3 + with: + path: | + ./core/deps/llvm/build/bin + ./core/deps/llvm/build/include + ./core/deps/llvm/build/lib + ./core/deps/llvm/build/libexec + ./core/deps/llvm/build/share + key: ${{ inputs.llvm_cache_key }} + + - name: Quit if cache miss + if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' + run: echo "::error::can not get prebuilt llvm libraries" && exit 1 + - name: generate iwasm binary release run: | cmake -S . -B build \ diff --git a/.github/workflows/build_wamr_vscode_ext.yml b/.github/workflows/build_wamr_vscode_ext.yml index f62a4bc98..5c1853e24 100644 --- a/.github/workflows/build_wamr_vscode_ext.yml +++ b/.github/workflows/build_wamr_vscode_ext.yml @@ -24,22 +24,25 @@ jobs: uses: actions/setup-node@v3 with: node-version: 14.x - - - name: set vscode extension to correct version + + - name: set vscode extension to correct version run: | npm install -g json json -I -f package.json -e "this.version=\"${{ inputs.ver_num }}\"" working-directory: test-tools/wamr-ide/VSCode-Extension + # [!workflow] + # bypass the step of publishing the extension to the Market. + # recover it after creating the secret in the Environment - name: generate wamr ide vscode extension - env: + env: credentials: ${{ secrets.TOKEN }} run: | npm install -g vsce rm -rf node_modules npm install vsce package - vsce publish -p ${{ secrets.TOKEN }} + # vsce publish -p ${{ secrets.TOKEN }} working-directory: test-tools/wamr-ide/VSCode-Extension - name: compress the vscode extension diff --git a/.github/workflows/build_wamrc.yml b/.github/workflows/build_wamrc.yml index 829b036ea..a88a1f715 100644 --- a/.github/workflows/build_wamrc.yml +++ b/.github/workflows/build_wamrc.yml @@ -38,7 +38,7 @@ jobs: - uses: actions/checkout@v3 - name: get cached LLVM libraries - id: cache_llvm + id: retrieve_llvm_libs uses: actions/cache@v3 with: path: | @@ -49,10 +49,9 @@ jobs: ./core/deps/llvm/build/share key: ${{ inputs.llvm_cache_key }} - - name: Build llvm and clang from source - if: steps.cache_llvm.outputs.cache-hit != 'true' - run: /usr/bin/env python3 ./build_llvm.py --arch X86 - working-directory: build-scripts + - name: Quit if cache miss + if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' + run: echo "::error::can not get prebuilt llvm libraries" && exit 1 - name: generate wamrc binary release run: | diff --git a/.github/workflows/release_process.yml b/.github/workflows/release_process.yml index 88f595dd1..4188b4d40 100644 --- a/.github/workflows/release_process.yml +++ b/.github/workflows/release_process.yml @@ -49,36 +49,56 @@ jobs: draft: false body: ${{ env.RELEASE_NOTE }} + # + # LLVM_LIBRARIES + build_llvm_libraries_on_ubuntu_2004: + needs: [create_tag, create_release] + uses: ./.github/workflows/build_llvm_libraries.yml + with: + os: "ubuntu-20.04" + arch: "X86" + + build_llvm_libraries_on_ubuntu_2204: + needs: [create_tag, create_release] + uses: ./.github/workflows/build_llvm_libraries.yml + with: + os: "ubuntu-22.04" + arch: "X86" + + build_llvm_libraries_on_macos: + needs: [create_tag, create_release] + uses: ./.github/workflows/build_llvm_libraries.yml + with: + os: "macos-latest" + arch: "X86" + # # WAMRC release_wamrc_on_ubuntu_2004: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2004] uses: ./.github/workflows/build_wamrc.yml with: - # can't take an env variable here - llvm_cache_key: ubuntu-20.04-build-llvm_libraries_ex + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} release: true runner: ubuntu-20.04 upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver}} release_wamrc_on_ubuntu_2204: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2204 ] uses: ./.github/workflows/build_wamrc.yml with: - # can't take an env variable here - llvm_cache_key: ubuntu-22.04-build-llvm_libraries_ex + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} release: true runner: ubuntu-22.04 upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver }} release_wamrc_on_ubuntu_macos: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_macos] uses: ./.github/workflows/build_wamrc.yml with: - # can't take an env variable here - llvm_cache_key: macos-latest-build-llvm_libraries_ex + llvm_cache_key: ${{ needs.build_llvm_libraries_on_macos.outputs.cache_key }} release: true runner: macos-latest upload_url: ${{ needs.create_release.outputs.upload_url }} @@ -87,28 +107,31 @@ jobs: # # IWASM release_iwasm_on_ubuntu_2004: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2004] uses: ./.github/workflows/build_iwasm_release.yml with: cwd: product-mini/platforms/linux + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} runner: ubuntu-20.04 upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver}} release_iwasm_on_ubuntu_2204: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_ubuntu_2204] uses: ./.github/workflows/build_iwasm_release.yml with: cwd: product-mini/platforms/linux + llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} runner: ubuntu-22.04 upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver}} release_iwasm_on_macos: - needs: [create_tag, create_release] + needs: [create_tag, create_release, build_llvm_libraries_on_macos] uses: ./.github/workflows/build_iwasm_release.yml with: cwd: product-mini/platforms/darwin + llvm_cache_key: ${{ needs.build_llvm_libraries_on_macos.outputs.cache_key }} runner: macos-latest upload_url: ${{ needs.create_release.outputs.upload_url }} ver_num: ${{ needs.create_tag.outputs.new_ver}} diff --git a/product-mini/platforms/android/build_llvm.sh b/product-mini/platforms/android/build_llvm.sh index 3ef343f98..145e2dbaa 100755 --- a/product-mini/platforms/android/build_llvm.sh +++ b/product-mini/platforms/android/build_llvm.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../../../build-scripts/requirements.txt /usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform android "$@" diff --git a/product-mini/platforms/darwin/build_llvm.sh b/product-mini/platforms/darwin/build_llvm.sh index 1cb00425a..b8a9761f8 100755 --- a/product-mini/platforms/darwin/build_llvm.sh +++ b/product-mini/platforms/darwin/build_llvm.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../../../build-scripts/requirements.txt /usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform darwin "$@" diff --git a/product-mini/platforms/freebsd/build_llvm.sh b/product-mini/platforms/freebsd/build_llvm.sh index 47387a3c3..c5666b7f5 100755 --- a/product-mini/platforms/freebsd/build_llvm.sh +++ b/product-mini/platforms/freebsd/build_llvm.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../../../build-scripts/requirements.txt /usr/bin/env python3 ../../../build-scripts/build_llvm.py "$@" diff --git a/product-mini/platforms/linux/build_llvm.sh b/product-mini/platforms/linux/build_llvm.sh index 47387a3c3..c5666b7f5 100755 --- a/product-mini/platforms/linux/build_llvm.sh +++ b/product-mini/platforms/linux/build_llvm.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../../../build-scripts/requirements.txt /usr/bin/env python3 ../../../build-scripts/build_llvm.py "$@" diff --git a/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile b/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile index 6ca210947..b2e24e93d 100644 --- a/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile +++ b/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile @@ -12,7 +12,7 @@ COPY resource /root/ ## - download cmake with wget and set up # hadolint ignore=DL3008 RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \ - && tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \ + && tar -zxf cmake-3.21.1-linux-x86_64.tar.gz \ && rm -f cmake-3.21.1-linux-x86_64.tar.gz \ && mv cmake-3.21.1-linux-x86_64 /opt/cmake \ && ln -s /opt/cmake/bin/cmake /bin/cmake \ @@ -26,13 +26,17 @@ RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/ ## - download wasi-sdk with wget and set up to /opt/wasi-sdk RUN wget --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz \ - && tar -zxvf wasi-sdk-*-linux.tar.gz \ + && tar -zxf wasi-sdk-*-linux.tar.gz \ && mv wasi-sdk-19.0 /opt/wasi-sdk/ \ && rm -f wasi-sdk-*-linux.tar.gz ## - clone wamr repo RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git +WORKDIR /root/wasm-micro-runtime/build-scripts +RUN apt-get update && apt-get install --no-install-recommends -y ccache ninja-build python3-pip +RUN pip3 install --user -r requirements.txt + WORKDIR /root/wasm-micro-runtime/wamr-compiler RUN ./build_llvm.sh \ && mkdir build diff --git a/wamr-compiler/build_llvm.sh b/wamr-compiler/build_llvm.sh index 35dc35edd..c3ec54b61 100755 --- a/wamr-compiler/build_llvm.sh +++ b/wamr-compiler/build_llvm.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../build-scripts/requirements.txt /usr/bin/env python3 ../build-scripts/build_llvm.py "$@" diff --git a/wamr-compiler/build_llvm_arc.sh b/wamr-compiler/build_llvm_arc.sh index f8f40edd9..d148e11ec 100755 --- a/wamr-compiler/build_llvm_arc.sh +++ b/wamr-compiler/build_llvm_arc.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../build-scripts/requirements.txt /usr/bin/env python3 ../build-scripts/build_llvm.py --platform arc "$@" diff --git a/wamr-compiler/build_llvm_xtensa.sh b/wamr-compiler/build_llvm_xtensa.sh index d75b62fe9..183ea379f 100755 --- a/wamr-compiler/build_llvm_xtensa.sh +++ b/wamr-compiler/build_llvm_xtensa.sh @@ -3,4 +3,5 @@ # Copyright (C) 2020 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +/usr/bin/env python3 -m pip install --user -r ../build-scripts/requirements.txt /usr/bin/env python3 ../build-scripts/build_llvm.py --platform xtensa "$@" From 61369d48fda69fdb3a336b41046b3e52101045cc Mon Sep 17 00:00:00 2001 From: Thomas Devoogdt Date: Tue, 28 Mar 2023 05:20:31 +0200 Subject: [PATCH 28/61] libc-wasi/posix.c: Fix POLL{RD,WR}NORM in uClibc (#2069) POLLRDNORM/POLLWRNORM may be not defined in uClibc, so replace them with the equivalent POLLIN/POLLOUT. Refer to https://www.man7.org/linux/man-pages/man2/poll.2.html POLLRDNORM Equivalent to POLLIN POLLWRNORM Equivalent to POLLOUT Signed-off-by: Thomas Devoogdt --- .../libc-wasi/sandboxed-system-primitives/src/posix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 9e29a3bac..61e841836 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 @@ -2655,8 +2655,8 @@ wasmtime_ssp_poll_oneoff( pfds[i] = (struct pollfd){ .fd = fd_number(fos[i]), .events = s->u.type == __WASI_EVENTTYPE_FD_READ - ? POLLRDNORM - : POLLWRNORM, + ? POLLIN + : POLLOUT, }; } else { @@ -2767,7 +2767,7 @@ wasmtime_ssp_poll_oneoff( __WASI_EVENT_FD_READWRITE_HANGUP, }; } - else if ((pfds[i].revents & (POLLRDNORM | POLLWRNORM)) != 0) { + else if ((pfds[i].revents & (POLLIN | POLLOUT)) != 0) { // Read or write possible. out[(*nevents)++] = (__wasi_event_t){ .userdata = in[i].userdata, From ff4be24726c7f3feb9e7fff291ecee0b9aa7d0ae Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Tue, 28 Mar 2023 05:18:39 +0100 Subject: [PATCH 29/61] Fix bh_assert for 64-bit platforms (#2071) In some cases, the memory address of some variables may have 4 least significant bytes set to zero. Because we cast the pointer to int, we look only at 4 least significant bytes; the assertion may fail because 4 least significant bytes are 0. Change bh_assert implementation to cast the assert expr to int64_t and it works well with 64-bit architectures. --- core/shared/utils/bh_assert.c | 2 +- core/shared/utils/bh_assert.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/shared/utils/bh_assert.c b/core/shared/utils/bh_assert.c index f341df4df..246c55d1b 100644 --- a/core/shared/utils/bh_assert.c +++ b/core/shared/utils/bh_assert.c @@ -6,7 +6,7 @@ #include "bh_assert.h" void -bh_assert_internal(int v, const char *file_name, int line_number, +bh_assert_internal(int64 v, const char *file_name, int line_number, const char *expr_string) { if (v) diff --git a/core/shared/utils/bh_assert.h b/core/shared/utils/bh_assert.h index 06f7f3b6c..b7c995af8 100644 --- a/core/shared/utils/bh_assert.h +++ b/core/shared/utils/bh_assert.h @@ -14,10 +14,10 @@ extern "C" { #if BH_DEBUG != 0 void -bh_assert_internal(int v, const char *file_name, int line_number, +bh_assert_internal(int64 v, const char *file_name, int line_number, const char *expr_string); #define bh_assert(expr) \ - bh_assert_internal((int)(uintptr_t)(expr), __FILE__, __LINE__, #expr) + bh_assert_internal((int64)(uintptr_t)(expr), __FILE__, __LINE__, #expr) #else #define bh_assert(expr) (void)0 #endif /* end of BH_DEBUG */ From 0a7994ac0aeab637cf0c1b65520f7c88fa1b13ad Mon Sep 17 00:00:00 2001 From: Wang Ning Date: Tue, 28 Mar 2023 14:21:32 +0800 Subject: [PATCH 30/61] wamr-ide: Modify Dockerfile to update base image version and fix build bug (#2068) --- .../src/utilities/lldbUtilities.ts | 2 +- .../WASM-Debug-Server/Docker/Dockerfile | 20 ++++++------- .../wamr-ide/WASM-Toolchain/Docker/Dockerfile | 28 +++++++------------ 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts index 210ad0208..92ac9f707 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts @@ -12,7 +12,7 @@ import { downloadFile, unzipFile, } from './directoryUtilities'; -import { SelectionOfPrompt, Status } from '../constants'; +import { SelectionOfPrompt } from '../constants'; const LLDB_RESOURCE_DIR = 'resource/debug'; const LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP: Partial< diff --git a/test-tools/wamr-ide/WASM-Debug-Server/Docker/Dockerfile b/test-tools/wamr-ide/WASM-Debug-Server/Docker/Dockerfile index 20e0be55a..8165bd5f5 100644 --- a/test-tools/wamr-ide/WASM-Debug-Server/Docker/Dockerfile +++ b/test-tools/wamr-ide/WASM-Debug-Server/Docker/Dockerfile @@ -1,31 +1,27 @@ # Copyright (C) 2019 Intel Corporation. All rights reserved. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -FROM gcc:9.3.0 AS BASE +FROM gcc:12.2.0 AS BASE ## set work directory WORKDIR /root/ COPY resource /root/ -## - download cmake with wget and set up # hadolint ignore=DL3008 -RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \ - && tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \ - && rm -f cmake-3.21.1-linux-x86_64.tar.gz \ - && mv cmake-3.21.1-linux-x86_64 /opt/cmake \ - && ln -s /opt/cmake/bin/cmake /bin/cmake \ - && apt-get -y install make --no-install-recommends +RUN apt-get update \ + && apt-get -y install make cmake --no-install-recommends ## -clone wamr-repo and build iwasm RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git \ - && mkdir -p /root/wasm-micro-runtime/product-mini/platforms/linux/build + && mkdir -p /root/wasm-micro-runtime/product-mini/platforms/linux/build -WORKDIR /root/wasm-micro-runtime/product-mini/platforms/linux/build -RUN cmake .. -DWAMR_BUILD_DEBUG_INTERP=1 && make \ +WORKDIR /root/wasm-micro-runtime/product-mini/platforms/linux/build +RUN cmake .. -DWAMR_BUILD_DEBUG_INTERP=1 \ + && make \ && cp /root/wasm-micro-runtime/product-mini/platforms/linux/build/iwasm /root/iwasm \ && rm -fr /root/wasm-micro-runtime -FROM ubuntu:20.04 +FROM ubuntu:22.04 # COPY files from BASE image COPY --from=BASE /root/iwasm /root COPY --from=BASE /root/debug.sh /root diff --git a/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile b/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile index b2e24e93d..cd8da38d9 100644 --- a/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile +++ b/test-tools/wamr-ide/WASM-Toolchain/Docker/Dockerfile @@ -2,29 +2,25 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ## Build docker image that consists of gcc, cmake, wasi-sdk & zephyr sdk -FROM gcc:9.3.0 AS BASE +FROM gcc:12.2.0 AS BASE ## set work directory WORKDIR /root/ COPY resource /root/ -## - download cmake with wget and set up +# - download cmake with wget and set up # hadolint ignore=DL3008 -RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \ - && tar -zxf cmake-3.21.1-linux-x86_64.tar.gz \ - && rm -f cmake-3.21.1-linux-x86_64.tar.gz \ - && mv cmake-3.21.1-linux-x86_64 /opt/cmake \ - && ln -s /opt/cmake/bin/cmake /bin/cmake \ - && apt-get -y install make --no-install-recommends +RUN apt-get update \ + && apt-get -y install ccache ninja-build make cmake python3-pip --no-install-recommends -## set compilation environment for wamrc +# set compilation environment for wamrc # - wamr repo # - cmake # - wasi-sdk # - wamr-sdk -## - download wasi-sdk with wget and set up to /opt/wasi-sdk +# - download wasi-sdk with wget and set up to /opt/wasi-sdk RUN wget --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz \ && tar -zxf wasi-sdk-*-linux.tar.gz \ && mv wasi-sdk-19.0 /opt/wasi-sdk/ \ @@ -34,8 +30,7 @@ RUN wget --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/do RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git WORKDIR /root/wasm-micro-runtime/build-scripts -RUN apt-get update && apt-get install --no-install-recommends -y ccache ninja-build python3-pip -RUN pip3 install --user -r requirements.txt +RUN pip3 install --no-cache-dir --user -r requirements.txt WORKDIR /root/wasm-micro-runtime/wamr-compiler RUN ./build_llvm.sh \ @@ -53,26 +48,23 @@ RUN cmake .. \ && rm -fr /root/wasm-micro-runtime # ## STAGE 2 -FROM ubuntu:20.04 +FROM ubuntu:22.04 ENV HOME_DIR=/home/wasm-toolchain RUN mkdir -p /opt/wasi-sdk \ - && mkdir -p /opt/cmake \ && mkdir -p /opt/wamr-sdk/app \ && mkdir -p /home/wasm-toolchain # COPY files from BASE image -COPY --from=BASE /opt/cmake/ /opt/cmake/ COPY --from=BASE /opt/wamr-sdk/app/ /opt/wamr-sdk/app/ COPY --from=BASE /opt/wasi-sdk /opt/wasi-sdk/ COPY --from=BASE /root/wamrc ${HOME_DIR} COPY --from=BASE /root/build_wasm.sh ${HOME_DIR} -RUN ln -s /opt/cmake/bin/cmake /usr/bin/cmake \ - && ln -s ${HOME_DIR}/wamrc /usr/bin/wamrc +RUN ln -s ${HOME_DIR}/wamrc /usr/bin/wamrc # hadolint ignore=DL3008 -RUN apt-get update && apt-get install -y make --no-install-recommends \ +RUN apt-get update && apt-get install -y cmake make --no-install-recommends \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* From 8ee8ab30999b7850b7db0d74b9e05211a6949c38 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 28 Mar 2023 14:50:31 +0800 Subject: [PATCH 31/61] Limit the minimal size of bh_hashmap (#2073) Limit the minimal size of bh_hashmap to avoid creating hashmap with size 0, and `divide by zero` when calling bh_hash_map_find. Reported by #2008. --- core/shared/utils/bh_hashmap.c | 3 +++ core/shared/utils/bh_hashmap.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/core/shared/utils/bh_hashmap.c b/core/shared/utils/bh_hashmap.c index 70119c770..3502239ad 100644 --- a/core/shared/utils/bh_hashmap.c +++ b/core/shared/utils/bh_hashmap.c @@ -33,6 +33,9 @@ bh_hash_map_create(uint32 size, bool use_lock, HashFunc hash_func, HashMap *map; uint64 total_size; + if (size < HASH_MAP_MIN_SIZE) + size = HASH_MAP_MIN_SIZE; + if (size > HASH_MAP_MAX_SIZE) { LOG_ERROR("HashMap create failed: size is too large.\n"); return NULL; diff --git a/core/shared/utils/bh_hashmap.h b/core/shared/utils/bh_hashmap.h index ef06960fb..38aa2c668 100644 --- a/core/shared/utils/bh_hashmap.h +++ b/core/shared/utils/bh_hashmap.h @@ -12,6 +12,9 @@ extern "C" { #endif +/* Minimum initial size of hash map */ +#define HASH_MAP_MIN_SIZE 4 + /* Maximum initial size of hash map */ #define HASH_MAP_MAX_SIZE 65536 From 0ce39a136846dc74dfbf72abc3ae5a7ffb5bdf67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 16:36:59 +0800 Subject: [PATCH 32/61] Bump tensorflow in /core/iwasm/libraries/wasi-nn/test (#2061) Bumps [tensorflow](https://github.com/tensorflow/tensorflow) from 2.10.1 to 2.11.1. - [Release notes](https://github.com/tensorflow/tensorflow/releases) - [Changelog](https://github.com/tensorflow/tensorflow/blob/master/RELEASE.md) - [Commits](https://github.com/tensorflow/tensorflow/compare/v2.10.1...v2.11.1) --- updated-dependencies: - dependency-name: tensorflow dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- core/iwasm/libraries/wasi-nn/test/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/iwasm/libraries/wasi-nn/test/requirements.txt b/core/iwasm/libraries/wasi-nn/test/requirements.txt index d0a393cb5..4cf2910db 100644 --- a/core/iwasm/libraries/wasi-nn/test/requirements.txt +++ b/core/iwasm/libraries/wasi-nn/test/requirements.txt @@ -1 +1 @@ -tensorflow==2.10.1 \ No newline at end of file +tensorflow==2.11.1 \ No newline at end of file From a35d39b353f2152245a9f66f48adedfa188dda18 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 28 Mar 2023 17:25:36 +0800 Subject: [PATCH 33/61] Bump tensorflow from 2.9.2 to 2.11.1 in install_tensorflow.sh (#2076) --- core/deps/install_tensorflow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/deps/install_tensorflow.sh b/core/deps/install_tensorflow.sh index 0b2a2ece6..125a8dc60 100755 --- a/core/deps/install_tensorflow.sh +++ b/core/deps/install_tensorflow.sh @@ -6,6 +6,6 @@ cd ${DEPS_ROOT} echo "Downloading tensorflow in ${PWD}..." git clone https://github.com/tensorflow/tensorflow.git tensorflow-src \ - --branch v2.9.2 + --branch v2.11.1 exit 0 From 10f1bf3af75d67f04bddf1782f2d99a9a69df9e2 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 28 Mar 2023 18:31:09 +0800 Subject: [PATCH 34/61] Fix module_malloc/module_free issues (#2072) Try using existing exec_env to execute wasm app's malloc/free func and execute post instantiation functions. Create a new exec_env only when no existing exec_env was found. --- core/iwasm/aot/aot_runtime.c | 124 +++++++++++++++++++++----- core/iwasm/interpreter/wasm_runtime.c | 124 +++++++++++++++++++++----- 2 files changed, 204 insertions(+), 44 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index b96e04edd..7ddbd6a91 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -932,7 +932,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = NULL; #endif - WASMExecEnv *exec_env = NULL; + WASMExecEnv *exec_env = NULL, *exec_env_created = NULL; bool ret = false; #if WASM_ENABLE_LIBC_WASI != 0 @@ -990,11 +990,29 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - aot_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + aot_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_main = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } @@ -1033,11 +1051,17 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, ret = true; fail: - if (is_sub_inst) + if (is_sub_inst) { /* Restore the parent exec_env's module inst */ exec_env_main->module_inst = module_inst_main; - else - wasm_exec_env_destroy(exec_env); + } + else { + if (module_inst_main) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_main; + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); + } return ret; } @@ -1596,6 +1620,8 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif + WASMExecEnv *exec_env_created = NULL; + WASMModuleInstanceCommon *module_inst_old = NULL; uint32 argv[2], argc; bool ret; @@ -1616,19 +1642,43 @@ execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, == (WASMModuleInstanceCommon *)module_inst); } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_old = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } ret = aot_call_function(exec_env, malloc_func, argc, argv); - if (retain_func && ret) { + if (retain_func && ret) ret = aot_call_function(exec_env, retain_func, 1, argv); - } + + if (module_inst_old) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_old; + + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); if (ret) *p_result = argv[0]; @@ -1642,7 +1692,10 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif + WASMExecEnv *exec_env_created = NULL; + WASMModuleInstanceCommon *module_inst_old = NULL; uint32 argv[2]; + bool ret; argv[0] = offset; @@ -1656,15 +1709,42 @@ execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env, == (WASMModuleInstanceCommon *)module_inst); } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_old = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } - return aot_call_function(exec_env, free_func, 1, argv); + ret = aot_call_function(exec_env, free_func, 1, argv); + + if (module_inst_old) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_old; + + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); + + return ret; } uint32 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 2338f90bf..ef580ac1b 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1016,7 +1016,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = NULL; #endif - WASMExecEnv *exec_env = NULL; + WASMExecEnv *exec_env = NULL, *exec_env_created = NULL; bool ret = false; #if WASM_ENABLE_LIBC_WASI != 0 @@ -1074,11 +1074,29 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_main = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } @@ -1105,11 +1123,17 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, ret = true; fail: - if (is_sub_inst) + if (is_sub_inst) { /* Restore the parent exec_env's module inst */ exec_env_main->module_inst = module_inst_main; - else - wasm_exec_env_destroy(exec_env); + } + else { + if (module_inst_main) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_main; + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); + } return ret; } @@ -1123,6 +1147,8 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif + WASMExecEnv *exec_env_created = NULL; + WASMModuleInstanceCommon *module_inst_old = NULL; uint32 argv[2], argc; bool ret; @@ -1151,19 +1177,43 @@ execute_malloc_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, == (WASMModuleInstanceCommon *)module_inst); } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_old = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } ret = wasm_call_function(exec_env, malloc_func, argc, argv); - if (retain_func && ret) { + if (retain_func && ret) ret = wasm_call_function(exec_env, retain_func, 1, argv); - } + + if (module_inst_old) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_old; + + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); if (ret) *p_result = argv[0]; @@ -1177,7 +1227,10 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, #ifdef OS_ENABLE_HW_BOUND_CHECK WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif + WASMExecEnv *exec_env_created = NULL; + WASMModuleInstanceCommon *module_inst_old = NULL; uint32 argv[2]; + bool ret; argv[0] = offset; @@ -1191,15 +1244,42 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, == (WASMModuleInstanceCommon *)module_inst); } else { - if (!(exec_env = - wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst, - module_inst->default_wasm_stack_size))) { - wasm_set_exception(module_inst, "allocate memory failed"); - return false; + /* Try using the existing exec_env */ +#ifdef OS_ENABLE_HW_BOUND_CHECK + exec_env = exec_env_tls; +#endif +#if WASM_ENABLE_THREAD_MGR != 0 + if (!exec_env) + exec_env = wasm_clusters_search_exec_env( + (WASMModuleInstanceCommon *)module_inst); +#endif + if (!exec_env) { + if (!(exec_env = exec_env_created = wasm_exec_env_create( + (WASMModuleInstanceCommon *)module_inst, + module_inst->default_wasm_stack_size))) { + wasm_set_exception(module_inst, "allocate memory failed"); + return false; + } + } + else { + /* Temporarily replace exec_env's module inst with current + module inst to ensure that the exec_env's module inst + is the correct one. */ + module_inst_old = exec_env->module_inst; + exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst; } } - return wasm_call_function(exec_env, free_func, 1, argv); + ret = wasm_call_function(exec_env, free_func, 1, argv); + + if (module_inst_old) + /* Restore the existing exec_env's module inst */ + exec_env->module_inst = module_inst_old; + + if (exec_env_created) + wasm_exec_env_destroy(exec_env_created); + + return ret; } #if WASM_ENABLE_MULTI_MODULE != 0 From 19ab3b8812acbf7a9e3fb8dcfd7ffbe76d81d2f5 Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Wed, 29 Mar 2023 17:24:44 +0800 Subject: [PATCH 35/61] spectest/nuttx: Increase stack size of iwasm task (#2082) --- .github/workflows/spec_test_on_nuttx.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/spec_test_on_nuttx.yml b/.github/workflows/spec_test_on_nuttx.yml index 42d3968b8..7b8403777 100644 --- a/.github/workflows/spec_test_on_nuttx.yml +++ b/.github/workflows/spec_test_on_nuttx.yml @@ -101,7 +101,7 @@ jobs: - name: Enable WAMR for NuttX run: | - find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_INTERPRETERS_WAMR=y\nCONFIG_INTERPRETERS_WAMR_AOT=y\nCONFIG_INTERPRETERS_WAMR_FAST=y\nCONFIG_INTERPRETERS_WAMR_LOG=y\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\n' + find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_INTERPRETERS_WAMR=y\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=32768\nCONFIG_INTERPRETERS_WAMR_AOT=y\nCONFIG_INTERPRETERS_WAMR_FAST=y\nCONFIG_INTERPRETERS_WAMR_LOG=y\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\n' find nuttx/boards -name defconfig | xargs sed -i '$a\CONFIG_EOL_IS_LF=y\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\nCONFIG_FS_HOSTFS=y\nCONFIG_LIBC_FLOATINGPOINT=y\n' - name: Build wamrc From b0736e2e88febd1454485134075062b8d59c17a9 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Wed, 29 Mar 2023 19:40:52 +0800 Subject: [PATCH 36/61] Fix issues reported by Coverity (#2083) Get exec_env_tls at the beginning of execute_post_instantiate_functions to avoid it is uninitialized when is_sub_inst is false. --- core/iwasm/aot/aot_runtime.c | 3 +-- core/iwasm/interpreter/wasm_runtime.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 7ddbd6a91..b5c406b96 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -930,7 +930,7 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, AOTFunctionInstance *call_ctors_func = NULL; WASMModuleInstanceCommon *module_inst_main = NULL; #ifdef OS_ENABLE_HW_BOUND_CHECK - WASMExecEnv *exec_env_tls = NULL; + WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif WASMExecEnv *exec_env = NULL, *exec_env_created = NULL; bool ret = false; @@ -976,7 +976,6 @@ execute_post_instantiate_functions(AOTModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - exec_env_tls = wasm_runtime_get_exec_env_tls(); bh_assert(exec_env_tls == exec_env_main); (void)exec_env_tls; #endif diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index ef580ac1b..8130d90af 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1014,7 +1014,7 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, #endif WASMModuleInstanceCommon *module_inst_main = NULL; #ifdef OS_ENABLE_HW_BOUND_CHECK - WASMExecEnv *exec_env_tls = NULL; + WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls(); #endif WASMExecEnv *exec_env = NULL, *exec_env_created = NULL; bool ret = false; @@ -1060,7 +1060,6 @@ execute_post_instantiate_functions(WASMModuleInstance *module_inst, if (is_sub_inst) { bh_assert(exec_env_main); #ifdef OS_ENABLE_HW_BOUND_CHECK - exec_env_tls = wasm_runtime_get_exec_env_tls(); bh_assert(exec_env_tls == exec_env_main); (void)exec_env_tls; #endif From 5aa22d41e9060f54e3236cc37e10b62210fc2c8a Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 30 Mar 2023 01:01:16 +0000 Subject: [PATCH 37/61] Fixing use after free when dumping call stack (#2084) In multi-threading, this line will eventually call `wasm_cluster_wait_for_all_except_self`: `DEINIT_VEC(store->instances, wasm_instance_vec_delete)` As the threads are joining they can call `wasm_interp_dump_call_stack` which tries to use the module frames but they were already freed by this line: `DEINIT_VEC(store->modules, wasm_module_vec_delete)` This PR swaps the order that these are deleted so module is deleted after the instances. Co-authored-by: Andrew Chambers --- core/iwasm/common/wasm_c_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 15eb9f011..639980ca2 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -687,8 +687,8 @@ wasm_store_delete(wasm_store_t *store) return; } - DEINIT_VEC(store->modules, wasm_module_vec_delete); DEINIT_VEC(store->instances, wasm_instance_vec_delete); + DEINIT_VEC(store->modules, wasm_module_vec_delete); if (store->foreigns) { bh_vector_destroy(store->foreigns); wasm_runtime_free(store->foreigns); From 08a4a7cf08b9a755406b58afe96d3ae7fe00568c Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Thu, 30 Mar 2023 02:34:30 +0100 Subject: [PATCH 38/61] ci: Refactor windows build definition (#2087) --- .github/workflows/compilation_on_windows.yml | 89 ++++---------------- 1 file changed, 16 insertions(+), 73 deletions(-) diff --git a/.github/workflows/compilation_on_windows.yml b/.github/workflows/compilation_on_windows.yml index 073f206ed..1cf06d626 100644 --- a/.github/workflows/compilation_on_windows.yml +++ b/.github/workflows/compilation_on_windows.yml @@ -48,6 +48,20 @@ concurrency: jobs: build: runs-on: windows-latest + strategy: + matrix: + build_options: [ + "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0", + "-DWAMR_BUILD_AOT=0", + "-DWAMR_BUILD_TAIL_CALL=1", + "-DWAMR_BUILD_CUSTOM_NAME_SECTION=1", + "-DWAMR_DISABLE_HW_BOUND_CHECK=1", + "-DWAMR_BUILD_REF_TYPES=1", + "-DWAMR_BUILD_SIMD=1", + "-DWAMR_BUILD_DEBUG_INTERP=1", + "-DWAMR_BUILD_LIB_PTHREAD=1", + "-DWAMR_BUILD_LIB_WASI_THREADS=1" + ] steps: - uses: actions/checkout@v3 @@ -55,80 +69,9 @@ jobs: run: | cd core/deps git clone https://github.com/nodejs/uvwasi.git - - name: Build iwasm [default] + - name: Build iwasm run: | cd product-mini/platforms/windows mkdir build && cd build - cmake .. + cmake .. ${{ matrix.build_options }} cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [aot only] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [interp only] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_AOT=0 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [tail call] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_TAIL_CALL=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [custom name section] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [disable hardware boundary check] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_DISABLE_HW_BOUND_CHECK=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [reference types] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_REF_TYPES=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [128-bit SIMD] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_SIMD=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [source debugger] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_DEBUG_INTERP=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [lib pthread] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_LIB_PTHREAD=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build - - name: Build iwasm [lib wasi-thread] - run: | - cd product-mini/platforms/windows - mkdir build && cd build - cmake .. -DWAMR_BUILD_LIB_WASI_THREADS=1 - cmake --build . --config Release --parallel 4 - cd .. && rm -force -r build From eaf1897a7000e69e41b577af04de066c9786e422 Mon Sep 17 00:00:00 2001 From: zoraaver <55952569+zoraaver@users.noreply.github.com> Date: Thu, 30 Mar 2023 02:53:07 +0100 Subject: [PATCH 39/61] Add support for universal binaries on OSX (#2060) When building for multiple architectures on OSX, it's necessary to use compiler macros to conditionally include architecture-specific code rather than conditionally including architecture-specific assembly files via cmake. See https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary and https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html for more details. Co-authored-by: Zoraaver Singh --- .../common/arch/invokeNative_osx_universal.s | 18 ++++++++++++++++++ core/iwasm/common/iwasm_common.cmake | 13 +++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 core/iwasm/common/arch/invokeNative_osx_universal.s diff --git a/core/iwasm/common/arch/invokeNative_osx_universal.s b/core/iwasm/common/arch/invokeNative_osx_universal.s new file mode 100644 index 000000000..e2ca654fd --- /dev/null +++ b/core/iwasm/common/arch/invokeNative_osx_universal.s @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#if defined(__aarch64__) +#if WASM_ENABLE_SIMD == 0 +#include "invokeNative_aarch64.s" +#else +#include "invokeNative_aarch64_simd.s" +#endif +#else +#if WASM_ENABLE_SIMD == 0 +#include "invokeNative_em64.s" +#else +#include "invokeNative_em64_simd.s" +#endif +#endif \ No newline at end of file diff --git a/core/iwasm/common/iwasm_common.cmake b/core/iwasm/common/iwasm_common.cmake index 11d6e0eaa..15895b8e5 100644 --- a/core/iwasm/common/iwasm_common.cmake +++ b/core/iwasm/common/iwasm_common.cmake @@ -14,6 +14,17 @@ if (WAMR_DISABLE_APP_ENTRY EQUAL 1) list(REMOVE_ITEM c_source_all "${IWASM_COMMON_DIR}/wasm_application.c") endif () +if (CMAKE_OSX_ARCHITECTURES) + string(TOLOWER "${CMAKE_OSX_ARCHITECTURES}" OSX_ARCHS) + + list(FIND OSX_ARCHS arm64 OSX_AARCH64) + list(FIND OSX_ARCHS x86_64 OSX_X86_64) + + if (NOT "${OSX_AARCH64}" STREQUAL "-1" AND NOT "${OSX_X86_64}" STREQUAL "-1") + set(OSX_UNIVERSAL_BUILD 1) + endif() +endif() + if (WAMR_BUILD_INVOKE_NATIVE_GENERAL EQUAL 1) # Use invokeNative C version instead of asm code version # if WAMR_BUILD_INVOKE_NATIVE_GENERAL is explicitly set. @@ -24,6 +35,8 @@ if (WAMR_BUILD_INVOKE_NATIVE_GENERAL EQUAL 1) # in arm and mips need to be 8-bytes aligned, and some arguments # of x86_64 are passed by registers but not stack set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_general.c) +elseif (OSX_UNIVERSAL_BUILD EQUAL 1) + set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_osx_universal.s) elseif (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") if (NOT WAMR_BUILD_SIMD EQUAL 1) if (WAMR_BUILD_PLATFORM STREQUAL "windows") From 403ccf02b72760888b5cf7f8bab69723dad69a8e Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Thu, 30 Mar 2023 03:05:00 +0100 Subject: [PATCH 40/61] ci: Enable WASI threads in CI (#2086) --- .github/workflows/build_iwasm_release.yml | 1 + .github/workflows/compilation_on_android_ubuntu.yml | 1 + .github/workflows/compilation_on_macos.yml | 1 + .github/workflows/compilation_on_sgx.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/build_iwasm_release.yml b/.github/workflows/build_iwasm_release.yml index ae1f6140b..a1a254215 100644 --- a/.github/workflows/build_iwasm_release.yml +++ b/.github/workflows/build_iwasm_release.yml @@ -73,6 +73,7 @@ jobs: -DWAMR_BUILD_BULK_MEMORY=1 \ -DWAMR_BUILD_LIB_PTHREAD=1 \ -DWAMR_BUILD_LIB_PTHREAD_SEMAPHORE=1 \ + -DWAMR_BUILD_LIB_WASI_THREADS=1 \ -DWAMR_BUILD_LIBC_BUILTIN=1 \ -DWAMR_BUILD_LIBC_WASI=1 \ -DWAMR_BUILD_REF_TYPES=1 \ diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 062b17297..e620b648a 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -138,6 +138,7 @@ jobs: "-DWAMR_BUILD_DEBUG_INTERP=1", "-DWAMR_BUILD_DUMP_CALL_STACK=1", "-DWAMR_BUILD_LIB_PTHREAD=1", + "-DWAMR_BUILD_LIB_WASI_THREADS=1", "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", "-DWAMR_BUILD_MINI_LOADER=1", "-DWAMR_BUILD_MEMORY_PROFILING=1", diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index 5f3828406..50d48d21f 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -115,6 +115,7 @@ jobs: "-DWAMR_BUILD_DEBUG_INTERP=1", "-DWAMR_BUILD_DUMP_CALL_STACK=1", "-DWAMR_BUILD_LIB_PTHREAD=1", + "-DWAMR_BUILD_LIB_WASI_THREADS=1", "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", "-DWAMR_BUILD_MINI_LOADER=1", "-DWAMR_BUILD_MEMORY_PROFILING=1", diff --git a/.github/workflows/compilation_on_sgx.yml b/.github/workflows/compilation_on_sgx.yml index a26f27aaf..985674f6e 100644 --- a/.github/workflows/compilation_on_sgx.yml +++ b/.github/workflows/compilation_on_sgx.yml @@ -80,6 +80,7 @@ jobs: # "-DWAMR_BUILD_DEBUG_INTERP=1", "-DWAMR_BUILD_DUMP_CALL_STACK=1", "-DWAMR_BUILD_LIB_PTHREAD=1", + "-DWAMR_BUILD_LIB_WASI_THREADS=1", "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", "-DWAMR_BUILD_MINI_LOADER=1", "-DWAMR_BUILD_MEMORY_PROFILING=1", From 48429da29fc839ad8b4c3039bdf9b0f3acccd9e4 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Thu, 30 Mar 2023 21:15:21 +0800 Subject: [PATCH 41/61] Fix compilation errors of workload xnnpack and meshoptimizer (#2081) --- .github/workflows/build_iwasm_release.yml | 5 +--- .github/workflows/build_wamrc.yml | 5 +--- samples/workload/XNNPACK/CMakeLists.txt | 5 ++-- samples/workload/XNNPACK/xnnpack.patch | 25 ++++++++++++++++--- samples/workload/meshoptimizer/CMakeLists.txt | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build_iwasm_release.yml b/.github/workflows/build_iwasm_release.yml index a1a254215..64aa9a92c 100644 --- a/.github/workflows/build_iwasm_release.yml +++ b/.github/workflows/build_iwasm_release.yml @@ -48,10 +48,7 @@ jobs: ./core/deps/llvm/build/libexec ./core/deps/llvm/build/share key: ${{ inputs.llvm_cache_key }} - - - name: Quit if cache miss - if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' - run: echo "::error::can not get prebuilt llvm libraries" && exit 1 + fail-on-cache-miss: true - name: generate iwasm binary release run: | diff --git a/.github/workflows/build_wamrc.yml b/.github/workflows/build_wamrc.yml index a88a1f715..11c5de9ba 100644 --- a/.github/workflows/build_wamrc.yml +++ b/.github/workflows/build_wamrc.yml @@ -48,10 +48,7 @@ jobs: ./core/deps/llvm/build/libexec ./core/deps/llvm/build/share key: ${{ inputs.llvm_cache_key }} - - - name: Quit if cache miss - if: steps.retrieve_llvm_libs.outputs.cache-hit != 'true' - run: echo "::error::can not get prebuilt llvm libraries" && exit 1 + fail-on-cache-miss: true - name: generate wamrc binary release run: | diff --git a/samples/workload/XNNPACK/CMakeLists.txt b/samples/workload/XNNPACK/CMakeLists.txt index 532544f9c..aef138d5e 100644 --- a/samples/workload/XNNPACK/CMakeLists.txt +++ b/samples/workload/XNNPACK/CMakeLists.txt @@ -11,11 +11,10 @@ include(ExternalProject) ExternalProject_Add(xnnpack PREFIX xnnpack GIT_REPOSITORY https://github.com/google/XNNPACK.git - GIT_TAG master + GIT_TAG 4570a7151aa4f3e57eca14a575eeff6bb13e26be GIT_PROGRESS ON SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack - UPDATE_COMMAND git checkout . - && git reset --hard 4570a7151aa4f3e57eca14a575eeff6bb13e26be + UPDATE_COMMAND git restore . && cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack/google3/third_party/XNNPACK/microkernels.bzl ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack/ && git apply ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack.patch diff --git a/samples/workload/XNNPACK/xnnpack.patch b/samples/workload/XNNPACK/xnnpack.patch index f7d0a01d4..3fb6b230b 100644 --- a/samples/workload/XNNPACK/xnnpack.patch +++ b/samples/workload/XNNPACK/xnnpack.patch @@ -15,10 +15,22 @@ index 688279da1..376996885 100644 +build:wasm --crosstool_top=@emsdk//emscripten_toolchain:everything +build:wasm --host_crosstool_top=@bazel_tools//tools/cpp:toolchain diff --git a/WORKSPACE b/WORKSPACE -index cd8960ffa..5d3e685f4 100644 +index cd8960ffa..787e03ca8 100644 --- a/WORKSPACE +++ b/WORKSPACE -@@ -92,8 +92,25 @@ http_archive( +@@ -29,8 +29,9 @@ http_archive( + # Google Benchmark library, used in micro-benchmarks. + http_archive( + name = "com_google_benchmark", +- strip_prefix = "benchmark-main", +- urls = ["https://github.com/google/benchmark/archive/main.zip"], ++ sha256 = "1ba14374fddcd9623f126b1a60945e4deac4cdc4fb25a5f25e7f779e36f2db52", ++ strip_prefix = "benchmark-d2a8a4ee41b923876c034afb939c4fc03598e622", ++ urls = ["https://github.com/google/benchmark/archive/d2a8a4ee41b923876c034afb939c4fc03598e622.zip"], + ) + + # FP16 library, used for half-precision conversions +@@ -92,8 +93,25 @@ http_archive( ], ) @@ -47,7 +59,7 @@ index cd8960ffa..5d3e685f4 100644 -android_sdk_repository(name = "androidsdk") +#android_sdk_repository(name = "androidsdk") diff --git a/build_defs.bzl b/build_defs.bzl -index b8217a18d..da232966e 100644 +index b8217a18d..6f2d1675e 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -380,7 +380,7 @@ def xnnpack_benchmark(name, srcs, copts = [], deps = [], tags = []): @@ -59,6 +71,13 @@ index b8217a18d..da232966e 100644 srcs = srcs, copts = xnnpack_std_cxxopts() + [ "-Iinclude", +@@ -405,5 +405,5 @@ def xnnpack_benchmark(name, srcs, copts = [], deps = [], tags = []): + ":emscripten": xnnpack_emscripten_deps(), + "//conditions:default": [], + }), +- tags = tags, ++ tags = tags, + ) diff --git a/emscripten.bzl b/emscripten.bzl index f1557a7b1..7f964a094 100644 --- a/emscripten.bzl diff --git a/samples/workload/meshoptimizer/CMakeLists.txt b/samples/workload/meshoptimizer/CMakeLists.txt index 263f6a182..d6a1c358a 100644 --- a/samples/workload/meshoptimizer/CMakeLists.txt +++ b/samples/workload/meshoptimizer/CMakeLists.txt @@ -22,7 +22,7 @@ ExternalProject_Add(codecbench PREFIX codecbench GIT_REPOSITORY https://github.com/zeux/meshoptimizer.git GIT_TAG f734fd572aed5bf76e84d9ed62ca6f4f6c47d84e - GIT_SHALLOW ON + GIT_SHALLOW OFF GIT_PROGRESS ON SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/meshoptimizer UPDATE_COMMAND git clean -fd && git checkout -- * From aaf671d688592784d1f8e000531cd98c2c22bfac Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Fri, 31 Mar 2023 16:18:43 +0800 Subject: [PATCH 42/61] Fix typo in Fast JIT's BUILD_COND_BR Macro (#2092) --- core/iwasm/fast-jit/fe/jit_emit_control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/iwasm/fast-jit/fe/jit_emit_control.c b/core/iwasm/fast-jit/fe/jit_emit_control.c index e6b03a1ee..f3aa31f39 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_control.c +++ b/core/iwasm/fast-jit/fe/jit_emit_control.c @@ -30,7 +30,7 @@ #define BUILD_COND_BR(value_if, block_then, block_else) \ do { \ - if (!GEN_INSN(CMP, cc->cmp_reg, value_if, NEW_CONST(cc, 0)) \ + if (!GEN_INSN(CMP, cc->cmp_reg, value_if, NEW_CONST(I32, 0)) \ || !GEN_INSN(BNE, cc->cmp_reg, jit_basic_block_label(block_then), \ jit_basic_block_label(block_else))) { \ jit_set_last_error(cc, "generate bne insn failed"); \ From 156318f0d4c8807ba8dc35c59d1582b6c0f4e760 Mon Sep 17 00:00:00 2001 From: Enrico Loparco Date: Mon, 3 Apr 2023 02:43:11 +0200 Subject: [PATCH 43/61] Use wasi-sdk-20 to build wasi-threads cases in CI (#2095) wasi-sdk-20 supports older versions of glibc and allow us to use it in the CI with Ubuntu 20.04. Refer to https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-20 And #2021 for previous upgrade to wasi-sdk-20 pre-release. --- .../compilation_on_android_ubuntu.yml | 77 +++++-------------- .github/workflows/compilation_on_macos.yml | 6 +- core/iwasm/libraries/lib-socket/test/build.sh | 1 - .../libraries/lib-wasi-threads/test/build.sh | 1 - 4 files changed, 21 insertions(+), 64 deletions(-) diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index e620b648a..0a87cb76e 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -274,7 +274,7 @@ jobs: os: [ubuntu-20.04, ubuntu-22.04] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz", ] wabt_release: [ @@ -334,17 +334,14 @@ jobs: strategy: matrix: os: [ubuntu-20.04, ubuntu-22.04] - include: - - os: ubuntu-20.04 - wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz" - wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" - wasi_sdk_folder_name: "wasi-sdk-19.0" - wasi_sysroot_option: "-DWASI_SYSROOT=`pwd`/../../../core/deps/wasi-libc/sysroot" - - os: ubuntu-22.04 - wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-linux.tar.gz" - wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" - wasi_sdk_folder_name: "wasi-sdk-20.0+threads" - wasi_sysroot_option: "" + wasi_sdk_release: + [ + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz" + ] + wabt_release: + [ + "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + ] steps: - name: checkout uses: actions/checkout@v3 @@ -354,7 +351,7 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv ${{ matrix.wasi_sdk_folder_name }} wasi-sdk + sudo mv wasi-sdk-20.0 wasi-sdk - name: download and install wabt run: | @@ -363,23 +360,6 @@ jobs: sudo tar -xzf wabt-1.0.31-*.tar.gz sudo mv wabt-1.0.31 wabt - - name: build wasi-libc (needed for wasi-threads) - if: matrix.os == 'ubuntu-20.04' - run: | - mkdir wasi-libc - cd wasi-libc - git init - # "Fix a_store operation in atomic.h" commit on main branch - git fetch https://github.com/WebAssembly/wasi-libc \ - 1dfe5c302d1c5ab621f7abf04620fae92700fd22 - git checkout FETCH_HEAD - make -j \ - AR=/opt/wasi-sdk/bin/llvm-ar \ - NM=/opt/wasi-sdk/bin/llvm-nm \ - CC=/opt/wasi-sdk/bin/clang \ - THREAD_MODEL=posix - working-directory: core/deps - - name: Build Sample [basic] run: | cd samples/basic @@ -437,7 +417,7 @@ jobs: run: | cd samples/wasi-threads mkdir build && cd build - cmake ${{ matrix.wasi_sysroot_option }} .. + cmake .. cmake --build . --config Release --parallel 4 ./iwasm wasm-apps/no_pthread.wasm @@ -470,20 +450,16 @@ jobs: $THREADS_TEST_OPTIONS, $WASI_TEST_OPTIONS, ] + wasi_sdk_release: + [ + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz" + ] include: - os: ubuntu-20.04 llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }} - wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz" - wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" - wasi_sdk_folder_name: "wasi-sdk-19.0" - wasi_sysroot_option: "WASI_SYSROOT_OPTION='--sysroot ../../../../../core/deps/wasi-libc/sysroot'" ubuntu_version: "20.04" - os: ubuntu-22.04 llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }} - wasi_sdk_release: "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-linux.tar.gz" - wabt_release: "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" - wasi_sdk_folder_name: "wasi-sdk-20.0+threads" - wasi_sysroot_option: "" ubuntu_version: "22.04" exclude: # uncompatiable modes and features @@ -525,24 +501,7 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv ${{ matrix.wasi_sdk_folder_name }} wasi-sdk - - - name: build wasi-libc (needed for wasi-threads) - if: matrix.os == 'ubuntu-20.04' && matrix.test_option == '$WASI_TEST_OPTIONS' - run: | - mkdir wasi-libc - cd wasi-libc - git init - # "Fix a_store operation in atomic.h" commit on main branch - git fetch https://github.com/WebAssembly/wasi-libc \ - 1dfe5c302d1c5ab621f7abf04620fae92700fd22 - git checkout FETCH_HEAD - make -j \ - AR=/opt/wasi-sdk/bin/llvm-ar \ - NM=/opt/wasi-sdk/bin/llvm-nm \ - CC=/opt/wasi-sdk/bin/clang \ - THREAD_MODEL=posix - working-directory: core/deps + sudo mv wasi-sdk-20.0 wasi-sdk - name: set env variable(if llvm are used) if: matrix.running_mode == 'aot' || matrix.running_mode == 'jit' || matrix.running_mode == 'multi-tier-jit' @@ -579,12 +538,12 @@ jobs: - name: Build WASI thread tests if: matrix.test_option == '$WASI_TEST_OPTIONS' - run: ${{ matrix.wasi_sysroot_option }} bash build.sh + run: bash build.sh working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/ - name: build socket api tests if: matrix.test_option == '$WASI_TEST_OPTIONS' - run: ${{ matrix.wasi_sysroot_option }} bash build.sh + run: bash build.sh working-directory: ./core/iwasm/libraries/lib-socket/test/ - name: run tests diff --git a/.github/workflows/compilation_on_macos.yml b/.github/workflows/compilation_on_macos.yml index 50d48d21f..ec81773f4 100644 --- a/.github/workflows/compilation_on_macos.yml +++ b/.github/workflows/compilation_on_macos.yml @@ -218,7 +218,7 @@ jobs: os: [macos-latest] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-macos.tar.gz", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz", ] wabt_release: [ @@ -250,7 +250,7 @@ jobs: os: [macos-latest] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20%2Bthreads/wasi-sdk-20.0.threads-macos.tar.gz", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz", ] wabt_release: [ @@ -265,7 +265,7 @@ jobs: cd /opt sudo wget ${{ matrix.wasi_sdk_release }} sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv wasi-sdk-20.0+threads wasi-sdk + sudo mv wasi-sdk-20.0 wasi-sdk - name: download and install wabt run: | diff --git a/core/iwasm/libraries/lib-socket/test/build.sh b/core/iwasm/libraries/lib-socket/test/build.sh index 5cdfbd8d6..24f5ee676 100755 --- a/core/iwasm/libraries/lib-socket/test/build.sh +++ b/core/iwasm/libraries/lib-socket/test/build.sh @@ -11,7 +11,6 @@ for file in "${files[@]}" do echo $file $CC \ - $WASI_SYSROOT_OPTION \ --target=wasm32-wasi-threads \ -I../inc \ ../src/wasi/wasi_socket_ext.c -pthread -ftls-model=local-exec \ diff --git a/core/iwasm/libraries/lib-wasi-threads/test/build.sh b/core/iwasm/libraries/lib-wasi-threads/test/build.sh index c8431bb91..bf7278248 100644 --- a/core/iwasm/libraries/lib-wasi-threads/test/build.sh +++ b/core/iwasm/libraries/lib-wasi-threads/test/build.sh @@ -14,7 +14,6 @@ for test_c in *.c; do echo "Compiling $test_c to $test_wasm" $CC \ - $WASI_SYSROOT_OPTION \ -target wasm32-wasi-threads \ -pthread -ftls-model=local-exec \ -z stack-size=32768 \ From 5c201995f1915c67e719bd22faed033ae506374b Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 3 Apr 2023 14:32:44 +0800 Subject: [PATCH 44/61] Fix sanitizer pointer overflow warning when perform pointer arithmetic (#2098) Convert the pointer to intptr_t to perform arithmetic to avoid the warning. --- core/shared/mem-alloc/ems/ems_kfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/shared/mem-alloc/ems/ems_kfc.c b/core/shared/mem-alloc/ems/ems_kfc.c index 3e2b3a29c..fe7732533 100644 --- a/core/shared/mem-alloc/ems/ems_kfc.c +++ b/core/shared/mem-alloc/ems/ems_kfc.c @@ -153,7 +153,7 @@ static void adjust_ptr(uint8 **p_ptr, intptr_t offset) { if (*p_ptr) - *p_ptr += offset; + *p_ptr = (uint8 *)((intptr_t)(*p_ptr) + offset); } int From 24a7e5c1e649b798a790dc8811002578c7a95128 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 3 Apr 2023 14:56:46 +0800 Subject: [PATCH 45/61] Update sample workload tensorflow (#2101) Auto download emsdk under core/deps and hack it, and fix multi-thread issues. --- samples/workload/tensorflow/README.md | 22 ++------ samples/workload/tensorflow/build.sh | 80 ++++++++++++++------------- 2 files changed, 49 insertions(+), 53 deletions(-) diff --git a/samples/workload/tensorflow/README.md b/samples/workload/tensorflow/README.md index 164b6bb09..7bc7dd259 100644 --- a/samples/workload/tensorflow/README.md +++ b/samples/workload/tensorflow/README.md @@ -1,29 +1,19 @@ "tensorflow" sample introduction ============== -This sample demonstrates how to build [tensorflow](https://github.com/tensorflow/tensorflow) into WebAssembly with emsdk toolchain and run it with iwasm. Please first install [emsdk](https://github.com/emscripten-core/emsdk): -```bash -git clone https://github.com/emscripten-core/emsdk.git -cd emsdk -./emsdk install 2.0.26 -./emsdk activate 2.0.26 -``` -And set up ensdk environment: -```bash -source emsdk_env.sh -``` -Then run +This sample demonstrates how to build [tensorflow](https://github.com/tensorflow/tensorflow) into WebAssembly with emsdk toolchain and run it with iwasm.: ```bash ./build.sh # for linux platform, or -./build.sh --sgx -# for linux-sgx platform or ./build.sh --threads -# for multi-thread execution (on linux platform) +# for multi-threading on linux platform +./build.sh --sgx +# for linux-sgx platform ``` to build tensorflow and run it with iwasm, which basically contains the following steps: +- clone emsdk under `/core/deps`, install and activate 2.0.26 - hack emcc to delete some objects in libc.a - build tf-lite with emcc compiler -- build iwasm with pthread enable and include libiary under libc-emcc +- build iwasm with lib-pthread and libc-emcc enabled - run benchmark model with iwasm: --max-secs 300: means the max training time cost is 5 minutes, you can adjust it by yourself diff --git a/samples/workload/tensorflow/build.sh b/samples/workload/tensorflow/build.sh index d997113fd..6df8db423 100755 --- a/samples/workload/tensorflow/build.sh +++ b/samples/workload/tensorflow/build.sh @@ -8,24 +8,20 @@ #################################### # build tensorflow-lite sample # #################################### -if [ ! -d "${EMSDK}" ]; then - echo "can not find emsdk. " - echo "please refer to https://emscripten.org/docs/getting_started/downloads.html " - echo "to install it, or active it by 'source emsdk_env.sh'" - exit -fi - -set -xe - -EMSDK_WASM_DIR="${EMSDK}/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten" BUILD_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +WAMR_DIR="${BUILD_SCRIPT_DIR}/../../.." +WAMR_PLATFORM_DIR="${WAMR_DIR}/product-mini/platforms" +WAMRC_DIR="${WAMR_DIR}/wamr-compiler" +CORE_DEPS_DIR="${WAMR_DIR}/core/deps" +EMSDK_DIR="${CORE_DEPS_DIR}/emsdk" + +EMSDK_WASM_DIR="${EMSDK_DIR}/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten" OUT_DIR="${BUILD_SCRIPT_DIR}/out" TENSORFLOW_DIR="${BUILD_SCRIPT_DIR}/tensorflow" TF_LITE_BUILD_DIR="${TENSORFLOW_DIR}/tensorflow/lite/tools/make" -WAMR_PLATFORM_DIR="${BUILD_SCRIPT_DIR}/../../../product-mini/platforms" -WAMRC_DIR="${BUILD_SCRIPT_DIR}/../../../wamr-compiler" -function Clear_Before_Exit +function Clear_Before_Exit() { [[ -f ${TENSORFLOW_DIR}/tf_lite.patch ]] && rm -f ${TENSORFLOW_DIR}/tf_lite.patch @@ -34,7 +30,18 @@ function Clear_Before_Exit mv libc.a.bak libc.a } -# 1.hack emcc +set -xe + +# 1.clone emsdk +cd ${CORE_DEPS_DIR} +rm -fr emsdk +git clone https://github.com/emscripten-core/emsdk.git +cd emsdk +./emsdk install 2.0.26 +./emsdk activate 2.0.26 +source emsdk_env.sh + +# 2.hack emcc cd ${EMSDK_WASM_DIR} # back up libc.a cp libc.a libc.a.bak @@ -42,11 +49,13 @@ cp libc.a libc.a.bak emar d libc.a open.o emar d libc.a mmap.o emar d libc.a munmap.o +emar d libc.a library_pthread_stub.o +emar d libc.a pthread_self.o emranlib libc.a -# 2. build tf-lite +# 3. build tf-lite cd ${BUILD_SCRIPT_DIR} -# 2.1 clone tf repo from Github and checkout to 2303ed commit +# 3.1 clone tf repo from Github and checkout to 2303ed commit if [ ! -d "tensorflow" ]; then git clone https://github.com/tensorflow/tensorflow.git fi @@ -54,7 +63,7 @@ fi cd ${TENSORFLOW_DIR} git checkout 2303ed4bdb344a1fc4545658d1df6d9ce20331dd -# 2.2 copy the tf-lite.patch to tensorflow_root_dir and apply +# 3.2 copy the tf-lite.patch to tensorflow_root_dir and apply it cd ${TENSORFLOW_DIR} cp ${BUILD_SCRIPT_DIR}/tf_lite.patch . git checkout tensorflow/lite/tools/make/Makefile @@ -67,12 +76,12 @@ if [[ $(git apply tf_lite.patch 2>&1) =~ "error" ]]; then fi cd ${TF_LITE_BUILD_DIR} -# 2.3 download dependencies +# 3.3 download dependencies if [ ! -d "${TF_LITE_BUILD_DIR}/downloads" ]; then source download_dependencies.sh fi -# 2.4 build tf-lite target +# 3.4 build tf-lite target if [ -d "${TF_LITE_BUILD_DIR}/gen" ]; then rm -fr ${TF_LITE_BUILD_DIR}/gen fi @@ -82,19 +91,19 @@ make -j 4 -C "${TENSORFLOW_DIR}" -f ${TF_LITE_BUILD_DIR}/Makefile # remove patch file and recover emcc libc.a after building Clear_Before_Exit -# 2.5 copy /make/gen target files to out/ +# 3.5 copy /make/gen target files to out/ rm -rf ${OUT_DIR} mkdir ${OUT_DIR} cp -r ${TF_LITE_BUILD_DIR}/gen/linux_x86_64/bin/. ${OUT_DIR}/ -# 3. compile tf-model.wasm to tf-model.aot with wamrc -# 3.1 build wamr-compiler +# 4. compile tf-model.wasm to tf-model.aot with wamrc +# 4.1 build wamr-compiler cd ${WAMRC_DIR} ./build_llvm.sh rm -fr build && mkdir build cd build && cmake .. make -# 3.2 compile tf-mode.wasm to tf-model.aot +# 4.2 compile tf-mode.wasm to tf-model.aot WAMRC_CMD="$(pwd)/wamrc" cd ${OUT_DIR} if [[ $1 == '--sgx' ]]; then @@ -105,14 +114,14 @@ else ${WAMRC_CMD} -o benchmark_model.aot benchmark_model.wasm fi -# 4. build iwasm with pthread and libc_emcc enable +# 5. build iwasm with pthread and libc_emcc enable # platform: # linux by default # linux-sgx if $1 equals '--sgx' if [[ $1 == '--sgx' ]]; then cd ${WAMR_PLATFORM_DIR}/linux-sgx rm -fr build && mkdir build - cd build && cmake .. -DWAMR_BUILD_LIB_PTHREAD=1 -DWAMR_BUILD_LIBC_EMCC=1 + cd build && cmake .. -DWAMR_BUILD_LIBC_EMCC=1 make cd ../enclave-sample make @@ -123,15 +132,13 @@ else make fi -# 5. run tensorflow with iwasm -cd ${BUILD_SCRIPT_DIR} -# 5.1 download tf-lite model -if [ ! -f mobilenet_quant_v1_224.tflite ]; then - wget "https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip" - unzip mobilenet_v1_224_android_quant_2017_11_08.zip -fi +# 6. run tensorflow with iwasm +cd ${OUT_DIR} +# 6.1 download tf-lite model +wget "https://storage.googleapis.com/download.tensorflow.org/models/tflite/mobilenet_v1_224_android_quant_2017_11_08.zip" +unzip mobilenet_v1_224_android_quant_2017_11_08.zip -# 5.2 run tf-lite model with iwasm +# 6.2 run tf-lite model with iwasm echo "---> run tensorflow benchmark model with iwasm" if [[ $1 == '--sgx' ]]; then IWASM_CMD="${WAMR_PLATFORM_DIR}/linux-sgx/enclave-sample/iwasm" @@ -139,13 +146,12 @@ else IWASM_CMD="${WAMR_PLATFORM_DIR}/linux/build/iwasm" fi -if [[ $1 == '--threads' ]]; then +if [[ $1 == '--threads' ]]; then ${IWASM_CMD} --heap-size=10475860 \ - ${OUT_DIR}/benchmark_model.aot --num_threads=4 \ + benchmark_model.aot --num_threads=4 \ --graph=mobilenet_quant_v1_224.tflite --max_secs=300 else ${IWASM_CMD} --heap-size=10475860 \ - ${OUT_DIR}/benchmark_model.aot \ + benchmark_model.aot \ --graph=mobilenet_quant_v1_224.tflite --max_secs=300 fi - From 7701b379e435f9a5c8fb8c3f8663b97a4df2261e Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 3 Apr 2023 15:54:44 +0800 Subject: [PATCH 46/61] Update documents (#2100) Fix linkage error, update build wamr document, update socket and sample documents. --- README.md | 3 ++- doc/build_wamr.md | 11 +++++++++++ doc/socket_api.md | 12 ++++++------ samples/README.md | 4 +++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6b38195c1..c83d83aaa 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ **[Guide](https://wamr.gitbook.io/)**  **[Website](https://bytecodealliance.github.io/wamr.dev)**  **[Chat](https://bytecodealliance.zulipchat.com/#narrow/stream/290350-wamr)** -[Build WAMR](./doc/build_wamr.md) | [Build AOT Compiler](./README.md#build-wamrc-aot-compiler) | [Embed WAMR](./doc/embed_wamr.md) | [Export Native API](./doc/export_native_api.md) | [Build Wasm Apps](./doc/build_wasm_app.md) | [Samples](./README.md#samples) +[Build WAMR](./doc/build_wamr.md) | [Build AOT Compiler](./wamr-compiler/README.md) | [Embed WAMR](./doc/embed_wamr.md) | [Export Native API](./doc/export_native_api.md) | [Build Wasm Apps](./doc/build_wasm_app.md) | [Samples](./README.md#samples) WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm) runtime with small footprint, high performance and highly configurable features for applications cross from embedded, IoT, edge to Trusted Execution Environment (TEE), smart contract, cloud native and so on. It includes a few parts as below: - [**VMcore**](./core/iwasm/): A set of runtime libraries for loading and running Wasm modules. It supports several execution modes including interpreter, Ahead-of-Time compilation(AoT) and Just-in-Time compilation (JIT). The WAMR supports two JIT tiers - Fast JIT, LLVM JIT, and dynamic tier-up from Fast JIT to LLVM JIT. @@ -33,6 +33,7 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm) - [Source debugging support](./doc/source_debugging.md), ref to [document](./doc/source_debugging.md) - [XIP (Execution In Place) support](./doc/xip.md), ref to [document](./doc/xip.md) - [Berkeley/Posix Socket support](./doc/socket_api.md), ref to [document](./doc/socket_api.md) and [sample](./samples/socket-api) +- [Multi-tier JIT](./product-mini#linux) and [Running mode control](https://bytecodealliance.github.io/wamr.dev/blog/introduction-to-wamr-running-modes/) - Language bindings: [Go](./language-bindings/go/README.md), [Python](./language-bindings/python/README.md) ### Wasm post-MVP features diff --git a/doc/build_wamr.md b/doc/build_wamr.md index 69a284129..a66f27be0 100644 --- a/doc/build_wamr.md +++ b/doc/build_wamr.md @@ -47,6 +47,7 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM - **WAMR_BUILD_AOT**=1/0, enable AOT or not, default to enable if not set - **WAMR_BUILD_JIT**=1/0, enable LLVM JIT or not, default to disable if not set - **WAMR_BUILD_FAST_JIT**=1/0, enable Fast JIT or not, default to disable if not set +- **WAMR_BUILD_FAST_JIT**=1 and **WAMR_BUILD_JIT**=1, enable Multi-tier JIT, default to disable if not set #### **Configure LIBC** @@ -85,6 +86,16 @@ cmake -DWAMR_BUILD_PLATFORM=linux -DWAMR_BUILD_TARGET=ARM - **WAMR_BUILD_LIB_PTHREAD_SEMAPHORE**=1/0, default to disable if not set > Note: This feature depends on `lib-pthread`, it will be enabled automatically if this feature is enabled. +#### **Enable lib wasi-threads** +- **WAMR_BUILD_LIB_WASI_THREADS**=1/0, default to disable if not set +> Note: The dependent feature of lib wasi-threads such as the `shared memory` and `thread manager` will be enabled automatically. + +#### **Enable lib wasi-nn** +- **WAMR_BUILD_WASI_NN**=1/0, default to disable if not set + +#### **Enable lib wasi-nn GPU mode** +- **WASI_NN_ENABLE_GPU**=1/0, default to disable if not set + #### **Disable boundary check with hardware trap** - **WAMR_DISABLE_HW_BOUND_CHECK**=1/0, default to enable if not set and supported by platform > Note: by default only platform linux/darwin/android/windows/vxworks 64-bit will enable the boundary check with hardware trap feature, and the wamrc tool will generate AOT code without boundary check instructions in all 64-bit targets except SGX to improve performance. The boundary check includes linear memory access boundary and native stack access boundary, if `WAMR_DISABLE_STACK_HW_BOUND_CHECK` below isn't set. diff --git a/doc/socket_api.md b/doc/socket_api.md index cdf7494c0..9e65d33cd 100644 --- a/doc/socket_api.md +++ b/doc/socket_api.md @@ -4,11 +4,11 @@ sockets. A socket is an abstract representation of the local endpoint of a network communication path. -Currently, WAMR supports a limit set of all well-known functions: -`accept()`, `bind()`, `connect()`, `listen()`, `recv()`, `send()`, `shutdown()` -and `socket()`. Users can call those functions in WebAssembly code directly. -Those WebAssembly socket calls will be dispatched to the imported -functions and eventually will be implemented by host socket APIs. +Currently, WAMR supports some Socket API features: +- Support TCP and UDP +- Support IPv4 and IPv6 +- Support get/set socket options +- Support access control This document introduces a way to support the _Berkeley/POSIX Socket API_ in WebAssembly code. @@ -86,4 +86,4 @@ Similarly to running _iwasm_ outside of an enclave, the allowed address ranges a $ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm ``` -Refer to [socket api sample](../samples/socket-api) for the compilation of the Wasm applications and [_iwasm_ for Intel SGX](../product-mini/platforms/linux-sgx) for the Wasm runtime. \ No newline at end of file +Refer to [socket api sample](../samples/socket-api) for the compilation of the Wasm applications and [_iwasm_ for Intel SGX](../product-mini/platforms/linux-sgx) for the Wasm runtime. diff --git a/samples/README.md b/samples/README.md index 6690c07f3..21a735268 100644 --- a/samples/README.md +++ b/samples/README.md @@ -7,9 +7,11 @@ - **[gui](./gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default. - **[multi-thread](./multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's. - **[spawn-thread](./spawn-thread)**: Demonstrating how to execute wasm functions of the same wasm application concurrently, in threads created by host embedder or runtime, but not the wasm application itself. +- **[wasi-threads](./wasi-threads/README.md)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently based on lib wasi-threads. - **[multi-module](./multi-module)**: Demonstrating the [multiple modules as dependencies](./doc/multi_module.md) feature which implements the [load-time dynamic linking](https://webassembly.org/docs/dynamic-linking/). - **[ref-types](./ref-types)**: Demonstrating how to call wasm functions with argument of externref type introduced by [reference types proposal](https://github.com/WebAssembly/reference-types). - **[wasm-c-api](./wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's. - **[socket-api](./socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other. -- **[workload](./workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa. +- **[native-lib](./native-lib/README.md)**: Demonstrating how to write required interfaces in native library, build it into a shared library and register the shared library to iwasm. - **[sgx-ra](./sgx-ra/README.md)**: Demonstrating how to execute Remote Attestation on SGX with [librats](https://github.com/inclavare-containers/librats), which enables mutual attestation with other runtimes or other entities that support librats to ensure that each is running within the TEE. +- **[workload](./workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa. From e1d0c27ef9382b1395e983ca3a113e524fe7d2e1 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 3 Apr 2023 15:55:24 +0800 Subject: [PATCH 47/61] Fix ref.func forward-declared function check (#2099) When ref.func opcode refers to a function whose function index no smaller than current function, the destination func should be forward-declared: it is declared in the table element segments, or is declared in the export list. --- core/iwasm/interpreter/wasm_loader.c | 16 ++++++++++++++-- core/iwasm/interpreter/wasm_mini_loader.c | 18 +++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index d3128dbd0..a3c4f4224 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -8222,12 +8222,13 @@ re_scan: goto fail; } - if (func_idx == cur_func_idx + module->import_function_count) { + /* Refer to a forward-declared function */ + if (func_idx >= cur_func_idx + module->import_function_count) { WASMTableSeg *table_seg = module->table_segments; bool func_declared = false; uint32 j; - /* Check whether current function is declared */ + /* Check whether the function is declared in table segs */ for (i = 0; i < module->table_seg_count; i++, table_seg++) { if (table_seg->elem_type == VALUE_TYPE_FUNCREF && wasm_elem_is_declarative(table_seg->mode)) { @@ -8239,6 +8240,17 @@ re_scan: } } } + if (!func_declared) { + /* Check whether the function is exported */ + for (i = 0; i < module->export_count; i++) { + if (module->exports[i].kind == EXPORT_KIND_FUNC + && module->exports[i].index == func_idx) { + func_declared = true; + break; + } + } + } + if (!func_declared) { set_error_buf(error_buf, error_buf_size, "undeclared function reference"); diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 3a983b293..aa5e18f6a 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -6384,12 +6384,13 @@ re_scan: goto fail; } - if (func_idx == cur_func_idx + module->import_function_count) { + /* Refer to a forward-declared function */ + if (func_idx >= cur_func_idx + module->import_function_count) { WASMTableSeg *table_seg = module->table_segments; bool func_declared = false; uint32 j; - /* Check whether current function is declared */ + /* Check whether the function is declared in table segs */ for (i = 0; i < module->table_seg_count; i++, table_seg++) { if (table_seg->elem_type == VALUE_TYPE_FUNCREF && wasm_elem_is_declarative(table_seg->mode)) { @@ -6402,10 +6403,17 @@ re_scan: } } if (!func_declared) { - set_error_buf(error_buf, error_buf_size, - "undeclared function reference"); - goto fail; + /* Check whether the function is exported */ + for (i = 0; i < module->export_count; i++) { + if (module->exports[i].kind == EXPORT_KIND_FUNC + && module->exports[i].index == func_idx) { + func_declared = true; + break; + } + } } + bh_assert(func_declared); + (void)func_declared; } #if WASM_ENABLE_FAST_INTERP != 0 From 5fc48e3584baa05514878997b6949e365626f977 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 4 Apr 2023 09:05:52 +0800 Subject: [PATCH 48/61] Fix interpreter read linear memory size for multi-threading (#2088) Load memory data size in each time memory access boundary check in multi-threading mode since it may be changed by other threads when memory growing. And use `memory->memory_data_size` instead of `memory->num_bytes_per_page * memory->cur_page_count` to refine the code. --- core/iwasm/interpreter/wasm_interp_classic.c | 58 +++++++++++++------- core/iwasm/interpreter/wasm_interp_fast.c | 43 ++++++++++----- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index a94dc1769..142504a25 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -28,12 +28,23 @@ typedef float64 CellType_F64; #define BR_TABLE_TMP_BUF_LEN 32 +#if WASM_ENABLE_THREAD_MGR == 0 +#define get_linear_mem_size() linear_mem_size +#else +/** + * Load memory data size in each time boundary check in + * multi-threading mode since it may be changed by other + * threads in memory.grow + */ +#define get_linear_mem_size() memory->memory_data_size +#endif + #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 #define CHECK_MEMORY_OVERFLOW(bytes) \ do { \ uint64 offset1 = (uint64)offset + (uint64)addr; \ - if (offset1 + bytes <= (uint64)linear_mem_size) \ + if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ /* If offset1 is in valid range, maddr must also \ be in valid range, no need to check it again. */ \ maddr = memory->memory_data + offset1; \ @@ -41,15 +52,15 @@ typedef float64 CellType_F64; goto out_of_bounds; \ } while (0) -#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ - do { \ - uint64 offset1 = (uint32)(start); \ - if (offset1 + bytes <= (uint64)linear_mem_size) \ - /* App heap space is not valid space for \ - bulk memory operation */ \ - maddr = memory->memory_data + offset1; \ - else \ - goto out_of_bounds; \ +#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ + do { \ + uint64 offset1 = (uint32)(start); \ + if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ + /* App heap space is not valid space for \ + bulk memory operation */ \ + maddr = memory->memory_data + offset1; \ + else \ + goto out_of_bounds; \ } while (0) #else #define CHECK_MEMORY_OVERFLOW(bytes) \ @@ -1134,22 +1145,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_SHARED_MEMORY != 0 WASMSharedMemNode *node = wasm_module_get_shared_memory((WASMModuleCommon *)module->module); -#else - void *node = NULL; #endif - WASMMemoryInstance *memory = wasm_get_default_memory(module); - uint8 *global_data = module->global_data; #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 - uint32 num_bytes_per_page = - memory ? wasm_get_num_bytes_per_page(memory, node) : 0; - uint32 linear_mem_size = - memory ? wasm_get_linear_memory_size(memory, node) : 0; + uint32 linear_mem_size = memory ? memory->memory_data_size : 0; #endif WASMType **wasm_types = module->module->types; WASMGlobalInstance *globals = module->e->globals, *global; + uint8 *global_data = module->global_data; uint8 opcode_IMPDEP = WASM_OP_IMPDEP; WASMInterpFrame *frame = NULL; /* Points to this special opcode so as to jump to the @@ -2122,8 +2127,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 - linear_mem_size = - num_bytes_per_page * memory->cur_page_count; + linear_mem_size = memory->memory_data_size; #endif } @@ -3127,6 +3131,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, offset = (uint64)(uint32)POP_I32(); addr = (uint32)POP_I32(); +#if WASM_ENABLE_THREAD_MGR != 0 + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); #else @@ -3165,6 +3173,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, src = POP_I32(); dst = POP_I32(); +#if WASM_ENABLE_THREAD_MGR != 0 + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); @@ -3192,6 +3204,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, fill_val = POP_I32(); dst = POP_I32(); +#if WASM_ENABLE_THREAD_MGR != 0 + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); #else @@ -3865,7 +3881,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 if (memory) - linear_mem_size = num_bytes_per_page * memory->cur_page_count; + linear_mem_size = memory->memory_data_size; #endif if (wasm_copy_exception(module, NULL)) goto got_exception; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index b4bab4605..80731a85e 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -19,12 +19,23 @@ typedef int64 CellType_I64; typedef float32 CellType_F32; typedef float64 CellType_F64; +#if WASM_ENABLE_THREAD_MGR == 0 +#define get_linear_mem_size() linear_mem_size +#else +/** + * Load memory data size in each time boundary check in + * multi-threading mode since it may be changed by other + * threads in memory.grow + */ +#define get_linear_mem_size() memory->memory_data_size +#endif + #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 #define CHECK_MEMORY_OVERFLOW(bytes) \ do { \ uint64 offset1 = (uint64)offset + (uint64)addr; \ - if (offset1 + bytes <= (uint64)linear_mem_size) \ + if (offset1 + bytes <= (uint64)get_linear_mem_size()) \ /* If offset1 is in valid range, maddr must also \ be in valid range, no need to check it again. */ \ maddr = memory->memory_data + offset1; \ @@ -35,7 +46,7 @@ typedef float64 CellType_F64; #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ do { \ uint64 offset1 = (uint32)(start); \ - if (offset1 + bytes <= linear_mem_size) \ + if (offset1 + bytes <= get_linear_mem_size()) \ /* App heap space is not valid space for \ bulk memory operation */ \ maddr = memory->memory_data + offset1; \ @@ -1158,23 +1169,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if WASM_ENABLE_SHARED_MEMORY != 0 WASMSharedMemNode *node = wasm_module_get_shared_memory((WASMModuleCommon *)module->module); -#else - void *node = NULL; #endif - WASMMemoryInstance *memory = wasm_get_default_memory(module); - #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 - uint32 num_bytes_per_page = - memory ? wasm_get_num_bytes_per_page(memory, node) : 0; - uint32 linear_mem_size = - memory ? wasm_get_linear_memory_size(memory, node) : 0; + uint32 linear_mem_size = memory ? memory->memory_data_size : 0; #endif - uint8 *global_data = module->global_data; WASMGlobalInstance *globals = module->e ? module->e->globals : NULL; WASMGlobalInstance *global; + uint8 *global_data = module->global_data; uint8 opcode_IMPDEP = WASM_OP_IMPDEP; WASMInterpFrame *frame = NULL; /* Points to this special opcode so as to jump to the @@ -1892,8 +1896,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, #if !defined(OS_ENABLE_HW_BOUND_CHECK) \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 - linear_mem_size = - num_bytes_per_page * memory->cur_page_count; + linear_mem_size = memory->memory_data_size; #endif } @@ -2975,6 +2978,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, offset = (uint64)POP_I32(); addr = POP_I32(); +#if WASM_ENABLE_THREAD_MGR + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); #else @@ -3012,6 +3019,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, src = POP_I32(); dst = POP_I32(); +#if WASM_ENABLE_THREAD_MGR + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); @@ -3038,6 +3049,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, fill_val = POP_I32(); dst = POP_I32(); +#if WASM_ENABLE_THREAD_MGR + linear_mem_size = memory->memory_data_size; +#endif + #ifndef OS_ENABLE_HW_BOUND_CHECK CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); #else @@ -3805,7 +3820,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_ENABLE_BULK_MEMORY != 0 if (memory) - linear_mem_size = num_bytes_per_page * memory->cur_page_count; + linear_mem_size = memory->memory_data_size; #endif if (wasm_copy_exception(module, NULL)) goto got_exception; From 6af87855b44d092082d43fc756a1dd37fb87a914 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Tue, 4 Apr 2023 12:13:40 +0800 Subject: [PATCH 49/61] Update version number and release notes (#2103) And restore the CI vsce publish and change the wamride publisher name. --- .github/workflows/build_wamr_vscode_ext.yml | 5 +- RELEASE_NOTES.md | 342 ++++++++++-------- core/version.h | 2 +- .../wamr-ide/VSCode-Extension/package.json | 2 +- 4 files changed, 192 insertions(+), 159 deletions(-) diff --git a/.github/workflows/build_wamr_vscode_ext.yml b/.github/workflows/build_wamr_vscode_ext.yml index 5c1853e24..378aebba9 100644 --- a/.github/workflows/build_wamr_vscode_ext.yml +++ b/.github/workflows/build_wamr_vscode_ext.yml @@ -31,9 +31,6 @@ jobs: json -I -f package.json -e "this.version=\"${{ inputs.ver_num }}\"" working-directory: test-tools/wamr-ide/VSCode-Extension - # [!workflow] - # bypass the step of publishing the extension to the Market. - # recover it after creating the secret in the Environment - name: generate wamr ide vscode extension env: credentials: ${{ secrets.TOKEN }} @@ -42,7 +39,7 @@ jobs: rm -rf node_modules npm install vsce package - # vsce publish -p ${{ secrets.TOKEN }} + vsce publish -p ${{ secrets.TOKEN }} working-directory: test-tools/wamr-ide/VSCode-Extension - name: compress the vscode extension diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 003ee607d..0dd38fe3f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,182 +1,216 @@ +## WAMR-1.2.1 + +### Breaking Changes + +### New Features + +### Bug Fixes +- libc-wasi/posix.c: Fix POLL{RD,WR}NORM in uClibc (#2069) +- Fix bh_assert for 64-bit platforms (#2071) +- wamr-ide: Modify Dockerfile to update base image version and fix build issue (#2068) +- Fix module_malloc/module_free issues (#2072) +- Fix use after free when dumping call stack (#2084) +- Fix compilation errors of workload xnnpack and meshoptimizer (#2081) +- Fix typo in Fast JIT's BUILD_COND_BR Macro (#2092) +- Fix sanitizer pointer overflow warning when perform pointer arithmetic (#2098) +- Update sample workload tensorflow (#2101) +- Fix ref.func forward-declared function check (#2099) +- Fix interpreter read linear memory size for multi-threading (#2088) + +### Enhancements +- Limit the minimal size of bh_hashmap (#2073) +- Bump tensorflow to 2.11.1 in /core/iwasm/libraries/wasi-nn/test (#2061) +- Bump tensorflow to 2.11.1 in install_tensorflow.sh (#2076) +- Add support for universal binaries on OSX (#2060) +- Update documents (#2100) + +### Others +- spectest/nuttx: Increase stack size of iwasm task (#2082) +- ci: Refactor windows build definition (#2087) +- ci: Enable WASI threads in CI (#2086) +- Use wasi-sdk-20 to build wasi-threads cases in CI (#2095) + +--- + ## WAMR-1.2.0 ### Breaking Changes ### New Features -Implement two-level Multi-tier JIT engine: tier-up from Fast JIT to LLVM JIT to get quick cold startup and better performance -Enable running mode control for runtime, wasm module instance and iwasm -Implement wasi-threads feature -Upgrade toolkits: upgrade to llvm-15.0, wasi-sdk-19.0, emsdk-3.1.28 and so on -Port WAMR to the FreeBSD platform -Refactor wasi-nn to simplify the support for multiple frameworks -wasi-nn: Enable GPU support -wasi-nn: Support multiple TFLite models -Add WAMR API bindings in Python -Add libsodium benchmark +- Implement two-level Multi-tier JIT engine: tier-up from Fast JIT to LLVM JIT to get quick cold startup and better performance +- Enable running mode control for runtime, wasm module instance and iwasm +- Implement wasi-threads feature +- Upgrade toolkits: upgrade to llvm-15.0, wasi-sdk-19.0, emsdk-3.1.28 and so on +- Port WAMR to the FreeBSD platform +- Refactor wasi-nn to simplify the support for multiple frameworks +- wasi-nn: Enable GPU support +- wasi-nn: Support multiple TFLite models +- Add WAMR API bindings in Python +- Add libsodium benchmark ### Bug Fixes -Fix wasm-c-api import func link issue in wasm_instance_new -Fix watchpoint segfault when using debug interp without server -libc-wasi: Fix spurious poll timeout -Fix typo verify_module in aot_compiler.c -Fix failure about preopen of reactor modules -Fix equal check in AOT XIP float cmp intrinsic -Fix issue of resolving func name in custom name section -Fix go language binding build on macos arm64 -Prevent undefined behavior from c_api_func_imports == NULL -Fix potential block issue in source debugger -SGX IPFS: Fix a segfault and support seeking beyond the end of files while using SEEK_CUR/SEEK_END -Fix undef error about WAMR_BUILD_MEMORY_PROFILING -Fix jit memory overwritten after instance deinstantiate -Fix stack alignment issue on ia32 -Fix explicit casts and types in espidf_socket.c -Fix potential integer overflow issue in wasm-c-api -Fix libc-wasi build failure when using clang -Fix wamrapi python binding for darwin -Fix getting port issue in posix os_socket_bind -Fix key error in build_llvm.py -nuttx: Add missing pthread.h header -Fix os_socket_addr_resolve() for IPv6 -Enhance/Fix sample socket-api and workload -Fix fast-jit build error -Fix dead lock in source debugger -fix debugger: Set termination flags also when in debug mode +- Fix wasm-c-api import func link issue in wasm_instance_new +- Fix watchpoint segfault when using debug interp without server +- libc-wasi: Fix spurious poll timeout +- Fix typo verify_module in aot_compiler.c +- Fix failure about preopen of reactor modules +- Fix equal check in AOT XIP float cmp intrinsic +- Fix issue of resolving func name in custom name section +- Fix go language binding build on macos arm64 +- Prevent undefined behavior from c_api_func_imports == NULL +- Fix potential block issue in source debugger +- SGX IPFS: Fix a segfault and support seeking beyond the end of files while using SEEK_CUR/SEEK_END +- Fix undef error about WAMR_BUILD_MEMORY_PROFILING +- Fix jit memory overwritten after instance deinstantiate +- Fix stack alignment issue on ia32 +- Fix explicit casts and types in espidf_socket.c +- Fix potential integer overflow issue in wasm-c-api +- Fix libc-wasi build failure when using clang +- Fix wamrapi python binding for darwin +- Fix getting port issue in posix os_socket_bind +- Fix key error in build_llvm.py +- nuttx: Add missing pthread.h header +- Fix os_socket_addr_resolve() for IPv6 +- Enhance/Fix sample socket-api and workload +- Fix fast-jit build error +- Fix dead lock in source debugger +- fix debugger: Set termination flags also when in debug mode ### Enhancements -Add WAMR-IDE vscode extension to the Visual Studio Marketplace -Refine Windows thread waiting list operations -Improve wasm-c-api instantiation-time linking -Enable platform support for esp-idf v5.0.1 -Readme refactoring -Add architecture diagram for wasm function -Add architecture document for wasm export -Add architecture diagram for wasm globals and classic-interp stack frame -Use boringssl instead of openssl to implement wasm cache loading -Implement i32.rem_s and i32.rem_u intrinsic -Perfect the codebase for wamr-ide -Remove unnecessary ret value control when spec test is enabled -Use float version library routine for XIP aot_intrinsic_xxx APIs -Register missing symbols for f32 to 64 bit integer conversion -Report error in instantiation when meeting unlinked import globals -Add more types and APIs for attr_container -Simplify fcmp intrinsic logic for AOT/XIP -Add some missing macros for int literals in wamr-sdk libc-builtin-sysroot stdint.h -nuttx: Mock socket APIs if NET is disabled -Main thread spread exception when thread-mgr is enabled -Implement opcode atomic.wait and atomic.notify for Fast JIT -Add docker images auto check and setup support for WAMR-IDE -Make memory profiling show native stack usage -Enable gcc-4.8 compilation -Enable specifying out-of-source platform configuration cmake file -Add gh api call for fetching llvm version (#1942) Fixes -Don't terminate other threads when create thread failed -Modify poll_oneoff in libc-wasi to make it interruptible -Expose wasm_runtime_call_indirect -Make a workaround for EGO when fstat returns NOT_SUPPORT -Re-org calling post instantiation functions -Enable custom llvm build flags -support SSH for git clone llvm -Support dump call stack on exception and dump call stack on nuttx -Update document for source debugging -Document some info about estimating memory usage +- Add WAMR-IDE vscode extension to the Visual Studio Marketplace +- Refine Windows thread waiting list operations +- Improve wasm-c-api instantiation-time linking +- Enable platform support for esp-idf v5.0.1 +- Readme refactoring +- Add architecture diagram for wasm function +- Add architecture document for wasm export +- Add architecture diagram for wasm globals and classic-interp stack frame +- Use boringssl instead of openssl to implement wasm cache loading +- Implement i32.rem_s and i32.rem_u intrinsic +- Perfect the codebase for wamr-ide +- Remove unnecessary ret value control when spec test is enabled +- Use float version library routine for XIP aot_intrinsic_xxx APIs +- Register missing symbols for f32 to 64 bit integer conversion +- Report error in instantiation when meeting unlinked import globals +- Add more types and APIs for attr_container +- Simplify fcmp intrinsic logic for AOT/XIP +- Add some missing macros for int literals in wamr-sdk libc-builtin-sysroot stdint.h +- nuttx: Mock socket APIs if NET is disabled +- Main thread spread exception when thread-mgr is enabled +- Implement opcode atomic.wait and atomic.notify for Fast JIT +- Add docker images auto check and setup support for WAMR-IDE +- Make memory profiling show native stack usage +- Enable gcc-4.8 compilation +- Enable specifying out-of-source platform configuration cmake file +- Add gh api call for fetching llvm version (#1942) Fixes +- Don't terminate other threads when create thread failed +- Modify poll_oneoff in libc-wasi to make it interruptible +- Expose wasm_runtime_call_indirect +- Make a workaround for EGO when fstat returns NOT_SUPPORT +- Re-org calling post instantiation functions +- Enable custom llvm build flags +- support SSH for git clone llvm +- Support dump call stack on exception and dump call stack on nuttx +- Update document for source debugging +- Document some info about estimating memory usage ### Others -Enable XIP in CI daily test -Integrate wasi test suite to wamr-test-suites and CI -Add CI for wasi-threads tests -Update CIs and documents to make naming of generated binaries consist -Enable CI wasi test suite for x86-32 classic/fast interpreter -CI: Enable libc-wasi compilation test on NuttX -CI: Enable Multi-tier JIT by default for released iwasm binary +- Enable XIP in CI daily test +- Integrate wasi test suite to wamr-test-suites and CI +- Add CI for wasi-threads tests +- Update CIs and documents to make naming of generated binaries consist +- Enable CI wasi test suite for x86-32 classic/fast interpreter +- CI: Enable libc-wasi compilation test on NuttX +- CI: Enable Multi-tier JIT by default for released iwasm binary --- ## WAMR-1.1.2 ### Breaking Changes -Remove the LLVM MCJIT mode, replace it with LLVM ORC JIT eager mode -Add option to pass user data to the allocator functions of RuntimeInitArgs -Change how iwasm returns: - return 1 if an exception was thrown, else - return the wasi exit code if the wasm app is a wasi app, else - keep the same behavior as before -Enable bulk memory by default +- Remove the LLVM MCJIT mode, replace it with LLVM ORC JIT eager mode +- Add option to pass user data to the allocator functions of RuntimeInitArgs +- Change how iwasm returns: + - return 1 if an exception was thrown, else + - return the wasi exit code if the wasm app is a wasi app, else + - keep the same behavior as before +- Enable bulk memory by default ### New Features -Add control for the native stack check with hardware trap -Add memory watchpoint support to debugger -Add wasm_module_obtain() to clone wasm_module_t -Implement Fast JIT dump call stack and perf profiling -esp-idf: Add socket support for esp-idf platform +- Add control for the native stack check with hardware trap +- Add memory watchpoint support to debugger +- Add wasm_module_obtain() to clone wasm_module_t +- Implement Fast JIT dump call stack and perf profiling +- esp-idf: Add socket support for esp-idf platform ### Bug Fixes -Fix XIP issue caused by rem_s on RISC-V -Fix XIP issues of fp to int cast and int rem/div -Fix missing float cmp for XIP -Correct the arch name for armv7a on NuttX -Fix issue of restoring wasm operand stack -Fix issue of thumb relocation R_ARM_THM_MOVT_ABS -Fix fast jit issue of translating opcode i32.rem_s/i64.rem_s -Fix interp/fast-jit float min/max issues -Fix missing intrinsics for risc-v which were reported by spec test -wasm-c-api: Fix init/destroy thread env multiple times issue -Fix wasm-c-api import func link issue in wasm_instance_new -Fix sample ref-types/wasm-c-api build error with wat2wasm low version -Fix zephyr sample build errors -Fix source debugger error handling: continue executing when detached -Fix scenario where the timeout for atomic wait is set to negative number -Fix link cxx object file error when building wamrc for docker image -Fix XIP issue of handling 64-bit const in 32-bit target +- Fix XIP issue caused by rem_s on RISC-V +- Fix XIP issues of fp to int cast and int rem/div +- Fix missing float cmp for XIP +- Correct the arch name for armv7a on NuttX +- Fix issue of restoring wasm operand stack +- Fix issue of thumb relocation R_ARM_THM_MOVT_ABS +- Fix fast jit issue of translating opcode i32.rem_s/i64.rem_s +- Fix interp/fast-jit float min/max issues +- Fix missing intrinsics for risc-v which were reported by spec test +- wasm-c-api: Fix init/destroy thread env multiple times issue +- Fix wasm-c-api import func link issue in wasm_instance_new +- Fix sample ref-types/wasm-c-api build error with wat2wasm low version +- Fix zephyr sample build errors +- Fix source debugger error handling: continue executing when detached +- Fix scenario where the timeout for atomic wait is set to negative number +- Fix link cxx object file error when building wamrc for docker image +- Fix XIP issue of handling 64-bit const in 32-bit target ### Enhancements -Refactor the layout of interpreter and AOT module instance -Refactor LLVM JIT: remove mcjit and legacy pass manager, upgrade to ORCv2 JIT -Refine Fast JIT call indirect and call native process -Refine Fast JIT accessing memory/table instance and global data -Refine AOT exception check when function return -Enable source debugger reconnection -Add wasm_runtime_get_wasi_exit_code -linux-sgx: Use non-destructive modes for opening files using SGX IPFS -Add wasm_runtime_unregister_natives -Implement invokeNative asm code for MinGW -Add wamr Blog link and Gitbook link to readme -Remove unnecessary app heap memory clean operations to reduce process RSS -Normalize how the global heap pool is configured across iwasm apps -Refine the stack frame size check in interpreter -Enlarge the default wasm operand stack size to 64KB -Use cmake POSITION_INDEPENDENT_CODE instead of hardcoding -pie -fPIE -Implement R_ARM_THM_MOVT_[ABS|REPL] for thumb -Suppress the warnings when building with GCC11 -samples/native-lib: Add a bit more complicated example -Add mutex initializer for wasm-c-api engine operations -XIP adaptation for xtensa platform -Update libuv version number -Remove an improper assumption when creating wasm_trap -Avoid initialize LLVM repeatedly -linux-sgx: Improve the remote attestation -linux-sgx: Improve the documentation of SGX-RA sample -linux-sgx: Allow to open files with arbitrary paths in the sandbox using IPFS -Avoid raising exception when debugging with VSCode -wamr-test-suites: Update runtest.py to support python3 -Enable Nuttx spec test option and register aot symbols -Use wabt binary instead of building from source in spec test -nuttx: Enable ref types by Kconfig -Update xtensa LLVM version to 15.x -Add bh_print_proc_mem() to dump memory info of current process -Create trap for error message when wasm_instance_new fails -wamr-test-suites: Add support for ARM/RISCV by QEMU -Enable to compile WAMR on platforms that don't support IPV6 -Fix warnings in the posix socket implementation -Update document for MacOS compilation -Install patched LLDB on vscode extension activation -Add ARM aeabi memcpy/memmove/memset symbols for AOT bulk memory ops -Enable wasm cache loading in wasm-c-api +- Refactor the layout of interpreter and AOT module instance +- Refactor LLVM JIT: remove mcjit and legacy pass manager, upgrade to ORCv2 JIT +- Refine Fast JIT call indirect and call native process +- Refine Fast JIT accessing memory/table instance and global data +- Refine AOT exception check when function return +- Enable source debugger reconnection +- Add wasm_runtime_get_wasi_exit_code +- linux-sgx: Use non-destructive modes for opening files using SGX IPFS +- Add wasm_runtime_unregister_natives +- Implement invokeNative asm code for MinGW +- Add wamr Blog link and Gitbook link to readme +- Remove unnecessary app heap memory clean operations to reduce process RSS +- Normalize how the global heap pool is configured across iwasm apps +- Refine the stack frame size check in interpreter +- Enlarge the default wasm operand stack size to 64KB +- Use cmake POSITION_INDEPENDENT_CODE instead of hardcoding -pie -fPIE +- Implement R_ARM_THM_MOVT_[ABS|REPL] for thumb +- Suppress the warnings when building with GCC11 +- samples/native-lib: Add a bit more complicated example +- Add mutex initializer for wasm-c-api engine operations +- XIP adaptation for xtensa platform +- Update libuv version number +- Remove an improper assumption when creating wasm_trap +- Avoid initialize LLVM repeatedly +- linux-sgx: Improve the remote attestation +- linux-sgx: Improve the documentation of SGX-RA sample +- linux-sgx: Allow to open files with arbitrary paths in the sandbox using IPFS +- Avoid raising exception when debugging with VSCode +- wamr-test-suites: Update runtest.py to support python3 +- Enable Nuttx spec test option and register aot symbols +- Use wabt binary instead of building from source in spec test +- nuttx: Enable ref types by Kconfig +- Update xtensa LLVM version to 15.x +- Add bh_print_proc_mem() to dump memory info of current process +- Create trap for error message when wasm_instance_new fails +- wamr-test-suites: Add support for ARM/RISCV by QEMU +- Enable to compile WAMR on platforms that don't support IPV6 +- Fix warnings in the posix socket implementation +- Update document for MacOS compilation +- Install patched LLDB on vscode extension activation +- Add ARM aeabi memcpy/memmove/memset symbols for AOT bulk memory ops +- Enable wasm cache loading in wasm-c-api ### Others -Add CIs to release new version and publish binary files -Add more compilation groups of fast jit into CI -Enable spec test on nuttx and daily run it +- Add CIs to release new version and publish binary files +- Add more compilation groups of fast jit into CI +- Enable spec test on nuttx and daily run it --- @@ -322,3 +356,5 @@ Enable spec test on nuttx and daily run it ### Others --- + + diff --git a/core/version.h b/core/version.h index 69df43d56..a999d534e 100644 --- a/core/version.h +++ b/core/version.h @@ -7,5 +7,5 @@ #define _WAMR_VERSION_H_ #define WAMR_VERSION_MAJOR 1 #define WAMR_VERSION_MINOR 2 -#define WAMR_VERSION_PATCH 0 +#define WAMR_VERSION_PATCH 1 #endif diff --git a/test-tools/wamr-ide/VSCode-Extension/package.json b/test-tools/wamr-ide/VSCode-Extension/package.json index 71cc74871..bb8a5cee1 100644 --- a/test-tools/wamr-ide/VSCode-Extension/package.json +++ b/test-tools/wamr-ide/VSCode-Extension/package.json @@ -1,6 +1,6 @@ { "name": "wamride", - "publisher": "wamr-publisher", + "publisher": "wamr-ide", "repository": { "url": "https://github.com/bytecodealliance/wasm-micro-runtime/tree/main/test-tools/wamr-ide" }, From e7b988e6ab18181ee609d6764920843a0237a1cc Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 4 Apr 2023 18:22:54 +0900 Subject: [PATCH 50/61] Document the summary of two pthread implementations (#2104) And add `wasi-threads` to the key feature list in README.md. --- README.md | 1 + doc/pthread_impls.md | 59 ++++++++++++++++++++++++++++++++++++++++++ doc/pthread_library.md | 3 +++ 3 files changed, 63 insertions(+) create mode 100644 doc/pthread_impls.md diff --git a/README.md b/README.md index c83d83aaa..6d7d4778b 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm) - [The mechanism to export native APIs to Wasm applications](./doc/export_native_api.md), see [how to register native APIs](./doc/export_native_api.md) - [Multiple modules as dependencies](./doc/multi_module.md), ref to [document](./doc/multi_module.md) and [sample](samples/multi-module) - [Multi-thread, pthread APIs and thread management](./doc/pthread_library.md), ref to [document](./doc/pthread_library.md) and [sample](samples/multi-thread) +- [wasi-threads](./doc/pthread_impls.md#wasi-threads-new), ref to [document](./doc/pthread_impls.md#wasi-threads-new) and [sample](samples/wasi-threads) - [Linux SGX (Intel Software Guard Extension) support](./doc/linux_sgx.md), ref to [document](./doc/linux_sgx.md) - [Source debugging support](./doc/source_debugging.md), ref to [document](./doc/source_debugging.md) - [XIP (Execution In Place) support](./doc/xip.md), ref to [document](./doc/xip.md) diff --git a/doc/pthread_impls.md b/doc/pthread_impls.md new file mode 100644 index 000000000..92b51cb4a --- /dev/null +++ b/doc/pthread_impls.md @@ -0,0 +1,59 @@ +# Pthread implementations + +WAMR has two pthread implementations available as of writing this. + +These implementations are not ABI-compatible. You at least need to rebuild +your wasm modules when migrating from one pthread implementation to another. + +For new users, we recommend to use (or at least experiment) +the new wasi-threads based implementation. +In future, we might remove the old implementation. + +## WAMR lib-pthread (old) + + * The pthread API is directly implemented as host functions in WAMR. + (`WAMR_BUILD_LIB_PTHREAD`) + + * Only minimum API is implemented as of writing this. + (eg. no pthread barriers) + + * WAMR-specific ABI + + * [Known limitations](pthread_library.md#known-limits) + +## wasi-threads (new) + + * The pthread API is implemented in wasi-libc, based on + [wasi-threads](https://github.com/WebAssembly/wasi-threads) + and [WASM threads](https://github.com/WebAssembly/threads) proposals. + + * It requires a recent-enough version of wasi-libc. The experimental support + is included in + [wasi-sdk 20.0](https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-20) + or later. + To build your application, cmake users can use the + [cmake toolchain file](https://github.com/WebAssembly/wasi-sdk/blob/main/wasi-sdk-pthread.cmake) + provided by wasi-sdk. + + * wasi-threads is implemented as a host function in WAMR. + (`WAMR_BUILD_LIB_WASI_THREADS`) + + * The ABI is specified in wasi-threads proposal. + You can run the same wasm modules on other runtimes which implement + the proposal. (wasmtime, toywasm, ...) + + * Basically more feature-rich and complete than WAMR lib-pthread. + + **EXCEPTION**: `pthread_exit` is not available as of writing this. + If `pthread_exit` is important for your use cases, please speak up in + the [GitHub issue](https://github.com/WebAssembly/wasi-threads/issues/7). + + **EXCEPTION**: For threads created by `pthread_create`, the AUX stack + (aka C shadow stack) overflow detection mechanism is disabled as of + writing this. + If it's important for your use cases, please speak up in the + [GitHub issue](https://github.com/WebAssembly/wasi-threads/issues/12). + +# References + +* https://github.com/bytecodealliance/wasm-micro-runtime/issues/1790 diff --git a/doc/pthread_library.md b/doc/pthread_library.md index cd188670d..ba43ee1c0 100644 --- a/doc/pthread_library.md +++ b/doc/pthread_library.md @@ -1,5 +1,8 @@ # WAMR pthread library +**Note**: This document describes the old pthread implementation. +See [Pthread implementations](pthread_impls.md). + WAMR provides a built-in library to support pthread APIs. You can call pthread APIs in your application source code. ## Build and run From 9adc6948d860131ac65557f49d761f466bab6e3a Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Thu, 6 Apr 2023 03:10:07 +0100 Subject: [PATCH 51/61] Enable CI build for gcc 4.8 on linux (#2106) In #1928 we added support for GCC 4.8 but we don't continuously test if it's working. This PR added a GitHub actions job to test compilation on GCC 4.8 for interpreters and Fast JIT (LLVM JIT/AOT might be added in the future). The compilation is done using ubuntu 14.04 image as that's the simplest way to get GCC 4.8 compiler. The job only compiles the code but does not run any tests. --- .../compilation_on_android_ubuntu.yml | 78 +++++++++++++++++++ .../platform/include/platform_api_extension.h | 5 ++ product-mini/platforms/linux/CMakeLists.txt | 1 + 3 files changed, 84 insertions(+) diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 0a87cb76e..3a495e5b4 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -115,6 +115,84 @@ jobs: cmake --build . --config Release --parallel 4 working-directory: wamr-compiler + build_iwasm_linux_gcc4_8: + runs-on: ubuntu-latest + container: + image: ubuntu:14.04 + strategy: + matrix: + make_options_run_mode: [ + # Running mode + $CLASSIC_INTERP_BUILD_OPTIONS, + $FAST_INTERP_BUILD_OPTIONS, + $FAST_JIT_BUILD_OPTIONS + ] + make_options_feature: [ + # Features + "-DWAMR_BUILD_CUSTOM_NAME_SECTION=1", + "-DWAMR_BUILD_DEBUG_AOT=1", + "-DWAMR_BUILD_DEBUG_INTERP=1", + "-DWAMR_BUILD_DUMP_CALL_STACK=1", + "-DWAMR_BUILD_LIB_PTHREAD=1", + "-DWAMR_BUILD_LIB_WASI_THREADS=1", + "-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1", + "-DWAMR_BUILD_MINI_LOADER=1", + "-DWAMR_BUILD_MEMORY_PROFILING=1", + "-DWAMR_BUILD_MULTI_MODULE=1", + "-DWAMR_BUILD_PERF_PROFILING=1", + "-DWAMR_BUILD_REF_TYPES=1", + "-DWAMR_BUILD_SIMD=1", + "-DWAMR_BUILD_TAIL_CALL=1", + "-DWAMR_DISABLE_HW_BOUND_CHECK=1", + ] + exclude: + # uncompatiable feature and platform + # uncompatiable mode and feature + # MULTI_MODULE only on INTERP mode + - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1" + # SIMD only on JIT/AOT mode + - make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_SIMD=1" + - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_SIMD=1" + # DEBUG_INTERP only on CLASSIC INTERP mode + - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1" + - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_DEBUG_INTERP=1" + # DEBUG_AOT only on JIT/AOT mode + - make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1" + - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1" + # TODO: DEBUG_AOT on JIT + - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_DEBUG_AOT=1" + # MINI_LOADER only on INTERP mode + - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS + make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: Install dependencies + run: apt update && apt install -y make g++-4.8 gcc-4.8 wget git + + - name: Install cmake + run: | + wget https://github.com/Kitware/CMake/releases/download/v3.26.1/cmake-3.26.1-linux-x86_64.tar.gz -O cmake.tar.gz + tar xzf cmake.tar.gz + cp cmake-3.26.1-linux-x86_64/bin/cmake /usr/local/bin + cp -r cmake-3.26.1-linux-x86_64/share/cmake-3.26/ /usr/local/share/ + + - name: Build iwasm + run: | + mkdir build && cd build + cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }} -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 + cmake --build . --config Release --parallel 4 + working-directory: product-mini/platforms/linux + build_iwasm: needs: [build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204] diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 938530a4e..94fe16ea3 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -116,6 +116,11 @@ os_thread_exit(void *retval); https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58016 */ #if __GNUC_PREREQ(4, 9) #define BH_HAS_STD_ATOMIC +#elif __GNUC_PREREQ(4, 7) +#define os_memory_order_acquire __ATOMIC_ACQUIRE +#define os_memory_order_release __ATOMIC_RELEASE +#define os_memory_order_seq_cst __ATOMIC_SEQ_CST +#define os_atomic_thread_fence __atomic_thread_fence #endif /* end of __GNUC_PREREQ(4, 9) */ #endif /* end of defined(__GNUC_PREREQ) */ diff --git a/product-mini/platforms/linux/CMakeLists.txt b/product-mini/platforms/linux/CMakeLists.txt index cc7ff8de9..4c6af78ea 100644 --- a/product-mini/platforms/linux/CMakeLists.txt +++ b/product-mini/platforms/linux/CMakeLists.txt @@ -16,6 +16,7 @@ set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") set (CMAKE_C_STANDARD 99) +set (CMAKE_CXX_STANDARD 14) # Set WAMR_BUILD_TARGET, currently values supported: # "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", From 62fc486c20b128459119318d2d5162d0c67d9e95 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 7 Apr 2023 06:47:24 +0800 Subject: [PATCH 52/61] Refine aot compiler check suspend_flags and fix issue of multi-tier jit (#2111) In LLVM AOT/JIT compiler, only need to check the suspend_flags when memory is a shared memory since the shared memory must be enabled for multi-threading, so as not to impact the performance in non-multi-threading memory mode. Also refine the LLVM IRs to check the suspend_flags. And fix an issue of multi-tier jit for multi-threading, the instance of the child thread should be removed from the instance list before it is de-instantiated. --- core/iwasm/compilation/aot_emit_control.c | 36 +++++++++++------------ core/iwasm/interpreter/wasm_runtime.c | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 68c286f43..8c15d4d17 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -671,9 +671,16 @@ bool check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) { LLVMValueRef terminate_addr, terminate_flags, flag, offset, res; - LLVMBasicBlockRef terminate_check_block, non_terminate_block; + LLVMBasicBlockRef terminate_block, non_terminate_block; AOTFuncType *aot_func_type = func_ctx->aot_func->func_type; - LLVMBasicBlockRef terminate_block; + bool is_shared_memory = + comp_ctx->comp_data->memories[0].memory_flags & 0x02 ? true : false; + + /* Only need to check the suspend flags when memory is shared since + shared memory must be enabled for multi-threading */ + if (!is_shared_memory) { + return true; + } /* Offset of suspend_flags */ offset = I32_FIVE; @@ -701,29 +708,20 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) will always be loaded from memory rather than register */ LLVMSetVolatile(terminate_flags, true); - CREATE_BLOCK(terminate_check_block, "terminate_check"); - MOVE_BLOCK_AFTER_CURR(terminate_check_block); - - CREATE_BLOCK(non_terminate_block, "non_terminate"); - MOVE_BLOCK_AFTER_CURR(non_terminate_block); - - BUILD_ICMP(LLVMIntSGT, terminate_flags, I32_ZERO, res, "need_terminate"); - BUILD_COND_BR(res, terminate_check_block, non_terminate_block); - - /* Move builder to terminate check block */ - SET_BUILDER_POS(terminate_check_block); - - CREATE_BLOCK(terminate_block, "terminate"); - MOVE_BLOCK_AFTER_CURR(terminate_block); - if (!(flag = LLVMBuildAnd(comp_ctx->builder, terminate_flags, I32_ONE, "termination_flag"))) { aot_set_last_error("llvm build AND failed"); return false; } - BUILD_ICMP(LLVMIntSGT, flag, I32_ZERO, res, "need_terminate"); - BUILD_COND_BR(res, terminate_block, non_terminate_block); + CREATE_BLOCK(non_terminate_block, "non_terminate"); + MOVE_BLOCK_AFTER_CURR(non_terminate_block); + + CREATE_BLOCK(terminate_block, "terminate"); + MOVE_BLOCK_AFTER_CURR(terminate_block); + + BUILD_ICMP(LLVMIntEQ, flag, I32_ZERO, res, "flag_terminate"); + BUILD_COND_BR(res, non_terminate_block, terminate_block); /* Move builder to terminate block */ SET_BUILDER_POS(terminate_block); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 8130d90af..29365024d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -2178,7 +2178,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) func_ptrs and fast_jit_func_ptrs of the instance, to avoid accessing the freed memory in the jit backend compilation threads */ - if (!is_sub_inst) { + { WASMModule *module = module_inst->module; WASMModuleInstance *instance_prev = NULL, *instance; os_mutex_lock(&module->instance_list_lock); From 4ca4f7913b47251836173d86c5c2ab815dc93463 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 7 Apr 2023 07:12:02 +0800 Subject: [PATCH 53/61] Update release notes (#2113) --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0dd38fe3f..0684d4805 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -114,6 +114,8 @@ - Support dump call stack on exception and dump call stack on nuttx - Update document for source debugging - Document some info about estimating memory usage +- Document the summary of two pthread implementations +- Refine aot compiler check suspend_flags and fix issue of multi-tier jit ### Others - Enable XIP in CI daily test @@ -123,6 +125,7 @@ - Enable CI wasi test suite for x86-32 classic/fast interpreter - CI: Enable libc-wasi compilation test on NuttX - CI: Enable Multi-tier JIT by default for released iwasm binary +- Enable CI build for gcc 4.8 on linux --- From a2d4744a2b2c587eacca66c357dc2e88925fcadd Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Sat, 8 Apr 2023 12:07:20 +0100 Subject: [PATCH 54/61] Add test for validating linear memory size updates (#2078) --- .../libraries/lib-wasi-threads/test/build.sh | 8 +- .../test/linear_memory_size_update.c | 94 +++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) mode change 100644 => 100755 core/iwasm/libraries/lib-wasi-threads/test/build.sh create mode 100644 core/iwasm/libraries/lib-wasi-threads/test/linear_memory_size_update.c diff --git a/core/iwasm/libraries/lib-wasi-threads/test/build.sh b/core/iwasm/libraries/lib-wasi-threads/test/build.sh old mode 100644 new mode 100755 index bf7278248..32586c20c --- a/core/iwasm/libraries/lib-wasi-threads/test/build.sh +++ b/core/iwasm/libraries/lib-wasi-threads/test/build.sh @@ -12,6 +12,12 @@ WAMR_DIR=../../../../.. for test_c in *.c; do test_wasm="$(basename $test_c .c).wasm" + if [ $test_wasm = "linear_memory_size_update.wasm" ]; then + thread_start_file="" + else + thread_start_file=$WAMR_DIR/samples/wasi-threads/wasm-apps/wasi_thread_start.S + fi + echo "Compiling $test_c to $test_wasm" $CC \ -target wasm32-wasi-threads \ @@ -24,6 +30,6 @@ for test_c in *.c; do -Wl,--export=malloc \ -Wl,--export=free \ -I $WAMR_DIR/samples/wasi-threads/wasm-apps \ - $WAMR_DIR/samples/wasi-threads/wasm-apps/wasi_thread_start.S \ + $thread_start_file \ $test_c -o $test_wasm done \ No newline at end of file diff --git a/core/iwasm/libraries/lib-wasi-threads/test/linear_memory_size_update.c b/core/iwasm/libraries/lib-wasi-threads/test/linear_memory_size_update.c new file mode 100644 index 000000000..9dcb34a6c --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/test/linear_memory_size_update.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ +#include +#include + +typedef enum { + APP_STARTED, + THREAD_STARTED, + MEMORY_ALLOCATED, +} app_state_t; +typedef struct { + + pthread_cond_t cond; + pthread_mutex_t mutex; + app_state_t state; + char *data; +} context_t; + +void +context_init(context_t *ctx) +{ + pthread_cond_init(&ctx->cond, NULL); + pthread_mutex_init(&ctx->mutex, NULL); + ctx->state = APP_STARTED; + ctx->data = NULL; +} + +void +context_destroy(context_t *ctx) +{ + pthread_cond_destroy(&ctx->cond); + pthread_mutex_destroy(&ctx->mutex); + if (ctx->data) { + free(ctx->data); + } +} + +void +context_set_state(context_t *ctx, app_state_t state) +{ + pthread_mutex_lock(&ctx->mutex); + ctx->state = state; + pthread_mutex_unlock(&ctx->mutex); + pthread_cond_signal(&ctx->cond); +} + +void +context_wait_for_state(context_t *ctx, app_state_t state) +{ + pthread_mutex_lock(&ctx->mutex); + while (ctx->state != state) { + pthread_cond_wait(&ctx->cond, &ctx->mutex); + } + pthread_mutex_unlock(&ctx->mutex); +} + +void * +fnc(void *p) +{ + context_t *ctx = (context_t *)p; + context_set_state(ctx, THREAD_STARTED); + + context_wait_for_state(ctx, MEMORY_ALLOCATED); + + // trigger memory.copy + __builtin_memcpy(ctx->data + 512 * 1024, ctx->data + 1024, 1024); + + return NULL; +} + +int +main() +{ + context_t ctx; + context_init(&ctx); + + pthread_t th; + pthread_create(&th, NULL, fnc, &ctx); + + context_wait_for_state(&ctx, THREAD_STARTED); + + // trigger memory.grow + ctx.data = calloc(1024 * 1024, 1); + + context_set_state(&ctx, MEMORY_ALLOCATED); + + pthread_join(th, NULL); + + context_destroy(&ctx); + + return 0; +} From 327b4a7f5965da462fd613f6d68446830d47bc21 Mon Sep 17 00:00:00 2001 From: John O'Connor Date: Wed, 12 Apr 2023 01:50:11 -0700 Subject: [PATCH 55/61] Update request.ts wasm_response_send signature (#2122) Update wasm_response_send function signature to match api by returning bool instead of void (was causing assemblyscript example to break) --- assembly-script/wamr_app_lib/request.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assembly-script/wamr_app_lib/request.ts b/assembly-script/wamr_app_lib/request.ts index db72ddd13..16a229277 100644 --- a/assembly-script/wamr_app_lib/request.ts +++ b/assembly-script/wamr_app_lib/request.ts @@ -7,7 +7,7 @@ import * as console from './console' import * as timer from './timer' @external("env", "wasm_response_send") -declare function wasm_response_send(buffer: ArrayBuffer, size: i32): void; +declare function wasm_response_send(buffer: ArrayBuffer, size: i32): bool; @external("env", "wasm_register_resource") declare function wasm_register_resource(url: ArrayBuffer): void; @@ -492,4 +492,4 @@ export function on_response(buffer_offset: i32, size: i32): void { trans.cb(resp); } -} \ No newline at end of file +} From 2f879862ffcb07791d158c9871ead658797a0fef Mon Sep 17 00:00:00 2001 From: Daniel Mangum <31777345+hasheddan@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:20:37 -0400 Subject: [PATCH 56/61] Update Zephyr docs to remove unsupported west subcommand (#2128) Removes the `west espressif install` command which is no longer supported. https://github.com/zephyrproject-rtos/hal_espressif/pull/130 Also adds a reference to the Zephyr SDK, which will install the necessary toolchains for all supported targets. Signed-off-by: Daniel Mangum --- product-mini/README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/product-mini/README.md b/product-mini/README.md index 736b35b0a..1499440e0 100644 --- a/product-mini/README.md +++ b/product-mini/README.md @@ -248,7 +248,7 @@ WAMR provides some features which can be easily configured by passing options to ## Zephyr -You need to prepare Zephyr first as described here https://docs.zephyrproject.org/latest/getting_started/index.html#get-zephyr-and-install-python-dependencies. +You need to prepare Zephyr first as described [here](https://docs.zephyrproject.org/latest/getting_started/index.html#get-zephyr-and-install-python-dependencies). After that you need to point the `ZEPHYR_BASE` variable to e.g. `~/zephyrproject/zephyr`. Also, it is important that you have `west` available for subsequent actions. @@ -258,14 +258,7 @@ cd /product-mini/platforms/zephyr/simple ./build_and_run.sh x86 ``` -If you want to use the Espressif toolchain (esp32 or esp32c3), you can most conveniently install it with `west`: - -``` Bash -cd $ZEPHYR_BASE -west espressif install -``` - -After that set `ESPRESSIF_TOOLCHAIN_PATH` according to the output, for example `~/.espressif/tools/zephyr`. +The [Zephyr SDK](https://github.com/zephyrproject-rtos/sdk-ng) provides toolchains for all supported targets. Follow the instructions in the [documentation](https://docs.zephyrproject.org/latest/develop/getting_started/index.html#install-zephyr-sdk) to ensure it is installed and configured correctly. Note: WAMR provides some features which can be easily configured by passing options to cmake, please see [WAMR vmcore cmake building configurations](../doc/build_wamr.md#wamr-vmcore-cmake-building-configurations) for details. Currently in Zephyr, interpreter, AOT and builtin libc are enabled by default. From dac86af2f2ae8a6e59e4913020fb85edb53e3106 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Tue, 18 Apr 2023 22:09:18 +0900 Subject: [PATCH 57/61] Update messages/comments to refer the new place of the version definition (#2133) --- .github/scripts/fetch_and_compare_version.py | 2 +- .github/workflows/create_tag.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/fetch_and_compare_version.py b/.github/scripts/fetch_and_compare_version.py index 913cb1aad..ac206cade 100644 --- a/.github/scripts/fetch_and_compare_version.py +++ b/.github/scripts/fetch_and_compare_version.py @@ -12,7 +12,7 @@ import sys def fetch_version_from_code(): """ - search the semantic version definition in build-scripts/config_common.cmake + search the semantic version definition in core/version.h """ major, minor, patch = "", "", "" with open("core/version.h", encoding="utf-8") as f: diff --git a/.github/workflows/create_tag.yml b/.github/workflows/create_tag.yml index 01dd8f168..3a145bf04 100644 --- a/.github/workflows/create_tag.yml +++ b/.github/workflows/create_tag.yml @@ -52,7 +52,7 @@ jobs: # # if [[ -z ${new_ver} ]]; then - echo "::error::please indicate the right semantic version in build-scripts/config_common.cmake" + echo "::error::please indicate the right semantic version in core/version.h" echo "new_ver=''" >> "$GITHUB_OUTPUT" echo "new_tag=''" >> "$GITHUB_OUTPUT" exit 1 From 0158eea965a6cb569862dcda69c10421d1a10c8d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 19 Apr 2023 15:01:48 +0900 Subject: [PATCH 58/61] build_wamr_lldb.yml: sync lldb build options between ubuntu and macos (#2132) Notably, this disables python scripting support on ubuntu: * It isn't necessary for the primary purpose of this build. (that is, the vscode extension) * It has been disabled in the macOS counterpart. * It allows to use the same binary for 22.04 and 20.04. (note: 22.04 and 20.04 provide different versions of libpython) --- .github/workflows/build_wamr_lldb.yml | 36 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_wamr_lldb.yml b/.github/workflows/build_wamr_lldb.yml index fab40758e..ba491ad3a 100644 --- a/.github/workflows/build_wamr_lldb.yml +++ b/.github/workflows/build_wamr_lldb.yml @@ -96,14 +96,23 @@ jobs: cmake -S ./llvm -B build \ -G Ninja \ -DCMAKE_INSTALL_PREFIX=../wamr-lldb \ - -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;lldb" \ - -DLLVM_TARGETS_TO_BUILD=X86 \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_BUILD_BENCHMARKS:BOOL=OFF \ - -DLLVM_BUILD_DOCS:BOOL=OFF -DLLVM_BUILD_EXAMPLES:BOOL=OFF \ - -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF -DLLVM_BUILD_TESTS:BOOL=OFF \ - -DLLVM_ENABLE_BINDINGS:BOOL=OFF -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \ - -DLLVM_INCLUDE_DOCS:BOOL=OFF -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ - -DLLVM_INCLUDE_TESTS:BOOL=OFF -DLLVM_ENABLE_LLD:BOOL=ON + -DCMAKE_BUILD_TYPE:STRING="Release" \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DLLVM_ENABLE_PROJECTS="clang;lldb" \ + -DLLVM_TARGETS_TO_BUILD:STRING="X86;WebAssembly" \ + -DLLVM_BUILD_BENCHMARKS:BOOL=OFF \ + -DLLVM_BUILD_DOCS:BOOL=OFF \ + -DLLVM_BUILD_EXAMPLES:BOOL=OFF \ + -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \ + -DLLVM_BUILD_TESTS:BOOL=OFF \ + -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \ + -DLLVM_INCLUDE_DOCS:BOOL=OFF \ + -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ + -DLLVM_INCLUDE_TESTS:BOOL=OFF \ + -DLLVM_ENABLE_BINDINGS:BOOL=OFF \ + -DLLVM_ENABLE_LIBXML2:BOOL=ON \ + -DLLDB_ENABLE_PYTHON:BOOL=OFF \ + -DLLVM_ENABLE_LLD:BOOL=ON cmake --build build --target lldb install --parallel $(nproc) working-directory: core/deps/llvm-project @@ -118,13 +127,20 @@ jobs: -DCMAKE_BUILD_TYPE:STRING="Release" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DLLVM_ENABLE_PROJECTS="clang;lldb" \ + -DLLVM_TARGETS_TO_BUILD:STRING="X86;WebAssembly" \ + -DLLVM_BUILD_BENCHMARKS:BOOL=OFF \ + -DLLVM_BUILD_DOCS:BOOL=OFF \ + -DLLVM_BUILD_EXAMPLES:BOOL=OFF \ + -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \ + -DLLVM_BUILD_TESTS:BOOL=OFF \ + -DLLVM_INCLUDE_BENCHMARKS:BOOL=OFF \ + -DLLVM_INCLUDE_DOCS:BOOL=OFF \ + -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ -DLLVM_INCLUDE_TESTS:BOOL=OFF \ - -DLLVM_INCLUDE_EXAMPLES:BOOL=OFF \ -DLLVM_BUILD_BENCHMARKS:BOOL=OFF \ -DLLVM_BUILD_DOCS:BOOL=OFF \ -DLLVM_BUILD_LLVM_DYLIB:BOOL=OFF \ -DLLVM_ENABLE_BINDINGS:BOOL=OFF \ - -DLLVM_TARGETS_TO_BUILD:STRING="X86;WebAssembly" \ -DLLVM_ENABLE_LIBXML2:BOOL=ON \ -DLLDB_ENABLE_PYTHON:BOOL=OFF \ -DLLDB_BUILD_FRAMEWORK:BOOL=OFF From dfca21d2397b5d777496676e3b3f6e93b6366788 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 19 Apr 2023 20:39:01 +0900 Subject: [PATCH 59/61] build_wamr_vscode_ext.yml: vsce publish only on the official repo (#2130) This makes it simpler to test workflow files on a fork. --- .github/workflows/build_wamr_vscode_ext.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_wamr_vscode_ext.yml b/.github/workflows/build_wamr_vscode_ext.yml index 378aebba9..297dc9b9e 100644 --- a/.github/workflows/build_wamr_vscode_ext.yml +++ b/.github/workflows/build_wamr_vscode_ext.yml @@ -32,13 +32,16 @@ jobs: working-directory: test-tools/wamr-ide/VSCode-Extension - name: generate wamr ide vscode extension - env: - credentials: ${{ secrets.TOKEN }} run: | npm install -g vsce rm -rf node_modules npm install vsce package + working-directory: test-tools/wamr-ide/VSCode-Extension + + - name: publish wamr ide vscode extension to the vsce marketplace + if: ${{ github.repository == 'bytecodealliance/wasm-micro-runtime' }} + run: | vsce publish -p ${{ secrets.TOKEN }} working-directory: test-tools/wamr-ide/VSCode-Extension From 7e9bf9cdf5ee27b0b03b623f755724a4432449d1 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Thu, 20 Apr 2023 10:09:34 +0800 Subject: [PATCH 60/61] Implement Fast JIT multi-threading feature (#2134) - Translate all the opcodes of threads spec proposal for Fast JIT - Add the atomic flag for Fast JIT load/store IRs to support atomic load/store - Add new atomic related Fast JIT IRs and translate them in the codegen - Add suspend_flags check in branch opcodes and before/after call function - Modify CI to enable Fast JIT multi-threading test Co-authored-by: TianlongLiang --- .../compilation_on_android_ubuntu.yml | 24 +- core/iwasm/compilation/aot_emit_control.c | 4 +- .../fast-jit/cg/x86-64/jit_codegen_x86_64.cpp | 1762 ++++++++++++++++- core/iwasm/fast-jit/fe/jit_emit_control.c | 55 + core/iwasm/fast-jit/fe/jit_emit_function.c | 31 + core/iwasm/fast-jit/fe/jit_emit_memory.c | 374 +++- core/iwasm/fast-jit/fe/jit_emit_memory.h | 3 + core/iwasm/fast-jit/jit_dump.c | 7 +- core/iwasm/fast-jit/jit_frontend.c | 65 +- core/iwasm/fast-jit/jit_frontend.h | 11 + core/iwasm/fast-jit/jit_ir.c | 18 +- core/iwasm/fast-jit/jit_ir.def | 44 + core/iwasm/fast-jit/jit_ir.h | 38 +- core/iwasm/fast-jit/jit_regalloc.c | 14 + tests/wamr-test-suites/test_wamr.sh | 8 - 15 files changed, 2290 insertions(+), 168 deletions(-) diff --git a/.github/workflows/compilation_on_android_ubuntu.yml b/.github/workflows/compilation_on_android_ubuntu.yml index 3a495e5b4..aa366833b 100644 --- a/.github/workflows/compilation_on_android_ubuntu.yml +++ b/.github/workflows/compilation_on_android_ubuntu.yml @@ -125,8 +125,8 @@ jobs: # Running mode $CLASSIC_INTERP_BUILD_OPTIONS, $FAST_INTERP_BUILD_OPTIONS, - $FAST_JIT_BUILD_OPTIONS - ] + $FAST_JIT_BUILD_OPTIONS, + ] make_options_feature: [ # Features "-DWAMR_BUILD_CUSTOM_NAME_SECTION=1", @@ -414,11 +414,11 @@ jobs: os: [ubuntu-20.04, ubuntu-22.04] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz" + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz", ] wabt_release: [ - "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz" + "https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz", ] steps: - name: checkout @@ -505,7 +505,7 @@ jobs: build_iwasm, build_llvm_libraries_on_ubuntu_2004, build_llvm_libraries_on_ubuntu_2204, - build_wamrc + build_wamrc, ] runs-on: ${{ matrix.os }} strategy: @@ -530,7 +530,7 @@ jobs: ] wasi_sdk_release: [ - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz" + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz", ] include: - os: ubuntu-20.04 @@ -551,24 +551,16 @@ jobs: test_option: $MULTI_MODULES_TEST_OPTIONS - running_mode: "jit" test_option: $MULTI_MODULES_TEST_OPTIONS - # fast-jit doesn't support multi module, simd, and threads + # fast-jit doesn't support multi module, simd - running_mode: "fast-jit" test_option: $MULTI_MODULES_TEST_OPTIONS - running_mode: "fast-jit" test_option: $SIMD_TEST_OPTIONS - - running_mode: "fast-jit" - test_option: $THREADS_TEST_OPTIONS - - running_mode: "fast-jit" - test_option: $WASI_TEST_OPTIONS - # multi-tier-jit doesn't support multi module, simd, and threads + # multi-tier-jit doesn't support multi module, simd - running_mode: "multi-tier-jit" test_option: $MULTI_MODULES_TEST_OPTIONS - running_mode: "multi-tier-jit" test_option: $SIMD_TEST_OPTIONS - - running_mode: "multi-tier-jit" - test_option: $THREADS_TEST_OPTIONS - - running_mode: "multi-tier-jit" - test_option: $WASI_TEST_OPTIONS steps: - name: checkout uses: actions/checkout@v3 diff --git a/core/iwasm/compilation/aot_emit_control.c b/core/iwasm/compilation/aot_emit_control.c index 8c15d4d17..2cf51cf67 100644 --- a/core/iwasm/compilation/aot_emit_control.c +++ b/core/iwasm/compilation/aot_emit_control.c @@ -701,7 +701,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) if (!(terminate_flags = LLVMBuildLoad2(comp_ctx->builder, I32_TYPE, terminate_addr, "terminate_flags"))) { - aot_set_last_error("llvm build bit cast failed"); + aot_set_last_error("llvm build LOAD failed"); return false; } /* Set terminate_flags memory accecc to volatile, so that the value @@ -729,7 +729,7 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx) goto fail; } - /* Move builder to terminate block */ + /* Move builder to non terminate block */ SET_BUILDER_POS(non_terminate_block); return true; diff --git a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp index 48d1486d5..e28acf98a 100644 --- a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp +++ b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp @@ -26,6 +26,28 @@ static char *code_block_return_to_interp_from_jitted = NULL; static char *code_block_compile_fast_jit_and_then_call = NULL; #endif +typedef enum { + REG_BPL_IDX = 0, + REG_AXL_IDX, + REG_BXL_IDX, + REG_CXL_IDX, + REG_DXL_IDX, + REG_DIL_IDX, + REG_SIL_IDX, + REG_I8_FREE_IDX = REG_SIL_IDX +} RegIndexI8; + +typedef enum { + REG_BP_IDX = 0, + REG_AX_IDX, + REG_BX_IDX, + REG_CX_IDX, + REG_DX_IDX, + REG_DI_IDX, + REG_SI_IDX, + REG_I16_FREE_IDX = REG_SI_IDX +} RegIndexI16; + typedef enum { REG_EBP_IDX = 0, REG_EAX_IDX, @@ -262,6 +284,13 @@ jit_codegen_interp_jitted_glue(void *exec_env, JitInterpSwitchInfo *info, r3 = *jit_insn_opnd(insn, 3); \ CHECK_NCONST(r0) +/* Load five operands from insn and check if r0 is non-const */ +#define LOAD_4ARGS_NO_ASSIGN() \ + r0 = *jit_insn_opnd(insn, 0); \ + r1 = *jit_insn_opnd(insn, 1); \ + r2 = *jit_insn_opnd(insn, 2); \ + r3 = *jit_insn_opnd(insn, 3); + class JitErrorHandler : public ErrorHandler { public: @@ -853,6 +882,47 @@ mov_imm_to_m(x86::Assembler &a, x86::Mem &m_dst, Imm imm_src, uint32 bytes_dst) return true; } +#if WASM_ENABLE_SHARED_MEMORY != 0 +/** + * Encode exchange register with memory + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * skipped by float and double + * @param kind_dst the kind of data to move, could only be I32 or I64 + * @param m_dst the dest memory operand + * @param reg_no_src the index of dest register + * + * @return true if success, false otherwise + */ +static bool +xchg_r_to_m(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, + x86::Mem &m_dst, int32 reg_no_src) +{ + bh_assert((kind_dst == JIT_REG_KIND_I32 && bytes_dst <= 4) + || kind_dst == JIT_REG_KIND_I64); + bh_assert(reg_no_src < 16); + switch (bytes_dst) { + case 1: + a.xchg(m_dst, regs_i8[reg_no_src]); + break; + case 2: + a.xchg(m_dst, regs_i16[reg_no_src]); + break; + case 4: + a.xchg(m_dst, regs_i32[reg_no_src]); + break; + case 8: + a.xchg(m_dst, regs_i64[reg_no_src]); + break; + default: + bh_assert(0); + return false; + } + return true; +} +#endif /** * Encode loading register data from memory with imm base and imm offset * @@ -967,9 +1037,13 @@ ld_r_from_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, static bool st_r_to_base_imm_offset_imm(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_src, int32 base, - int32 offset) + int32 offset, bool atomic) { x86::Mem m((uintptr_t)(base + offset), bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); +#endif return mov_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); } @@ -990,9 +1064,14 @@ st_r_to_base_imm_offset_imm(x86::Assembler &a, uint32 bytes_dst, */ static bool st_r_to_base_imm_offset_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, - int32 reg_no_src, int32 base, int32 reg_no_offset) + int32 reg_no_src, int32 base, int32 reg_no_offset, + bool atomic) { x86::Mem m(regs_i64[reg_no_offset], base, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); +#endif return mov_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); } @@ -1012,9 +1091,14 @@ st_r_to_base_imm_offset_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, */ static bool st_r_to_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, - int32 reg_no_src, int32 reg_no_base, int32 offset) + int32 reg_no_src, int32 reg_no_base, int32 offset, + bool atomic) { x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); +#endif return mov_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); } @@ -1036,9 +1120,13 @@ st_r_to_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, static bool st_r_to_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_src, int32 reg_no_base, - int32 reg_no_offset) + int32 reg_no_offset, bool atomic) { x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); +#endif return mov_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src); } @@ -1063,6 +1151,37 @@ imm_set_value(Imm &imm, void *data, uint32 bytes) } } +#if WASM_ENABLE_SHARED_MEMORY != 0 +static uint32 +mov_imm_to_free_reg(x86::Assembler &a, Imm &imm, uint32 bytes) +{ + uint32 reg_no; + + switch (bytes) { + case 1: + reg_no = REG_I8_FREE_IDX; + a.mov(regs_i8[reg_no], imm); + break; + case 2: + reg_no = REG_I16_FREE_IDX; + a.mov(regs_i16[reg_no], imm); + break; + case 4: + reg_no = REG_I32_FREE_IDX; + a.mov(regs_i32[reg_no], imm); + break; + case 8: + reg_no = REG_I64_FREE_IDX; + a.mov(regs_i64[reg_no], imm); + break; + default: + bh_assert(0); + } + + return reg_no; +} +#endif + /** * Encode storing int32 imm data to memory with imm base and imm offset * @@ -1077,11 +1196,18 @@ imm_set_value(Imm &imm, void *data, uint32 bytes) */ static bool st_imm_to_base_imm_offset_imm(x86::Assembler &a, uint32 bytes_dst, - void *data_src, int32 base, int32 offset) + void *data_src, int32 base, int32 offset, + bool atomic) { x86::Mem m((uintptr_t)(base + offset), bytes_dst); Imm imm; imm_set_value(imm, data_src, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + if (atomic) { + return xchg_r_to_m(a, bytes_dst, JIT_REG_KIND_I64, m, reg_no_src); + } +#endif return mov_imm_to_m(a, m, imm, bytes_dst); } @@ -1100,11 +1226,17 @@ st_imm_to_base_imm_offset_imm(x86::Assembler &a, uint32 bytes_dst, */ static bool st_imm_to_base_imm_offset_r(x86::Assembler &a, uint32 bytes_dst, void *data_src, - int32 base, int32 reg_no_offset) + int32 base, int32 reg_no_offset, bool atomic) { x86::Mem m(regs_i64[reg_no_offset], base, bytes_dst); Imm imm; imm_set_value(imm, data_src, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + if (atomic) { + return xchg_r_to_m(a, bytes_dst, JIT_REG_KIND_I64, m, reg_no_src); + } +#endif return mov_imm_to_m(a, m, imm, bytes_dst); } @@ -1123,11 +1255,17 @@ st_imm_to_base_imm_offset_r(x86::Assembler &a, uint32 bytes_dst, void *data_src, */ static bool st_imm_to_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, void *data_src, - int32 reg_no_base, int32 offset) + int32 reg_no_base, int32 offset, bool atomic) { x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); Imm imm; imm_set_value(imm, data_src, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + if (atomic) { + return xchg_r_to_m(a, bytes_dst, JIT_REG_KIND_I64, m, reg_no_src); + } +#endif return mov_imm_to_m(a, m, imm, bytes_dst); } @@ -1147,11 +1285,17 @@ st_imm_to_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, void *data_src, */ static bool st_imm_to_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, void *data_src, - int32 reg_no_base, int32 reg_no_offset) + int32 reg_no_base, int32 reg_no_offset, bool atomic) { x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); Imm imm; imm_set_value(imm, data_src, bytes_dst); +#if WASM_ENABLE_SHARED_MEMORY != 0 + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + if (atomic) { + return xchg_r_to_m(a, bytes_dst, JIT_REG_KIND_I64, m, reg_no_src); + } +#endif return mov_imm_to_m(a, m, imm, bytes_dst); } @@ -4555,82 +4699,84 @@ cmp_r_imm_to_r_f64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no1_src, * Encode insn sd: ST_type r0, r1, r2 * @param kind the data kind, such as I32, I64, F32 and F64 * @param bytes_dst the byte number of dst data + * @param atomic whether it's atomic store */ -#define ST_R_R_R(kind, type, bytes_dst) \ - do { \ - type data_src = 0; \ - int32 reg_no_src = 0, reg_no_base = 0, reg_no_offset = 0; \ - int32 base = 0, offset = 0; \ - bool _ret = false; \ - \ - if (jit_reg_is_const(r1)) { \ - CHECK_KIND(r1, JIT_REG_KIND_I32); \ - } \ - else { \ - CHECK_KIND(r1, JIT_REG_KIND_I64); \ - } \ - if (jit_reg_is_const(r2)) { \ - CHECK_KIND(r2, JIT_REG_KIND_I32); \ - } \ - else { \ - CHECK_KIND(r2, JIT_REG_KIND_I64); \ - } \ - \ - if (jit_reg_is_const(r0)) \ - data_src = jit_cc_get_const_##kind(cc, r0); \ - else { \ - reg_no_src = jit_reg_no(r0); \ - CHECK_REG_NO(reg_no_src, jit_reg_kind(r0)); \ - } \ - if (jit_reg_is_const(r1)) \ - base = jit_cc_get_const_I32(cc, r1); \ - else { \ - reg_no_base = jit_reg_no(r1); \ - CHECK_REG_NO(reg_no_base, jit_reg_kind(r1)); \ - } \ - if (jit_reg_is_const(r2)) \ - offset = jit_cc_get_const_I32(cc, r2); \ - else { \ - reg_no_offset = jit_reg_no(r2); \ - CHECK_REG_NO(reg_no_offset, jit_reg_kind(r2)); \ - } \ - \ - if (jit_reg_is_const(r0)) { \ - if (jit_reg_is_const(r1)) { \ - if (jit_reg_is_const(r2)) \ - _ret = st_imm_to_base_imm_offset_imm( \ - a, bytes_dst, &data_src, base, offset); \ - else \ - _ret = st_imm_to_base_imm_offset_r( \ - a, bytes_dst, &data_src, base, reg_no_offset); \ - } \ - else if (jit_reg_is_const(r2)) \ - _ret = st_imm_to_base_r_offset_imm(a, bytes_dst, &data_src, \ - reg_no_base, offset); \ - else \ - _ret = st_imm_to_base_r_offset_r(a, bytes_dst, &data_src, \ - reg_no_base, reg_no_offset); \ - } \ - else if (jit_reg_is_const(r1)) { \ - if (jit_reg_is_const(r2)) \ - _ret = st_r_to_base_imm_offset_imm(a, bytes_dst, \ - JIT_REG_KIND_##kind, \ - reg_no_src, base, offset); \ - else \ - _ret = st_r_to_base_imm_offset_r( \ - a, bytes_dst, JIT_REG_KIND_##kind, reg_no_src, base, \ - reg_no_offset); \ - } \ - else if (jit_reg_is_const(r2)) \ - _ret = \ - st_r_to_base_r_offset_imm(a, bytes_dst, JIT_REG_KIND_##kind, \ - reg_no_src, reg_no_base, offset); \ - else \ - _ret = st_r_to_base_r_offset_r(a, bytes_dst, JIT_REG_KIND_##kind, \ - reg_no_src, reg_no_base, \ - reg_no_offset); \ - if (!_ret) \ - GOTO_FAIL; \ +#define ST_R_R_R(kind, type, bytes_dst, atomic) \ + do { \ + type data_src = 0; \ + int32 reg_no_src = 0, reg_no_base = 0, reg_no_offset = 0; \ + int32 base = 0, offset = 0; \ + bool _ret = false; \ + \ + if (jit_reg_is_const(r1)) { \ + CHECK_KIND(r1, JIT_REG_KIND_I32); \ + } \ + else { \ + CHECK_KIND(r1, JIT_REG_KIND_I64); \ + } \ + if (jit_reg_is_const(r2)) { \ + CHECK_KIND(r2, JIT_REG_KIND_I32); \ + } \ + else { \ + CHECK_KIND(r2, JIT_REG_KIND_I64); \ + } \ + \ + if (jit_reg_is_const(r0)) \ + data_src = jit_cc_get_const_##kind(cc, r0); \ + else { \ + reg_no_src = jit_reg_no(r0); \ + CHECK_REG_NO(reg_no_src, jit_reg_kind(r0)); \ + } \ + if (jit_reg_is_const(r1)) \ + base = jit_cc_get_const_I32(cc, r1); \ + else { \ + reg_no_base = jit_reg_no(r1); \ + CHECK_REG_NO(reg_no_base, jit_reg_kind(r1)); \ + } \ + if (jit_reg_is_const(r2)) \ + offset = jit_cc_get_const_I32(cc, r2); \ + else { \ + reg_no_offset = jit_reg_no(r2); \ + CHECK_REG_NO(reg_no_offset, jit_reg_kind(r2)); \ + } \ + \ + if (jit_reg_is_const(r0)) { \ + if (jit_reg_is_const(r1)) { \ + if (jit_reg_is_const(r2)) \ + _ret = st_imm_to_base_imm_offset_imm( \ + a, bytes_dst, &data_src, base, offset, atomic); \ + else \ + _ret = st_imm_to_base_imm_offset_r( \ + a, bytes_dst, &data_src, base, reg_no_offset, atomic); \ + } \ + else if (jit_reg_is_const(r2)) \ + _ret = st_imm_to_base_r_offset_imm( \ + a, bytes_dst, &data_src, reg_no_base, offset, atomic); \ + else \ + _ret = st_imm_to_base_r_offset_r(a, bytes_dst, &data_src, \ + reg_no_base, reg_no_offset, \ + atomic); \ + } \ + else if (jit_reg_is_const(r1)) { \ + if (jit_reg_is_const(r2)) \ + _ret = st_r_to_base_imm_offset_imm( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_src, base, \ + offset, atomic); \ + else \ + _ret = st_r_to_base_imm_offset_r( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_src, base, \ + reg_no_offset, atomic); \ + } \ + else if (jit_reg_is_const(r2)) \ + _ret = st_r_to_base_r_offset_imm(a, bytes_dst, \ + JIT_REG_KIND_##kind, reg_no_src, \ + reg_no_base, offset, atomic); \ + else \ + _ret = st_r_to_base_r_offset_r(a, bytes_dst, JIT_REG_KIND_##kind, \ + reg_no_src, reg_no_base, \ + reg_no_offset, atomic); \ + if (!_ret) \ + GOTO_FAIL; \ } while (0) /** @@ -6242,12 +6388,1192 @@ cast_r_f64_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) GOTO_FAIL; \ } while (0) +#if WASM_ENABLE_SHARED_MEMORY != 0 + +/** + * Encode extend certain bytes in the src register to a I32 or I64 kind value in + * dst register + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to extend to, could be I32, I64 + * @param reg_no_src the index of register hold src value + * + * @return true if success, false otherwise + */ +static bool +extend_r_to_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, + int32 reg_no_src, int32 reg_no_dst) +{ + if (kind_dst == JIT_REG_KIND_I32) { + bh_assert(reg_no_src < 16 && reg_no_dst < 16); + switch (bytes_dst) { + case 1: + extend_r8_to_r32(a, reg_no_dst, reg_no_src, false); + break; + case 2: + extend_r16_to_r32(a, reg_no_dst, reg_no_src, false); + break; + case 4: + mov_r_to_r_i32(a, reg_no_dst, reg_no_src); + break; + default: + bh_assert(0); + return false; + } + } + else if (kind_dst == JIT_REG_KIND_I64) { + bh_assert(reg_no_src < 16 && reg_no_dst < 16); + switch (bytes_dst) { + case 1: + extend_r8_to_r64(a, reg_no_dst, reg_no_src, false); + break; + case 2: + extend_r16_to_r64(a, reg_no_dst, reg_no_src, false); + break; + case 4: + extend_r32_to_r64(a, reg_no_dst, reg_no_src, false); + break; + case 8: + mov_r_to_r_i64(a, reg_no_dst, reg_no_src); + break; + default: + bh_assert(0); + return false; + } + } + else { + bh_assert(0); + } + return true; +} + +/** + * Encode atomic compare and exchange, when calling this function, + * value for comparison should be already moved in register + * al/ax/eax/rax + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param m_dst the dest memory operand + * @param reg_no_xchg the index of register hold exchange value + * + * @return true if success, false otherwise + */ +static bool +at_cmpxchg(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, + int32 reg_no_xchg, x86::Mem &m_dst) +{ + bh_assert((kind_dst == JIT_REG_KIND_I32 && bytes_dst <= 4) + || kind_dst == JIT_REG_KIND_I64); + bh_assert(reg_no_xchg < 16); + switch (bytes_dst) { + case 1: + a.lock().cmpxchg(m_dst, regs_i8[reg_no_xchg]); + break; + case 2: + a.lock().cmpxchg(m_dst, regs_i16[reg_no_xchg]); + break; + case 4: + a.lock().cmpxchg(m_dst, regs_i32[reg_no_xchg]); + break; + case 8: + a.lock().cmpxchg(m_dst, regs_i64[reg_no_xchg]); + break; + default: + bh_assert(0); + return false; + } + return true; +} + +/** + * Encode atomic compare and exchange: load value into a register from + * memory with reg base and reg offset, compare (expected) reg data with the + * loaded value, if equal, store the (replacement) reg data to the same + * memory, else, do nothing. Either way, returns the loaded value + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_xchg the no of register that stores the conditionally + * replacement value + * @param reg_no_base the no of register that stores the base address + * of src&dst memory + * @param reg_no_offset the no of register that stores the offset address + * of src&dst memory + * @return true if success, false otherwise + */ +static bool +at_cmpxchg_r_ra_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_xchg, + int32 reg_no_base, int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return at_cmpxchg(a, bytes_dst, kind_dst, reg_no_xchg, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, REG_RAX_IDX); +} + +/** + * Encode atomic compare and exchange: load value into a register from + * memory with reg base and imm offset, compare (expected) reg data with the + * loaded value, if equal, store the (replacement) reg data to the same + * memory, else, do nothing. Either way, returns the loaded value + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_xchg the no of register that stores the conditionally + * replacement value + * @param reg_no_base the no of register that stores the base address + * of src&dst memory + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_cmpxchg_r_ra_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_xchg, + int32 reg_no_base, int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return at_cmpxchg(a, bytes_dst, kind_dst, reg_no_xchg, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, REG_RAX_IDX); +} + +/** + * Encode atomic compare and exchange: load value into a register from + * memory with reg base and reg offset, compare (expected) reg data with the + * loaded value, if equal, store the (replacement) imm data to the same + * memory, else, do nothing. Either way, returns the loaded value + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param data_xchg the immediate data for exchange(conditionally replacment + * value) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory + * @param reg_no_offset the no of register that stores the offset address + * of src&dst memory + * @return true if success, false otherwise + */ +static bool +at_cmpxchg_imm_ra_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, void *data_xchg, + int32 reg_no_base, int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_xchg, bytes_dst); + uint32 reg_no_xchg = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_cmpxchg(a, bytes_dst, kind_dst, reg_no_xchg, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, REG_RAX_IDX); +} + +/** + * Encode atomic compare and exchange: load value into a register from + * memory with reg base and imm offset, compare (expected) reg data with the + * loaded value, if equal, store the (replacement) imm data to the same + * memory, else, do nothing. Either way, returns the loaded value + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param data_xchg the immediate data for exchange(conditionally replacment + * value) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_cmpxchg_imm_ra_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, void *data_xchg, + int32 reg_no_base, int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_xchg, bytes_dst); + uint32 reg_no_xchg = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_cmpxchg(a, bytes_dst, kind_dst, reg_no_xchg, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, REG_RAX_IDX); +} + +/** + * Encode insn cmpxchg: CMPXCHG_type r0, r1, r2, r3, r4 + * @param kind the data kind, can only be I32 or I64 + * @param bytes_dst the byte number of dst data + */ +#define CMPXCHG_R_R_R_R_R(kind, type, bytes_dst) \ + do { \ + type data_xchg = 0; \ + int32 reg_no_xchg = 0, reg_no_cmp = 0, reg_no_base = 0, \ + reg_no_offset = 0; \ + int32 offset = 0; \ + bool _ret = false; \ + if (jit_reg_is_const(r3)) { \ + CHECK_KIND(r3, JIT_REG_KIND_I32); \ + } \ + else { \ + CHECK_KIND(r3, JIT_REG_KIND_I64); \ + } \ + /* r1: expected value(it must in register a) \ + * r2: memory base addr can't be const */ \ + CHECK_NCONST(r1); \ + reg_no_cmp = jit_reg_no(r1); \ + bh_assert(reg_no_cmp == REG_EAX_IDX || reg_no_cmp == REG_RAX_IDX); \ + CHECK_REG_NO(reg_no_cmp, jit_reg_kind(r1)); \ + CHECK_NCONST(r2); \ + reg_no_base = jit_reg_no(r2); \ + CHECK_REG_NO(reg_no_base, jit_reg_kind(r2)); \ + /* r0: replacement value r3: offset can be const */ \ + if (jit_reg_is_const(r0)) \ + data_xchg = jit_cc_get_const_##kind(cc, r0); \ + else { \ + reg_no_xchg = jit_reg_no(r0); \ + CHECK_REG_NO(reg_no_xchg, jit_reg_kind(r0)); \ + } \ + if (jit_reg_is_const(r3)) \ + offset = jit_cc_get_const_I32(cc, r3); \ + else { \ + reg_no_offset = jit_reg_no(r3); \ + CHECK_REG_NO(reg_no_offset, jit_reg_kind(r3)); \ + } \ + \ + if (jit_reg_is_const(r0)) { \ + if (jit_reg_is_const(r3)) \ + _ret = at_cmpxchg_imm_ra_base_r_offset_imm( \ + a, bytes_dst, JIT_REG_KIND_##kind, &data_xchg, \ + reg_no_base, offset); \ + else \ + _ret = at_cmpxchg_imm_ra_base_r_offset_r( \ + a, bytes_dst, JIT_REG_KIND_##kind, &data_xchg, \ + reg_no_base, reg_no_offset); \ + } \ + else { \ + if (jit_reg_is_const(r3)) \ + _ret = at_cmpxchg_r_ra_base_r_offset_imm( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_xchg, \ + reg_no_base, offset); \ + else \ + _ret = at_cmpxchg_r_ra_base_r_offset_r( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_xchg, \ + reg_no_base, reg_no_offset); \ + } \ + if (!_ret) \ + GOTO_FAIL; \ + } while (0) + +/** + * Encode negate a value in the register + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param reg_no_src the index of register hold src value + * + * @return true if success, false otherwise + */ +static bool +neg_r(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_src) +{ + bh_assert((kind_dst == JIT_REG_KIND_I32 && bytes_dst <= 4) + || kind_dst == JIT_REG_KIND_I64); + bh_assert(reg_no_src < 16); + switch (bytes_dst) { + case 1: + a.neg(regs_i8[reg_no_src]); + break; + case 2: + a.neg(regs_i16[reg_no_src]); + break; + case 4: + a.neg(regs_i32[reg_no_src]); + break; + case 8: + a.neg(regs_i64[reg_no_src]); + break; + default: + bh_assert(0); + return false; + } + return true; +} + +/** + * Encode atomic exchange and add + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param reg_no_src the index of register hold operand value of add operation + * @param m_dst the dest memory operand + * + * @return true if success, false otherwise + */ +static bool +at_xadd(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_src, + x86::Mem &m_dst) +{ + bh_assert((kind_dst == JIT_REG_KIND_I32 && bytes_dst <= 4) + || kind_dst == JIT_REG_KIND_I64); + bh_assert(reg_no_src < 16); + switch (bytes_dst) { + case 1: + a.lock().xadd(m_dst, regs_i8[reg_no_src]); + break; + case 2: + a.lock().xadd(m_dst, regs_i16[reg_no_src]); + break; + case 4: + a.lock().xadd(m_dst, regs_i32[reg_no_src]); + break; + case 8: + a.lock().xadd(m_dst, regs_i64[reg_no_src]); + break; + default: + bh_assert(0); + return false; + } + + return true; +} + +/** + * Encode atomic rmw add: load value into a register from memory + * with reg base and reg offset, add loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_add_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw add: load value into a register from memory + * with reg base and reg offset, add loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_add_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw add: load value into a register from memory + * with reg base and imm offset, add loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_add_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw add: load value into a register from memory + * with reg base and reg offset, add loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_add_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw sub: load value into a register from memory + * with reg base and reg offset, sub loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_sub_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return neg_r(a, bytes_dst, kind_dst, reg_no_src) + && at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw sub: load value into a register from memory + * with reg base and reg offset, sub loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_sub_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return neg_r(a, bytes_dst, kind_dst, reg_no_src) + && at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw sub: load value into a register from memory + * with reg base and imm offset, sub loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_sub_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return neg_r(a, bytes_dst, kind_dst, reg_no_src) + && at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw sub: load value into a register from memory + * with reg base and reg offset, sub loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_sub_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return neg_r(a, bytes_dst, kind_dst, reg_no_src) + && at_xadd(a, bytes_dst, kind_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw xchg: load value into a register from memory + * with reg base and reg offset, exchange loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xchg_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw xchg: load value into a register from memory + * with reg base and reg offset, exchange loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xchg_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw xchg: load value into a register from memory + * with reg base and imm offset, exchange loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xchg_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode atomic rmw xchg: load value into a register from memory + * with reg base and reg offset, exchange loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xchg_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return xchg_r_to_m(a, bytes_dst, kind_dst, m, reg_no_src) + && extend_r_to_r(a, bytes_dst, kind_dst, reg_no_src, reg_no_dst); +} + +/** + * Encode insn rmw logical operation: generate a loop to make sure it's atomic + * @param bin_op the operation, can be and/or/xor + * @param kind the data kind, can only be I32 or I64 + * @param bytes_dst the byte number of dst data + */ +#define AT_RMW_LOGICAL_LOOP(bin_op, kind, bytes_dst) \ + do { \ + bh_assert((kind_dst == JIT_REG_KIND_I32 && bytes_dst <= 4) \ + || kind_dst == JIT_REG_KIND_I64); \ + bh_assert(reg_no_src < 16 && reg_no_dst < 16); \ + /* read original value in memory(operand 1) to rax(expected) */ \ + mov_m_to_r(a, bytes_dst, kind_dst, false, REG_RAX_IDX, m_dst); \ + Label loop = a.newLabel(); \ + /* check whether loop is valid, and bind the loop label \ + * to the current position in the code. */ \ + if (!loop.isValid() || a.bind(loop) != kErrorOk) \ + return false; \ + /* move operand 1 to temp reg rb */ \ + mov_r_to_r(a, kind_dst, REG_RBX_IDX, REG_RAX_IDX); \ + /* actual logical operation with operand 2, result save to rbx */ \ + switch (bytes_dst) { \ + case 1: \ + a.bin_op##_(regs_i8[REG_RBX_IDX], regs_i8[reg_no_src]); \ + break; \ + case 2: \ + a.bin_op##_(regs_i16[REG_RBX_IDX], regs_i16[reg_no_src]); \ + break; \ + case 4: \ + a.bin_op##_(regs_i32[REG_RBX_IDX], regs_i32[reg_no_src]); \ + break; \ + case 8: \ + a.bin_op##_(regs_i64[REG_RBX_IDX], regs_i64[reg_no_src]); \ + break; \ + default: \ + bh_assert(0); \ + return false; \ + } \ + /* cmp with read value in RAX, try to change with result value in RBX \ + * REG, if change successfully, mem data is changed and exit loop(ZF \ + * is set) if not, loop again(ZF is clear) and tries to do logical ops \ + * atomically */ \ + at_cmpxchg(a, bytes_dst, kind_dst, REG_RBX_IDX, m_dst); \ + a.jne(loop); \ + return true; \ + } while (0) + +/** + * Encode atomic logical binary operation: and + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param reg_no_dst the index of dest register + * @param reg_no_src the index of register hold operand value of add operation + * @param m_dst the dest memory operand + * + * @return true if success, false otherwise + */ +static bool +at_and(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, x86::Mem &m_dst) +{ + AT_RMW_LOGICAL_LOOP(and, kind_dst, bytes_dst); +} + +/** + * Encode atomic logical binary operation: or + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param reg_no_dst the index of dest register + * @param reg_no_src the index of register hold operand value of add operation + * @param m_dst the dest memory operand + * + * @return true if success, false otherwise + */ +static bool +at_or(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, x86::Mem &m_dst) +{ + AT_RMW_LOGICAL_LOOP(or, kind_dst, bytes_dst); +} +/** + * Encode atomic logical binary operation: xor + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data, + * could be 1(byte), 2(short), 4(int32), 8(int64), + * @param kind_dst the kind of data to move, could be I32, I64 + * @param reg_no_dst the index of dest register + * @param reg_no_src the index of register hold operand value of add operation + * @param m_dst the dest memory operand + * + * @return true if success, false otherwise + */ +static bool +at_xor(x86::Assembler &a, uint32 bytes_dst, uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, x86::Mem &m_dst) +{ + AT_RMW_LOGICAL_LOOP(xor, kind_dst, bytes_dst); +} + +/** + * Encode atomic rmw and: load value into a register from memory with reg base + * and reg offset, bitwise and loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_and_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_and(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw and: load value into a register from memory with reg base + * and reg offset, bitwise and loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_and_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_and(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw and: load value into a register from memory with reg base + * and imm offset, bitwise and value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_and_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return at_and(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw and: load value into a register from memory with reg base + * and reg offset, bitwise and loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_and_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return at_and(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw or: load value into a register from memory with reg base + * and reg offset, bitwise or loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_or_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_or(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw or: load value into a register from memory with reg base + * and reg offset, bitwise or loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_or_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, void *data_src, + int32 reg_no_base, int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_or(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw or: load value into a register from memory with reg base + * and imm offset, bitwise or loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_or_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return at_or(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw or: load value into a register from memory with reg base + * and reg offset, bitwise or loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_or_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, int32 reg_no_src, + int32 reg_no_base, int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return at_or(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw xor: load value into a register from memory with reg base + * and reg offset, bitwise xor loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(first operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(second operand&store back) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xor_imm_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_xor(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw xor: load value into a register from memory with reg base + * and reg offset, bitwise xor loaded value with imm data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param data_src the immediate data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xor_imm_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + void *data_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + Imm imm; + imm_set_value(imm, data_src, bytes_dst); + uint32 reg_no_src = mov_imm_to_free_reg(a, imm, bytes_dst); + return at_xor(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw xor: load value into a register from memory with reg base + * and imm offset, bitwise xor exchange loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back location) + * @param offset the offset address of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xor_r_base_r_offset_imm(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 offset) +{ + x86::Mem m(regs_i64[reg_no_base], offset, bytes_dst); + return at_xor(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode atomic rmw xor: load value into a register from memory with reg base + * and reg offset, bitwise xor loaded value with reg data, store back + * + * @param a the assembler to emit the code + * @param bytes_dst the bytes number of the data to actual operated on(load, + * compare, replacement) could be 1(byte), 2(short), 4(int32), 8(int64) + * @param reg_no_dst the no of register that stores the returned value + * @param reg_no_src the no of register store the src data(second operand) + * @param reg_no_base the no of register that stores the base address + * of src&dst memory(first operand&store back) + * @param reg_no_offset the no of register that stores the offset of the memory + * @return true if success, false otherwise + */ +static bool +at_rmw_xor_r_base_r_offset_r(x86::Assembler &a, uint32 bytes_dst, + uint32 kind_dst, int32 reg_no_dst, + int32 reg_no_src, int32 reg_no_base, + int32 reg_no_offset) +{ + x86::Mem m(regs_i64[reg_no_base], regs_i64[reg_no_offset], 0, 0, bytes_dst); + return at_xor(a, bytes_dst, kind_dst, reg_no_dst, reg_no_src, m) + && extend_r_to_r(a, bytes_dst, kind_dst, REG_RAX_IDX, reg_no_dst); +} + +/** + * Encode insn rmw RMW_type r0, r1, r2, r3 + * @param bin_op the operation, can be add/sub/xchg/and/or/xor + * @param kind the data kind, can only be I32 or I64 + * @param bytes_dst the byte number of dst data + */ +#define AT_RMW_R_R_R_R(bin_op, kind, type, bytes_dst) \ + do { \ + type data_src = 0; \ + int32 reg_no_dst = 0, reg_no_src = 0, reg_no_base = 0, \ + reg_no_offset = 0; \ + int32 offset = 0; \ + bool _ret = false; \ + if (jit_reg_is_const(r3)) { \ + CHECK_KIND(r3, JIT_REG_KIND_I32); \ + } \ + else { \ + CHECK_KIND(r3, JIT_REG_KIND_I64); \ + } \ + /* r0: read/return value r2: memory base addr can't be const */ \ + /* already check it's not const in LOAD_4ARGS(); */ \ + reg_no_dst = jit_reg_no(r0); \ + CHECK_REG_NO(reg_no_dst, jit_reg_kind(r0)); \ + /* mem_data base address has to be non-const */ \ + CHECK_NCONST(r2); \ + reg_no_base = jit_reg_no(r2); \ + CHECK_REG_NO(reg_no_base, jit_reg_kind(r2)); \ + /* r1: source operand value r3: offset can be const */ \ + if (jit_reg_is_const(r1)) \ + data_src = jit_cc_get_const_##kind(cc, r1); \ + else { \ + reg_no_src = jit_reg_no(r1); \ + CHECK_REG_NO(reg_no_src, jit_reg_kind(r1)); \ + } \ + if (jit_reg_is_const(r3)) \ + offset = jit_cc_get_const_I32(cc, r3); \ + else { \ + reg_no_offset = jit_reg_no(r3); \ + CHECK_REG_NO(reg_no_offset, jit_reg_kind(r3)); \ + } \ + \ + if (jit_reg_is_const(r1)) { \ + if (jit_reg_is_const(r3)) \ + _ret = at_rmw_##bin_op##_imm_base_r_offset_imm( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_dst, &data_src, \ + reg_no_base, offset); \ + else \ + _ret = at_rmw_##bin_op##_imm_base_r_offset_r( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_dst, &data_src, \ + reg_no_base, reg_no_offset); \ + } \ + else { \ + if (jit_reg_is_const(r3)) \ + _ret = at_rmw_##bin_op##_r_base_r_offset_imm( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_dst, reg_no_src, \ + reg_no_base, offset); \ + else \ + _ret = at_rmw_##bin_op##_r_base_r_offset_r( \ + a, bytes_dst, JIT_REG_KIND_##kind, reg_no_dst, reg_no_src, \ + reg_no_base, reg_no_offset); \ + } \ + if (!_ret) \ + GOTO_FAIL; \ + } while (0) + +/** + * Encode insn mfence + **/ +static void +fence(x86::Assembler &a) +{ + a.mfence(); +} + +/** + * Encode insn fence + */ +#define FENCE() fence(a) + +#endif + bool jit_codegen_gen_native(JitCompContext *cc) { + bool atomic; JitBasicBlock *block; JitInsn *insn; - JitReg r0, r1, r2, r3; + JitReg r0, r1, r2, r3, r4; JmpInfo jmp_info_head; bh_list *jmp_info_list = (bh_list *)&jmp_info_head; uint32 label_index, label_num, i; @@ -6615,33 +7941,41 @@ jit_codegen_gen_native(JitCompContext *cc) case JIT_OP_STI8: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(I32, int32, 1); + atomic = insn->flags_u8 & 0x1; + ST_R_R_R(I32, int32, 1, atomic); break; case JIT_OP_STI16: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(I32, int32, 2); + atomic = insn->flags_u8 & 0x1; + ST_R_R_R(I32, int32, 2, atomic); break; case JIT_OP_STI32: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(I32, int32, 4); + atomic = insn->flags_u8 & 0x1; + ST_R_R_R(I32, int32, 4, atomic); break; case JIT_OP_STI64: + LOAD_3ARGS_NO_ASSIGN(); + atomic = insn->flags_u8 & 0x1; + ST_R_R_R(I64, int64, 8, atomic); + break; + case JIT_OP_STPTR: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(I64, int64, 8); + ST_R_R_R(I64, int64, 8, false); break; case JIT_OP_STF32: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(F32, float32, 4); + ST_R_R_R(F32, float32, 4, false); break; case JIT_OP_STF64: LOAD_3ARGS_NO_ASSIGN(); - ST_R_R_R(F64, float64, 8); + ST_R_R_R(F64, float64, 8, false); break; case JIT_OP_JMP: @@ -6720,6 +8054,254 @@ jit_codegen_gen_native(JitCompContext *cc) CAST_R_R(I64, F64, i64, f64, double); break; +#if WASM_ENABLE_SHARED_MEMORY != 0 + case JIT_OP_AT_CMPXCHGU8: + LOAD_4ARGS_NO_ASSIGN(); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + CMPXCHG_R_R_R_R_R(I32, int32, 1); + else + CMPXCHG_R_R_R_R_R(I64, int64, 1); + break; + + case JIT_OP_AT_CMPXCHGU16: + LOAD_4ARGS_NO_ASSIGN(); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + CMPXCHG_R_R_R_R_R(I32, int32, 2); + else + CMPXCHG_R_R_R_R_R(I64, int64, 2); + break; + + case JIT_OP_AT_CMPXCHGI32: + LOAD_4ARGS_NO_ASSIGN(); + CMPXCHG_R_R_R_R_R(I32, int32, 4); + break; + + case JIT_OP_AT_CMPXCHGU32: + LOAD_4ARGS_NO_ASSIGN(); + CMPXCHG_R_R_R_R_R(I64, int32, 4); + break; + + case JIT_OP_AT_CMPXCHGI64: + LOAD_4ARGS_NO_ASSIGN(); + CMPXCHG_R_R_R_R_R(I64, int64, 8); + break; + + case JIT_OP_AT_ADDU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(add, I32, int32, 1); + else + AT_RMW_R_R_R_R(add, I64, int64, 1); + break; + + case JIT_OP_AT_ADDU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(add, I32, int32, 2); + else + AT_RMW_R_R_R_R(add, I64, int64, 2); + break; + + case JIT_OP_AT_ADDI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(add, I32, int32, 4); + break; + + case JIT_OP_AT_ADDU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(add, I64, int64, 4); + break; + + case JIT_OP_AT_ADDI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(add, I64, int64, 8); + break; + + case JIT_OP_AT_SUBU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(sub, I32, int32, 1); + else + AT_RMW_R_R_R_R(sub, I64, int64, 1); + break; + + case JIT_OP_AT_SUBU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(sub, I32, int32, 2); + else + AT_RMW_R_R_R_R(sub, I64, int64, 2); + break; + + case JIT_OP_AT_SUBI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(sub, I32, int32, 4); + break; + + case JIT_OP_AT_SUBU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(sub, I64, int64, 4); + break; + + case JIT_OP_AT_SUBI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(sub, I64, int64, 8); + break; + + case JIT_OP_AT_XCHGU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(xchg, I32, int32, 1); + else + AT_RMW_R_R_R_R(xchg, I64, int64, 1); + break; + + case JIT_OP_AT_XCHGU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(xchg, I32, int32, 2); + else + AT_RMW_R_R_R_R(xchg, I64, int64, 2); + break; + + case JIT_OP_AT_XCHGI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xchg, I32, int32, 4); + break; + + case JIT_OP_AT_XCHGU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xchg, I64, int64, 4); + break; + + case JIT_OP_AT_XCHGI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xchg, I64, int64, 8); + break; + + case JIT_OP_AT_ANDU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(and, I32, int32, 1); + else + AT_RMW_R_R_R_R(and, I64, int64, 1); + break; + + case JIT_OP_AT_ANDU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(and, I32, int32, 2); + else + AT_RMW_R_R_R_R(and, I64, int64, 2); + break; + + case JIT_OP_AT_ANDI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(and, I32, int32, 4); + break; + + case JIT_OP_AT_ANDU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(and, I64, int64, 4); + break; + + case JIT_OP_AT_ANDI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(and, I64, int64, 8); + break; + + case JIT_OP_AT_ORU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(or, I32, int32, 1); + else + AT_RMW_R_R_R_R(or, I64, int64, 1); + break; + + case JIT_OP_AT_ORU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(or, I32, int32, 2); + else + AT_RMW_R_R_R_R(or, I64, int64, 2); + break; + + case JIT_OP_AT_ORI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(or, I32, int32, 4); + break; + + case JIT_OP_AT_ORU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(or, I64, int64, 4); + break; + + case JIT_OP_AT_ORI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(or, I64, int64, 8); + break; + + case JIT_OP_AT_XORU8: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(xor, I32, int32, 1); + else + AT_RMW_R_R_R_R(xor, I64, int64, 1); + break; + + case JIT_OP_AT_XORU16: + LOAD_4ARGS(); + bh_assert(jit_reg_kind(r0) == JIT_REG_KIND_I32 + || jit_reg_kind(r0) == JIT_REG_KIND_I64); + if (jit_reg_kind(r0) == JIT_REG_KIND_I32) + AT_RMW_R_R_R_R(xor, I32, int32, 2); + else + AT_RMW_R_R_R_R(xor, I64, int64, 2); + break; + + case JIT_OP_AT_XORI32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xor, I32, int32, 4); + break; + + case JIT_OP_AT_XORU32: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xor, I64, int64, 4); + break; + + case JIT_OP_AT_XORI64: + LOAD_4ARGS(); + AT_RMW_R_R_R_R(xor, I64, int64, 8); + break; + + case JIT_OP_FENCE: + FENCE(); + break; + +#endif + default: jit_set_last_error_v(cc, "unsupported JIT opcode 0x%2x", insn->opcode); diff --git a/core/iwasm/fast-jit/fe/jit_emit_control.c b/core/iwasm/fast-jit/fe/jit_emit_control.c index f3aa31f39..f7536c73e 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_control.c +++ b/core/iwasm/fast-jit/fe/jit_emit_control.c @@ -904,6 +904,42 @@ check_copy_arities(const JitBlock *block_dst, JitFrame *jit_frame) } } +#if WASM_ENABLE_THREAD_MGR != 0 +bool +jit_check_suspend_flags(JitCompContext *cc) +{ + JitReg exec_env, suspend_flags, terminate_flag, offset; + JitBasicBlock *terminate_block, *cur_basic_block; + JitFrame *jit_frame = cc->jit_frame; + + cur_basic_block = cc->cur_basic_block; + terminate_block = jit_cc_new_basic_block(cc, 0); + if (!terminate_block) { + return false; + } + + gen_commit_values(jit_frame, jit_frame->lp, jit_frame->sp); + exec_env = cc->exec_env_reg; + suspend_flags = jit_cc_new_reg_I32(cc); + terminate_flag = jit_cc_new_reg_I32(cc); + + offset = jit_cc_new_const_I32(cc, offsetof(WASMExecEnv, suspend_flags)); + GEN_INSN(LDI32, suspend_flags, exec_env, offset); + GEN_INSN(AND, terminate_flag, suspend_flags, NEW_CONST(I32, 1)); + + GEN_INSN(CMP, cc->cmp_reg, terminate_flag, NEW_CONST(I32, 0)); + GEN_INSN(BNE, cc->cmp_reg, jit_basic_block_label(terminate_block), 0); + + cc->cur_basic_block = terminate_block; + GEN_INSN(RETURN, NEW_CONST(I32, 0)); + + cc->cur_basic_block = cur_basic_block; + + return true; +} + +#endif + static bool handle_op_br(JitCompContext *cc, uint32 br_depth, uint8 **p_frame_ip) { @@ -986,6 +1022,13 @@ fail: bool jit_compile_op_br(JitCompContext *cc, uint32 br_depth, uint8 **p_frame_ip) { + +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + return false; +#endif + return handle_op_br(cc, br_depth, p_frame_ip) && handle_next_reachable_block(cc, p_frame_ip); } @@ -1105,6 +1148,12 @@ jit_compile_op_br_if(JitCompContext *cc, uint32 br_depth, jit_insn_delete(insn_select); } +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + return false; +#endif + SET_BUILDER_POS(if_basic_block); SET_BB_BEGIN_BCIP(if_basic_block, *p_frame_ip - 1); @@ -1144,6 +1193,12 @@ jit_compile_op_br_table(JitCompContext *cc, uint32 *br_depths, uint32 br_count, uint32 i = 0; JitOpndLookupSwitch *opnd = NULL; +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + return false; +#endif + cur_basic_block = cc->cur_basic_block; POP_I32(value); diff --git a/core/iwasm/fast-jit/fe/jit_emit_function.c b/core/iwasm/fast-jit/fe/jit_emit_function.c index a89f2ff59..3ac9e3ed6 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_function.c +++ b/core/iwasm/fast-jit/fe/jit_emit_function.c @@ -5,6 +5,7 @@ #include "jit_emit_function.h" #include "jit_emit_exception.h" +#include "jit_emit_control.h" #include "../jit_frontend.h" #include "../jit_codegen.h" #include "../../interpreter/wasm_runtime.h" @@ -232,6 +233,12 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) bool is_pointer_arg; bool return_value = false; +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif + if (func_idx < wasm_module->import_function_count) { /* The function to call is an import function */ func_import = &wasm_module->import_functions[func_idx].u.function; @@ -275,6 +282,12 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) goto fail; } +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif + return true; } @@ -416,6 +429,12 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) } } +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif + /* Clear part of memory regs and table regs as their values may be changed in the function call */ if (cc->cur_wasm_module->possible_memory_grow) @@ -540,6 +559,12 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx, GEN_INSN(STI32, func_idx, cc->exec_env_reg, NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache) + 4)); +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif + block_import = jit_cc_new_basic_block(cc, 0); block_nonimport = jit_cc_new_basic_block(cc, 0); func_return = jit_cc_new_basic_block(cc, 0); @@ -742,6 +767,12 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx, goto fail; } +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif + /* Clear part of memory regs and table regs as their values may be changed in the function call */ if (cc->cur_wasm_module->possible_memory_grow) diff --git a/core/iwasm/fast-jit/fe/jit_emit_memory.c b/core/iwasm/fast-jit/fe/jit_emit_memory.c index b71d98ba1..9635d4e57 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_memory.c +++ b/core/iwasm/fast-jit/fe/jit_emit_memory.c @@ -9,6 +9,7 @@ #include "../jit_frontend.h" #include "../jit_codegen.h" #include "../../interpreter/wasm_runtime.h" +#include "jit_emit_control.h" #ifndef OS_ENABLE_HW_BOUND_CHECK static JitReg @@ -60,6 +61,14 @@ fail: } #endif +#if WASM_ENABLE_SHARED_MEMORY != 0 +static void +set_load_or_store_atomic(JitInsn *load_or_store_inst) +{ + load_or_store_inst->flags_u8 |= 0x1; +} +#endif + #if UINTPTR_MAX == UINT64_MAX static JitReg check_and_seek_on_64bit_platform(JitCompContext *cc, JitReg addr, JitReg offset, @@ -177,23 +186,36 @@ fail: return 0; } -#define CHECK_ALIGNMENT(maddr, memory_data, offset1) \ +#if UINTPTR_MAX == UINT64_MAX +#define CHECK_ALIGNMENT(offset1) \ do { \ - GEN_INSN(ADD, maddr, memory_data, offset1); \ JitReg align_mask = NEW_CONST(I64, ((uint64)1 << align) - 1); \ JitReg AND_res = jit_cc_new_reg_I64(cc); \ - GEN_INSN(AND, AND_res, maddr, align_mask); \ + GEN_INSN(AND, AND_res, offset1, align_mask); \ GEN_INSN(CMP, cc->cmp_reg, AND_res, NEW_CONST(I64, 0)); \ if (!jit_emit_exception(cc, EXCE_UNALIGNED_ATOMIC, JIT_OP_BNE, \ cc->cmp_reg, NULL)) \ goto fail; \ } while (0) +#else +#define CHECK_ALIGNMENT(offset1) \ + do { \ + JitReg align_mask = NEW_CONST(I32, (1 << align) - 1); \ + JitReg AND_res = jit_cc_new_reg_I32(cc); \ + GEN_INSN(AND, AND_res, offset1, align_mask); \ + GEN_INSN(CMP, cc->cmp_reg, AND_res, NEW_CONST(I32, 0)); \ + if (!jit_emit_exception(cc, EXCE_UNALIGNED_ATOMIC, JIT_OP_BNE, \ + cc->cmp_reg, NULL)) \ + goto fail; \ + } while (0) +#endif bool jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool sign, bool atomic) { JitReg addr, offset1, value, memory_data; + JitInsn *load_insn = NULL; POP_I32(addr); @@ -201,6 +223,11 @@ jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset, if (!offset1) { goto fail; } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) { + CHECK_ALIGNMENT(offset1); + } +#endif memory_data = get_memory_data_reg(cc->jit_frame, 0); @@ -209,30 +236,30 @@ jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset, case 1: { if (sign) { - GEN_INSN(LDI8, value, memory_data, offset1); + load_insn = GEN_INSN(LDI8, value, memory_data, offset1); } else { - GEN_INSN(LDU8, value, memory_data, offset1); + load_insn = GEN_INSN(LDU8, value, memory_data, offset1); } break; } case 2: { if (sign) { - GEN_INSN(LDI16, value, memory_data, offset1); + load_insn = GEN_INSN(LDI16, value, memory_data, offset1); } else { - GEN_INSN(LDU16, value, memory_data, offset1); + load_insn = GEN_INSN(LDU16, value, memory_data, offset1); } break; } case 4: { if (sign) { - GEN_INSN(LDI32, value, memory_data, offset1); + load_insn = GEN_INSN(LDI32, value, memory_data, offset1); } else { - GEN_INSN(LDU32, value, memory_data, offset1); + load_insn = GEN_INSN(LDU32, value, memory_data, offset1); } break; } @@ -243,6 +270,13 @@ jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset, } } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic && load_insn) + set_load_or_store_atomic(load_insn); +#else + (void)load_insn; +#endif + PUSH_I32(value); return true; fail: @@ -254,6 +288,7 @@ jit_compile_op_i64_load(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool sign, bool atomic) { JitReg addr, offset1, value, memory_data; + JitInsn *load_insn = NULL; POP_I32(addr); @@ -261,6 +296,11 @@ jit_compile_op_i64_load(JitCompContext *cc, uint32 align, uint32 offset, if (!offset1) { goto fail; } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) { + CHECK_ALIGNMENT(offset1); + } +#endif memory_data = get_memory_data_reg(cc->jit_frame, 0); @@ -269,40 +309,40 @@ jit_compile_op_i64_load(JitCompContext *cc, uint32 align, uint32 offset, case 1: { if (sign) { - GEN_INSN(LDI8, value, memory_data, offset1); + load_insn = GEN_INSN(LDI8, value, memory_data, offset1); } else { - GEN_INSN(LDU8, value, memory_data, offset1); + load_insn = GEN_INSN(LDU8, value, memory_data, offset1); } break; } case 2: { if (sign) { - GEN_INSN(LDI16, value, memory_data, offset1); + load_insn = GEN_INSN(LDI16, value, memory_data, offset1); } else { - GEN_INSN(LDU16, value, memory_data, offset1); + load_insn = GEN_INSN(LDU16, value, memory_data, offset1); } break; } case 4: { if (sign) { - GEN_INSN(LDI32, value, memory_data, offset1); + load_insn = GEN_INSN(LDI32, value, memory_data, offset1); } else { - GEN_INSN(LDU32, value, memory_data, offset1); + load_insn = GEN_INSN(LDU32, value, memory_data, offset1); } break; } case 8: { if (sign) { - GEN_INSN(LDI64, value, memory_data, offset1); + load_insn = GEN_INSN(LDI64, value, memory_data, offset1); } else { - GEN_INSN(LDU64, value, memory_data, offset1); + load_insn = GEN_INSN(LDU64, value, memory_data, offset1); } break; } @@ -313,6 +353,13 @@ jit_compile_op_i64_load(JitCompContext *cc, uint32 align, uint32 offset, } } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic && load_insn) + set_load_or_store_atomic(load_insn); +#else + (void)load_insn; +#endif + PUSH_I64(value); return true; fail: @@ -370,6 +417,7 @@ jit_compile_op_i32_store(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool atomic) { JitReg value, addr, offset1, memory_data; + JitInsn *store_insn = NULL; POP_I32(value); POP_I32(addr); @@ -378,23 +426,28 @@ jit_compile_op_i32_store(JitCompContext *cc, uint32 align, uint32 offset, if (!offset1) { goto fail; } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) { + CHECK_ALIGNMENT(offset1); + } +#endif memory_data = get_memory_data_reg(cc->jit_frame, 0); switch (bytes) { case 1: { - GEN_INSN(STI8, value, memory_data, offset1); + store_insn = GEN_INSN(STI8, value, memory_data, offset1); break; } case 2: { - GEN_INSN(STI16, value, memory_data, offset1); + store_insn = GEN_INSN(STI16, value, memory_data, offset1); break; } case 4: { - GEN_INSN(STI32, value, memory_data, offset1); + store_insn = GEN_INSN(STI32, value, memory_data, offset1); break; } default: @@ -403,6 +456,12 @@ jit_compile_op_i32_store(JitCompContext *cc, uint32 align, uint32 offset, goto fail; } } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic && store_insn) + set_load_or_store_atomic(store_insn); +#else + (void)store_insn; +#endif return true; fail: @@ -414,6 +473,7 @@ jit_compile_op_i64_store(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes, bool atomic) { JitReg value, addr, offset1, memory_data; + JitInsn *store_insn = NULL; POP_I64(value); POP_I32(addr); @@ -422,6 +482,11 @@ jit_compile_op_i64_store(JitCompContext *cc, uint32 align, uint32 offset, if (!offset1) { goto fail; } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic) { + CHECK_ALIGNMENT(offset1); + } +#endif if (jit_reg_is_const(value) && bytes < 8) { value = NEW_CONST(I32, (int32)jit_cc_get_const_I64(cc, value)); @@ -432,22 +497,22 @@ jit_compile_op_i64_store(JitCompContext *cc, uint32 align, uint32 offset, switch (bytes) { case 1: { - GEN_INSN(STI8, value, memory_data, offset1); + store_insn = GEN_INSN(STI8, value, memory_data, offset1); break; } case 2: { - GEN_INSN(STI16, value, memory_data, offset1); + store_insn = GEN_INSN(STI16, value, memory_data, offset1); break; } case 4: { - GEN_INSN(STI32, value, memory_data, offset1); + store_insn = GEN_INSN(STI32, value, memory_data, offset1); break; } case 8: { - GEN_INSN(STI64, value, memory_data, offset1); + store_insn = GEN_INSN(STI64, value, memory_data, offset1); break; } default: @@ -456,6 +521,12 @@ jit_compile_op_i64_store(JitCompContext *cc, uint32 align, uint32 offset, goto fail; } } +#if WASM_ENABLE_SHARED_MEMORY != 0 + if (atomic && store_insn) + set_load_or_store_atomic(store_insn); +#else + (void)store_insn; +#endif return true; fail: @@ -774,10 +845,153 @@ fail: #endif #if WASM_ENABLE_SHARED_MEMORY != 0 +#define GEN_AT_RMW_INSN(op, op_type, bytes, result, value, memory_data, \ + offset1) \ + do { \ + switch (bytes) { \ + case 1: \ + { \ + insn = GEN_INSN(AT_##op##U8, result, value, memory_data, \ + offset1); \ + break; \ + } \ + case 2: \ + { \ + insn = GEN_INSN(AT_##op##U16, result, value, memory_data, \ + offset1); \ + break; \ + } \ + case 4: \ + { \ + if (op_type == VALUE_TYPE_I32) \ + insn = GEN_INSN(AT_##op##I32, result, value, memory_data, \ + offset1); \ + else \ + insn = GEN_INSN(AT_##op##U32, result, value, memory_data, \ + offset1); \ + break; \ + } \ + case 8: \ + { \ + insn = GEN_INSN(AT_##op##I64, result, value, memory_data, \ + offset1); \ + break; \ + } \ + default: \ + { \ + bh_assert(0); \ + goto fail; \ + } \ + } \ + } while (0) + bool jit_compile_op_atomic_rmw(JitCompContext *cc, uint8 atomic_op, uint8 op_type, uint32 align, uint32 offset, uint32 bytes) { + JitReg addr, offset1, memory_data, value, result, eax_hreg, rax_hreg, + ebx_hreg, rbx_hreg; + JitInsn *insn = NULL; + bool is_i32 = op_type == VALUE_TYPE_I32; + bool is_logical_op = atomic_op == AtomicRMWBinOpAnd + || atomic_op == AtomicRMWBinOpOr + || atomic_op == AtomicRMWBinOpXor; + + /* currently we only implement atomic rmw on x86-64 target */ +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) + + /* For atomic logical binary ops, it implicitly uses rax in cmpxchg + * instruction and implicitly uses rbx for storing temp value in the + * generated loop */ + eax_hreg = jit_codegen_get_hreg_by_name("eax"); + rax_hreg = jit_codegen_get_hreg_by_name("rax"); + ebx_hreg = jit_codegen_get_hreg_by_name("ebx"); + rbx_hreg = jit_codegen_get_hreg_by_name("rbx"); + + bh_assert(op_type == VALUE_TYPE_I32 || op_type == VALUE_TYPE_I64); + if (op_type == VALUE_TYPE_I32) { + POP_I32(value); + } + else { + POP_I64(value); + } + POP_I32(addr); + + offset1 = check_and_seek(cc, addr, offset, bytes); + if (!offset1) { + goto fail; + } + CHECK_ALIGNMENT(offset1); + + memory_data = get_memory_data_reg(cc->jit_frame, 0); + + if (op_type == VALUE_TYPE_I32) + result = jit_cc_new_reg_I32(cc); + else + result = jit_cc_new_reg_I64(cc); + + switch (atomic_op) { + case AtomicRMWBinOpAdd: + { + GEN_AT_RMW_INSN(ADD, op_type, bytes, result, value, memory_data, + offset1); + break; + } + case AtomicRMWBinOpSub: + { + GEN_AT_RMW_INSN(SUB, op_type, bytes, result, value, memory_data, + offset1); + break; + } + case AtomicRMWBinOpAnd: + { + GEN_AT_RMW_INSN(AND, op_type, bytes, result, value, memory_data, + offset1); + break; + } + case AtomicRMWBinOpOr: + { + GEN_AT_RMW_INSN(OR, op_type, bytes, result, value, memory_data, + offset1); + break; + } + case AtomicRMWBinOpXor: + { + GEN_AT_RMW_INSN(XOR, op_type, bytes, result, value, memory_data, + offset1); + break; + } + case AtomicRMWBinOpXchg: + { + GEN_AT_RMW_INSN(XCHG, op_type, bytes, result, value, memory_data, + offset1); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + if (is_logical_op + && (!insn + || !jit_lock_reg_in_insn(cc, insn, is_i32 ? eax_hreg : rax_hreg) + || !jit_lock_reg_in_insn(cc, insn, is_i32 ? ebx_hreg : rbx_hreg))) { + jit_set_last_error( + cc, "generate atomic logical insn or lock ra&rb hreg failed"); + goto fail; + } + + if (op_type == VALUE_TYPE_I32) + PUSH_I32(result); + else + PUSH_I64(result); + + return true; +#endif /* defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) */ + +fail: return false; } @@ -785,6 +999,93 @@ bool jit_compile_op_atomic_cmpxchg(JitCompContext *cc, uint8 op_type, uint32 align, uint32 offset, uint32 bytes) { + JitReg addr, offset1, memory_data, value, expect, result; + bool is_i32 = op_type == VALUE_TYPE_I32; + /* currently we only implement atomic cmpxchg on x86-64 target */ +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) + /* cmpxchg will use register al/ax/eax/rax to store parameter expected + * value, and the read result will also be stored to al/ax/eax/rax */ + JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax"); + JitReg rax_hreg = jit_codegen_get_hreg_by_name("rax"); + JitInsn *insn = NULL; + + bh_assert(op_type == VALUE_TYPE_I32 || op_type == VALUE_TYPE_I64); + if (is_i32) { + POP_I32(value); + POP_I32(expect); + result = jit_cc_new_reg_I32(cc); + } + else { + POP_I64(value); + POP_I64(expect); + result = jit_cc_new_reg_I64(cc); + } + POP_I32(addr); + + offset1 = check_and_seek(cc, addr, offset, bytes); + if (!offset1) { + goto fail; + } + CHECK_ALIGNMENT(offset1); + + memory_data = get_memory_data_reg(cc->jit_frame, 0); + + GEN_INSN(MOV, is_i32 ? eax_hreg : rax_hreg, expect); + switch (bytes) { + case 1: + { + insn = GEN_INSN(AT_CMPXCHGU8, value, is_i32 ? eax_hreg : rax_hreg, + memory_data, offset1); + break; + } + case 2: + { + insn = GEN_INSN(AT_CMPXCHGU16, value, is_i32 ? eax_hreg : rax_hreg, + memory_data, offset1); + break; + } + case 4: + { + if (op_type == VALUE_TYPE_I32) + insn = + GEN_INSN(AT_CMPXCHGI32, value, is_i32 ? eax_hreg : rax_hreg, + memory_data, offset1); + else + insn = + GEN_INSN(AT_CMPXCHGU32, value, is_i32 ? eax_hreg : rax_hreg, + memory_data, offset1); + break; + } + case 8: + { + insn = GEN_INSN(AT_CMPXCHGI64, value, is_i32 ? eax_hreg : rax_hreg, + memory_data, offset1); + break; + } + default: + { + bh_assert(0); + goto fail; + } + } + + if (!insn + || !jit_lock_reg_in_insn(cc, insn, is_i32 ? eax_hreg : rax_hreg)) { + jit_set_last_error(cc, "generate cmpxchg insn or lock ra hreg failed"); + goto fail; + } + + GEN_INSN(MOV, result, is_i32 ? eax_hreg : rax_hreg); + + if (is_i32) + PUSH_I32(result); + else + PUSH_I64(result); + + return true; +#endif /* defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) */ + +fail: return false; } @@ -812,8 +1113,10 @@ jit_compile_op_atomic_wait(JitCompContext *cc, uint8 op_type, uint32 align, JitReg offset1 = check_and_seek(cc, addr, offset, bytes); if (!offset1) goto fail; - JitReg maddr = jit_cc_new_reg_I64(cc); - CHECK_ALIGNMENT(maddr, memory_data, offset1); + CHECK_ALIGNMENT(offset1); + + JitReg maddr = jit_cc_new_reg_ptr(cc); + GEN_INSN(ADD, maddr, memory_data, offset1); // Prepare `wasm_runtime_atomic_wait` arguments JitReg res = jit_cc_new_reg_I32(cc); @@ -835,6 +1138,12 @@ jit_compile_op_atomic_wait(JitCompContext *cc, uint8 op_type, uint32 align, goto fail; PUSH_I32(res); + +#if WASM_ENABLE_THREAD_MGR != 0 + /* Insert suspend check point */ + if (!jit_check_suspend_flags(cc)) + goto fail; +#endif return true; fail: return false; @@ -854,8 +1163,10 @@ jit_compiler_op_atomic_notify(JitCompContext *cc, uint32 align, uint32 offset, JitReg offset1 = check_and_seek(cc, addr, offset, bytes); if (!offset1) goto fail; - JitReg maddr = jit_cc_new_reg_I64(cc); - CHECK_ALIGNMENT(maddr, memory_data, offset1); + CHECK_ALIGNMENT(offset1); + + JitReg maddr = jit_cc_new_reg_ptr(cc); + GEN_INSN(ADD, maddr, memory_data, offset1); // Prepare `wasm_runtime_atomic_notify` arguments JitReg res = jit_cc_new_reg_I32(cc); @@ -879,4 +1190,11 @@ jit_compiler_op_atomic_notify(JitCompContext *cc, uint32 align, uint32 offset, fail: return false; } + +bool +jit_compiler_op_atomic_fence(JitCompContext *cc) +{ + GEN_INSN(FENCE); + return true; +} #endif diff --git a/core/iwasm/fast-jit/fe/jit_emit_memory.h b/core/iwasm/fast-jit/fe/jit_emit_memory.h index bbf715f2a..6565cdc11 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_memory.h +++ b/core/iwasm/fast-jit/fe/jit_emit_memory.h @@ -80,6 +80,9 @@ jit_compile_op_atomic_wait(JitCompContext *cc, uint8 op_type, uint32 align, bool jit_compiler_op_atomic_notify(JitCompContext *cc, uint32 align, uint32 offset, uint32 bytes); + +bool +jit_compiler_op_atomic_fence(JitCompContext *cc); #endif #ifdef __cplusplus diff --git a/core/iwasm/fast-jit/jit_dump.c b/core/iwasm/fast-jit/jit_dump.c index 4dba5c3b7..d61ed5dc7 100644 --- a/core/iwasm/fast-jit/jit_dump.c +++ b/core/iwasm/fast-jit/jit_dump.c @@ -114,7 +114,10 @@ jit_dump_insn(JitCompContext *cc, JitInsn *insn) switch (insn->opcode) { #define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) \ case JIT_OP_##NAME: \ - os_printf(" %-15s", #NAME); \ + if (insn->flags_u8 & 0x1) \ + os_printf(" ATOMIC %-8s", #NAME); \ + else \ + os_printf(" %-15s", #NAME); \ jit_dump_insn_##OPND_KIND(cc, insn, OPND_NUM); \ break; #include "jit_ir.def" @@ -319,7 +322,9 @@ jit_pass_dump(JitCompContext *cc) os_printf("JIT.COMPILER.DUMP: PASS_NO=%d PREV_PASS=%s\n\n", pass_no, pass_name); + jit_dump_cc(cc); + os_printf("\n"); return true; } diff --git a/core/iwasm/fast-jit/jit_frontend.c b/core/iwasm/fast-jit/jit_frontend.c index 5ca829645..ec68ad91d 100644 --- a/core/iwasm/fast-jit/jit_frontend.c +++ b/core/iwasm/fast-jit/jit_frontend.c @@ -223,18 +223,37 @@ get_memory_data_reg(JitFrame *frame, uint32 mem_idx) { JitCompContext *cc = frame->cc; JitReg module_inst_reg = get_module_inst_reg(frame); - uint32 memory_data_offset = - (uint32)offsetof(WASMModuleInstance, global_table_data.bytes) - + (uint32)offsetof(WASMMemoryInstance, memory_data); + uint32 memory_data_offset; bh_assert(mem_idx == 0); - +#if WASM_ENABLE_SHARED_MEMORY != 0 + uint32 memories_offset = (uint32)offsetof(WASMModuleInstance, memories); + JitReg memories_addr = jit_cc_new_reg_ptr(cc); + JitReg memories_0_addr = jit_cc_new_reg_ptr(cc); + memory_data_offset = (uint32)offsetof(WASMMemoryInstance, memory_data); + if (!frame->memory_regs[mem_idx].memory_data) { + frame->memory_regs[mem_idx].memory_data = + cc->memory_regs[mem_idx].memory_data; + /* module_inst->memories */ + GEN_INSN(LDPTR, memories_addr, module_inst_reg, + NEW_CONST(I32, memories_offset)); + /* module_inst->memories[0] */ + GEN_INSN(LDPTR, memories_0_addr, memories_addr, NEW_CONST(I32, 0)); + /* memories[0]->memory_data */ + GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data, + memories_0_addr, NEW_CONST(I32, memory_data_offset)); + } +#else + memory_data_offset = + (uint32)offsetof(WASMModuleInstance, global_table_data.bytes) + + (uint32)offsetof(WASMMemoryInstance, memory_data); if (!frame->memory_regs[mem_idx].memory_data) { frame->memory_regs[mem_idx].memory_data = cc->memory_regs[mem_idx].memory_data; GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data, module_inst_reg, NEW_CONST(I32, memory_data_offset)); } +#endif return frame->memory_regs[mem_idx].memory_data; } @@ -1078,6 +1097,39 @@ read_leb(JitCompContext *cc, const uint8 *buf, const uint8 *buf_end, res = (int64)res64; \ } while (0) +#if WASM_ENABLE_SHARED_MEMORY != 0 +#define COMPILE_ATOMIC_RMW(OP, NAME) \ + case WASM_OP_ATOMIC_RMW_I32_##NAME: \ + bytes = 4; \ + op_type = VALUE_TYPE_I32; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I64_##NAME: \ + bytes = 8; \ + op_type = VALUE_TYPE_I64; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I32_##NAME##8_U: \ + bytes = 1; \ + op_type = VALUE_TYPE_I32; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I32_##NAME##16_U: \ + bytes = 2; \ + op_type = VALUE_TYPE_I32; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I64_##NAME##8_U: \ + bytes = 1; \ + op_type = VALUE_TYPE_I64; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I64_##NAME##16_U: \ + bytes = 2; \ + op_type = VALUE_TYPE_I64; \ + goto OP_ATOMIC_##OP; \ + case WASM_OP_ATOMIC_RMW_I64_##NAME##32_U: \ + bytes = 4; \ + op_type = VALUE_TYPE_I64; \ + OP_ATOMIC_##OP : bin_op = AtomicRMWBinOp##OP; \ + goto build_atomic_rmw; +#endif + static bool jit_compile_func(JitCompContext *cc) { @@ -2096,6 +2148,8 @@ jit_compile_func(JitCompContext *cc) case WASM_OP_ATOMIC_FENCE: /* Skip memory index */ frame_ip++; + if (!jit_compiler_op_atomic_fence(cc)) + return false; break; case WASM_OP_ATOMIC_I32_LOAD: bytes = 4; @@ -2192,15 +2246,12 @@ jit_compile_func(JitCompContext *cc) return false; break; - /* TODO */ - /* COMPILE_ATOMIC_RMW(Add, ADD); COMPILE_ATOMIC_RMW(Sub, SUB); COMPILE_ATOMIC_RMW(And, AND); COMPILE_ATOMIC_RMW(Or, OR); COMPILE_ATOMIC_RMW(Xor, XOR); COMPILE_ATOMIC_RMW(Xchg, XCHG); - */ build_atomic_rmw: if (!jit_compile_op_atomic_rmw(cc, bin_op, op_type, diff --git a/core/iwasm/fast-jit/jit_frontend.h b/core/iwasm/fast-jit/jit_frontend.h index fce8ecfd2..7aa460fd9 100644 --- a/core/iwasm/fast-jit/jit_frontend.h +++ b/core/iwasm/fast-jit/jit_frontend.h @@ -108,6 +108,17 @@ typedef enum FloatArithmetic { FLOAT_MAX, } FloatArithmetic; +#if WASM_ENABLE_SHARED_MEMORY != 0 +typedef enum AtomicRMWBinOp { + AtomicRMWBinOpAdd, + AtomicRMWBinOpSub, + AtomicRMWBinOpAnd, + AtomicRMWBinOpOr, + AtomicRMWBinOpXor, + AtomicRMWBinOpXchg +} AtomicRMWBinOp; +#endif + /** * Translate instructions in a function. The translated block must * end with a branch instruction whose targets are offsets relating to diff --git a/core/iwasm/fast-jit/jit_ir.c b/core/iwasm/fast-jit/jit_ir.c index db0d86ca5..68503e3f5 100644 --- a/core/iwasm/fast-jit/jit_ir.c +++ b/core/iwasm/fast-jit/jit_ir.c @@ -10,7 +10,11 @@ /** * Operand kinds of instructions. */ -enum { JIT_OPND_KIND_Reg, JIT_OPND_KIND_VReg, JIT_OPND_KIND_LookupSwitch }; +enum { + JIT_OPND_KIND_Reg, + JIT_OPND_KIND_VReg, + JIT_OPND_KIND_LookupSwitch, +}; /** * Operand kind of each instruction. @@ -45,6 +49,18 @@ static const uint8 insn_opnd_first_use[] = { jit_calloc(offsetof(JitInsn, _opnd._opnd_VReg._reg) \ + sizeof(JitReg) * (OPND_NUM)) +JitInsn * +_jit_insn_new_Reg_0(JitOpcode opc) +{ + JitInsn *insn = JIT_INSN_NEW_Reg(0); + + if (insn) { + insn->opcode = opc; + } + + return insn; +} + JitInsn * _jit_insn_new_Reg_1(JitOpcode opc, JitReg r0) { diff --git a/core/iwasm/fast-jit/jit_ir.def b/core/iwasm/fast-jit/jit_ir.def index 8a4396da5..046bea1ff 100644 --- a/core/iwasm/fast-jit/jit_ir.def +++ b/core/iwasm/fast-jit/jit_ir.def @@ -200,6 +200,50 @@ INSN(CALLBC, Reg, 4, 2) INSN(RETURNBC, Reg, 3, 0) INSN(RETURN, Reg, 1, 0) +#if WASM_ENABLE_SHARED_MEMORY != 0 +/* Atomic Memory Accesses */ +/* op1(replacement val) op2(expected val) op3(mem data) op4(offset) + * and in x86, the result is stored in register al/ax/eax/rax */ +INSN(AT_CMPXCHGU8, Reg, 4, 0) +INSN(AT_CMPXCHGU16, Reg, 4, 0) +INSN(AT_CMPXCHGI32, Reg, 4, 0) +INSN(AT_CMPXCHGU32, Reg, 4, 0) +INSN(AT_CMPXCHGI64, Reg, 4, 0) +/* rmw operations: + * op1(read value) op2(operand value) op3(mem data) op4(offset) */ +INSN(AT_ADDU8, Reg, 4, 1) +INSN(AT_ADDU16, Reg, 4, 1) +INSN(AT_ADDI32, Reg, 4, 1) +INSN(AT_ADDU32, Reg, 4, 1) +INSN(AT_ADDI64, Reg, 4, 1) +INSN(AT_SUBU8, Reg, 4, 1) +INSN(AT_SUBU16, Reg, 4, 1) +INSN(AT_SUBI32, Reg, 4, 1) +INSN(AT_SUBU32, Reg, 4, 1) +INSN(AT_SUBI64, Reg, 4, 1) +INSN(AT_ANDU8, Reg, 4, 1) +INSN(AT_ANDU16, Reg, 4, 1) +INSN(AT_ANDI32, Reg, 4, 1) +INSN(AT_ANDU32, Reg, 4, 1) +INSN(AT_ANDI64, Reg, 4, 1) +INSN(AT_ORU8, Reg, 4, 1) +INSN(AT_ORU16, Reg, 4, 1) +INSN(AT_ORI32, Reg, 4, 1) +INSN(AT_ORU32, Reg, 4, 1) +INSN(AT_ORI64, Reg, 4, 1) +INSN(AT_XORU8, Reg, 4, 1) +INSN(AT_XORU16, Reg, 4, 1) +INSN(AT_XORI32, Reg, 4, 1) +INSN(AT_XORU32, Reg, 4, 1) +INSN(AT_XORI64, Reg, 4, 1) +INSN(AT_XCHGU8, Reg, 4, 1) +INSN(AT_XCHGU16, Reg, 4, 1) +INSN(AT_XCHGI32, Reg, 4, 1) +INSN(AT_XCHGU32, Reg, 4, 1) +INSN(AT_XCHGI64, Reg, 4, 1) +INSN(FENCE, Reg, 0, 0) +#endif + #undef INSN /** diff --git a/core/iwasm/fast-jit/jit_ir.h b/core/iwasm/fast-jit/jit_ir.h index 632e8ed18..e13a41d1d 100644 --- a/core/iwasm/fast-jit/jit_ir.h +++ b/core/iwasm/fast-jit/jit_ir.h @@ -313,7 +313,8 @@ typedef struct JitInsn { /* Opcode of the instruction. */ uint16 opcode; - /* Reserved field that may be used by optimizations locally. */ + /* Reserved field that may be used by optimizations locally. + * bit_0(Least Significant Bit) is atomic flag for load/store */ uint8 flags_u8; /* The unique ID of the instruction. */ @@ -346,6 +347,9 @@ typedef enum JitOpcode { * Helper functions for creating new instructions. Don't call them * directly. Use jit_insn_new_NAME, such as jit_insn_new_MOV instead. */ + +JitInsn * +_jit_insn_new_Reg_0(JitOpcode opc); JitInsn * _jit_insn_new_Reg_1(JitOpcode opc, JitReg r0); JitInsn * @@ -368,31 +372,35 @@ _jit_insn_new_LookupSwitch_1(JitOpcode opc, JitReg value, uint32 num); * Instruction creation functions jit_insn_new_NAME, where NAME is the * name of the instruction defined in jit_ir.def. */ +#define ARG_DECL_Reg_0 +#define ARG_LIST_Reg_0 #define ARG_DECL_Reg_1 JitReg r0 -#define ARG_LIST_Reg_1 r0 +#define ARG_LIST_Reg_1 , r0 #define ARG_DECL_Reg_2 JitReg r0, JitReg r1 -#define ARG_LIST_Reg_2 r0, r1 +#define ARG_LIST_Reg_2 , r0, r1 #define ARG_DECL_Reg_3 JitReg r0, JitReg r1, JitReg r2 -#define ARG_LIST_Reg_3 r0, r1, r2 +#define ARG_LIST_Reg_3 , r0, r1, r2 #define ARG_DECL_Reg_4 JitReg r0, JitReg r1, JitReg r2, JitReg r3 -#define ARG_LIST_Reg_4 r0, r1, r2, r3 +#define ARG_LIST_Reg_4 , r0, r1, r2, r3 #define ARG_DECL_Reg_5 JitReg r0, JitReg r1, JitReg r2, JitReg r3, JitReg r4 -#define ARG_LIST_Reg_5 r0, r1, r2, r3, r4 +#define ARG_LIST_Reg_5 , r0, r1, r2, r3, r4 #define ARG_DECL_VReg_1 JitReg r0, int n -#define ARG_LIST_VReg_1 r0, n +#define ARG_LIST_VReg_1 , r0, n #define ARG_DECL_VReg_2 JitReg r0, JitReg r1, int n -#define ARG_LIST_VReg_2 r0, r1, n +#define ARG_LIST_VReg_2 , r0, r1, n #define ARG_DECL_LookupSwitch_1 JitReg value, uint32 num -#define ARG_LIST_LookupSwitch_1 value, num -#define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) \ - static inline JitInsn *jit_insn_new_##NAME( \ - ARG_DECL_##OPND_KIND##_##OPND_NUM) \ - { \ - return _jit_insn_new_##OPND_KIND##_##OPND_NUM( \ - JIT_OP_##NAME, ARG_LIST_##OPND_KIND##_##OPND_NUM); \ +#define ARG_LIST_LookupSwitch_1 , value, num +#define INSN(NAME, OPND_KIND, OPND_NUM, FIRST_USE) \ + static inline JitInsn *jit_insn_new_##NAME( \ + ARG_DECL_##OPND_KIND##_##OPND_NUM) \ + { \ + return _jit_insn_new_##OPND_KIND##_##OPND_NUM( \ + JIT_OP_##NAME ARG_LIST_##OPND_KIND##_##OPND_NUM); \ } #include "jit_ir.def" #undef INSN +#undef ARG_DECL_Reg_0 +#undef ARG_LIST_Reg_0 #undef ARG_DECL_Reg_1 #undef ARG_LIST_Reg_1 #undef ARG_DECL_Reg_2 diff --git a/core/iwasm/fast-jit/jit_regalloc.c b/core/iwasm/fast-jit/jit_regalloc.c index 5bff465fb..70ca228ac 100644 --- a/core/iwasm/fast-jit/jit_regalloc.c +++ b/core/iwasm/fast-jit/jit_regalloc.c @@ -410,6 +410,13 @@ collect_distances(RegallocContext *rc, JitBasicBlock *basic_block) JIT_FOREACH_INSN(basic_block, insn) { +#if WASM_ENABLE_SHARED_MEMORY != 0 + /* fence insn doesn't have any operand, hence, no regs involved */ + if (insn->opcode == JIT_OP_FENCE) { + continue; + } +#endif + JitRegVec regvec = jit_insn_opnd_regs(insn); unsigned i; JitReg *regp; @@ -737,6 +744,13 @@ allocate_for_basic_block(RegallocContext *rc, JitBasicBlock *basic_block, JIT_FOREACH_INSN_REVERSE(basic_block, insn) { +#if WASM_ENABLE_SHARED_MEMORY != 0 + /* fence insn doesn't have any operand, hence, no regs involved */ + if (insn->opcode == JIT_OP_FENCE) { + continue; + } +#endif + JitRegVec regvec = jit_insn_opnd_regs(insn); unsigned first_use = jit_insn_opnd_first_use(insn); unsigned i; diff --git a/tests/wamr-test-suites/test_wamr.sh b/tests/wamr-test-suites/test_wamr.sh index cf0bc970b..67868b9c9 100755 --- a/tests/wamr-test-suites/test_wamr.sh +++ b/tests/wamr-test-suites/test_wamr.sh @@ -444,14 +444,6 @@ function spec_test() if [[ ${ENABLE_MULTI_THREAD} == 1 ]]; then ARGS_FOR_SPEC_TEST+="-p " - if [[ $1 == 'fast-jit' ]]; then - echo "fast-jit doesn't support multi-thread feature yet, skip it" - return - fi - if [[ $1 == 'multi-tier-jit' ]]; then - echo "multi-tier-jit doesn't support multi-thread feature yet, skip it" - return - fi fi if [[ ${ENABLE_XIP} == 1 ]]; then From 8abb1535467b08b34e913da64e36c645c93fdea9 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Sun, 23 Apr 2023 15:33:52 +0900 Subject: [PATCH 61/61] VSCode-Extension: Download lldb built for ubuntu 20.04 (#2139) This should allow users to use the vscode extension on ubuntu 20.04. After https://github.com/bytecodealliance/wasm-micro-runtime/pull/2132 , our lldb binary for 20.04 works on ubuntu 22.04 as well. On the other hand, lldb for 22.04 has no chance to work on ubuntu 20.04. (because of glibc version requirement.) --- .../wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts index 92ac9f707..9170a75d3 100644 --- a/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts +++ b/test-tools/wamr-ide/VSCode-Extension/src/utilities/lldbUtilities.ts @@ -18,7 +18,7 @@ const LLDB_RESOURCE_DIR = 'resource/debug'; const LLDB_OS_DOWNLOAD_URL_SUFFIX_MAP: Partial< Record > = { - linux: 'x86_64-ubuntu-22.04', + linux: 'x86_64-ubuntu-20.04', darwin: 'universal-macos-latest', };