diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:53:24 +0000 |
commit | b5f8ee61a7f7e9bd291dd26b0585d03eb686c941 (patch) | |
tree | d4d31289c39fc00da064a825df13a0b98ce95b10 /fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c | |
parent | Adding upstream version 1.44.3. (diff) | |
download | netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.tar.xz netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.zip |
Adding upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c')
-rw-r--r-- | fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c | 5227 |
1 files changed, 0 insertions, 5227 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c deleted file mode 100644 index 7b8cf4779..000000000 --- a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/common/wasm_c_api.c +++ /dev/null @@ -1,5227 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ - -#include "bh_log.h" -#include "wasm_c_api_internal.h" - -#include "bh_assert.h" -#include "wasm_export.h" -#include "wasm_memory.h" -#if WASM_ENABLE_INTERP != 0 -#include "wasm_runtime.h" -#endif -#if WASM_ENABLE_AOT != 0 -#include "aot_runtime.h" -#if WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0 -#include "aot.h" -#include "aot_llvm.h" -#endif /*WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0*/ -#endif /*WASM_ENABLE_AOT != 0*/ - -#if WASM_ENABLE_WASM_CACHE != 0 -#include <openssl/sha.h> -#endif -#if WASM_ENABLE_THREAD_MGR != 0 -#include "thread_manager.h" -#endif - -/* - * Thread Model: - * - Only one wasm_engine_t in one process - * - One wasm_store_t is only accessed by one thread. wasm_store_t can't be - * shared in threads - * - wasm_module_t can be shared in threads - * - wasm_instance_t can not be shared in threads - */ - -#define ASSERT_NOT_IMPLEMENTED() bh_assert(!"not implemented") -#define UNREACHABLE() bh_assert(!"unreachable") - -typedef struct wasm_module_ex_t { - struct WASMModuleCommon *module_comm_rt; - wasm_byte_vec_t *binary; - korp_mutex lock; - uint32 ref_count; -#if WASM_ENABLE_WASM_CACHE != 0 - char hash[SHA256_DIGEST_LENGTH]; -#endif -} wasm_module_ex_t; - -#ifndef os_thread_local_attribute -typedef struct thread_local_stores { - korp_tid tid; - unsigned stores_num; -} thread_local_stores; -#endif - -static void -wasm_module_delete_internal(wasm_module_t *); - -static void -wasm_instance_delete_internal(wasm_instance_t *); - -/* temporarily put stubs here */ -static wasm_store_t * -wasm_store_copy(const wasm_store_t *src) -{ - (void)src; - LOG_WARNING("in the stub of %s", __FUNCTION__); - return NULL; -} - -wasm_module_t * -wasm_module_copy(const wasm_module_t *src) -{ - (void)src; - LOG_WARNING("in the stub of %s", __FUNCTION__); - return NULL; -} - -wasm_instance_t * -wasm_instance_copy(const wasm_instance_t *src) -{ - (void)src; - LOG_WARNING("in the stub of %s", __FUNCTION__); - return NULL; -} - -/* ---------------------------------------------------------------------- */ -static inline void * -malloc_internal(uint64 size) -{ - void *mem = NULL; - - if (size < UINT32_MAX && (mem = wasm_runtime_malloc((uint32)size))) { - memset(mem, 0, size); - } - - return mem; -} - -/* clang-format off */ -#define RETURN_OBJ(obj, obj_del_func) \ - return obj; \ -failed: \ - obj_del_func(obj); \ - return NULL; - -#define RETURN_VOID(obj, obj_del_func) \ - return; \ -failed: \ - obj_del_func(obj); \ - return; -/* clang-format on */ - -/* Vectors */ -#define INIT_VEC(vector_p, init_func, ...) \ - do { \ - if (!(vector_p = malloc_internal(sizeof(*(vector_p))))) { \ - goto failed; \ - } \ - \ - init_func(vector_p, ##__VA_ARGS__); \ - if (vector_p->size && !vector_p->data) { \ - LOG_DEBUG("%s failed", #init_func); \ - goto failed; \ - } \ - } while (false) - -#define DEINIT_VEC(vector_p, deinit_func) \ - if ((vector_p)) { \ - deinit_func(vector_p); \ - wasm_runtime_free(vector_p); \ - vector_p = NULL; \ - } - -#define WASM_DEFINE_VEC(name) \ - void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t *out) \ - { \ - wasm_##name##_vec_new_uninitialized(out, 0); \ - } \ - void wasm_##name##_vec_new_uninitialized(own wasm_##name##_vec_t *out, \ - size_t size) \ - { \ - wasm_##name##_vec_new(out, size, NULL); \ - } - -/* vectors with no ownership management of elements */ -#define WASM_DEFINE_VEC_PLAIN(name) \ - WASM_DEFINE_VEC(name) \ - void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \ - own wasm_##name##_t const data[]) \ - { \ - if (!out) { \ - return; \ - } \ - \ - memset(out, 0, sizeof(wasm_##name##_vec_t)); \ - \ - if (!size) { \ - return; \ - } \ - \ - if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t), \ - true)) { \ - LOG_DEBUG("bh_vector_init failed"); \ - goto failed; \ - } \ - \ - if (data) { \ - uint32 size_in_bytes = 0; \ - size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t)); \ - bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \ - out->num_elems = size; \ - } \ - \ - RETURN_VOID(out, wasm_##name##_vec_delete) \ - } \ - void wasm_##name##_vec_copy(wasm_##name##_vec_t *out, \ - const wasm_##name##_vec_t *src) \ - { \ - if (!src) { \ - return; \ - } \ - wasm_##name##_vec_new(out, src->size, src->data); \ - } \ - void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \ - { \ - if (v) { \ - bh_vector_destroy((Vector *)v); \ - } \ - } - -/* vectors that own their elements */ -#define WASM_DEFINE_VEC_OWN(name, elem_destroy_func) \ - WASM_DEFINE_VEC(name) \ - void wasm_##name##_vec_new(own wasm_##name##_vec_t *out, size_t size, \ - own wasm_##name##_t *const data[]) \ - { \ - if (!out) { \ - return; \ - } \ - \ - memset(out, 0, sizeof(wasm_##name##_vec_t)); \ - \ - if (!size) { \ - return; \ - } \ - \ - if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t *), \ - true)) { \ - LOG_DEBUG("bh_vector_init failed"); \ - goto failed; \ - } \ - \ - if (data) { \ - uint32 size_in_bytes = 0; \ - size_in_bytes = (uint32)(size * sizeof(wasm_##name##_t *)); \ - bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); \ - out->num_elems = size; \ - } \ - \ - RETURN_VOID(out, wasm_##name##_vec_delete) \ - } \ - void wasm_##name##_vec_copy(own wasm_##name##_vec_t *out, \ - const wasm_##name##_vec_t *src) \ - { \ - size_t i = 0; \ - \ - if (!out) { \ - return; \ - } \ - memset(out, 0, sizeof(Vector)); \ - \ - if (!src || !src->size) { \ - return; \ - } \ - \ - if (!bh_vector_init((Vector *)out, src->size, \ - sizeof(wasm_##name##_t *), true)) { \ - LOG_DEBUG("bh_vector_init failed"); \ - goto failed; \ - } \ - \ - for (i = 0; i != src->num_elems; ++i) { \ - if (!(out->data[i] = wasm_##name##_copy(src->data[i]))) { \ - LOG_DEBUG("wasm_%s_copy failed", #name); \ - goto failed; \ - } \ - } \ - out->num_elems = src->num_elems; \ - \ - RETURN_VOID(out, wasm_##name##_vec_delete) \ - } \ - void wasm_##name##_vec_delete(wasm_##name##_vec_t *v) \ - { \ - size_t i = 0; \ - if (!v) { \ - return; \ - } \ - for (i = 0; i != v->num_elems && v->data; ++i) { \ - elem_destroy_func(*(v->data + i)); \ - } \ - bh_vector_destroy((Vector *)v); \ - } - -WASM_DEFINE_VEC_PLAIN(byte) -WASM_DEFINE_VEC_PLAIN(val) - -WASM_DEFINE_VEC_OWN(exporttype, wasm_exporttype_delete) -WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete) -WASM_DEFINE_VEC_OWN(frame, wasm_frame_delete) -WASM_DEFINE_VEC_OWN(functype, wasm_functype_delete) -WASM_DEFINE_VEC_OWN(importtype, wasm_importtype_delete) -WASM_DEFINE_VEC_OWN(instance, wasm_instance_delete_internal) -WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal) -WASM_DEFINE_VEC_OWN(store, wasm_store_delete) -WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete) - -#ifndef NDEBUG -#if WASM_ENABLE_MEMORY_PROFILING != 0 -#define WASM_C_DUMP_PROC_MEM() LOG_PROC_MEM() -#else -#define WASM_C_DUMP_PROC_MEM() (void)0 -#endif -#else -#define WASM_C_DUMP_PROC_MEM() (void)0 -#endif - -/* Runtime Environment */ -own wasm_config_t * -wasm_config_new(void) -{ - return NULL; -} - -void -wasm_config_delete(own wasm_config_t *config) -{ - (void)config; -} - -static void -wasm_engine_delete_internal(wasm_engine_t *engine) -{ - if (engine) { - /* clean all created wasm_module_t and their locks */ - unsigned i; - - for (i = 0; i < engine->modules.num_elems; i++) { - wasm_module_ex_t *module; - if (bh_vector_get(&engine->modules, i, &module)) { - os_mutex_destroy(&module->lock); - wasm_runtime_free(module); - } - } - - bh_vector_destroy(&engine->modules); - -#ifndef os_thread_local_attribute - bh_vector_destroy(&engine->stores_by_tid); -#endif - - wasm_runtime_free(engine); - } - - wasm_runtime_destroy(); -} - -static wasm_engine_t * -wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) -{ - wasm_engine_t *engine = NULL; - /* init runtime */ - RuntimeInitArgs init_args = { 0 }; - init_args.mem_alloc_type = type; - -#ifndef NDEBUG - bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE); -#else - bh_log_set_verbose_level(BH_LOG_LEVEL_WARNING); -#endif - - WASM_C_DUMP_PROC_MEM(); - - if (type == Alloc_With_Pool) { - if (!opts) { - return NULL; - } - - init_args.mem_alloc_option.pool.heap_buf = opts->pool.heap_buf; - init_args.mem_alloc_option.pool.heap_size = opts->pool.heap_size; - } - else if (type == Alloc_With_Allocator) { - if (!opts) { - return NULL; - } - - init_args.mem_alloc_option.allocator.malloc_func = - opts->allocator.malloc_func; - init_args.mem_alloc_option.allocator.free_func = - opts->allocator.free_func; - init_args.mem_alloc_option.allocator.realloc_func = - opts->allocator.realloc_func; -#if WASM_MEM_ALLOC_WITH_USER_DATA != 0 - init_args.mem_alloc_option.allocator.user_data = - opts->allocator.user_data; -#endif - } - else { - init_args.mem_alloc_option.pool.heap_buf = NULL; - init_args.mem_alloc_option.pool.heap_size = 0; - } - - if (!wasm_runtime_full_init(&init_args)) { - LOG_DEBUG("wasm_runtime_full_init failed"); - goto failed; - } - - /* create wasm_engine_t */ - if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) { - goto failed; - } - - if (!bh_vector_init(&engine->modules, DEFAULT_VECTOR_INIT_SIZE, - sizeof(wasm_module_ex_t *), true)) - goto failed; - -#ifndef os_thread_local_attribute - if (!bh_vector_init(&engine->stores_by_tid, DEFAULT_VECTOR_INIT_SIZE, - sizeof(thread_local_stores), true)) - goto failed; -#endif - - engine->ref_count = 1; - - WASM_C_DUMP_PROC_MEM(); - - RETURN_OBJ(engine, wasm_engine_delete_internal) -} - -/* global engine instance */ -static wasm_engine_t *singleton_engine; -#ifdef os_thread_local_attribute -/* categorize wasm_store_t as threads*/ -static os_thread_local_attribute unsigned thread_local_stores_num = 0; -#endif -#if defined(OS_THREAD_MUTEX_INITIALIZER) -/** - * lock for the singleton_engine - * Note: if the platform has mutex initializer, we use a global lock to - * lock the operations of the singleton_engine, otherwise when there are - * operations happening simultaneously in multiple threads, developer - * must create the lock by himself, and use it to lock the operations - */ -static korp_mutex engine_lock = OS_THREAD_MUTEX_INITIALIZER; -#endif - -own wasm_engine_t * -wasm_engine_new_with_args(mem_alloc_type_t type, const MemAllocOption *opts) -{ -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_lock(&engine_lock); -#endif - - if (!singleton_engine) - singleton_engine = wasm_engine_new_internal(type, opts); - else - singleton_engine->ref_count++; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif - - return singleton_engine; -} - -own wasm_engine_t * -wasm_engine_new() -{ - return wasm_engine_new_with_args(Alloc_With_System_Allocator, NULL); -} - -own wasm_engine_t * -wasm_engine_new_with_config(own wasm_config_t *config) -{ - (void)config; - return wasm_engine_new_with_args(Alloc_With_System_Allocator, NULL); -} - -void -wasm_engine_delete(wasm_engine_t *engine) -{ - if (!engine) - return; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_lock(&engine_lock); -#endif - - if (!singleton_engine) { -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif - return; - } - - bh_assert(engine == singleton_engine); - bh_assert(singleton_engine->ref_count > 0); - - singleton_engine->ref_count--; - if (singleton_engine->ref_count == 0) { - wasm_engine_delete_internal(engine); - singleton_engine = NULL; - } - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif -} - -#ifndef os_thread_local_attribute -static bool -search_thread_local_store_num(Vector *stores_by_tid, korp_tid tid, - thread_local_stores *out_ts, unsigned *out_i) -{ - unsigned i; - - for (i = 0; i < stores_by_tid->num_elems; i++) { - bool ret = bh_vector_get(stores_by_tid, i, out_ts); - bh_assert(ret); - (void)ret; - - if (out_ts->tid == tid) { - *out_i = i; - return true; - } - } - - return false; -} -#endif - -static unsigned -retrive_thread_local_store_num(Vector *stores_by_tid, korp_tid tid) -{ -#ifndef os_thread_local_attribute - unsigned i = 0; - thread_local_stores ts = { 0 }; - unsigned ret = 0; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_lock(&engine_lock); -#endif - - if (search_thread_local_store_num(stores_by_tid, tid, &ts, &i)) - ret = ts.stores_num; - else - ret = 0; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif - - return ret; -#else - (void)stores_by_tid; - (void)tid; - - return thread_local_stores_num; -#endif -} - -static bool -increase_thread_local_store_num(Vector *stores_by_tid, korp_tid tid) -{ -#ifndef os_thread_local_attribute - unsigned i = 0; - thread_local_stores ts = { 0 }; - bool ret = false; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_lock(&engine_lock); -#endif - - if (search_thread_local_store_num(stores_by_tid, tid, &ts, &i)) { - /* just in case if integer overflow */ - if (ts.stores_num + 1 < ts.stores_num) { - ret = false; - } - else { - ts.stores_num++; - ret = bh_vector_set(stores_by_tid, i, &ts); - bh_assert(ret); - } - } - else { - ts.tid = tid; - ts.stores_num = 1; - ret = bh_vector_append(stores_by_tid, &ts); - } - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif - return ret; -#else - (void)stores_by_tid; - (void)tid; - - /* just in case if integer overflow */ - if (thread_local_stores_num + 1 < thread_local_stores_num) - return false; - - thread_local_stores_num++; - return true; -#endif -} - -static bool -decrease_thread_local_store_num(Vector *stores_by_tid, korp_tid tid) -{ -#ifndef os_thread_local_attribute - unsigned i = 0; - thread_local_stores ts = { 0 }; - bool ret = false; - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_lock(&engine_lock); -#endif - - ret = search_thread_local_store_num(stores_by_tid, tid, &ts, &i); - bh_assert(ret); - - /* just in case if integer overflow */ - if (ts.stores_num - 1 > ts.stores_num) { - ret = false; - } - else { - ts.stores_num--; - ret = bh_vector_set(stores_by_tid, i, &ts); - bh_assert(ret); - } - -#if defined(OS_THREAD_MUTEX_INITIALIZER) - os_mutex_unlock(&engine_lock); -#endif - - return ret; -#else - (void)stores_by_tid; - (void)tid; - - /* just in case if integer overflow */ - if (thread_local_stores_num - 1 > thread_local_stores_num) - return false; - - thread_local_stores_num--; - return true; -#endif -} - -wasm_store_t * -wasm_store_new(wasm_engine_t *engine) -{ - wasm_store_t *store = NULL; - - WASM_C_DUMP_PROC_MEM(); - - if (!engine || singleton_engine != engine) - return NULL; - - if (!retrive_thread_local_store_num(&engine->stores_by_tid, - os_self_thread())) { - if (!wasm_runtime_init_thread_env()) { - LOG_ERROR("init thread environment failed"); - return NULL; - } - - if (!increase_thread_local_store_num(&engine->stores_by_tid, - os_self_thread())) { - wasm_runtime_destroy_thread_env(); - return NULL; - } - - if (!(store = malloc_internal(sizeof(wasm_store_t)))) { - decrease_thread_local_store_num(&singleton_engine->stores_by_tid, - os_self_thread()); - wasm_runtime_destroy_thread_env(); - return NULL; - } - } - else { - if (!increase_thread_local_store_num(&engine->stores_by_tid, - os_self_thread())) - return NULL; - - if (!(store = malloc_internal(sizeof(wasm_store_t)))) { - decrease_thread_local_store_num(&singleton_engine->stores_by_tid, - os_self_thread()); - return NULL; - } - } - - /* new a vector, and new its data */ - INIT_VEC(store->modules, wasm_module_vec_new_uninitialized, - DEFAULT_VECTOR_INIT_LENGTH); - INIT_VEC(store->instances, wasm_instance_vec_new_uninitialized, - DEFAULT_VECTOR_INIT_LENGTH); - - if (!(store->foreigns = malloc_internal(sizeof(Vector))) - || !(bh_vector_init(store->foreigns, 24, sizeof(wasm_foreign_t *), - true))) { - goto failed; - } - - WASM_C_DUMP_PROC_MEM(); - - return store; -failed: - wasm_store_delete(store); - return NULL; -} - -void -wasm_store_delete(wasm_store_t *store) -{ - if (!store) { - return; - } - - 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); - } - - wasm_runtime_free(store); - - if (decrease_thread_local_store_num(&singleton_engine->stores_by_tid, - os_self_thread())) { - if (!retrive_thread_local_store_num(&singleton_engine->stores_by_tid, - os_self_thread())) { - wasm_runtime_destroy_thread_env(); - } - } -} - -/* Type Representations */ -static inline wasm_valkind_t -val_type_rt_2_valkind(uint8 val_type_rt) -{ - switch (val_type_rt) { -#define WAMR_VAL_TYPE_2_WASM_VAL_KIND(name) \ - case VALUE_TYPE_##name: \ - return WASM_##name; - - WAMR_VAL_TYPE_2_WASM_VAL_KIND(I32) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(I64) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(F32) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(F64) - WAMR_VAL_TYPE_2_WASM_VAL_KIND(FUNCREF) -#undef WAMR_VAL_TYPE_2_WASM_VAL_KIND - - default: - return WASM_ANYREF; - } -} - -static wasm_valtype_t * -wasm_valtype_new_internal(uint8 val_type_rt) -{ - return wasm_valtype_new(val_type_rt_2_valkind(val_type_rt)); -} - -wasm_valtype_t * -wasm_valtype_new(wasm_valkind_t kind) -{ - wasm_valtype_t *val_type; - - if (kind > WASM_F64 && WASM_FUNCREF != kind -#if WASM_ENABLE_REF_TYPES != 0 - && WASM_ANYREF != kind -#endif - ) { - return NULL; - } - - if (!(val_type = malloc_internal(sizeof(wasm_valtype_t)))) { - return NULL; - } - - val_type->kind = kind; - - return val_type; -} - -void -wasm_valtype_delete(wasm_valtype_t *val_type) -{ - if (val_type) { - wasm_runtime_free(val_type); - } -} - -wasm_valtype_t * -wasm_valtype_copy(const wasm_valtype_t *src) -{ - return src ? wasm_valtype_new(src->kind) : NULL; -} - -wasm_valkind_t -wasm_valtype_kind(const wasm_valtype_t *val_type) -{ - return val_type ? val_type->kind : WASM_ANYREF; -} - -static wasm_functype_t * -wasm_functype_new_internal(WASMType *type_rt) -{ - wasm_functype_t *type = NULL; - wasm_valtype_t *param_type = NULL, *result_type = NULL; - uint32 i = 0; - - if (!type_rt) { - return NULL; - } - - if (!(type = malloc_internal(sizeof(wasm_functype_t)))) { - return NULL; - } - - type->extern_kind = WASM_EXTERN_FUNC; - - /* WASMType->types[0 : type_rt->param_count) -> type->params */ - INIT_VEC(type->params, wasm_valtype_vec_new_uninitialized, - type_rt->param_count); - for (i = 0; i < type_rt->param_count; ++i) { - if (!(param_type = wasm_valtype_new_internal(*(type_rt->types + i)))) { - goto failed; - } - - if (!bh_vector_append((Vector *)type->params, ¶m_type)) { - LOG_DEBUG("bh_vector_append failed"); - goto failed; - } - } - - /* WASMType->types[type_rt->param_count : type_rt->result_count) -> - * type->results */ - INIT_VEC(type->results, wasm_valtype_vec_new_uninitialized, - type_rt->result_count); - for (i = 0; i < type_rt->result_count; ++i) { - if (!(result_type = wasm_valtype_new_internal( - *(type_rt->types + type_rt->param_count + i)))) { - goto failed; - } - - if (!bh_vector_append((Vector *)type->results, &result_type)) { - LOG_DEBUG("bh_vector_append failed"); - goto failed; - } - } - - return type; - -failed: - wasm_valtype_delete(param_type); - wasm_valtype_delete(result_type); - wasm_functype_delete(type); - return NULL; -} - -wasm_functype_t * -wasm_functype_new(own wasm_valtype_vec_t *params, - own wasm_valtype_vec_t *results) -{ - wasm_functype_t *type = NULL; - - if (!(type = malloc_internal(sizeof(wasm_functype_t)))) { - goto failed; - } - - type->extern_kind = WASM_EXTERN_FUNC; - - /* take ownership */ - if (!(type->params = malloc_internal(sizeof(wasm_valtype_vec_t)))) { - goto failed; - } - if (params) { - bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params, - sizeof(wasm_valtype_vec_t)); - } - - if (!(type->results = malloc_internal(sizeof(wasm_valtype_vec_t)))) { - goto failed; - } - if (results) { - bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results, - sizeof(wasm_valtype_vec_t)); - } - - return type; - -failed: - wasm_functype_delete(type); - return NULL; -} - -wasm_functype_t * -wasm_functype_copy(const wasm_functype_t *src) -{ - wasm_functype_t *functype; - wasm_valtype_vec_t params = { 0 }, results = { 0 }; - - if (!src) { - return NULL; - } - - wasm_valtype_vec_copy(¶ms, src->params); - if (src->params->size && !params.data) { - goto failed; - } - - wasm_valtype_vec_copy(&results, src->results); - if (src->results->size && !results.data) { - goto failed; - } - - if (!(functype = wasm_functype_new(¶ms, &results))) { - goto failed; - } - - return functype; - -failed: - wasm_valtype_vec_delete(¶ms); - wasm_valtype_vec_delete(&results); - return NULL; -} - -void -wasm_functype_delete(wasm_functype_t *func_type) -{ - if (!func_type) { - return; - } - - DEINIT_VEC(func_type->params, wasm_valtype_vec_delete); - DEINIT_VEC(func_type->results, wasm_valtype_vec_delete); - - wasm_runtime_free(func_type); -} - -const wasm_valtype_vec_t * -wasm_functype_params(const wasm_functype_t *func_type) -{ - if (!func_type) { - return NULL; - } - - return func_type->params; -} - -const wasm_valtype_vec_t * -wasm_functype_results(const wasm_functype_t *func_type) -{ - if (!func_type) { - return NULL; - } - - return func_type->results; -} - -static bool -cmp_val_kind_with_val_type(wasm_valkind_t v_k, uint8 v_t) -{ - return (v_k == WASM_I32 && v_t == VALUE_TYPE_I32) - || (v_k == WASM_I64 && v_t == VALUE_TYPE_I64) - || (v_k == WASM_F32 && v_t == VALUE_TYPE_F32) - || (v_k == WASM_F64 && v_t == VALUE_TYPE_F64) - || (v_k == WASM_ANYREF && v_t == VALUE_TYPE_EXTERNREF) - || (v_k == WASM_FUNCREF && v_t == VALUE_TYPE_FUNCREF); -} - -/* - *to compare a function type of wasm-c-api with a function type of wasm_runtime - */ -static bool -wasm_functype_same_internal(const wasm_functype_t *type, - const WASMType *type_intl) -{ - uint32 i = 0; - - if (!type || !type_intl || type->params->num_elems != type_intl->param_count - || type->results->num_elems != type_intl->result_count) - return false; - - for (i = 0; i < type->params->num_elems; i++) { - wasm_valtype_t *v_t = type->params->data[i]; - if (!cmp_val_kind_with_val_type(wasm_valtype_kind(v_t), - type_intl->types[i])) - return false; - } - - for (i = 0; i < type->results->num_elems; i++) { - wasm_valtype_t *v_t = type->results->data[i]; - if (!cmp_val_kind_with_val_type( - wasm_valtype_kind(v_t), - type_intl->types[i + type->params->num_elems])) - return false; - } - - return true; -} - -wasm_globaltype_t * -wasm_globaltype_new(own wasm_valtype_t *val_type, wasm_mutability_t mut) -{ - wasm_globaltype_t *global_type = NULL; - - if (!val_type) { - return NULL; - } - - if (!(global_type = malloc_internal(sizeof(wasm_globaltype_t)))) { - return NULL; - } - - global_type->extern_kind = WASM_EXTERN_GLOBAL; - global_type->val_type = val_type; - global_type->mutability = mut; - - return global_type; -} - -wasm_globaltype_t * -wasm_globaltype_new_internal(uint8 val_type_rt, bool is_mutable) -{ - wasm_globaltype_t *globaltype; - wasm_valtype_t *val_type; - - if (!(val_type = wasm_valtype_new(val_type_rt_2_valkind(val_type_rt)))) { - return NULL; - } - - if (!(globaltype = wasm_globaltype_new( - val_type, is_mutable ? WASM_VAR : WASM_CONST))) { - wasm_valtype_delete(val_type); - } - - return globaltype; -} - -void -wasm_globaltype_delete(wasm_globaltype_t *global_type) -{ - if (!global_type) { - return; - } - - if (global_type->val_type) { - wasm_valtype_delete(global_type->val_type); - global_type->val_type = NULL; - } - - wasm_runtime_free(global_type); -} - -wasm_globaltype_t * -wasm_globaltype_copy(const wasm_globaltype_t *src) -{ - wasm_globaltype_t *global_type; - wasm_valtype_t *val_type; - - if (!src) { - return NULL; - } - - if (!(val_type = wasm_valtype_copy(src->val_type))) { - return NULL; - } - - if (!(global_type = wasm_globaltype_new(val_type, src->mutability))) { - wasm_valtype_delete(val_type); - } - - return global_type; -} - -const wasm_valtype_t * -wasm_globaltype_content(const wasm_globaltype_t *global_type) -{ - if (!global_type) { - return NULL; - } - - return global_type->val_type; -} - -wasm_mutability_t -wasm_globaltype_mutability(const wasm_globaltype_t *global_type) -{ - if (!global_type) { - return false; - } - - return global_type->mutability; -} - -static wasm_tabletype_t * -wasm_tabletype_new_internal(uint8 val_type_rt, uint32 init_size, - uint32 max_size) -{ - wasm_tabletype_t *table_type; - wasm_limits_t limits = { init_size, max_size }; - wasm_valtype_t *val_type; - - if (!(val_type = wasm_valtype_new_internal(val_type_rt))) { - return NULL; - } - - if (!(table_type = wasm_tabletype_new(val_type, &limits))) { - wasm_valtype_delete(val_type); - } - - return table_type; -} - -wasm_tabletype_t * -wasm_tabletype_new(own wasm_valtype_t *val_type, const wasm_limits_t *limits) -{ - wasm_tabletype_t *table_type = NULL; - - if (!val_type || !limits) { - return NULL; - } - - if (wasm_valtype_kind(val_type) != WASM_FUNCREF -#if WASM_ENABLE_REF_TYPES != 0 - && wasm_valtype_kind(val_type) != WASM_ANYREF -#endif - ) { - return NULL; - } - - if (!(table_type = malloc_internal(sizeof(wasm_tabletype_t)))) { - return NULL; - } - - table_type->extern_kind = WASM_EXTERN_TABLE; - table_type->val_type = val_type; - table_type->limits.min = limits->min; - table_type->limits.max = limits->max; - - return table_type; -} - -wasm_tabletype_t * -wasm_tabletype_copy(const wasm_tabletype_t *src) -{ - wasm_tabletype_t *table_type; - wasm_valtype_t *val_type; - - if (!src) { - return NULL; - } - - if (!(val_type = wasm_valtype_copy(src->val_type))) { - return NULL; - } - - if (!(table_type = wasm_tabletype_new(val_type, &src->limits))) { - wasm_valtype_delete(val_type); - } - - return table_type; -} - -void -wasm_tabletype_delete(wasm_tabletype_t *table_type) -{ - if (!table_type) { - return; - } - - if (table_type->val_type) { - wasm_valtype_delete(table_type->val_type); - table_type->val_type = NULL; - } - - wasm_runtime_free(table_type); -} - -const wasm_valtype_t * -wasm_tabletype_element(const wasm_tabletype_t *table_type) -{ - if (!table_type) { - return NULL; - } - - return table_type->val_type; -} - -const wasm_limits_t * -wasm_tabletype_limits(const wasm_tabletype_t *table_type) -{ - if (!table_type) { - return NULL; - } - - return &(table_type->limits); -} - -static wasm_memorytype_t * -wasm_memorytype_new_internal(uint32 min_pages, uint32 max_pages) -{ - wasm_limits_t limits = { min_pages, max_pages }; - return wasm_memorytype_new(&limits); -} - -wasm_memorytype_t * -wasm_memorytype_new(const wasm_limits_t *limits) -{ - wasm_memorytype_t *memory_type = NULL; - - if (!limits) { - return NULL; - } - - if (!(memory_type = malloc_internal(sizeof(wasm_memorytype_t)))) { - return NULL; - } - - memory_type->extern_kind = WASM_EXTERN_MEMORY; - memory_type->limits.min = limits->min; - memory_type->limits.max = limits->max; - - return memory_type; -} - -wasm_memorytype_t * -wasm_memorytype_copy(const wasm_memorytype_t *src) -{ - if (!src) { - return NULL; - } - - return wasm_memorytype_new(&src->limits); -} - -void -wasm_memorytype_delete(wasm_memorytype_t *memory_type) -{ - if (memory_type) { - wasm_runtime_free(memory_type); - } -} - -const wasm_limits_t * -wasm_memorytype_limits(const wasm_memorytype_t *memory_type) -{ - if (!memory_type) { - return NULL; - } - - return &(memory_type->limits); -} - -wasm_externkind_t -wasm_externtype_kind(const wasm_externtype_t *extern_type) -{ - if (!extern_type) { - return WASM_EXTERN_FUNC; - } - - return extern_type->extern_kind; -} - -#define BASIC_FOUR_TYPE_LIST(V) \ - V(functype) \ - V(globaltype) \ - V(memorytype) \ - V(tabletype) - -#define WASM_EXTERNTYPE_AS_OTHERTYPE(name) \ - wasm_##name##_t *wasm_externtype_as_##name(wasm_externtype_t *extern_type) \ - { \ - return (wasm_##name##_t *)extern_type; \ - } - -BASIC_FOUR_TYPE_LIST(WASM_EXTERNTYPE_AS_OTHERTYPE) -#undef WASM_EXTERNTYPE_AS_OTHERTYPE - -#define WASM_OTHERTYPE_AS_EXTERNTYPE(name) \ - wasm_externtype_t *wasm_##name##_as_externtype(wasm_##name##_t *other) \ - { \ - return (wasm_externtype_t *)other; \ - } - -BASIC_FOUR_TYPE_LIST(WASM_OTHERTYPE_AS_EXTERNTYPE) -#undef WASM_OTHERTYPE_AS_EXTERNTYPE - -#define WASM_EXTERNTYPE_AS_OTHERTYPE_CONST(name) \ - const wasm_##name##_t *wasm_externtype_as_##name##_const( \ - const wasm_externtype_t *extern_type) \ - { \ - return (const wasm_##name##_t *)extern_type; \ - } - -BASIC_FOUR_TYPE_LIST(WASM_EXTERNTYPE_AS_OTHERTYPE_CONST) -#undef WASM_EXTERNTYPE_AS_OTHERTYPE_CONST - -#define WASM_OTHERTYPE_AS_EXTERNTYPE_CONST(name) \ - const wasm_externtype_t *wasm_##name##_as_externtype_const( \ - const wasm_##name##_t *other) \ - { \ - return (const wasm_externtype_t *)other; \ - } - -BASIC_FOUR_TYPE_LIST(WASM_OTHERTYPE_AS_EXTERNTYPE_CONST) -#undef WASM_OTHERTYPE_AS_EXTERNTYPE_CONST - -wasm_externtype_t * -wasm_externtype_copy(const wasm_externtype_t *src) -{ - wasm_externtype_t *extern_type = NULL; - - if (!src) { - return NULL; - } - - switch (src->extern_kind) { -#define COPY_EXTERNTYPE(NAME, name) \ - case WASM_EXTERN_##NAME: \ - { \ - extern_type = wasm_##name##_as_externtype( \ - wasm_##name##_copy(wasm_externtype_as_##name##_const(src))); \ - break; \ - } - COPY_EXTERNTYPE(FUNC, functype) - COPY_EXTERNTYPE(GLOBAL, globaltype) - COPY_EXTERNTYPE(MEMORY, memorytype) - COPY_EXTERNTYPE(TABLE, tabletype) -#undef COPY_EXTERNTYPE - default: - LOG_WARNING("%s meets unsupported kind %u", __FUNCTION__, - src->extern_kind); - break; - } - return extern_type; -} - -void -wasm_externtype_delete(wasm_externtype_t *extern_type) -{ - if (!extern_type) { - return; - } - - switch (wasm_externtype_kind(extern_type)) { - case WASM_EXTERN_FUNC: - wasm_functype_delete(wasm_externtype_as_functype(extern_type)); - break; - case WASM_EXTERN_GLOBAL: - wasm_globaltype_delete(wasm_externtype_as_globaltype(extern_type)); - break; - case WASM_EXTERN_MEMORY: - wasm_memorytype_delete(wasm_externtype_as_memorytype(extern_type)); - break; - case WASM_EXTERN_TABLE: - wasm_tabletype_delete(wasm_externtype_as_tabletype(extern_type)); - break; - default: - LOG_WARNING("%s meets unsupported type %u", __FUNCTION__, - wasm_externtype_kind(extern_type)); - break; - } -} - -own wasm_importtype_t * -wasm_importtype_new(own wasm_byte_vec_t *module_name, - own wasm_byte_vec_t *field_name, - own wasm_externtype_t *extern_type) -{ - wasm_importtype_t *import_type = NULL; - - if (!module_name || !field_name || !extern_type) { - return NULL; - } - - if (!(import_type = malloc_internal(sizeof(wasm_importtype_t)))) { - return NULL; - } - - /* take ownership */ - if (!(import_type->module_name = - malloc_internal(sizeof(wasm_byte_vec_t)))) { - goto failed; - } - bh_memcpy_s(import_type->module_name, sizeof(wasm_byte_vec_t), module_name, - sizeof(wasm_byte_vec_t)); - - if (!(import_type->name = malloc_internal(sizeof(wasm_byte_vec_t)))) { - goto failed; - } - bh_memcpy_s(import_type->name, sizeof(wasm_byte_vec_t), field_name, - sizeof(wasm_byte_vec_t)); - - import_type->extern_type = extern_type; - - return import_type; -failed: - wasm_importtype_delete(import_type); - return NULL; -} - -void -wasm_importtype_delete(own wasm_importtype_t *import_type) -{ - if (!import_type) { - return; - } - - DEINIT_VEC(import_type->module_name, wasm_byte_vec_delete); - DEINIT_VEC(import_type->name, wasm_byte_vec_delete); - wasm_externtype_delete(import_type->extern_type); - import_type->extern_type = NULL; - wasm_runtime_free(import_type); -} - -own wasm_importtype_t * -wasm_importtype_copy(const wasm_importtype_t *src) -{ - wasm_byte_vec_t module_name = { 0 }, name = { 0 }; - wasm_externtype_t *extern_type = NULL; - wasm_importtype_t *import_type = NULL; - - if (!src) { - return NULL; - } - - wasm_byte_vec_copy(&module_name, src->module_name); - if (src->module_name->size && !module_name.data) { - goto failed; - } - - wasm_byte_vec_copy(&name, src->name); - if (src->name->size && !name.data) { - goto failed; - } - - if (!(extern_type = wasm_externtype_copy(src->extern_type))) { - goto failed; - } - - if (!(import_type = - wasm_importtype_new(&module_name, &name, extern_type))) { - goto failed; - } - - return import_type; - -failed: - wasm_byte_vec_delete(&module_name); - wasm_byte_vec_delete(&name); - wasm_externtype_delete(extern_type); - wasm_importtype_delete(import_type); - return NULL; -} - -const wasm_byte_vec_t * -wasm_importtype_module(const wasm_importtype_t *import_type) -{ - if (!import_type) { - return NULL; - } - - return import_type->module_name; -} - -const wasm_byte_vec_t * -wasm_importtype_name(const wasm_importtype_t *import_type) -{ - if (!import_type) { - return NULL; - } - - return import_type->name; -} - -const wasm_externtype_t * -wasm_importtype_type(const wasm_importtype_t *import_type) -{ - if (!import_type) { - return NULL; - } - - return import_type->extern_type; -} - -bool -wasm_importtype_is_linked(const wasm_importtype_t *import_type) -{ - if (!import_type) - return false; - - const wasm_name_t *module_name = wasm_importtype_module(import_type); - const wasm_name_t *field_name = wasm_importtype_name(import_type); - - switch (wasm_externtype_kind(wasm_importtype_type(import_type))) { - case WASM_EXTERN_FUNC: - return wasm_runtime_is_import_func_linked(module_name->data, - field_name->data); - case WASM_EXTERN_GLOBAL: - return wasm_runtime_is_import_global_linked(module_name->data, - field_name->data); - case WASM_EXTERN_MEMORY: - case WASM_EXTERN_TABLE: - default: - break; - } - return false; -} - -own wasm_exporttype_t * -wasm_exporttype_new(own wasm_byte_vec_t *name, - own wasm_externtype_t *extern_type) -{ - wasm_exporttype_t *export_type = NULL; - - if (!name || !extern_type) { - return NULL; - } - - if (!(export_type = malloc_internal(sizeof(wasm_exporttype_t)))) { - return NULL; - } - - if (!(export_type->name = malloc_internal(sizeof(wasm_byte_vec_t)))) { - wasm_exporttype_delete(export_type); - return NULL; - } - bh_memcpy_s(export_type->name, sizeof(wasm_byte_vec_t), name, - sizeof(wasm_byte_vec_t)); - - export_type->extern_type = extern_type; - - return export_type; -} - -wasm_exporttype_t * -wasm_exporttype_copy(const wasm_exporttype_t *src) -{ - wasm_exporttype_t *export_type; - wasm_byte_vec_t name = { 0 }; - wasm_externtype_t *extern_type = NULL; - - if (!src) { - return NULL; - } - - wasm_byte_vec_copy(&name, src->name); - if (src->name->size && !name.data) { - goto failed; - } - - if (!(extern_type = wasm_externtype_copy(src->extern_type))) { - goto failed; - } - - if (!(export_type = wasm_exporttype_new(&name, extern_type))) { - goto failed; - } - - return export_type; -failed: - wasm_byte_vec_delete(&name); - wasm_externtype_delete(extern_type); - return NULL; -} - -void -wasm_exporttype_delete(wasm_exporttype_t *export_type) -{ - if (!export_type) { - return; - } - - DEINIT_VEC(export_type->name, wasm_byte_vec_delete); - - wasm_externtype_delete(export_type->extern_type); - - wasm_runtime_free(export_type); -} - -const wasm_byte_vec_t * -wasm_exporttype_name(const wasm_exporttype_t *export_type) -{ - if (!export_type) { - return NULL; - } - return export_type->name; -} - -const wasm_externtype_t * -wasm_exporttype_type(const wasm_exporttype_t *export_type) -{ - if (!export_type) { - return NULL; - } - return export_type->extern_type; -} - -/* Runtime Objects */ -void -wasm_val_delete(wasm_val_t *v) -{ - if (v) - wasm_runtime_free(v); -} - -void -wasm_val_copy(wasm_val_t *out, const wasm_val_t *src) -{ - if (!out || !src) { - return; - } - - bh_memcpy_s(out, sizeof(wasm_val_t), src, sizeof(wasm_val_t)); -} - -bool -rt_val_to_wasm_val(const uint8 *data, uint8 val_type_rt, wasm_val_t *out) -{ - bool ret = true; - switch (val_type_rt) { - case VALUE_TYPE_I32: - out->kind = WASM_I32; - out->of.i32 = *((int32 *)data); - break; - case VALUE_TYPE_F32: - out->kind = WASM_F32; - out->of.f32 = *((float32 *)data); - break; - case VALUE_TYPE_I64: - out->kind = WASM_I64; - out->of.i64 = *((int64 *)data); - break; - case VALUE_TYPE_F64: - out->kind = WASM_F64; - out->of.f64 = *((float64 *)data); - break; -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - out->kind = WASM_ANYREF; - if (NULL_REF == *(uint32 *)data) { - out->of.ref = NULL; - } - else { - ret = wasm_externref_ref2obj(*(uint32 *)data, - (void **)&out->of.ref); - } - break; -#endif - default: - LOG_WARNING("unexpected value type %d", val_type_rt); - ret = false; - } - return ret; -} - -bool -wasm_val_to_rt_val(WASMModuleInstanceCommon *inst_comm_rt, uint8 val_type_rt, - const wasm_val_t *v, uint8 *data) -{ - bool ret = true; - switch (val_type_rt) { - case VALUE_TYPE_I32: - bh_assert(WASM_I32 == v->kind); - *((int32 *)data) = v->of.i32; - break; - case VALUE_TYPE_F32: - bh_assert(WASM_F32 == v->kind); - *((float32 *)data) = v->of.f32; - break; - case VALUE_TYPE_I64: - bh_assert(WASM_I64 == v->kind); - *((int64 *)data) = v->of.i64; - break; - case VALUE_TYPE_F64: - bh_assert(WASM_F64 == v->kind); - *((float64 *)data) = v->of.f64; - break; -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - bh_assert(WASM_ANYREF == v->kind); - ret = - wasm_externref_obj2ref(inst_comm_rt, v->of.ref, (uint32 *)data); - break; -#endif - default: - LOG_WARNING("unexpected value type %d", val_type_rt); - ret = false; - break; - } - - (void)inst_comm_rt; - return ret; -} - -wasm_ref_t * -wasm_ref_new_internal(wasm_store_t *store, enum wasm_reference_kind kind, - uint32 ref_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_ref_t *ref; - - if (!store) { - return NULL; - } - - if (!(ref = malloc_internal(sizeof(wasm_ref_t)))) { - return NULL; - } - - ref->store = store; - ref->kind = kind; - ref->ref_idx_rt = ref_idx_rt; - ref->inst_comm_rt = inst_comm_rt; - - /* workaround */ - if (WASM_REF_foreign == kind) { - wasm_foreign_t *foreign; - - if (!(bh_vector_get(ref->store->foreigns, ref->ref_idx_rt, &foreign)) - || !foreign) { - wasm_runtime_free(ref); - return NULL; - } - - foreign->ref_cnt++; - } - /* others doesn't include ref counters */ - - return ref; -} - -own wasm_ref_t * -wasm_ref_copy(const wasm_ref_t *src) -{ - if (!src) - return NULL; - - /* host_info are different in wasm_ref_t(s) */ - return wasm_ref_new_internal(src->store, src->kind, src->ref_idx_rt, - src->inst_comm_rt); -} - -#define DELETE_HOST_INFO(obj) \ - if (obj->host_info.info) { \ - if (obj->host_info.finalizer) { \ - obj->host_info.finalizer(obj->host_info.info); \ - } \ - } - -void -wasm_ref_delete(own wasm_ref_t *ref) -{ - if (!ref || !ref->store) - return; - - DELETE_HOST_INFO(ref); - - if (WASM_REF_foreign == ref->kind) { - wasm_foreign_t *foreign = NULL; - - if (bh_vector_get(ref->store->foreigns, ref->ref_idx_rt, &foreign) - && foreign) { - wasm_foreign_delete(foreign); - } - } - - wasm_runtime_free(ref); -} - -#define WASM_DEFINE_REF_BASE(name) \ - bool wasm_##name##_same(const wasm_##name##_t *o1, \ - const wasm_##name##_t *o2) \ - { \ - return (!o1 && !o2) ? true \ - : (!o1 || !o2) ? false \ - : (o1->kind != o2->kind) \ - ? false \ - : o1->name##_idx_rt == o2->name##_idx_rt; \ - } \ - \ - void *wasm_##name##_get_host_info(const wasm_##name##_t *obj) \ - { \ - return obj ? obj->host_info.info : NULL; \ - } \ - \ - void wasm_##name##_set_host_info(wasm_##name##_t *obj, void *host_info) \ - { \ - if (obj) { \ - obj->host_info.info = host_info; \ - obj->host_info.finalizer = NULL; \ - } \ - } \ - \ - void wasm_##name##_set_host_info_with_finalizer( \ - wasm_##name##_t *obj, void *host_info, void (*finalizer)(void *)) \ - { \ - if (obj) { \ - obj->host_info.info = host_info; \ - obj->host_info.finalizer = finalizer; \ - } \ - } - -#define WASM_DEFINE_REF(name) \ - WASM_DEFINE_REF_BASE(name) \ - \ - wasm_ref_t *wasm_##name##_as_ref(wasm_##name##_t *name) \ - { \ - if (!name) { \ - return NULL; \ - } \ - \ - return wasm_ref_new_internal(name->store, WASM_REF_##name, \ - name->name##_idx_rt, name->inst_comm_rt); \ - } \ - \ - const wasm_ref_t *wasm_##name##_as_ref_const(const wasm_##name##_t *name) \ - { \ - if (!name) { \ - return NULL; \ - } \ - \ - return wasm_ref_new_internal(name->store, WASM_REF_##name, \ - name->name##_idx_rt, name->inst_comm_rt); \ - } \ - \ - wasm_##name##_t *wasm_ref_as_##name(wasm_ref_t *ref) \ - { \ - if (!ref || WASM_REF_##name != ref->kind) { \ - return NULL; \ - } \ - \ - return wasm_##name##_new_internal(ref->store, ref->ref_idx_rt, \ - ref->inst_comm_rt); \ - } \ - \ - const wasm_##name##_t *wasm_ref_as_##name##_const(const wasm_ref_t *ref) \ - { \ - if (!ref || WASM_REF_##name != ref->kind) { \ - return NULL; \ - } \ - \ - return wasm_##name##_new_internal(ref->store, ref->ref_idx_rt, \ - ref->inst_comm_rt); \ - } - -WASM_DEFINE_REF_BASE(ref) -WASM_DEFINE_REF(foreign) -WASM_DEFINE_REF(func) -WASM_DEFINE_REF(global) -WASM_DEFINE_REF(memory) -WASM_DEFINE_REF(table) - -static wasm_frame_t * -wasm_frame_new(wasm_instance_t *instance, size_t module_offset, - uint32 func_index, size_t func_offset) -{ - wasm_frame_t *frame; - - if (!(frame = malloc_internal(sizeof(wasm_frame_t)))) { - return NULL; - } - - frame->instance = instance; - frame->module_offset = (uint32)module_offset; - frame->func_index = func_index; - frame->func_offset = (uint32)func_offset; - return frame; -} - -own wasm_frame_t * -wasm_frame_copy(const wasm_frame_t *src) -{ - if (!src) { - return NULL; - } - - return wasm_frame_new(src->instance, src->module_offset, src->func_index, - src->func_offset); -} - -void -wasm_frame_delete(own wasm_frame_t *frame) -{ - if (frame) { - wasm_runtime_free(frame); - } -} - -struct wasm_instance_t * -wasm_frame_instance(const wasm_frame_t *frame) -{ - return frame ? frame->instance : NULL; -} - -size_t -wasm_frame_module_offset(const wasm_frame_t *frame) -{ - return frame ? frame->module_offset : 0; -} - -uint32_t -wasm_frame_func_index(const wasm_frame_t *frame) -{ - return frame ? frame->func_index : 0; -} - -size_t -wasm_frame_func_offset(const wasm_frame_t *frame) -{ - return frame ? frame->func_offset : 0; -} - -static wasm_trap_t * -wasm_trap_new_internal(wasm_store_t *store, - WASMModuleInstanceCommon *inst_comm_rt, - const char *error_info) -{ - wasm_trap_t *trap; -#if WASM_ENABLE_DUMP_CALL_STACK != 0 - wasm_instance_vec_t *instances; - wasm_instance_t *frame_instance = NULL; - uint32 i; -#endif - - if (!singleton_engine) - return NULL; - - if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) { - return NULL; - } - - /* fill in message */ - if (error_info && strlen(error_info) > 0) { - if (!(trap->message = malloc_internal(sizeof(wasm_byte_vec_t)))) { - goto failed; - } - - wasm_name_new_from_string_nt(trap->message, error_info); - if (!trap->message->data) { - goto failed; - } - } - - /* fill in frames */ -#if WASM_ENABLE_DUMP_CALL_STACK != 0 - trap->frames = ((WASMModuleInstance *)inst_comm_rt)->frames; - - if (trap->frames) { - /* fill in instances */ - instances = store->instances; - bh_assert(instances != NULL); - - for (i = 0; i < instances->num_elems; i++) { - if (instances->data[i]->inst_comm_rt == inst_comm_rt) { - frame_instance = instances->data[i]; - break; - } - } - - for (i = 0; i < trap->frames->num_elems; i++) { - (((wasm_frame_t *)trap->frames->data) + i)->instance = - frame_instance; - } - } -#else - (void)store; - (void)inst_comm_rt; -#endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */ - - return trap; -failed: - wasm_trap_delete(trap); - return NULL; -} - -wasm_trap_t * -wasm_trap_new(wasm_store_t *store, const wasm_message_t *message) -{ - wasm_trap_t *trap; - - if (!store) { - return NULL; - } - - if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) { - return NULL; - } - - if (message) { - INIT_VEC(trap->message, wasm_byte_vec_new, message->size, - message->data); - } - - return trap; -failed: - wasm_trap_delete(trap); - return NULL; -} - -void -wasm_trap_delete(wasm_trap_t *trap) -{ - if (!trap) { - return; - } - - DEINIT_VEC(trap->message, wasm_byte_vec_delete); - /* reuse frames of WASMModuleInstance, do not free it here */ - - wasm_runtime_free(trap); -} - -void -wasm_trap_message(const wasm_trap_t *trap, own wasm_message_t *out) -{ - if (!trap || !out) { - return; - } - - wasm_byte_vec_copy(out, trap->message); -} - -own wasm_frame_t * -wasm_trap_origin(const wasm_trap_t *trap) -{ - wasm_frame_t *latest_frame; - - if (!trap || !trap->frames || !trap->frames->num_elems) { - return NULL; - } - - /* first frame is the latest frame */ - latest_frame = (wasm_frame_t *)trap->frames->data; - return wasm_frame_copy(latest_frame); -} - -void -wasm_trap_trace(const wasm_trap_t *trap, own wasm_frame_vec_t *out) -{ - uint32 i; - - if (!trap || !out) { - return; - } - - if (!trap->frames || !trap->frames->num_elems) { - wasm_frame_vec_new_empty(out); - return; - } - - wasm_frame_vec_new_uninitialized(out, trap->frames->num_elems); - if (out->size == 0 || !out->data) { - return; - } - - for (i = 0; i < trap->frames->num_elems; i++) { - wasm_frame_t *frame; - - frame = ((wasm_frame_t *)trap->frames->data) + i; - - if (!(out->data[i] = - wasm_frame_new(frame->instance, frame->module_offset, - frame->func_index, frame->func_offset))) { - goto failed; - } - out->num_elems++; - } - - return; -failed: - for (i = 0; i < out->num_elems; i++) { - if (out->data[i]) { - wasm_runtime_free(out->data[i]); - } - } - - wasm_runtime_free(out->data); -} - -wasm_foreign_t * -wasm_foreign_new_internal(wasm_store_t *store, uint32 foreign_idx_rt, - WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_foreign_t *foreign = NULL; - - if (!store || !store->foreigns) - return NULL; - - if (!(bh_vector_get(store->foreigns, foreign_idx_rt, &foreign)) - || !foreign) { - return NULL; - } - - foreign->ref_cnt++; - (void)inst_comm_rt; - return foreign; -} - -own wasm_foreign_t * -wasm_foreign_new(wasm_store_t *store) -{ - wasm_foreign_t *foreign; - - if (!store) - return NULL; - - if (!(foreign = malloc_internal(sizeof(wasm_foreign_t)))) - return NULL; - - foreign->store = store; - foreign->kind = WASM_REF_foreign; - foreign->foreign_idx_rt = (uint32)bh_vector_size(store->foreigns); - if (!(bh_vector_append(store->foreigns, &foreign))) { - wasm_runtime_free(foreign); - return NULL; - } - - return foreign; -} - -void -wasm_foreign_delete(wasm_foreign_t *foreign) -{ - if (!foreign) - return; - - if (foreign->ref_cnt < 1) { - return; - } - - foreign->ref_cnt--; - if (!foreign->ref_cnt) { - wasm_runtime_free(foreign); - } -} - -static inline wasm_module_t * -module_ext_to_module(wasm_module_ex_t *module_ex) -{ - return (wasm_module_t *)module_ex; -} - -static inline wasm_module_ex_t * -module_to_module_ext(wasm_module_t *module) -{ - return (wasm_module_ex_t *)module; -} - -#if WASM_ENABLE_INTERP != 0 -#define MODULE_INTERP(module_comm) ((WASMModule *)(*module_comm)) -#endif - -#if WASM_ENABLE_AOT != 0 -#define MODULE_AOT(module_comm) ((AOTModule *)(*module_comm)) -#endif - -#if WASM_ENABLE_WASM_CACHE != 0 -static wasm_module_ex_t * -check_loaded_module(Vector *modules, char *binary_hash) -{ - unsigned i; - wasm_module_ex_t *module = NULL; - - for (i = 0; i < modules->num_elems; i++) { - bh_vector_get(modules, i, &module); - if (!module) { - LOG_ERROR("Unexpected failure at %d\n", __LINE__); - return NULL; - } - - if (!module->ref_count) - /* deleted */ - continue; - - if (memcmp(module->hash, binary_hash, SHA256_DIGEST_LENGTH) == 0) - return module; - } - return NULL; -} - -static wasm_module_ex_t * -try_reuse_loaded_module(wasm_store_t *store, char *binary_hash) -{ - wasm_module_ex_t *cached = NULL; - wasm_module_ex_t *ret = NULL; - - cached = check_loaded_module(&singleton_engine->modules, binary_hash); - if (!cached) - goto quit; - - os_mutex_lock(&cached->lock); - if (!cached->ref_count) - goto unlock; - - if (!bh_vector_append((Vector *)store->modules, &cached)) - goto unlock; - - cached->ref_count += 1; - ret = cached; - -unlock: - os_mutex_unlock(&cached->lock); -quit: - return ret; -} -#endif /* WASM_ENABLE_WASM_CACHE != 0 */ - -wasm_module_t * -wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) -{ - char error_buf[128] = { 0 }; - wasm_module_ex_t *module_ex = NULL; -#if WASM_ENABLE_WASM_CACHE != 0 - char binary_hash[SHA256_DIGEST_LENGTH] = { 0 }; -#endif - - bh_assert(singleton_engine); - - if (!store || !binary || binary->size == 0 || binary->size > UINT32_MAX) - goto quit; - - /* whether the combination of compilation flags are compatable with the - * package type */ - { - PackageType pkg_type; - pkg_type = - get_package_type((uint8 *)binary->data, (uint32)binary->size); - bool result = false; -#if WASM_ENABLE_INTERP != 0 - result = (pkg_type == Wasm_Module_Bytecode); -#endif - -#if WASM_ENABLE_AOT != 0 - result = result || (pkg_type == Wasm_Module_AoT); -#endif - if (!result) { - LOG_VERBOSE("current building isn't compatiable with the module," - "may need recompile"); - goto quit; - } - } - -#if WASM_ENABLE_WASM_CACHE != 0 - /* if cached */ - SHA256((void *)binary->data, binary->num_elems, (uint8_t *)binary_hash); - module_ex = try_reuse_loaded_module(store, binary_hash); - if (module_ex) - return module_ext_to_module(module_ex); -#endif - - WASM_C_DUMP_PROC_MEM(); - - module_ex = malloc_internal(sizeof(wasm_module_ex_t)); - if (!module_ex) - goto quit; - - module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t)); - if (!module_ex->binary) - goto free_module; - - wasm_byte_vec_copy(module_ex->binary, binary); - if (!module_ex->binary->data) - goto free_binary; - - module_ex->module_comm_rt = wasm_runtime_load( - (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, - error_buf, (uint32)sizeof(error_buf)); - if (!(module_ex->module_comm_rt)) { - LOG_ERROR(error_buf); - goto free_vec; - } - - /* append it to a watching list in store */ - if (!bh_vector_append((Vector *)store->modules, &module_ex)) - goto unload; - - if (os_mutex_init(&module_ex->lock) != BHT_OK) - goto remove_last; - - if (!bh_vector_append(&singleton_engine->modules, &module_ex)) - goto destroy_lock; - -#if WASM_ENABLE_WASM_CACHE != 0 - bh_memcpy_s(module_ex->hash, sizeof(module_ex->hash), binary_hash, - sizeof(binary_hash)); -#endif - - module_ex->ref_count = 1; - - WASM_C_DUMP_PROC_MEM(); - - return module_ext_to_module(module_ex); - -destroy_lock: - os_mutex_destroy(&module_ex->lock); -remove_last: - bh_vector_remove((Vector *)store->modules, - (uint32)(store->modules->num_elems - 1), NULL); -unload: - wasm_runtime_unload(module_ex->module_comm_rt); -free_vec: - wasm_byte_vec_delete(module_ex->binary); -free_binary: - wasm_runtime_free(module_ex->binary); -free_module: - wasm_runtime_free(module_ex); -quit: - LOG_ERROR("%s failed", __FUNCTION__); - return NULL; -} - -bool -wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary) -{ - struct WASMModuleCommon *module_rt; - char error_buf[128] = { 0 }; - - bh_assert(singleton_engine); - - if (!store || !binary || binary->size > UINT32_MAX) { - LOG_ERROR("%s failed", __FUNCTION__); - return false; - } - - if ((module_rt = wasm_runtime_load((uint8 *)binary->data, - (uint32)binary->size, error_buf, 128))) { - wasm_runtime_unload(module_rt); - return true; - } - else { - LOG_VERBOSE(error_buf); - return false; - } -} - -static void -wasm_module_delete_internal(wasm_module_t *module) -{ - wasm_module_ex_t *module_ex; - - if (!module) { - return; - } - - module_ex = module_to_module_ext(module); - - os_mutex_lock(&module_ex->lock); - - /* N -> N-1 -> 0 -> UINT32_MAX */ - module_ex->ref_count--; - if (module_ex->ref_count > 0) { - os_mutex_unlock(&module_ex->lock); - return; - } - - DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete); - - if (module_ex->module_comm_rt) { - wasm_runtime_unload(module_ex->module_comm_rt); - module_ex->module_comm_rt = NULL; - } - -#if WASM_ENABLE_WASM_CACHE != 0 - memset(module_ex->hash, 0, sizeof(module_ex->hash)); -#endif - - os_mutex_unlock(&module_ex->lock); -} - -void -wasm_module_delete(wasm_module_t *module) -{ - /* the module will be released when releasing the store */ - (void)module; -} - -void -wasm_module_imports(const wasm_module_t *module, own wasm_importtype_vec_t *out) -{ - uint32 i, import_func_count = 0, import_memory_count = 0, - import_global_count = 0, import_table_count = 0, import_count = 0; - wasm_byte_vec_t module_name = { 0 }, name = { 0 }; - wasm_externtype_t *extern_type = NULL; - wasm_importtype_t *import_type = NULL; - - if (!module || !out) { - return; - } - - if (((const wasm_module_ex_t *)(module))->ref_count == 0) - return; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - import_func_count = MODULE_INTERP(module)->import_function_count; - import_global_count = MODULE_INTERP(module)->import_global_count; - import_memory_count = MODULE_INTERP(module)->import_memory_count; - import_table_count = MODULE_INTERP(module)->import_table_count; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - import_func_count = MODULE_AOT(module)->import_func_count; - import_global_count = MODULE_AOT(module)->import_global_count; - import_memory_count = MODULE_AOT(module)->import_memory_count; - import_table_count = MODULE_AOT(module)->import_table_count; - } -#endif - - import_count = import_func_count + import_global_count + import_table_count - + import_memory_count; - - wasm_importtype_vec_new_uninitialized(out, import_count); - /* - * a wrong combination of module filetype and compilation flags - * also leads to below branch - */ - if (!out->data) { - return; - } - - for (i = 0; i != import_count; ++i) { - char *module_name_rt = NULL, *field_name_rt = NULL; - - memset(&module_name, 0, sizeof(wasm_val_vec_t)); - memset(&name, 0, sizeof(wasm_val_vec_t)); - extern_type = NULL; - import_type = NULL; - - if (i < import_func_count) { - wasm_functype_t *type = NULL; - WASMType *type_rt = NULL; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - WASMImport *import = - MODULE_INTERP(module)->import_functions + i; - module_name_rt = import->u.names.module_name; - field_name_rt = import->u.names.field_name; - type_rt = import->u.function.func_type; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - AOTImportFunc *import = MODULE_AOT(module)->import_funcs + i; - module_name_rt = import->module_name; - field_name_rt = import->func_name; - type_rt = import->func_type; - } -#endif - - if (!module_name_rt || !field_name_rt || !type_rt) { - continue; - } - - if (!(type = wasm_functype_new_internal(type_rt))) { - goto failed; - } - - extern_type = wasm_functype_as_externtype(type); - } - else if (i < import_func_count + import_global_count) { - wasm_globaltype_t *type = NULL; - uint8 val_type_rt = 0; - bool mutability_rt = 0; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - WASMImport *import = MODULE_INTERP(module)->import_globals - + (i - import_func_count); - module_name_rt = import->u.names.module_name; - field_name_rt = import->u.names.field_name; - val_type_rt = import->u.global.type; - mutability_rt = import->u.global.is_mutable; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - AOTImportGlobal *import = MODULE_AOT(module)->import_globals - + (i - import_func_count); - module_name_rt = import->module_name; - field_name_rt = import->global_name; - val_type_rt = import->type; - mutability_rt = import->is_mutable; - } -#endif - - if (!module_name_rt || !field_name_rt) { - continue; - } - - if (!(type = wasm_globaltype_new_internal(val_type_rt, - mutability_rt))) { - goto failed; - } - - extern_type = wasm_globaltype_as_externtype(type); - } - else if (i < import_func_count + import_global_count - + import_memory_count) { - wasm_memorytype_t *type = NULL; - uint32 min_page = 0, max_page = 0; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - WASMImport *import = - MODULE_INTERP(module)->import_memories - + (i - import_func_count - import_global_count); - module_name_rt = import->u.names.module_name; - field_name_rt = import->u.names.field_name; - min_page = import->u.memory.init_page_count; - max_page = import->u.memory.max_page_count; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - AOTImportMemory *import = - MODULE_AOT(module)->import_memories - + (i - import_func_count - import_global_count); - module_name_rt = import->module_name; - field_name_rt = import->memory_name; - min_page = import->mem_init_page_count; - max_page = import->mem_max_page_count; - } -#endif - - if (!module_name_rt || !field_name_rt) { - continue; - } - - if (!(type = wasm_memorytype_new_internal(min_page, max_page))) { - goto failed; - } - - extern_type = wasm_memorytype_as_externtype(type); - } - else { - wasm_tabletype_t *type = NULL; - uint8 elem_type_rt = 0; - uint32 min_size = 0, max_size = 0; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - WASMImport *import = - MODULE_INTERP(module)->import_tables - + (i - import_func_count - import_global_count - - import_memory_count); - module_name_rt = import->u.names.module_name; - field_name_rt = import->u.names.field_name; - elem_type_rt = import->u.table.elem_type; - min_size = import->u.table.init_size; - max_size = import->u.table.max_size; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - AOTImportTable *import = - MODULE_AOT(module)->import_tables - + (i - import_func_count - import_global_count - - import_memory_count); - module_name_rt = import->module_name; - field_name_rt = import->table_name; - elem_type_rt = import->elem_type; - min_size = import->table_init_size; - max_size = import->table_max_size; - } -#endif - - if (!module_name_rt || !field_name_rt) { - continue; - } - - if (!(type = wasm_tabletype_new_internal(elem_type_rt, min_size, - max_size))) { - goto failed; - } - - extern_type = wasm_tabletype_as_externtype(type); - } - - bh_assert(extern_type); - - wasm_name_new_from_string_nt(&module_name, module_name_rt); - if (strlen(module_name_rt) && !module_name.data) { - goto failed; - } - - wasm_name_new_from_string_nt(&name, field_name_rt); - if (strlen(field_name_rt) && !name.data) { - goto failed; - } - - if (!(import_type = - wasm_importtype_new(&module_name, &name, extern_type))) { - goto failed; - } - - if (!bh_vector_append((Vector *)out, &import_type)) { - goto failed_importtype_new; - } - - continue; - - failed: - wasm_byte_vec_delete(&module_name); - wasm_byte_vec_delete(&name); - wasm_externtype_delete(extern_type); - failed_importtype_new: - wasm_importtype_delete(import_type); - } -} - -void -wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out) -{ - uint32 i, export_count = 0; - wasm_byte_vec_t name = { 0 }; - wasm_externtype_t *extern_type = NULL; - wasm_exporttype_t *export_type = NULL; - - if (!module || !out) { - return; - } - - if (((const wasm_module_ex_t *)(module))->ref_count == 0) - return; - -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - export_count = MODULE_INTERP(module)->export_count; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - export_count = MODULE_AOT(module)->export_count; - } -#endif - - wasm_exporttype_vec_new_uninitialized(out, export_count); - /* - * a wrong combination of module filetype and compilation flags - * also leads to below branch - */ - if (!out->data) { - return; - } - - for (i = 0; i != export_count; i++) { - WASMExport *export = NULL; -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - export = MODULE_INTERP(module)->exports + i; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - export = MODULE_AOT(module)->exports + i; - } -#endif - - if (!export) { - continue; - } - - /* byte* -> wasm_byte_vec_t */ - wasm_name_new_from_string_nt(&name, export->name); - if (strlen(export->name) && !name.data) { - goto failed; - } - - /* WASMExport -> (WASMType, (uint8, bool)) -> (wasm_functype_t, - * wasm_globaltype_t) -> wasm_externtype_t*/ - switch (export->kind) { - case EXPORT_KIND_FUNC: - { - wasm_functype_t *type = NULL; - WASMType *type_rt; - - if (!wasm_runtime_get_export_func_type(*module, export, - &type_rt)) { - goto failed; - } - - if (!(type = wasm_functype_new_internal(type_rt))) { - goto failed; - } - - extern_type = wasm_functype_as_externtype(type); - break; - } - case EXPORT_KIND_GLOBAL: - { - wasm_globaltype_t *type = NULL; - uint8 val_type_rt = 0; - bool mutability_rt = 0; - - if (!wasm_runtime_get_export_global_type( - *module, export, &val_type_rt, &mutability_rt)) { - goto failed; - } - - if (!(type = wasm_globaltype_new_internal(val_type_rt, - mutability_rt))) { - goto failed; - } - - extern_type = wasm_globaltype_as_externtype(type); - break; - } - case EXPORT_KIND_MEMORY: - { - wasm_memorytype_t *type = NULL; - uint32 min_page = 0, max_page = 0; - - if (!wasm_runtime_get_export_memory_type( - *module, export, &min_page, &max_page)) { - goto failed; - } - - if (!(type = - wasm_memorytype_new_internal(min_page, max_page))) { - goto failed; - } - - extern_type = wasm_memorytype_as_externtype(type); - break; - } - case EXPORT_KIND_TABLE: - { - wasm_tabletype_t *type = NULL; - uint8 elem_type_rt = 0; - uint32 min_size = 0, max_size = 0; - - if (!wasm_runtime_get_export_table_type( - *module, export, &elem_type_rt, &min_size, &max_size)) { - goto failed; - } - - if (!(type = wasm_tabletype_new_internal(elem_type_rt, min_size, - max_size))) { - goto failed; - } - - extern_type = wasm_tabletype_as_externtype(type); - break; - } - default: - { - LOG_WARNING("%s meets unsupported type %u", __FUNCTION__, - export->kind); - break; - } - } - - if (!(export_type = wasm_exporttype_new(&name, extern_type))) { - goto failed; - } - - if (!(bh_vector_append((Vector *)out, &export_type))) { - goto failed_exporttype_new; - } - } - - return; - -failed: - wasm_byte_vec_delete(&name); - wasm_externtype_delete(extern_type); -failed_exporttype_new: - wasm_exporttype_delete(export_type); - wasm_exporttype_vec_delete(out); -} - -#if WASM_ENABLE_JIT == 0 || WASM_ENABLE_LAZY_JIT != 0 -void -wasm_module_serialize(wasm_module_t *module, own wasm_byte_vec_t *out) -{ - (void)module; - (void)out; - LOG_ERROR("only supported serialization in JIT with eager compilation"); -} - -own wasm_module_t * -wasm_module_deserialize(wasm_store_t *module, const wasm_byte_vec_t *binary) -{ - (void)module; - (void)binary; - LOG_ERROR("only supported deserialization in JIT with eager compilation"); - return NULL; -} -#else - -extern uint8 * -aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data, - uint32 *p_aot_file_size); -void -wasm_module_serialize(wasm_module_t *module, own wasm_byte_vec_t *out) -{ - wasm_module_ex_t *module_ex; - AOTCompContext *comp_ctx; - AOTCompData *comp_data; - uint8 *aot_file_buf = NULL; - uint32 aot_file_size = 0; - - if (!module || !out) - return; - - if (((const wasm_module_ex_t *)(module))->ref_count == 0) - return; - - module_ex = module_to_module_ext(module); - comp_ctx = ((WASMModule *)(module_ex->module_comm_rt))->comp_ctx; - comp_data = ((WASMModule *)(module_ex->module_comm_rt))->comp_data; - bh_assert(comp_ctx != NULL && comp_data != NULL); - - aot_file_buf = aot_emit_aot_file_buf(comp_ctx, comp_data, &aot_file_size); - if (!aot_file_buf) - return; - - wasm_byte_vec_new(out, aot_file_size, (wasm_byte_t *)aot_file_buf); - wasm_runtime_free(aot_file_buf); - return; -} - -own wasm_module_t * -wasm_module_deserialize(wasm_store_t *store, const wasm_byte_vec_t *binary) -{ - return wasm_module_new(store, binary); -} -#endif - -wasm_module_t * -wasm_module_obtain(wasm_store_t *store, wasm_shared_module_t *shared_module) -{ - wasm_module_ex_t *module_ex = NULL; - - if (!store || !shared_module) - return NULL; - - module_ex = (wasm_module_ex_t *)shared_module; - - os_mutex_lock(&module_ex->lock); - - /* deleting the module... */ - if (module_ex->ref_count == 0) { - LOG_WARNING("wasm_module_obtain re-enter a module under deleting."); - os_mutex_unlock(&module_ex->lock); - return NULL; - } - - /* add it to a watching list in store */ - if (!bh_vector_append((Vector *)store->modules, &module_ex)) { - os_mutex_unlock(&module_ex->lock); - return NULL; - } - - module_ex->ref_count++; - os_mutex_unlock(&module_ex->lock); - - return (wasm_module_t *)shared_module; -} - -wasm_shared_module_t * -wasm_module_share(wasm_module_t *module) -{ - wasm_module_ex_t *module_ex = NULL; - - if (!module) - return NULL; - - module_ex = (wasm_module_ex_t *)module; - - os_mutex_lock(&module_ex->lock); - - /* deleting the module... */ - if (module_ex->ref_count == 0) { - LOG_WARNING("wasm_module_share re-enter a module under deleting."); - os_mutex_unlock(&module_ex->lock); - return NULL; - } - - module_ex->ref_count++; - - os_mutex_unlock(&module_ex->lock); - - return (wasm_shared_module_t *)module; -} - -void -wasm_shared_module_delete(own wasm_shared_module_t *shared_module) -{ - wasm_module_delete_internal((wasm_module_t *)shared_module); -} - -static wasm_func_t * -wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type, - wasm_func_callback_t func_callback) -{ - wasm_func_t *func = NULL; - - if (!type) { - goto failed; - } - - if (!(func = malloc_internal(sizeof(wasm_func_t)))) { - goto failed; - } - - func->store = store; - func->kind = WASM_EXTERN_FUNC; - func->func_idx_rt = (uint16)-1; - func->with_env = false; - func->u.cb = func_callback; - - if (!(func->type = wasm_functype_copy(type))) { - goto failed; - } - - RETURN_OBJ(func, wasm_func_delete) -} - -static wasm_func_t * -wasm_func_new_with_env_basic(wasm_store_t *store, const wasm_functype_t *type, - wasm_func_callback_with_env_t callback, void *env, - void (*finalizer)(void *)) -{ - wasm_func_t *func = NULL; - - if (!type) { - goto failed; - } - - if (!(func = malloc_internal(sizeof(wasm_func_t)))) { - goto failed; - } - - func->store = store; - func->kind = WASM_EXTERN_FUNC; - func->func_idx_rt = (uint16)-1; - func->with_env = true; - func->u.cb_env.cb = callback; - func->u.cb_env.env = env; - func->u.cb_env.finalizer = finalizer; - - if (!(func->type = wasm_functype_copy(type))) { - goto failed; - } - - RETURN_OBJ(func, wasm_func_delete) -} - -wasm_func_t * -wasm_func_new(wasm_store_t *store, const wasm_functype_t *type, - wasm_func_callback_t callback) -{ - bh_assert(singleton_engine); - if (!callback) { - return NULL; - } - return wasm_func_new_basic(store, type, callback); -} - -wasm_func_t * -wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *type, - wasm_func_callback_with_env_t callback, void *env, - void (*finalizer)(void *)) -{ - bh_assert(singleton_engine); - if (!callback) { - return NULL; - } - return wasm_func_new_with_env_basic(store, type, callback, env, finalizer); -} - -wasm_func_t * -wasm_func_new_internal(wasm_store_t *store, uint16 func_idx_rt, - WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_func_t *func = NULL; - WASMType *type_rt = NULL; - - bh_assert(singleton_engine); - - if (!inst_comm_rt) { - return NULL; - } - - func = malloc_internal(sizeof(wasm_func_t)); - if (!func) { - goto failed; - } - - func->kind = WASM_EXTERN_FUNC; - -#if WASM_ENABLE_INTERP != 0 - if (inst_comm_rt->module_type == Wasm_Module_Bytecode) { - bh_assert(func_idx_rt - < ((WASMModuleInstance *)inst_comm_rt)->e->function_count); - WASMFunctionInstance *func_interp = - ((WASMModuleInstance *)inst_comm_rt)->e->functions + func_idx_rt; - type_rt = func_interp->is_import_func - ? func_interp->u.func_import->func_type - : func_interp->u.func->func_type; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (inst_comm_rt->module_type == Wasm_Module_AoT) { - /* use same index to trace the function type in AOTFuncType **func_types - */ - AOTModule *module_aot = - (AOTModule *)((AOTModuleInstance *)inst_comm_rt)->module; - if (func_idx_rt < module_aot->import_func_count) { - type_rt = (module_aot->import_funcs + func_idx_rt)->func_type; - } - else { - type_rt = - module_aot->func_types[module_aot->func_type_indexes - [func_idx_rt - - module_aot->import_func_count]]; - } - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * also leads to below branch - */ - if (!type_rt) { - goto failed; - } - - func->type = wasm_functype_new_internal(type_rt); - if (!func->type) { - goto failed; - } - - /* will add name information when processing "exports" */ - func->store = store; - func->module_name = NULL; - func->name = NULL; - func->func_idx_rt = func_idx_rt; - func->inst_comm_rt = inst_comm_rt; - return func; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_func_delete(func); - return NULL; -} - -static wasm_func_t * -wasm_func_new_empty(wasm_store_t *store) -{ - wasm_func_t *func = NULL; - - if (!(func = malloc_internal(sizeof(wasm_func_t)))) - goto failed; - - func->store = store; - func->kind = WASM_EXTERN_FUNC; - - RETURN_OBJ(func, wasm_func_delete) -} - -void -wasm_func_delete(wasm_func_t *func) -{ - if (!func) { - return; - } - - if (func->type) { - wasm_functype_delete(func->type); - func->type = NULL; - } - - if (func->with_env) { - if (func->u.cb_env.finalizer) { - func->u.cb_env.finalizer(func->u.cb_env.env); - func->u.cb_env.finalizer = NULL; - func->u.cb_env.env = NULL; - } - } - - DELETE_HOST_INFO(func) - - wasm_runtime_free(func); -} - -own wasm_func_t * -wasm_func_copy(const wasm_func_t *func) -{ - wasm_func_t *cloned = NULL; - - if (!func) { - return NULL; - } - - if (!(cloned = func->with_env ? wasm_func_new_with_env_basic( - func->store, func->type, func->u.cb_env.cb, - func->u.cb_env.env, func->u.cb_env.finalizer) - : wasm_func_new_basic(func->store, func->type, - func->u.cb))) { - goto failed; - } - - cloned->func_idx_rt = func->func_idx_rt; - cloned->inst_comm_rt = func->inst_comm_rt; - - RETURN_OBJ(cloned, wasm_func_delete) -} - -own wasm_functype_t * -wasm_func_type(const wasm_func_t *func) -{ - if (!func) { - return NULL; - } - return wasm_functype_copy(func->type); -} - -static bool -params_to_argv(const wasm_val_vec_t *params, - const wasm_valtype_vec_t *param_defs, uint32 *argv, - uint32 *ptr_argc) -{ - size_t i = 0; - - if (!param_defs->num_elems) { - return true; - } - - if (!params || !params->num_elems || !params->size || !params->data) { - LOG_ERROR("the parameter params is invalid"); - return false; - } - - *ptr_argc = 0; - for (i = 0; i < param_defs->num_elems; ++i) { - const wasm_val_t *param = params->data + i; - bh_assert((*(param_defs->data + i))->kind == param->kind); - - switch (param->kind) { - case WASM_I32: - *(int32 *)argv = param->of.i32; - argv += 1; - *ptr_argc += 1; - break; - case WASM_I64: - *(int64 *)argv = param->of.i64; - argv += 2; - *ptr_argc += 2; - break; - case WASM_F32: - *(float32 *)argv = param->of.f32; - argv += 1; - *ptr_argc += 1; - break; - case WASM_F64: - *(float64 *)argv = param->of.f64; - argv += 2; - *ptr_argc += 2; - break; -#if WASM_ENABLE_REF_TYPES != 0 - case WASM_ANYREF: - *(uintptr_t *)argv = (uintptr_t)param->of.ref; - argv += sizeof(uintptr_t) / sizeof(uint32); - *ptr_argc += 1; - break; -#endif - default: - LOG_WARNING("unexpected parameter val type %d", param->kind); - return false; - } - } - - return true; -} - -static bool -argv_to_results(const uint32 *argv, const wasm_valtype_vec_t *result_defs, - wasm_val_vec_t *results) -{ - size_t i = 0, argv_i = 0; - wasm_val_t *result; - - if (!result_defs->num_elems) { - return true; - } - - if (!results || !results->size || !results->data) { - LOG_ERROR("the parameter results is invalid"); - return false; - } - - for (i = 0, result = results->data, argv_i = 0; i < result_defs->num_elems; - i++, result++) { - switch (result_defs->data[i]->kind) { - case WASM_I32: - { - result->kind = WASM_I32; - result->of.i32 = *(int32 *)(argv + argv_i); - argv_i += 1; - break; - } - case WASM_I64: - { - result->kind = WASM_I64; - result->of.i64 = *(int64 *)(argv + argv_i); - argv_i += 2; - break; - } - case WASM_F32: - { - result->kind = WASM_F32; - result->of.f32 = *(float32 *)(argv + argv_i); - argv_i += 1; - break; - } - case WASM_F64: - { - result->kind = WASM_F64; - result->of.f64 = *(float64 *)(argv + argv_i); - argv_i += 2; - break; - } -#if WASM_ENABLE_REF_TYPES != 0 - case WASM_ANYREF: - { - result->kind = WASM_ANYREF; - result->of.ref = - (struct wasm_ref_t *)(*(uintptr_t *)(argv + argv_i)); - argv_i += sizeof(uintptr_t) / sizeof(uint32); - break; - } -#endif - default: - LOG_WARNING("%s meets unsupported type: %d", __FUNCTION__, - result_defs->data[i]->kind); - return false; - } - } - - return true; -} - -wasm_trap_t * -wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params, - wasm_val_vec_t *results) -{ - /* parameters count as if all are uint32 */ - /* a int64 or float64 parameter means 2 */ - uint32 argc = 0; - /* a parameter list and a return value list */ - uint32 argv_buf[32] = { 0 }, *argv = argv_buf; - WASMFunctionInstanceCommon *func_comm_rt = NULL; - WASMExecEnv *exec_env = NULL; - size_t param_count, result_count, alloc_count; - - if (!func) { - return NULL; - } - - if (!func->inst_comm_rt) { - wasm_name_t message = { 0 }; - wasm_trap_t *trap; - - wasm_name_new_from_string_nt(&message, - "failed to call unlinked function"); - trap = wasm_trap_new(func->store, &message); - wasm_byte_vec_delete(&message); - - return trap; - } - - bh_assert(func->type); - -#if WASM_ENABLE_INTERP != 0 - if (func->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - func_comm_rt = ((WASMModuleInstance *)func->inst_comm_rt)->e->functions - + func->func_idx_rt; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (func->inst_comm_rt->module_type == Wasm_Module_AoT) { - if (!(func_comm_rt = func->func_comm_rt)) { - AOTModuleInstance *inst_aot = - (AOTModuleInstance *)func->inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->module; - uint32 export_i = 0, export_func_j = 0; - - for (; export_i < module_aot->export_count; ++export_i) { - AOTExport *export = module_aot->exports + export_i; - if (export->kind == EXPORT_KIND_FUNC) { - if (export->index == func->func_idx_rt) { - func_comm_rt = - (AOTFunctionInstance *)inst_aot->export_functions - + export_func_j; - ((wasm_func_t *)func)->func_comm_rt = func_comm_rt; - break; - } - export_func_j++; - } - } - } - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * also leads to below branch - */ - if (!func_comm_rt) { - goto failed; - } - - param_count = wasm_func_param_arity(func); - result_count = wasm_func_result_arity(func); - - alloc_count = (param_count > result_count) ? param_count : result_count; - if (alloc_count > (size_t)sizeof(argv_buf) / sizeof(uint64)) { - if (!(argv = malloc_internal(sizeof(uint64) * alloc_count))) { - goto failed; - } - } - - /* copy parametes */ - if (param_count - && !params_to_argv(params, wasm_functype_params(func->type), argv, - &argc)) { - goto failed; - } - -#ifdef OS_ENABLE_HW_BOUND_CHECK - exec_env = wasm_runtime_get_exec_env_tls(); -#endif -#if WASM_ENABLE_THREAD_MGR != 0 - if (!exec_env) { - exec_env = wasm_clusters_search_exec_env(func->inst_comm_rt); - } -#endif - if (!exec_env) { - exec_env = wasm_runtime_get_exec_env_singleton(func->inst_comm_rt); - } - if (!exec_env) { - goto failed; - } - - wasm_runtime_set_exception(func->inst_comm_rt, NULL); - if (!wasm_runtime_call_wasm(exec_env, func_comm_rt, argc, argv)) { - if (wasm_runtime_get_exception(func->inst_comm_rt)) { - LOG_DEBUG(wasm_runtime_get_exception(func->inst_comm_rt)); - goto failed; - } - } - - /* copy results */ - if (result_count) { - if (!argv_to_results(argv, wasm_functype_results(func->type), - results)) { - goto failed; - } - results->num_elems = result_count; - results->size = result_count; - } - - if (argv != argv_buf) - wasm_runtime_free(argv); - return NULL; - -failed: - if (argv != argv_buf) - wasm_runtime_free(argv); - - return wasm_trap_new_internal( - func->store, func->inst_comm_rt, - wasm_runtime_get_exception(func->inst_comm_rt)); -} - -size_t -wasm_func_param_arity(const wasm_func_t *func) -{ - if (!func || !func->type || !func->type->params) { - return 0; - } - return func->type->params->num_elems; -} - -size_t -wasm_func_result_arity(const wasm_func_t *func) -{ - if (!func || !func->type || !func->type->results) { - return 0; - } - return func->type->results->num_elems; -} - -wasm_global_t * -wasm_global_new(wasm_store_t *store, const wasm_globaltype_t *global_type, - const wasm_val_t *init) -{ - wasm_global_t *global = NULL; - - bh_assert(singleton_engine); - - if (!global_type || !init) { - goto failed; - } - - global = malloc_internal(sizeof(wasm_global_t)); - if (!global) { - goto failed; - } - - global->store = store; - global->kind = WASM_EXTERN_GLOBAL; - global->type = wasm_globaltype_copy(global_type); - if (!global->type) { - goto failed; - } - - global->init = malloc_internal(sizeof(wasm_val_t)); - if (!global->init) { - goto failed; - } - - wasm_val_copy(global->init, init); - /* TODO: how to check if above is failed */ - - return global; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_global_delete(global); - return NULL; -} - -static wasm_global_t * -wasm_global_new_empty(wasm_store_t *store) -{ - wasm_global_t *global = NULL; - - global = malloc_internal(sizeof(wasm_global_t)); - if (!global) - goto failed; - - global->store = store; - global->kind = WASM_EXTERN_GLOBAL; - - return global; -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_global_delete(global); - return NULL; -} - -/* almost same with wasm_global_new */ -wasm_global_t * -wasm_global_copy(const wasm_global_t *src) -{ - wasm_global_t *global = NULL; - - if (!src) { - return NULL; - } - - global = malloc_internal(sizeof(wasm_global_t)); - if (!global) { - goto failed; - } - - global->kind = WASM_EXTERN_GLOBAL; - global->type = wasm_globaltype_copy(src->type); - if (!global->type) { - goto failed; - } - - global->init = malloc_internal(sizeof(wasm_val_t)); - if (!global->init) { - goto failed; - } - - wasm_val_copy(global->init, src->init); - - global->global_idx_rt = src->global_idx_rt; - global->inst_comm_rt = src->inst_comm_rt; - - return global; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_global_delete(global); - return NULL; -} - -void -wasm_global_delete(wasm_global_t *global) -{ - if (!global) { - return; - } - - if (global->init) { - wasm_val_delete(global->init); - global->init = NULL; - } - - if (global->type) { - wasm_globaltype_delete(global->type); - global->type = NULL; - } - - DELETE_HOST_INFO(global) - - wasm_runtime_free(global); -} - -#if WASM_ENABLE_INTERP != 0 -static bool -interp_global_set(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, - const wasm_val_t *v) -{ - const WASMGlobalInstance *global_interp = - inst_interp->e->globals + global_idx_rt; - uint8 val_type_rt = global_interp->type; -#if WASM_ENABLE_MULTI_MODULE != 0 - uint8 *data = global_interp->import_global_inst - ? global_interp->import_module_inst->global_data - + global_interp->import_global_inst->data_offset - : inst_interp->global_data + global_interp->data_offset; -#else - uint8 *data = inst_interp->global_data + global_interp->data_offset; -#endif - - return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_interp, - val_type_rt, v, data); -} - -static bool -interp_global_get(const WASMModuleInstance *inst_interp, uint16 global_idx_rt, - wasm_val_t *out) -{ - WASMGlobalInstance *global_interp = inst_interp->e->globals + global_idx_rt; - uint8 val_type_rt = global_interp->type; -#if WASM_ENABLE_MULTI_MODULE != 0 - uint8 *data = global_interp->import_global_inst - ? global_interp->import_module_inst->global_data - + global_interp->import_global_inst->data_offset - : inst_interp->global_data + global_interp->data_offset; -#else - uint8 *data = inst_interp->global_data + global_interp->data_offset; -#endif - - return rt_val_to_wasm_val(data, val_type_rt, out); -} -#endif - -#if WASM_ENABLE_AOT != 0 -static bool -aot_global_set(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, - const wasm_val_t *v) -{ - AOTModule *module_aot = (AOTModule *)inst_aot->module; - uint8 val_type_rt = 0; - uint32 data_offset = 0; - void *data = NULL; - - if (global_idx_rt < module_aot->import_global_count) { - data_offset = module_aot->import_globals[global_idx_rt].data_offset; - val_type_rt = module_aot->import_globals[global_idx_rt].type; - } - else { - data_offset = - module_aot->globals[global_idx_rt - module_aot->import_global_count] - .data_offset; - val_type_rt = - module_aot->globals[global_idx_rt - module_aot->import_global_count] - .type; - } - - data = (void *)(inst_aot->global_data + data_offset); - return wasm_val_to_rt_val((WASMModuleInstanceCommon *)inst_aot, val_type_rt, - v, data); -} - -static bool -aot_global_get(const AOTModuleInstance *inst_aot, uint16 global_idx_rt, - wasm_val_t *out) -{ - AOTModule *module_aot = (AOTModule *)inst_aot->module; - uint8 val_type_rt = 0; - uint32 data_offset = 0; - uint8 *data = NULL; - - if (global_idx_rt < module_aot->import_global_count) { - data_offset = module_aot->import_globals[global_idx_rt].data_offset; - val_type_rt = module_aot->import_globals[global_idx_rt].type; - } - else { - data_offset = - module_aot->globals[global_idx_rt - module_aot->import_global_count] - .data_offset; - val_type_rt = - module_aot->globals[global_idx_rt - module_aot->import_global_count] - .type; - } - - data = inst_aot->global_data + data_offset; - return rt_val_to_wasm_val(data, val_type_rt, out); -} -#endif - -void -wasm_global_set(wasm_global_t *global, const wasm_val_t *v) -{ - if (!global || !v || !global->inst_comm_rt) { - return; - } - -#if WASM_ENABLE_INTERP != 0 - if (global->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - (void)interp_global_set((WASMModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, v); - return; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (global->inst_comm_rt->module_type == Wasm_Module_AoT) { - (void)aot_global_set((AOTModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, v); - return; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - UNREACHABLE(); -} - -void -wasm_global_get(const wasm_global_t *global, wasm_val_t *out) -{ - if (!global || !out) { - return; - } - - if (!global->inst_comm_rt) { - return; - } - - memset(out, 0, sizeof(wasm_val_t)); - -#if WASM_ENABLE_INTERP != 0 - if (global->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - (void)interp_global_get((WASMModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, out); - return; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (global->inst_comm_rt->module_type == Wasm_Module_AoT) { - (void)aot_global_get((AOTModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, out); - return; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - UNREACHABLE(); -} - -wasm_global_t * -wasm_global_new_internal(wasm_store_t *store, uint16 global_idx_rt, - WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_global_t *global = NULL; - uint8 val_type_rt = 0; - bool is_mutable = 0; - bool init = false; - - bh_assert(singleton_engine); - - if (!inst_comm_rt) { - return NULL; - } - - global = malloc_internal(sizeof(wasm_global_t)); - if (!global) { - goto failed; - } - - global->store = store; - global->kind = WASM_EXTERN_GLOBAL; - -#if WASM_ENABLE_INTERP != 0 - if (inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMGlobalInstance *global_interp = - ((WASMModuleInstance *)inst_comm_rt)->e->globals + global_idx_rt; - val_type_rt = global_interp->type; - is_mutable = global_interp->is_mutable; - init = true; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->module; - - init = true; - - if (global_idx_rt < module_aot->import_global_count) { - AOTImportGlobal *global_import_aot = - module_aot->import_globals + global_idx_rt; - val_type_rt = global_import_aot->type; - is_mutable = global_import_aot->is_mutable; - } - else { - AOTGlobal *global_aot = - module_aot->globals - + (global_idx_rt - module_aot->import_global_count); - val_type_rt = global_aot->type; - is_mutable = global_aot->is_mutable; - } - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - if (!init) { - goto failed; - } - - global->type = wasm_globaltype_new_internal(val_type_rt, is_mutable); - if (!global->type) { - goto failed; - } - - global->init = malloc_internal(sizeof(wasm_val_t)); - if (!global->init) { - goto failed; - } - -#if WASM_ENABLE_INTERP != 0 - if (inst_comm_rt->module_type == Wasm_Module_Bytecode) { - interp_global_get((WASMModuleInstance *)inst_comm_rt, global_idx_rt, - global->init); - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (inst_comm_rt->module_type == Wasm_Module_AoT) { - aot_global_get((AOTModuleInstance *)inst_comm_rt, global_idx_rt, - global->init); - } -#endif - - global->inst_comm_rt = inst_comm_rt; - global->global_idx_rt = global_idx_rt; - - return global; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_global_delete(global); - return NULL; -} - -wasm_globaltype_t * -wasm_global_type(const wasm_global_t *global) -{ - if (!global) { - return NULL; - } - return wasm_globaltype_copy(global->type); -} - -static wasm_table_t * -wasm_table_new_basic(wasm_store_t *store, const wasm_tabletype_t *type) -{ - wasm_table_t *table = NULL; - - if (!(table = malloc_internal(sizeof(wasm_table_t)))) { - goto failed; - } - - table->store = store; - table->kind = WASM_EXTERN_TABLE; - - if (!(table->type = wasm_tabletype_copy(type))) { - goto failed; - } - - RETURN_OBJ(table, wasm_table_delete); -} - -wasm_table_t * -wasm_table_new_internal(wasm_store_t *store, uint16 table_idx_rt, - WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_table_t *table = NULL; - uint8 val_type_rt = 0; - uint32 init_size = 0, max_size = 0; - - bh_assert(singleton_engine); - - if (!inst_comm_rt) { - return NULL; - } - - if (!(table = malloc_internal(sizeof(wasm_table_t)))) { - goto failed; - } - - table->store = store; - table->kind = WASM_EXTERN_TABLE; - - if (!wasm_runtime_get_table_inst_elem_type( - inst_comm_rt, table_idx_rt, &val_type_rt, &init_size, &max_size)) { - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - goto failed; - } - - if (!(table->type = - wasm_tabletype_new_internal(val_type_rt, init_size, max_size))) { - goto failed; - } - - table->inst_comm_rt = inst_comm_rt; - table->table_idx_rt = table_idx_rt; - - RETURN_OBJ(table, wasm_table_delete); -} - -/* will not actually apply this new table into the runtime */ -wasm_table_t * -wasm_table_new(wasm_store_t *store, const wasm_tabletype_t *table_type, - wasm_ref_t *init) -{ - wasm_table_t *table; - (void)init; - - bh_assert(singleton_engine); - - if ((table = wasm_table_new_basic(store, table_type))) { - table->store = store; - } - - return table; -} - -wasm_table_t * -wasm_table_copy(const wasm_table_t *src) -{ - wasm_table_t *table; - - if (!(table = wasm_table_new_basic(src->store, src->type))) { - return NULL; - } - - table->table_idx_rt = src->table_idx_rt; - table->inst_comm_rt = src->inst_comm_rt; - return table; -} - -void -wasm_table_delete(wasm_table_t *table) -{ - if (!table) { - return; - } - - if (table->type) { - wasm_tabletype_delete(table->type); - table->type = NULL; - } - - DELETE_HOST_INFO(table) - - wasm_runtime_free(table); -} - -wasm_tabletype_t * -wasm_table_type(const wasm_table_t *table) -{ - if (!table) { - return NULL; - } - return wasm_tabletype_copy(table->type); -} - -own wasm_ref_t * -wasm_table_get(const wasm_table_t *table, wasm_table_size_t index) -{ - uint32 ref_idx = NULL_REF; - - if (!table || !table->inst_comm_rt) { - return NULL; - } - -#if WASM_ENABLE_INTERP != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMTableInstance *table_interp = - ((WASMModuleInstance *)table->inst_comm_rt) - ->tables[table->table_idx_rt]; - if (index >= table_interp->cur_size) { - return NULL; - } - ref_idx = table_interp->elems[index]; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt; - AOTTableInstance *table_aot = inst_aot->tables[table->table_idx_rt]; - if (index >= table_aot->cur_size) { - return NULL; - } - ref_idx = table_aot->elems[index]; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * also leads to below branch - */ - if (ref_idx == NULL_REF) { - return NULL; - } - -#if WASM_ENABLE_REF_TYPES != 0 - if (table->type->val_type->kind == WASM_ANYREF) { - void *externref_obj; - if (!wasm_externref_ref2obj(ref_idx, &externref_obj)) { - return NULL; - } - - return externref_obj; - } - else -#endif - { - return wasm_ref_new_internal(table->store, WASM_REF_func, ref_idx, - table->inst_comm_rt); - } -} - -bool -wasm_table_set(wasm_table_t *table, wasm_table_size_t index, - own wasm_ref_t *ref) -{ - uint32 *p_ref_idx = NULL; - uint32 function_count = 0; - - if (!table || !table->inst_comm_rt) { - return false; - } - - if (ref -#if WASM_ENABLE_REF_TYPES != 0 - && !(WASM_REF_foreign == ref->kind - && WASM_ANYREF == table->type->val_type->kind) -#endif - && !(WASM_REF_func == ref->kind - && WASM_FUNCREF == table->type->val_type->kind)) { - return false; - } - -#if WASM_ENABLE_INTERP != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMTableInstance *table_interp = - ((WASMModuleInstance *)table->inst_comm_rt) - ->tables[table->table_idx_rt]; - - if (index >= table_interp->cur_size) { - return false; - } - - p_ref_idx = table_interp->elems + index; - function_count = - ((WASMModuleInstance *)table->inst_comm_rt)->e->function_count; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->module; - AOTTableInstance *table_aot = inst_aot->tables[table->table_idx_rt]; - - if (index >= table_aot->cur_size) { - return false; - } - - p_ref_idx = table_aot->elems + index; - function_count = module_aot->func_count; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - if (!p_ref_idx) { - return false; - } - -#if WASM_ENABLE_REF_TYPES != 0 - if (table->type->val_type->kind == WASM_ANYREF) { - return wasm_externref_obj2ref(table->inst_comm_rt, ref, p_ref_idx); - } - else -#endif - { - if (ref) { - if (NULL_REF != ref->ref_idx_rt) { - if (ref->ref_idx_rt >= function_count) { - return false; - } - } - *p_ref_idx = ref->ref_idx_rt; - wasm_ref_delete(ref); - } - else { - *p_ref_idx = NULL_REF; - } - } - - return true; -} - -wasm_table_size_t -wasm_table_size(const wasm_table_t *table) -{ - if (!table || !table->inst_comm_rt) { - return 0; - } - -#if WASM_ENABLE_INTERP != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMTableInstance *table_interp = - ((WASMModuleInstance *)table->inst_comm_rt) - ->tables[table->table_idx_rt]; - return table_interp->cur_size; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (table->inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)table->inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->module; - - if (table->table_idx_rt < module_aot->import_table_count) { - AOTImportTable *table_aot = - module_aot->import_tables + table->table_idx_rt; - return table_aot->table_init_size; - } - else { - AOTTable *table_aot = - module_aot->tables - + (table->table_idx_rt - module_aot->import_table_count); - return table_aot->table_init_size; - } - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - return 0; -} - -bool -wasm_table_grow(wasm_table_t *table, wasm_table_size_t delta, - own wasm_ref_t *init) -{ - (void)table; - (void)delta; - (void)init; - LOG_WARNING("Calling wasm_table_grow() by host is not supported." - "Only allow growing a table via the opcode table.grow"); - return false; -} - -static wasm_memory_t * -wasm_memory_new_basic(wasm_store_t *store, const wasm_memorytype_t *type) -{ - wasm_memory_t *memory = NULL; - - if (!type) { - goto failed; - } - - if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) { - goto failed; - } - - memory->store = store; - memory->kind = WASM_EXTERN_MEMORY; - memory->type = wasm_memorytype_copy(type); - - RETURN_OBJ(memory, wasm_memory_delete) -} - -wasm_memory_t * -wasm_memory_new(wasm_store_t *store, const wasm_memorytype_t *type) -{ - bh_assert(singleton_engine); - return wasm_memory_new_basic(store, type); -} - -wasm_memory_t * -wasm_memory_copy(const wasm_memory_t *src) -{ - wasm_memory_t *dst = NULL; - - if (!src) { - return NULL; - } - - if (!(dst = wasm_memory_new_basic(src->store, src->type))) { - goto failed; - } - - dst->memory_idx_rt = src->memory_idx_rt; - dst->inst_comm_rt = src->inst_comm_rt; - - RETURN_OBJ(dst, wasm_memory_delete) -} - -wasm_memory_t * -wasm_memory_new_internal(wasm_store_t *store, uint16 memory_idx_rt, - WASMModuleInstanceCommon *inst_comm_rt) -{ - wasm_memory_t *memory = NULL; - uint32 min_pages = 0, max_pages = 0; - bool init_flag = false; - - bh_assert(singleton_engine); - - if (!inst_comm_rt) { - return NULL; - } - - if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) { - goto failed; - } - - memory->store = store; - memory->kind = WASM_EXTERN_MEMORY; - -#if WASM_ENABLE_INTERP != 0 - if (inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMMemoryInstance *memory_interp = - ((WASMModuleInstance *)inst_comm_rt)->memories[memory_idx_rt]; - min_pages = memory_interp->cur_page_count; - max_pages = memory_interp->max_page_count; - init_flag = true; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; - AOTModule *module_aot = (AOTModule *)inst_aot->module; - - if (memory_idx_rt < module_aot->import_memory_count) { - min_pages = module_aot->import_memories->mem_init_page_count; - max_pages = module_aot->import_memories->mem_max_page_count; - } - else { - min_pages = module_aot->memories->mem_init_page_count; - max_pages = module_aot->memories->mem_max_page_count; - } - init_flag = true; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - if (!init_flag) { - goto failed; - } - - if (!(memory->type = wasm_memorytype_new_internal(min_pages, max_pages))) { - goto failed; - } - - memory->inst_comm_rt = inst_comm_rt; - memory->memory_idx_rt = memory_idx_rt; - - RETURN_OBJ(memory, wasm_memory_delete); -} - -void -wasm_memory_delete(wasm_memory_t *memory) -{ - if (!memory) { - return; - } - - if (memory->type) { - wasm_memorytype_delete(memory->type); - memory->type = NULL; - } - - DELETE_HOST_INFO(memory) - - wasm_runtime_free(memory); -} - -wasm_memorytype_t * -wasm_memory_type(const wasm_memory_t *memory) -{ - if (!memory) { - return NULL; - } - - return wasm_memorytype_copy(memory->type); -} - -byte_t * -wasm_memory_data(wasm_memory_t *memory) -{ - WASMModuleInstanceCommon *module_inst_comm; - - if (!memory || !memory->inst_comm_rt) { - return NULL; - } - - module_inst_comm = memory->inst_comm_rt; -#if WASM_ENABLE_INTERP != 0 - if (module_inst_comm->module_type == Wasm_Module_Bytecode) { - WASMModuleInstance *module_inst = - (WASMModuleInstance *)module_inst_comm; - WASMMemoryInstance *memory_inst = - module_inst->memories[memory->memory_idx_rt]; - return (byte_t *)memory_inst->memory_data; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (module_inst_comm->module_type == Wasm_Module_AoT) { - AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm; - AOTMemoryInstance *memory_inst = - ((AOTMemoryInstance **) - module_inst->memories)[memory->memory_idx_rt]; - return (byte_t *)memory_inst->memory_data; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - return NULL; -} - -size_t -wasm_memory_data_size(const wasm_memory_t *memory) -{ - WASMModuleInstanceCommon *module_inst_comm; - - if (!memory || !memory->inst_comm_rt) { - return 0; - } - - module_inst_comm = memory->inst_comm_rt; -#if WASM_ENABLE_INTERP != 0 - if (module_inst_comm->module_type == Wasm_Module_Bytecode) { - WASMModuleInstance *module_inst = - (WASMModuleInstance *)module_inst_comm; - WASMMemoryInstance *memory_inst = - module_inst->memories[memory->memory_idx_rt]; - return (size_t)memory_inst->cur_page_count - * memory_inst->num_bytes_per_page; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (module_inst_comm->module_type == Wasm_Module_AoT) { - AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm; - AOTMemoryInstance *memory_inst = - ((AOTMemoryInstance **) - module_inst->memories)[memory->memory_idx_rt]; - return (size_t)memory_inst->cur_page_count - * memory_inst->num_bytes_per_page; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - return 0; -} - -wasm_memory_pages_t -wasm_memory_size(const wasm_memory_t *memory) -{ - WASMModuleInstanceCommon *module_inst_comm; - - if (!memory || !memory->inst_comm_rt) { - return 0; - } - - module_inst_comm = memory->inst_comm_rt; -#if WASM_ENABLE_INTERP != 0 - if (module_inst_comm->module_type == Wasm_Module_Bytecode) { - WASMModuleInstance *module_inst = - (WASMModuleInstance *)module_inst_comm; - WASMMemoryInstance *memory_inst = - module_inst->memories[memory->memory_idx_rt]; - return memory_inst->cur_page_count; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (module_inst_comm->module_type == Wasm_Module_AoT) { - AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm; - AOTMemoryInstance *memory_inst = - ((AOTMemoryInstance **) - module_inst->memories)[memory->memory_idx_rt]; - return memory_inst->cur_page_count; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - return 0; -} - -bool -wasm_memory_grow(wasm_memory_t *memory, wasm_memory_pages_t delta) -{ - (void)memory; - (void)delta; - LOG_WARNING("Calling wasm_memory_grow() by host is not supported." - "Only allow growing a memory via the opcode memory.grow"); - return false; -} - -#if WASM_ENABLE_INTERP != 0 -static bool -interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, - uint16 func_idx_rt, wasm_func_t *import) -{ - WASMImport *imported_func_interp = NULL; - - bh_assert(inst && module_interp && import); - bh_assert(func_idx_rt < module_interp->import_function_count); - bh_assert(WASM_EXTERN_FUNC == import->kind); - - imported_func_interp = module_interp->import_functions + func_idx_rt; - bh_assert(imported_func_interp); - bh_assert(imported_func_interp->kind == IMPORT_KIND_FUNC); - - /* it is a placeholder and let's skip it*/ - if (!import->type) - return true; - - /* type comparison */ - if (!wasm_functype_same_internal( - import->type, imported_func_interp->u.function.func_type)) - return false; - - imported_func_interp->u.function.call_conv_wasm_c_api = true; - /* only set func_ptr_linked to avoid unlink warning during instantiation, - func_ptr_linked, with_env and env will be stored in module instance's - c_api_func_imports later and used when calling import function */ - if (import->with_env) - imported_func_interp->u.function.func_ptr_linked = import->u.cb_env.cb; - else - imported_func_interp->u.function.func_ptr_linked = import->u.cb; - bh_assert(imported_func_interp->u.function.func_ptr_linked); - - import->func_idx_rt = func_idx_rt; - - (void)inst; - return true; -} - -static bool -interp_link_global(const WASMModule *module_interp, uint16 global_idx_rt, - wasm_global_t *import) -{ - WASMImport *imported_global_interp = NULL; - - bh_assert(module_interp && import); - bh_assert(global_idx_rt < module_interp->import_global_count); - bh_assert(WASM_EXTERN_GLOBAL == import->kind); - - imported_global_interp = module_interp->import_globals + global_idx_rt; - bh_assert(imported_global_interp); - bh_assert(imported_global_interp->kind == IMPORT_KIND_GLOBAL); - - /* it is a placeholder and let's skip it*/ - if (!import->type) - return true; - - /* type comparison */ - if (!cmp_val_kind_with_val_type(wasm_valtype_kind(import->type->val_type), - imported_global_interp->u.global.type)) - return false; - - /* set init value */ - bh_assert(import->init); - switch (wasm_valtype_kind(import->type->val_type)) { - case WASM_I32: - imported_global_interp->u.global.global_data_linked.i32 = - import->init->of.i32; - break; - case WASM_I64: - imported_global_interp->u.global.global_data_linked.i64 = - import->init->of.i64; - break; - case WASM_F32: - imported_global_interp->u.global.global_data_linked.f32 = - import->init->of.f32; - break; - case WASM_F64: - imported_global_interp->u.global.global_data_linked.f64 = - import->init->of.f64; - break; - default: - return false; - } - - import->global_idx_rt = global_idx_rt; - imported_global_interp->u.global.is_linked = true; - return true; -} - -static bool -interp_process_export(wasm_store_t *store, - const WASMModuleInstance *inst_interp, - wasm_extern_vec_t *externals) -{ - WASMExport *exports = NULL; - WASMExport *export = NULL; - wasm_extern_t *external = NULL; - uint32 export_cnt = 0; - uint32 i = 0; - - bh_assert(store && inst_interp && inst_interp->module && externals); - - exports = inst_interp->module->exports; - export_cnt = inst_interp->module->export_count; - - for (i = 0; i < export_cnt; ++i) { - export = exports + i; - - switch (export->kind) { - case EXPORT_KIND_FUNC: - { - wasm_func_t *func; - if (!(func = wasm_func_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp))) { - goto failed; - } - - external = wasm_func_as_extern(func); - break; - } - case EXPORT_KIND_GLOBAL: - { - wasm_global_t *global; - if (!(global = wasm_global_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp))) { - goto failed; - } - - external = wasm_global_as_extern(global); - break; - } - case EXPORT_KIND_TABLE: - { - wasm_table_t *table; - if (!(table = wasm_table_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp))) { - goto failed; - } - - external = wasm_table_as_extern(table); - break; - } - case EXPORT_KIND_MEMORY: - { - wasm_memory_t *memory; - if (!(memory = wasm_memory_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp))) { - goto failed; - } - - external = wasm_memory_as_extern(memory); - break; - } - default: - LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, - export->kind); - goto failed; - } - - if (!bh_vector_append((Vector *)externals, &external)) { - goto failed; - } - } - - return true; - -failed: - wasm_extern_delete(external); - return false; -} -#endif /* WASM_ENABLE_INTERP */ - -#if WASM_ENABLE_AOT != 0 -static bool -aot_link_func(const wasm_instance_t *inst, const AOTModule *module_aot, - uint32 import_func_idx_rt, wasm_func_t *import) -{ - AOTImportFunc *import_aot_func = NULL; - - bh_assert(inst && module_aot && import); - - import_aot_func = module_aot->import_funcs + import_func_idx_rt; - bh_assert(import_aot_func); - - /* it is a placeholder and let's skip it*/ - if (!import->type) - return true; - - /* type comparison */ - if (!wasm_functype_same_internal(import->type, import_aot_func->func_type)) - return false; - - import_aot_func->call_conv_wasm_c_api = true; - /* only set func_ptr_linked to avoid unlink warning during instantiation, - func_ptr_linked, with_env and env will be stored in module instance's - c_api_func_imports later and used when calling import function */ - if (import->with_env) - import_aot_func->func_ptr_linked = import->u.cb_env.cb; - else - import_aot_func->func_ptr_linked = import->u.cb; - bh_assert(import_aot_func->func_ptr_linked); - - import->func_idx_rt = import_func_idx_rt; - - return true; -} - -static bool -aot_link_global(const AOTModule *module_aot, uint16 global_idx_rt, - wasm_global_t *import) -{ - AOTImportGlobal *import_aot_global = NULL; - const wasm_valtype_t *val_type = NULL; - - bh_assert(module_aot && import); - - import_aot_global = module_aot->import_globals + global_idx_rt; - bh_assert(import_aot_global); - - /* it is a placeholder and let's skip it*/ - if (!import->type) - return true; - - val_type = wasm_globaltype_content(import->type); - bh_assert(val_type); - - if (!cmp_val_kind_with_val_type(wasm_valtype_kind(val_type), - import_aot_global->type)) - return false; - - bh_assert(import->init); - switch (wasm_valtype_kind(val_type)) { - case WASM_I32: - import_aot_global->global_data_linked.i32 = import->init->of.i32; - break; - case WASM_I64: - import_aot_global->global_data_linked.i64 = import->init->of.i64; - break; - case WASM_F32: - import_aot_global->global_data_linked.f32 = import->init->of.f32; - break; - case WASM_F64: - import_aot_global->global_data_linked.f64 = import->init->of.f64; - break; - default: - goto failed; - } - - import->global_idx_rt = global_idx_rt; - import_aot_global->is_linked = true; - return true; -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - return false; -} - -static bool -aot_process_export(wasm_store_t *store, const AOTModuleInstance *inst_aot, - wasm_extern_vec_t *externals) -{ - uint32 i; - wasm_extern_t *external = NULL; - AOTModule *module_aot = NULL; - - bh_assert(store && inst_aot && externals); - - module_aot = (AOTModule *)inst_aot->module; - bh_assert(module_aot); - - for (i = 0; i < module_aot->export_count; ++i) { - AOTExport *export = module_aot->exports + i; - - switch (export->kind) { - case EXPORT_KIND_FUNC: - { - wasm_func_t *func = NULL; - if (!(func = wasm_func_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_aot))) { - goto failed; - } - - external = wasm_func_as_extern(func); - break; - } - case EXPORT_KIND_GLOBAL: - { - wasm_global_t *global = NULL; - if (!(global = wasm_global_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_aot))) { - goto failed; - } - - external = wasm_global_as_extern(global); - break; - } - case EXPORT_KIND_TABLE: - { - wasm_table_t *table; - if (!(table = wasm_table_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_aot))) { - goto failed; - } - - external = wasm_table_as_extern(table); - break; - } - case EXPORT_KIND_MEMORY: - { - wasm_memory_t *memory; - if (!(memory = wasm_memory_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_aot))) { - goto failed; - } - - external = wasm_memory_as_extern(memory); - break; - } - default: - LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, - export->kind); - goto failed; - } - - if (!(external->name = malloc_internal(sizeof(wasm_byte_vec_t)))) { - goto failed; - } - - wasm_name_new_from_string_nt(external->name, export->name); - if (strlen(export->name) && !external->name->data) { - goto failed; - } - - if (!bh_vector_append((Vector *)externals, &external)) { - goto failed; - } - } - - return true; - -failed: - wasm_extern_delete(external); - return false; -} -#endif /* WASM_ENABLE_AOT */ - -static bool -do_link(const wasm_instance_t *inst, const wasm_module_t *module, - const wasm_extern_vec_t *imports) -{ - uint32 i, import_func_i, import_global_i; - - bh_assert(inst && module); - - /* we have run a module_type check before. */ - - for (i = 0, import_func_i = 0, import_global_i = 0; i < imports->num_elems; - i++) { - wasm_extern_t *import = imports->data[i]; - - if (!import) { - LOG_ERROR("imports[%d] is NULL and it is fatal\n", i); - goto failed; - } - - switch (wasm_extern_kind(import)) { - case WASM_EXTERN_FUNC: - { - bool ret = false; -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - ret = interp_link_func(inst, MODULE_INTERP(module), - import_func_i, - wasm_extern_as_func(import)); - } -#endif -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - ret = aot_link_func(inst, MODULE_AOT(module), import_func_i, - wasm_extern_as_func(import)); - } -#endif - if (!ret) { - LOG_WARNING("link function #%d failed", import_func_i); - goto failed; - } - - import_func_i++; - break; - } - case WASM_EXTERN_GLOBAL: - { - bool ret = false; -#if WASM_ENABLE_INTERP != 0 - if ((*module)->module_type == Wasm_Module_Bytecode) { - ret = interp_link_global(MODULE_INTERP(module), - import_global_i, - wasm_extern_as_global(import)); - } -#endif -#if WASM_ENABLE_AOT != 0 - if ((*module)->module_type == Wasm_Module_AoT) { - ret = aot_link_global(MODULE_AOT(module), import_global_i, - wasm_extern_as_global(import)); - } -#endif - if (!ret) { - LOG_WARNING("link global #%d failed", import_global_i); - goto failed; - } - - import_global_i++; - break; - } - case WASM_EXTERN_MEMORY: - case WASM_EXTERN_TABLE: - { - LOG_WARNING("doesn't support import memories and tables for " - "now, ignore them"); - break; - } - default: - { - UNREACHABLE(); - break; - } - } - } - - return true; -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - return false; -} - -wasm_instance_t * -wasm_instance_new(wasm_store_t *store, const wasm_module_t *module, - const wasm_extern_vec_t *imports, own wasm_trap_t **trap) -{ - return wasm_instance_new_with_args(store, module, imports, trap, - KILOBYTE(32), KILOBYTE(32)); -} - -wasm_instance_t * -wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module, - const wasm_extern_vec_t *imports, - own wasm_trap_t **trap, const uint32 stack_size, - const uint32 heap_size) -{ - char sub_error_buf[128] = { 0 }; - char error_buf[256] = { 0 }; - wasm_instance_t *instance = NULL; - CApiFuncImport *func_import = NULL, **p_func_imports = NULL; - uint32 i = 0, import_func_count = 0; - uint64 total_size; - bool build_exported = false; - - bh_assert(singleton_engine); - - if (!module) - return NULL; - - /* - * will do the check at the end of wasm_runtime_instantiate - */ - - WASM_C_DUMP_PROC_MEM(); - - instance = malloc_internal(sizeof(wasm_instance_t)); - if (!instance) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to malloc instance"); - goto failed; - } - - /* executes the instantiate-time linking if provided */ - if (imports) { - if (!do_link(instance, module, imports)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to validate imports"); - goto failed; - } - } - /* - * will do the linking result check at the end of wasm_runtime_instantiate - */ - - instance->inst_comm_rt = wasm_runtime_instantiate( - *module, stack_size, heap_size, sub_error_buf, sizeof(sub_error_buf)); - if (!instance->inst_comm_rt) { - goto failed; - } - - if (!wasm_runtime_create_exec_env_singleton(instance->inst_comm_rt)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to create exec env singleton"); - goto failed; - } - - /* create the c-api func import list */ -#if WASM_ENABLE_INTERP != 0 - if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - WASMModuleInstanceExtra *e = - ((WASMModuleInstance *)instance->inst_comm_rt)->e; - p_func_imports = &(e->c_api_func_imports); - import_func_count = MODULE_INTERP(module)->import_function_count; - } -#endif -#if WASM_ENABLE_AOT != 0 - if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) { - AOTModuleInstanceExtra *e = - (AOTModuleInstanceExtra *)((AOTModuleInstance *) - instance->inst_comm_rt) - ->e; - p_func_imports = &(e->c_api_func_imports); - import_func_count = MODULE_AOT(module)->import_func_count; - } -#endif - bh_assert(p_func_imports); - - total_size = (uint64)sizeof(CApiFuncImport) * import_func_count; - if (total_size > 0 - && !(*p_func_imports = func_import = malloc_internal(total_size))) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to create wasm-c-api func imports"); - goto failed; - } - - /* fill in module_inst->e->c_api_func_imports */ - for (i = 0; imports && i < imports->num_elems; i++) { - wasm_func_t *func_host = NULL; - wasm_extern_t *in = imports->data[i]; - bh_assert(in); - - if (wasm_extern_kind(in) != WASM_EXTERN_FUNC) - continue; - - func_host = wasm_extern_as_func(in); - /* it is a placeholder and let's skip it*/ - if (!func_host->type) { - func_import++; - continue; - } - - func_import->with_env_arg = func_host->with_env; - if (func_host->with_env) { - func_import->func_ptr_linked = func_host->u.cb_env.cb; - func_import->env_arg = func_host->u.cb_env.env; - } - else { - func_import->func_ptr_linked = func_host->u.cb; - func_import->env_arg = NULL; - } - bh_assert(func_import->func_ptr_linked); - - func_import++; - } - - /* fill with inst */ - for (i = 0; imports && imports->data && i < imports->num_elems; ++i) { - wasm_extern_t *import = imports->data[i]; - bh_assert(import); - - switch (import->kind) { - case WASM_EXTERN_FUNC: - wasm_extern_as_func(import)->inst_comm_rt = - instance->inst_comm_rt; - break; - case WASM_EXTERN_GLOBAL: - wasm_extern_as_global(import)->inst_comm_rt = - instance->inst_comm_rt; - break; - case WASM_EXTERN_MEMORY: - wasm_extern_as_memory(import)->inst_comm_rt = - instance->inst_comm_rt; - break; - case WASM_EXTERN_TABLE: - wasm_extern_as_table(import)->inst_comm_rt = - instance->inst_comm_rt; - break; - default: - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Unknown import kind"); - goto failed; - } - } - - /* build the exports list */ -#if WASM_ENABLE_INTERP != 0 - if (instance->inst_comm_rt->module_type == Wasm_Module_Bytecode) { - uint32 export_cnt = ((WASMModuleInstance *)instance->inst_comm_rt) - ->module->export_count; - - INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized, - export_cnt); - - if (!interp_process_export(store, - (WASMModuleInstance *)instance->inst_comm_rt, - instance->exports)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Interpreter failed to process exports"); - goto failed; - } - - build_exported = true; - } -#endif - -#if WASM_ENABLE_AOT != 0 - if (instance->inst_comm_rt->module_type == Wasm_Module_AoT) { - uint32 export_cnt = - ((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count - + ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count - + ((AOTModuleInstance *)instance->inst_comm_rt)->export_table_count - + ((AOTModuleInstance *)instance->inst_comm_rt) - ->export_memory_count; - - INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized, - export_cnt); - - if (!aot_process_export(store, - (AOTModuleInstance *)instance->inst_comm_rt, - instance->exports)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "AOT failed to process exports"); - goto failed; - } - - build_exported = true; - } -#endif - - /* - * a wrong combination of module filetype and compilation flags - * leads to below branch - */ - if (!build_exported) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Incorrect filetype and compilation flags"); - goto failed; - } - - /* add it to a watching list in store */ - if (!bh_vector_append((Vector *)store->instances, &instance)) { - snprintf(sub_error_buf, sizeof(sub_error_buf), - "Failed to add to store instances"); - goto failed; - } - - WASM_C_DUMP_PROC_MEM(); - - return instance; - -failed: - snprintf(error_buf, sizeof(error_buf), "%s failed: %s", __FUNCTION__, - sub_error_buf); - if (trap != NULL) { - wasm_message_t message = { 0 }; - wasm_name_new_from_string_nt(&message, error_buf); - *trap = wasm_trap_new(store, &message); - wasm_byte_vec_delete(&message); - } - LOG_DEBUG(error_buf); - wasm_instance_delete_internal(instance); - return NULL; -} - -static void -wasm_instance_delete_internal(wasm_instance_t *instance) -{ - if (!instance) { - return; - } - - DEINIT_VEC(instance->exports, wasm_extern_vec_delete); - - if (instance->inst_comm_rt) { - wasm_runtime_deinstantiate(instance->inst_comm_rt); - instance->inst_comm_rt = NULL; - } - wasm_runtime_free(instance); -} - -void -wasm_instance_delete(wasm_instance_t *inst) -{ - DELETE_HOST_INFO(inst) - /* will release instance when releasing the store */ -} - -void -wasm_instance_exports(const wasm_instance_t *instance, - own wasm_extern_vec_t *out) -{ - if (!instance || !out) { - return; - } - wasm_extern_vec_copy(out, instance->exports); -} - -wasm_extern_t * -wasm_extern_copy(const wasm_extern_t *src) -{ - wasm_extern_t *dst = NULL; - - if (!src) { - return NULL; - } - - switch (wasm_extern_kind(src)) { - case WASM_EXTERN_FUNC: - dst = wasm_func_as_extern( - wasm_func_copy(wasm_extern_as_func_const(src))); - break; - case WASM_EXTERN_GLOBAL: - dst = wasm_global_as_extern( - wasm_global_copy(wasm_extern_as_global_const(src))); - break; - case WASM_EXTERN_MEMORY: - dst = wasm_memory_as_extern( - wasm_memory_copy(wasm_extern_as_memory_const(src))); - break; - case WASM_EXTERN_TABLE: - dst = wasm_table_as_extern( - wasm_table_copy(wasm_extern_as_table_const(src))); - break; - default: - LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, - src->kind); - break; - } - - if (!dst) { - goto failed; - } - - return dst; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_extern_delete(dst); - return NULL; -} - -void -wasm_extern_delete(wasm_extern_t *external) -{ - if (!external) { - return; - } - - if (external->name) { - wasm_byte_vec_delete(external->name); - wasm_runtime_free(external->name); - external->name = NULL; - } - - switch (wasm_extern_kind(external)) { - case WASM_EXTERN_FUNC: - wasm_func_delete(wasm_extern_as_func(external)); - break; - case WASM_EXTERN_GLOBAL: - wasm_global_delete(wasm_extern_as_global(external)); - break; - case WASM_EXTERN_MEMORY: - wasm_memory_delete(wasm_extern_as_memory(external)); - break; - case WASM_EXTERN_TABLE: - wasm_table_delete(wasm_extern_as_table(external)); - break; - default: - LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, - external->kind); - break; - } -} - -wasm_externkind_t -wasm_extern_kind(const wasm_extern_t *external) -{ - if (!external) { - return WASM_ANYREF; - } - - return external->kind; -} - -own wasm_externtype_t * -wasm_extern_type(const wasm_extern_t *external) -{ - if (!external) { - return NULL; - } - - switch (wasm_extern_kind(external)) { - case WASM_EXTERN_FUNC: - return wasm_functype_as_externtype( - wasm_func_type(wasm_extern_as_func_const(external))); - case WASM_EXTERN_GLOBAL: - return wasm_globaltype_as_externtype( - wasm_global_type(wasm_extern_as_global_const(external))); - case WASM_EXTERN_MEMORY: - return wasm_memorytype_as_externtype( - wasm_memory_type(wasm_extern_as_memory_const(external))); - case WASM_EXTERN_TABLE: - return wasm_tabletype_as_externtype( - wasm_table_type(wasm_extern_as_table_const(external))); - default: - LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, - external->kind); - break; - } - return NULL; -} - -#define BASIC_FOUR_LIST(V) \ - V(func) \ - V(global) \ - V(memory) \ - V(table) - -#define WASM_EXTERN_AS_OTHER(name) \ - wasm_##name##_t *wasm_extern_as_##name(wasm_extern_t *external) \ - { \ - return (wasm_##name##_t *)external; \ - } - -BASIC_FOUR_LIST(WASM_EXTERN_AS_OTHER) -#undef WASM_EXTERN_AS_OTHER - -#define WASM_OTHER_AS_EXTERN(name) \ - wasm_extern_t *wasm_##name##_as_extern(wasm_##name##_t *other) \ - { \ - return (wasm_extern_t *)other; \ - } - -BASIC_FOUR_LIST(WASM_OTHER_AS_EXTERN) -#undef WASM_OTHER_AS_EXTERN - -#define WASM_EXTERN_AS_OTHER_CONST(name) \ - const wasm_##name##_t *wasm_extern_as_##name##_const( \ - const wasm_extern_t *external) \ - { \ - return (const wasm_##name##_t *)external; \ - } - -BASIC_FOUR_LIST(WASM_EXTERN_AS_OTHER_CONST) -#undef WASM_EXTERN_AS_OTHER_CONST - -#define WASM_OTHER_AS_EXTERN_CONST(name) \ - const wasm_extern_t *wasm_##name##_as_extern_const( \ - const wasm_##name##_t *other) \ - { \ - return (const wasm_extern_t *)other; \ - } - -BASIC_FOUR_LIST(WASM_OTHER_AS_EXTERN_CONST) -#undef WASM_OTHER_AS_EXTERN_CONST - -wasm_extern_t * -wasm_extern_new_empty(wasm_store_t *store, wasm_externkind_t extern_kind) -{ - if (extern_kind == WASM_EXTERN_FUNC) - return wasm_func_as_extern(wasm_func_new_empty(store)); - - if (extern_kind == WASM_EXTERN_GLOBAL) - return wasm_global_as_extern(wasm_global_new_empty(store)); - - LOG_ERROR("Don't support linking table and memory for now"); - return NULL; -} |