diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000..c3e4a1eaea --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,140 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +cmake_minimum_required (VERSION 2.8) + +project (iwasm) +# set (CMAKE_VERBOSE_MAKEFILE 1) + +set (WAMR_BUILD_PLATFORM "linux") + +# Reset default linker flags +set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") +set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") + +set (CMAKE_C_STANDARD 99) + +# Set WAMR_BUILD_TARGET, currently values supported: +# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]", +# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]" +if (NOT DEFINED WAMR_BUILD_TARGET) + if (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set (WAMR_BUILD_TARGET "AARCH64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") + set (WAMR_BUILD_TARGET "RISCV64") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + # Build as X86_64 by default in 64-bit platform + set (WAMR_BUILD_TARGET "X86_64") + else () + # Build as X86_32 by default in 32-bit platform + set (WAMR_BUILD_TARGET "X86_32") + endif () +endif () + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () + +if (NOT DEFINED WAMR_BUILD_INTERP) + # Enable Interpreter by default + set (WAMR_BUILD_INTERP 1) +endif () + +if (NOT DEFINED WAMR_BUILD_AOT) + # Enable AOT by default. + set (WAMR_BUILD_AOT 1) +endif () + +if (NOT DEFINED WAMR_BUILD_JIT) + # Disable JIT by default. + set (WAMR_BUILD_JIT 0) +endif () + +if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN) + # Enable libc builtin support by default + set (WAMR_BUILD_LIBC_BUILTIN 1) +endif () + +if (NOT DEFINED WAMR_BUILD_LIBC_WASI) + # Enable libc wasi support by default + set (WAMR_BUILD_LIBC_WASI 1) +endif () + +if (NOT DEFINED WAMR_BUILD_FAST_INTERP) + # Enable fast interpreter + set (WAMR_BUILD_FAST_INTERP 1) +endif () + +if (NOT DEFINED WAMR_BUILD_MULTI_MODULE) + # Enable multiple modules + set (WAMR_BUILD_MULTI_MODULE 0) +endif () + +if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD) + # Disable pthread library by default + set (WAMR_BUILD_LIB_PTHREAD 0) +endif () + +if (NOT DEFINED WAMR_BUILD_MINI_LOADER) + # Disable wasm mini loader by default + set (WAMR_BUILD_MINI_LOADER 0) +endif () + +if (NOT DEFINED WAMR_BUILD_SIMD) + # Enable SIMD by default + set (WAMR_BUILD_SIMD 1) +endif () + +if (NOT DEFINED WAMR_BUILD_REF_TYPES) + # Disable reference types by default + set (WAMR_BUILD_REF_TYPES 0) +endif () + +if (COLLECT_CODE_COVERAGE EQUAL 1) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") +endif () + +set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake) +add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE}) + +set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE") + +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security") +# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion") + +if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") + if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang")) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register") + endif () +endif () + +# The following flags are to enhance security, but it may impact performance, +# we disable them by default. +#if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64") +# set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftrapv -D_FORTIFY_SOURCE=2") +#endif () +#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4") +#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now") + +include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) + +# STATIC LIBRARY +add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE}) +set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib) + +install (TARGETS iwasm_static ARCHIVE DESTINATION lib) + +# SHARED LIBRARY +add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE}) +set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm) +target_link_libraries (iwasm_shared ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread) + +install (TARGETS iwasm_shared LIBRARY DESTINATION lib) + +# HEADERS +install (FILES + ${WAMR_ROOT_DIR}/core/iwasm/include/wasm_c_api.h + ${WAMR_ROOT_DIR}/core/iwasm/include/wasm_export.h + DESTINATION include) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 0657804e65..c233889757 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -784,11 +784,6 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, uint64 size; uint32 i, func_index, ftype_index; - for (i = 0; i < module->export_count; i++) { - if (exports[i].kind == EXPORT_KIND_FUNC) - module_inst->export_func_count++; - } - if (module_inst->export_func_count > 0) { /* Allocate memory */ size = sizeof(AOTFunctionInstance) @@ -829,6 +824,28 @@ static bool create_exports(AOTModuleInstance *module_inst, AOTModule *module, char *error_buf, uint32 error_buf_size) { + AOTExport *exports = module->exports; + uint32 i; + + for (i = 0; i < module->export_count; i++) { + switch (exports[i].kind) { + case EXPORT_KIND_FUNC: + module_inst->export_func_count++; + break; + case EXPORT_KIND_GLOBAL: + module_inst->export_global_count++; + break; + case EXPORT_KIND_TABLE: + module_inst->export_tab_count++; + break; + case EXPORT_KIND_MEMORY: + module_inst->export_mem_count++; + break; + default: + return false; + } + } + return create_export_funcs(module_inst, module, error_buf, error_buf_size); } diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 5087c30b6e..4e883153f3 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -12,27 +12,47 @@ #include "aot_runtime.h" #endif -#define NOT_REACHED() bh_assert(!"should not be reached") +#define ASSERT_NOT_IMPLEMENTED() bh_assert(!"not implemented") typedef struct wasm_module_ex_t wasm_module_ex_t; -void +static void wasm_module_delete_internal(wasm_module_t *); -void +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 void * malloc_internal(uint64 size) { void *mem = NULL; - if (size >= UINT32_MAX) { - return NULL; - } - - mem = wasm_runtime_malloc((uint32)size); - if (mem) { + if (size < UINT32_MAX && (mem = wasm_runtime_malloc((uint32)size))) { memset(mem, 0, size); } @@ -44,109 +64,170 @@ malloc_internal(uint64 size) wasm_runtime_free(p); \ } +/* 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, func_prefix, size) \ +#define INIT_VEC(vector_p, init_func, ...) \ do { \ if (!(vector_p = malloc_internal(sizeof(*(vector_p))))) { \ goto failed; \ } \ - func_prefix##_new_uninitialized(vector_p, size); \ - if (!(vector_p)->data) { \ + \ + 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, delete_func) \ +#define DEINIT_VEC(vector_p, deinit_func) \ if ((vector_p)) { \ - if ((vector_p)->data) { \ - delete_func(vector_p); \ - } \ + deinit_func(vector_p); \ wasm_runtime_free(vector_p); \ vector_p = NULL; \ } -#define FREE_VEC_ELEMS(vec, del_func) \ - for (i = 0; i < (vec)->num_elems; ++i) { \ - del_func(*((vec)->data + i)); \ - *((vec)->data + i) = NULL; \ - } - -static inline void -generic_vec_init_data(Vector *out, size_t num_of_elems, size_t size_of_elem) -{ - /* size 0 is meaningless for a elemment */ - if (!size_of_elem || !bh_vector_init(out, num_of_elems, size_of_elem)) { - out->data = NULL; - out->max_elems = 0; - out->num_elems = 0; - } - else { - memset(out->data, 0, num_of_elems * size_of_elem); - } -} - -void -wasm_byte_vec_new_uninitialized(wasm_byte_vec_t *out, size_t size) -{ - bh_assert(out); - generic_vec_init_data((Vector *)out, size, sizeof(wasm_byte_t)); -} - -void -wasm_byte_vec_copy(wasm_byte_vec_t *out, const wasm_byte_vec_t *src) -{ - uint32 len = 0; - - bh_assert(out && src); - - generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_byte_t)); - if (!out->data) { - goto failed; +#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[]) \ + { \ + bh_assert(out); \ + \ + memset(out, 0, sizeof(wasm_##name##_vec_t)); \ + \ + if (!size) { \ + return; \ + } \ + \ + if (!bh_vector_init((Vector *)out, size, sizeof(wasm_##name##_t))) { \ + LOG_DEBUG("bh_vector_init failed"); \ + goto failed; \ + } \ + \ + if (data) { \ + unsigned int size_in_bytes = 0; \ + size_in_bytes = 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) \ + { \ + 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); \ + } \ } - /* integer overflow has been checked in generic_vec_init_data, - no need to check again */ - len = (uint32)(src->size * src->size_of_elem); - bh_memcpy_s(out->data, len, src->data, len); - out->num_elems = src->num_elems; - return; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_byte_vec_delete(out); -} - -void -wasm_byte_vec_new(wasm_byte_vec_t *out, size_t size, const wasm_byte_t *data) -{ - uint32 size_in_bytes = 0; - - bh_assert(out && data); - - generic_vec_init_data((Vector *)out, size, sizeof(wasm_byte_t)); - if (!out->data) { - goto failed; +/* 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[]) \ + { \ + bh_assert(out); \ + \ + memset(out, 0, sizeof(wasm_##name##_vec_t)); \ + \ + if (!size) { \ + return; \ + } \ + \ + if (!bh_vector_init((Vector *)out, size, \ + sizeof(wasm_##name##_t *))) { \ + LOG_DEBUG("bh_vector_init failed"); \ + goto failed; \ + } \ + \ + if (data) { \ + unsigned int size_in_bytes = 0; \ + size_in_bytes = 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; \ + memset(out, 0, sizeof(Vector)); \ + \ + if (!src->size) { \ + return; \ + } \ + \ + if (!bh_vector_init((Vector *)out, src->size, \ + sizeof(wasm_##name##_t *))) { \ + 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; ++i) { \ + elem_destroy_func(*(v->data + i)); \ + } \ + bh_vector_destroy((Vector *)v); \ } - /* integer overflow has been checked in generic_vec_init_data, - no need to check again */ - size_in_bytes = (uint32)(size * sizeof(wasm_byte_t)); - bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); - out->num_elems = size; - return; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_byte_vec_delete(out); -} +WASM_DEFINE_VEC_PLAIN(byte) +WASM_DEFINE_VEC_PLAIN(val) -void -wasm_byte_vec_delete(wasm_byte_vec_t *byte_vec) -{ - if (byte_vec && byte_vec->data) { - bh_vector_destroy((Vector *)byte_vec); - } -} +WASM_DEFINE_VEC_OWN(valtype, wasm_valtype_delete) +WASM_DEFINE_VEC_OWN(functype, wasm_functype_delete) +WASM_DEFINE_VEC_OWN(exporttype, wasm_exporttype_delete) +WASM_DEFINE_VEC_OWN(importtype, wasm_importtype_delete) +WASM_DEFINE_VEC_OWN(store, wasm_store_delete) +WASM_DEFINE_VEC_OWN(module, wasm_module_delete_internal) +WASM_DEFINE_VEC_OWN(instance, wasm_instance_delete_internal) +WASM_DEFINE_VEC_OWN(extern, wasm_extern_delete) /* Runtime Environment */ static void @@ -161,9 +242,7 @@ wasm_engine_delete_internal(wasm_engine_t *engine) } static wasm_engine_t * -wasm_engine_new_internal(mem_alloc_type_t type, - const MemAllocOption *opts, - runtime_mode_e mode) +wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts) { wasm_engine_t *engine = NULL; /* init runtime */ @@ -188,6 +267,7 @@ wasm_engine_new_internal(mem_alloc_type_t type, } if (!wasm_runtime_full_init(&init_args)) { + LOG_DEBUG("wasm_runtime_full_init failed"); goto failed; } @@ -198,73 +278,52 @@ wasm_engine_new_internal(mem_alloc_type_t type, #endif /* create wasm_engine_t */ - engine = malloc_internal(sizeof(wasm_engine_t)); - if (!engine) { + if (!(engine = malloc_internal(sizeof(wasm_engine_t)))) { goto failed; } - /* set running mode */ - LOG_WARNING("running under mode %d", mode); - engine->mode = mode; - /* create wasm_store_vec_t */ - INIT_VEC(engine->stores, wasm_store_vec, 1); + INIT_VEC(engine->stores, wasm_store_vec_new_uninitialized, 1); - return engine; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_engine_delete_internal(engine); - return NULL; + RETURN_OBJ(engine, wasm_engine_delete_internal) } /* global engine instance */ static wasm_engine_t *singleton_engine = NULL; -static inline runtime_mode_e -current_runtime_mode() +static inline bool +run_with_bytecode_module(const wasm_module_t *module) +{ + return Wasm_Module_Bytecode == (*module)->module_type; +} + +static inline bool +run_with_bytecode_module_inst(const WASMModuleInstanceCommon *inst_comm_rt) { - bh_assert(singleton_engine); - return singleton_engine->mode; + return Wasm_Module_Bytecode == inst_comm_rt->module_type; } wasm_engine_t * wasm_engine_new() { - runtime_mode_e mode = INTERP_MODE; -#if WASM_ENABLE_INTERP == 0 && WASM_ENABLE_AOT != 0 - mode = AOT_MODE; -#endif - - if (INTERP_MODE == mode) { -#if WASM_ENABLE_INTERP == 0 - bh_assert(!"does not support INTERP_MODE. Please recompile"); -#endif - } - else { -#if WASM_ENABLE_AOT == 0 - bh_assert(!"does not support AOT_MODE. Please recompile"); -#endif - } - if (!singleton_engine) { singleton_engine = - wasm_engine_new_internal(Alloc_With_System_Allocator, NULL, mode); + wasm_engine_new_internal(Alloc_With_System_Allocator, NULL); } return singleton_engine; } wasm_engine_t * wasm_engine_new_with_args(mem_alloc_type_t type, - const MemAllocOption *opts, - runtime_mode_e mode) + const MemAllocOption *opts) { if (!singleton_engine) { - singleton_engine = wasm_engine_new_internal(type, opts, mode); + singleton_engine = wasm_engine_new_internal(type, opts); } return singleton_engine; } +/* BE AWARE: will RESET the singleton */ void wasm_engine_delete(wasm_engine_t *engine) { @@ -281,36 +340,24 @@ wasm_store_new(wasm_engine_t *engine) bh_assert(engine && singleton_engine == engine); - /* always return the first store */ - if (bh_vector_size((Vector *)singleton_engine->stores) > 0) { - /* - * although it is a copy of the first store, but still point to - * the wasm_store_t - */ - if (!bh_vector_get((Vector *)singleton_engine->stores, 0, &store)) { - goto failed; - } - return store; - } - - store = malloc_internal(sizeof(wasm_store_t)); - if (!store) { - goto failed; + if (!(store = malloc_internal(sizeof(wasm_store_t)))) { + return NULL; } /* new a vector, and new its data */ - INIT_VEC(store->modules, wasm_module_vec, DEFAULT_VECTOR_INIT_LENGTH); - INIT_VEC(store->instances, wasm_instance_vec, DEFAULT_VECTOR_INIT_LENGTH); + 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); /* append to a store list of engine */ if (!bh_vector_append((Vector *)singleton_engine->stores, &store)) { + LOG_DEBUG("bh_vector_append failed"); goto failed; } return store; - failed: - LOG_DEBUG("%s failed", __FUNCTION__); wasm_store_delete(store); return NULL; } @@ -318,82 +365,91 @@ wasm_store_new(wasm_engine_t *engine) void wasm_store_delete(wasm_store_t *store) { - if (!store || singleton_engine->stores->num_elems == 0) { + size_t i, store_count; + + if (!store) { return; } - DEINIT_VEC(store->modules, wasm_module_vec_delete); - DEINIT_VEC(store->instances, wasm_instance_vec_delete); - - wasm_runtime_free(store); - bh_vector_remove((Vector *)singleton_engine->stores, 0, NULL); -} + /* remove it from the list in the engine */ + store_count = bh_vector_size((Vector *)singleton_engine->stores); + for (i = 0; i != store_count; ++i) { + wasm_store_t *tmp; -void -wasm_store_vec_new_uninitialized(wasm_store_vec_t *out, size_t size) -{ - bh_assert(out); - generic_vec_init_data((Vector *)out, size, sizeof(wasm_store_t *)); -} + if (!bh_vector_get((Vector *)singleton_engine->stores, i, &tmp)) { + break; + } -void -wasm_store_vec_delete(wasm_store_vec_t *store_vec) -{ - size_t i = 0; - if (!store_vec || !store_vec->data) { - return; + if (tmp == store) { + bh_vector_remove((Vector *)singleton_engine->stores, i, NULL); + break; + } } - FREE_VEC_ELEMS(store_vec, wasm_store_delete); - bh_vector_destroy((Vector *)store_vec); + DEINIT_VEC(store->modules, wasm_module_vec_delete); + DEINIT_VEC(store->instances, wasm_instance_vec_delete); + wasm_runtime_free(store); } static inline void check_engine_and_store(wasm_engine_t *engine, wasm_store_t *store) { /* remove it if we are supporting more than one store */ - bh_assert(engine && store && engine->stores->data[0] == store); + bh_assert(engine && store); } /* Type Representations */ -static wasm_valtype_t * -wasm_valtype_new_internal(uint8 val_type_rt) +static wasm_valkind_t +val_type_rt_2_valkind(uint8 val_type_rt) { switch (val_type_rt) { case VALUE_TYPE_I32: - return wasm_valtype_new_i32(); + return WASM_I32; case VALUE_TYPE_I64: - return wasm_valtype_new_i64(); + return WASM_I64; case VALUE_TYPE_F32: - return wasm_valtype_new_f32(); + return WASM_F32; case VALUE_TYPE_F64: - return wasm_valtype_new_f64(); + return WASM_F64; case VALUE_TYPE_ANY: - return wasm_valtype_new_anyref(); + return WASM_ANYREF; + case VALUE_TYPE_FUNCREF: + return WASM_FUNCREF; default: - return NULL; + LOG_WARNING("%s meets unsupported type: %d", __FUNCTION__, + val_type_rt); + 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 = malloc_internal(sizeof(wasm_valtype_t)); - if (val_type) { - val_type->kind = kind; + wasm_valtype_t *val_type; + + 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) { - bh_assert(val_type); - wasm_runtime_free(val_type); + FREEIF(val_type); } wasm_valtype_t * -wasm_valtype_copy(wasm_valtype_t *src) +wasm_valtype_copy(const wasm_valtype_t *src) { bh_assert(src); return wasm_valtype_new(src->kind); @@ -420,218 +476,121 @@ wasm_valtype_same(const wasm_valtype_t *vt1, const wasm_valtype_t *vt2) return vt1->kind == vt2->kind; } -void -wasm_valtype_vec_new_uninitialized(wasm_valtype_vec_t *out, size_t size) -{ - bh_assert(out); - generic_vec_init_data((Vector *)out, size, sizeof(wasm_valtype_t *)); -} - -void -wasm_valtype_vec_new_empty(wasm_valtype_vec_t *out) -{ - bh_assert(out); - memset(out, 0, sizeof(wasm_valtype_vec_t)); -} - -void -wasm_valtype_vec_new(wasm_valtype_vec_t *out, - size_t size, - wasm_valtype_t *const data[]) -{ - uint32 size_in_bytes = 0; - bh_assert(out && data); - generic_vec_init_data((Vector *)out, size, sizeof(wasm_valtype_t *)); - if (!out->data) { - goto failed; - } - - /* integer overflow has been checked in generic_vec_init_data, - no need to check again */ - size_in_bytes = (uint32)(size * sizeof(wasm_valtype_t *)); - bh_memcpy_s(out->data, size_in_bytes, data, size_in_bytes); - out->num_elems = size; - return; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_valtype_vec_delete(out); -} - -void -wasm_valtype_vec_copy(wasm_valtype_vec_t *out, const wasm_valtype_vec_t *src) -{ - size_t i = 0; - - bh_assert(out && src); - - generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_valtype_t *)); - if (!out->data) { - goto failed; - } - - /* clone every wasm_valtype_t */ - for (i = 0; i < src->num_elems; i++) { - wasm_valtype_t *cloned = wasm_valtype_copy(*(src->data + i)); - if (!cloned) { - goto failed; - } - if (!bh_vector_append((Vector *)out, &cloned)) { - goto failed; - } - } - - return; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_valtype_vec_delete(out); -} - -void -wasm_valtype_vec_delete(wasm_valtype_vec_t *val_type_vec) -{ - size_t i = 0; - if (!val_type_vec || !val_type_vec->data) { - return; - } - - FREE_VEC_ELEMS(val_type_vec, wasm_valtype_delete); - bh_vector_destroy((Vector *)val_type_vec); -} - static wasm_functype_t * wasm_functype_new_internal(WASMType *type_rt) { - wasm_functype_t *func_type = NULL; + wasm_functype_t *type = NULL; + wasm_valtype_t *param_type = NULL, *result_type = NULL; uint32 i = 0; bh_assert(type_rt); - func_type = malloc_internal(sizeof(wasm_functype_t)); - if (!func_type) { - goto failed; + if (!(type = malloc_internal(sizeof(wasm_functype_t)))) { + return NULL; } - /* WASMType->types[0 : type_rt->param_count) -> func_type->params */ - INIT_VEC(func_type->params, wasm_valtype_vec, type_rt->param_count); + 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) { - wasm_valtype_t *param_type = - wasm_valtype_new_internal(*(type_rt->types + i)); - if (!param_type) { + if (!(param_type = wasm_valtype_new_internal(*(type_rt->types + i)))) { goto failed; } - if (!bh_vector_append((Vector *)func_type->params, ¶m_type)) { + 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) -> func_type->results */ - INIT_VEC(func_type->results, wasm_valtype_vec, type_rt->result_count); + /* 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) { - wasm_valtype_t *result_type = - wasm_valtype_new_internal(*(type_rt->types + type_rt->param_count + i)); - if (!result_type) { + if (!(result_type = wasm_valtype_new_internal( + *(type_rt->types + type_rt->param_count + i)))) { goto failed; } - if (!bh_vector_append((Vector *)func_type->results, &result_type)) { + if (!bh_vector_append((Vector *)type->results, &result_type)) { + LOG_DEBUG("bh_vector_append failed"); goto failed; } } - return func_type; + return type; failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_functype_delete(func_type); + wasm_valtype_delete(param_type); + wasm_valtype_delete(result_type); + wasm_functype_delete(type); return NULL; } wasm_functype_t * -wasm_functype_new(wasm_valtype_vec_t *params, wasm_valtype_vec_t *results) +wasm_functype_new(own wasm_valtype_vec_t *params, + own wasm_valtype_vec_t *results) { - wasm_functype_t *func_type = NULL; + wasm_functype_t *type = NULL; bh_assert(params); bh_assert(results); - func_type = malloc_internal(sizeof(wasm_functype_t)); - if (!func_type) { + if (!(type = malloc_internal(sizeof(wasm_functype_t)))) { goto failed; } - func_type->extern_kind = WASM_EXTERN_FUNC; + type->extern_kind = WASM_EXTERN_FUNC; - func_type->params = malloc_internal(sizeof(wasm_valtype_vec_t)); - if (!func_type->params) { + /* take ownership */ + if (!(type->params = malloc_internal(sizeof(wasm_valtype_vec_t)))) { goto failed; } - - /* transfer ownership of contents of params and results */ - bh_memcpy_s(func_type->params, sizeof(wasm_valtype_vec_t), params, + bh_memcpy_s(type->params, sizeof(wasm_valtype_vec_t), params, sizeof(wasm_valtype_vec_t)); - func_type->results = malloc_internal(sizeof(wasm_valtype_vec_t)); - if (!func_type->results) { + if (!(type->results = malloc_internal(sizeof(wasm_valtype_vec_t)))) { goto failed; } - - bh_memcpy_s(func_type->results, sizeof(wasm_valtype_vec_t), results, + bh_memcpy_s(type->results, sizeof(wasm_valtype_vec_t), results, sizeof(wasm_valtype_vec_t)); - return func_type; + return type; failed: - LOG_DEBUG("%s failed", __FUNCTION__); - if (func_type) - FREEIF(func_type->params); - if (func_type) - FREEIF(func_type->results); - FREEIF(func_type); + wasm_functype_delete(type); return NULL; } wasm_functype_t * -wasm_functype_copy(wasm_functype_t *src) +wasm_functype_copy(const wasm_functype_t *src) { - wasm_functype_t *dst = NULL; + wasm_functype_t *functype; + wasm_valtype_vec_t params = { 0 }, results = { 0 }; bh_assert(src); - dst = malloc_internal(sizeof(wasm_functype_t)); - if (!dst) { - goto failed; - } - - dst->extern_kind = src->extern_kind; - - dst->params = malloc_internal(sizeof(wasm_valtype_vec_t)); - if (!dst->params) { - goto failed; - } - - wasm_valtype_vec_copy(dst->params, src->params); - if (!dst->params) { + wasm_valtype_vec_copy(¶ms, src->params); + if (src->params->size && !params.data) { goto failed; } - dst->results = malloc_internal(sizeof(wasm_valtype_vec_t)); - if (!dst->results) { + wasm_valtype_vec_copy(&results, src->results); + if (src->results->size && !results.data) { goto failed; } - wasm_valtype_vec_copy(dst->results, src->results); - if (!dst->results) { + if (!(functype = wasm_functype_new(¶ms, &results))) { goto failed; } - return dst; + return functype; failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_functype_delete(dst); + wasm_valtype_vec_delete(¶ms); + wasm_valtype_vec_delete(&results); return NULL; } @@ -642,17 +601,8 @@ wasm_functype_delete(wasm_functype_t *func_type) return; } - if (func_type->params) { - wasm_valtype_vec_delete(func_type->params); - wasm_runtime_free(func_type->params); - func_type->params = NULL; - } - - if (func_type->results) { - wasm_valtype_vec_delete(func_type->results); - wasm_runtime_free(func_type->results); - func_type->results = NULL; - } + DEINIT_VEC(func_type->params, wasm_valtype_vec_delete); + DEINIT_VEC(func_type->results, wasm_valtype_vec_delete); wasm_runtime_free(func_type); } @@ -672,51 +622,39 @@ wasm_functype_results(const wasm_functype_t *func_type) } wasm_globaltype_t * -wasm_globaltype_new(wasm_valtype_t *val_type, wasm_mutability_t mut) +wasm_globaltype_new(own wasm_valtype_t *val_type, wasm_mutability_t mut) { wasm_globaltype_t *global_type = NULL; bh_assert(val_type); - global_type = malloc_internal(sizeof(wasm_globaltype_t)); - if (!global_type) { - goto failed; + 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; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_globaltype_delete(global_type); - return NULL; } wasm_globaltype_t * wasm_globaltype_new_internal(uint8 val_type_rt, bool is_mutable) { - wasm_globaltype_t *global_type = NULL; + wasm_globaltype_t *globaltype; + wasm_valtype_t *val_type; - global_type = malloc_internal(sizeof(wasm_globaltype_t)); - if (!global_type) { - goto failed; + if (!(val_type = wasm_valtype_new(val_type_rt_2_valkind(val_type_rt)))) { + return NULL; } - global_type->val_type = wasm_valtype_new_internal(val_type_rt); - if (!global_type->val_type) { - goto failed; + if (!(globaltype = wasm_globaltype_new( + val_type, is_mutable ? WASM_VAR : WASM_CONST))) { + wasm_valtype_delete(val_type); } - global_type->mutability = is_mutable ? WASM_VAR : WASM_CONST; - - return global_type; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_globaltype_delete(global_type); - return NULL; + return globaltype; } void @@ -735,30 +673,22 @@ wasm_globaltype_delete(wasm_globaltype_t *global_type) } wasm_globaltype_t * -wasm_globaltype_copy(wasm_globaltype_t *src) +wasm_globaltype_copy(const wasm_globaltype_t *src) { - wasm_globaltype_t *dst = NULL; + wasm_globaltype_t *global_type; + wasm_valtype_t *val_type; bh_assert(src); - dst = malloc_internal(sizeof(wasm_globaltype_t)); - if (!dst) { - goto failed; + if (!(val_type = wasm_valtype_copy(src->val_type))) { + return NULL; } - dst->val_type = wasm_valtype_copy(src->val_type); - if (!dst->val_type) { - goto failed; + if (!(global_type = wasm_globaltype_new(val_type, src->mutability))) { + wasm_valtype_delete(val_type); } - dst->mutability = src->mutability; - - return dst; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_globaltype_delete(dst); - return NULL; + return global_type; } const wasm_valtype_t * @@ -791,32 +721,434 @@ wasm_globaltype_same(const wasm_globaltype_t *gt1, || gt1->mutability == gt2->mutability; } -wasm_tabletype_t * -wasm_tabletype_new(wasm_valtype_t *val_type, const wasm_limits_t *limits) +static wasm_tabletype_t * +wasm_tabletype_new_internal(uint8 val_type_rt, + uint32 init_size, + uint32 max_size) { - return NULL; -} + wasm_tabletype_t *table_type; + wasm_limits_t limits = { init_size, max_size }; + wasm_valtype_t *val_type; -void -wasm_tabletype_delete(wasm_tabletype_t *table_type) -{} + if (!(val_type = wasm_valtype_new_internal(val_type_rt))) { + return NULL; + } -wasm_memorytype_t * -wasm_memorytype_new(const wasm_limits_t *limits) -{ - return NULL; -} + if (!(table_type = wasm_tabletype_new(val_type, &limits))) { + wasm_valtype_delete(val_type); + } -void -wasm_memorytype_delete(wasm_memorytype_t *memory_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; + + bh_assert(val_type); + + 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; + + bh_assert(src); + + 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) +{ + bh_assert(table_type); + return table_type->val_type; +} + +const wasm_limits_t * +wasm_tabletype_limits(const wasm_tabletype_t *table_type) +{ + bh_assert(table_type); + 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; + bh_assert(limits); + + 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) +{ + bh_assert(src); + return wasm_memorytype_new(&src->limits); +} + +void +wasm_memorytype_delete(wasm_memorytype_t *memory_type) +{ + FREEIF(memory_type); +} + +const wasm_limits_t * +wasm_memorytype_limits(const wasm_memorytype_t *memory_type) +{ + bh_assert(memory_type); + return &(memory_type->limits); +} + +wasm_externkind_t +wasm_externtype_kind(const wasm_externtype_t *extern_type) +{ + bh_assert(extern_type); + 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; + + bh_assert(src); + + 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", __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", __FUNCTION__, + extern_type); + break; + } +} + +own wasm_importtype_t * +wasm_importtype_new(own wasm_byte_vec_t *module, + own wasm_byte_vec_t *name, + own wasm_externtype_t *extern_type) +{ + wasm_importtype_t *import_type = 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, + 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), 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); + 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; + + bh_assert(src); + + 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) +{ + bh_assert(import_type); + return import_type->module_name; +} + +const wasm_byte_vec_t * +wasm_importtype_name(const wasm_importtype_t *import_type) +{ + bh_assert(import_type); + return import_type->name; +} + +const wasm_externtype_t * +wasm_importtype_type(const wasm_importtype_t *import_type) +{ + bh_assert(import_type); + return import_type->extern_type; +} + +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 (!(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; + + bh_assert(src); + + 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) +{ + bh_assert(export_type); + return export_type->name; +} + +const wasm_externtype_t * +wasm_exporttype_type(const wasm_exporttype_t *export_type) +{ + bh_assert(export_type); + return export_type->extern_type; +} /* Runtime Objects */ void wasm_val_delete(wasm_val_t *v) { - /* do nothing */ + FREEIF(v); } void @@ -858,25 +1190,44 @@ wasm_val_same(const wasm_val_t *v1, const wasm_val_t *v2) return false; } -wasm_trap_t * -wasm_trap_new(wasm_store_t *store, const wasm_message_t *message) +static wasm_trap_t * +wasm_trap_new_internal(const char *string) { wasm_trap_t *trap; - bh_assert(store && message); + if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) { + return NULL; + } - trap = malloc_internal(sizeof(wasm_trap_t)); - if (!trap) { + if (!(trap->message = malloc_internal(sizeof(wasm_byte_vec_t)))) { goto failed; } - wasm_byte_vec_new(trap->message, message->num_elems, message->data); - if (!trap->message->data) { + wasm_name_new_from_string_nt(trap->message, string); + if (strlen(string) && !trap->message->data) { goto failed; } 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; + + bh_assert(store && message); + + if (!(trap = malloc_internal(sizeof(wasm_trap_t)))) { + return NULL; + } + INIT_VEC(trap->message, wasm_byte_vec_new, message->size, message->data); + + return trap; failed: wasm_trap_delete(trap); return NULL; @@ -889,15 +1240,13 @@ wasm_trap_delete(wasm_trap_t *trap) return; } - if (trap->message) { - wasm_byte_vec_delete(trap->message); - } + DEINIT_VEC(trap->message, wasm_byte_vec_delete); wasm_runtime_free(trap); } void -wasm_trap_message(const wasm_trap_t *trap, wasm_message_t *out) +wasm_trap_message(const wasm_trap_t *trap, own wasm_message_t *out) { bh_assert(trap && out); wasm_byte_vec_copy(out, trap->message); @@ -920,12 +1269,19 @@ module_to_module_ext(wasm_module_t *module) return (wasm_module_ex_t *)module; } +#if WASM_ENABLE_INTERP != 0 +#define MODULE_INTERP(module) ((WASMModule *)(*module)) +#endif + +#if WASM_ENABLE_AOT != 0 +#define MODULE_AOT(module) ((AOTModule *)(*module)) +#endif + wasm_module_t * wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) { char error[128] = { 0 }; wasm_module_ex_t *module_ex = NULL; - PackageType pkg_type = Package_Type_Unknown; check_engine_and_store(singleton_engine, store); bh_assert(binary && binary->data && binary->size); @@ -935,41 +1291,19 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) return NULL; } - pkg_type = get_package_type((uint8 *)binary->data, (uint32)binary->size); - if (Package_Type_Unknown == pkg_type - || (Wasm_Module_Bytecode == pkg_type - && INTERP_MODE != current_runtime_mode()) - || (Wasm_Module_AoT == pkg_type - && INTERP_MODE == current_runtime_mode())) { - LOG_ERROR( - "current runtime mode %d doesn\'t support the package type %d", - current_runtime_mode(), pkg_type); - return NULL; - } - module_ex = malloc_internal(sizeof(wasm_module_ex_t)); if (!module_ex) { goto failed; } - module_ex->binary = malloc_internal(sizeof(wasm_byte_vec_t)); - if (!module_ex->binary) { - goto failed; - } + INIT_VEC(module_ex->binary, wasm_byte_vec_new, binary->size, binary->data); - wasm_byte_vec_copy(module_ex->binary, binary); - if (!module_ex->binary->data) { - goto failed; - } - - module_ex->module_comm_rt = - wasm_runtime_load((uint8 *)module_ex->binary->data, - (uint32)module_ex->binary->size, - error, (uint32)sizeof(error)); + module_ex->module_comm_rt = wasm_runtime_load( + (uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, error, + (uint32)sizeof(error)); if (!(module_ex->module_comm_rt)) { LOG_ERROR(error); - wasm_module_delete_internal(module_ext_to_module(module_ex)); - return NULL; + goto failed; } /* add it to a watching list in store */ @@ -985,7 +1319,7 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary) return NULL; } -void +static void wasm_module_delete_internal(wasm_module_t *module) { wasm_module_ex_t *module_ex; @@ -994,11 +1328,7 @@ wasm_module_delete_internal(wasm_module_t *module) } module_ex = module_to_module_ext(module); - if (module_ex->binary) { - wasm_byte_vec_delete(module_ex->binary); - wasm_runtime_free(module_ex->binary); - module_ex->binary = NULL; - } + DEINIT_VEC(module_ex->binary, wasm_byte_vec_delete); if (module_ex->module_comm_rt) { wasm_runtime_unload(module_ex->module_comm_rt); @@ -1008,39 +1338,405 @@ wasm_module_delete_internal(wasm_module_t *module) wasm_runtime_free(module_ex); } -/* will release module when releasing the store */ void wasm_module_delete(wasm_module_t *module) { - /* pass */ + /* will release module when releasing the store */ } void -wasm_module_vec_new_uninitialized(wasm_module_vec_t *out, size_t size) +wasm_module_imports(const wasm_module_t *module, + own wasm_importtype_vec_t *out) { - generic_vec_init_data((Vector *)out, size, sizeof(wasm_module_t *)); + uint32 i, import_func_count, import_memory_count, import_global_count, + import_table_count, import_count; + wasm_byte_vec_t module_name = { 0 }, name = { 0 }; + wasm_externtype_t *extern_type = NULL; + wasm_importtype_t *import_type = NULL; + + bh_assert(out); + + if (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + 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 + } + else { +#if WASM_ENABLE_AOT != 0 + 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); + if (import_count && !out->data) { + return; + } + + for (i = 0; i != import_count; ++i) { + char *module_name_rt, *field_name_rt; + + if (i < import_func_count) { + wasm_functype_t *type = NULL; + WASMType *type_rt; + + if (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + 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 + } + else { +#if WASM_ENABLE_AOT != 0 + 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; + } + + 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 (!(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 (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + 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 + } + else { +#if WASM_ENABLE_AOT != 0 + 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 (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + 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 + } + else { +#if WASM_ENABLE_AOT != 0 + 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; + } + + 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 (!(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 (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + 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 + } + else { +#if WASM_ENABLE_AOT != 0 + 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 = VALUE_TYPE_FUNCREF; + 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); + } + + if (!extern_type) { + continue; + } + + 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; + } + } + + return; + +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); + wasm_importtype_vec_delete(out); } void -wasm_module_vec_delete(wasm_module_vec_t *module_vec) +wasm_module_exports(const wasm_module_t *module, wasm_exporttype_vec_t *out) { - size_t i = 0; - if (!module_vec || !module_vec->data) { + uint32 i, export_count; + wasm_byte_vec_t name = { 0 }; + wasm_externtype_t *extern_type = NULL; + wasm_exporttype_t *export_type = NULL; + + bh_assert(out); + + if (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + export_count = MODULE_INTERP(module)->export_count; +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + export_count = MODULE_AOT(module)->export_count; +#endif + } + + wasm_exporttype_vec_new_uninitialized(out, export_count); + if (export_count && !out->data) { return; } - FREE_VEC_ELEMS(module_vec, wasm_module_delete_internal); - bh_vector_destroy((Vector *)module_vec); + for (i = 0; i != export_count; i++) { + WASMExport *export = NULL; + if (run_with_bytecode_module(module)) { +#if WASM_ENABLE_INTERP != 0 + export = MODULE_INTERP(module)->exports + i; +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + 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", __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); } static uint32 argv_to_params(const uint64 *argv, const wasm_valtype_vec_t *param_defs, - wasm_val_t *out) + wasm_val_t out[]) { size_t i = 0; uint32 argc = 0; - void *argv_p = (void *)argv; for (i = 0; i < param_defs->num_elems; i++) { wasm_valtype_t *param_def = param_defs->data[i]; @@ -1048,30 +1744,27 @@ argv_to_params(const uint64 *argv, switch (param_def->kind) { case WASM_I32: param->kind = WASM_I32; - param->of.i32 = *(int32 *)argv_p; - argv_p = (uint32 *)argv_p + 1; + param->of.i32 = *(uint32 *)(argv + i); argc++; break; case WASM_I64: param->kind = WASM_I64; - param->of.i64 = *(int64 *)argv_p; - argv_p = (uint64 *)argv_p + 1; + param->of.i64 = *(uint64 *)(argv + i); argc++; break; case WASM_F32: param->kind = WASM_F32; - param->of.f32 = *(float32 *)argv_p; - argv_p = (float32 *)argv_p + 1; + param->of.f32 = *(float32 *)(argv + i); argc++; break; case WASM_F64: param->kind = WASM_F64; - param->of.f64 = *(float64 *)argv_p; - argv_p = (float64 *)argv_p + 1; + param->of.f64 = *(float64 *)(argv + i); argc++; break; default: - NOT_REACHED(); + LOG_WARNING("%s meets unsupported type: %d", __FUNCTION__, + param_def->kind); goto failed; } } @@ -1088,35 +1781,33 @@ results_to_argv(const wasm_val_t *results, { size_t i = 0; uint32 argc = 0; - void *argv_p = out; for (i = 0; i < result_defs->num_elems; ++i) { wasm_valtype_t *result_def = result_defs->data[i]; const wasm_val_t *result = results + i; switch (result_def->kind) { case WASM_I32: - *(int32 *)argv_p = result->of.i32; - argv_p = (uint32 *)argv_p + 1; + *(int32 *)(out + i) = result->of.i32; argc++; break; case WASM_I64: - *(int64 *)argv_p = result->of.i64; - argv_p = (uint64 *)argv_p + 1; + *(int64 *)(out + i) = result->of.i64; argc++; break; case WASM_F32: - *(float32 *)argv_p = result->of.f32; - argv_p = (float32 *)argv_p + 1; + *(float32 *)(out + i) = result->of.f32; argc++; break; case WASM_F64: - *(float64 *)argv_p = result->of.f64; - argv_p = (float64 *)argv_p + 1; + *(float64 *)(out + i) = result->of.f64; argc++; break; default: - NOT_REACHED(); + { + LOG_WARNING("%s meets unsupported kind", __FUNCTION__, + result_def->kind); goto failed; + } } } @@ -1125,6 +1816,7 @@ results_to_argv(const wasm_val_t *results, return 0; } +static wasm_trap_t *cur_trap = NULL; static void native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) { @@ -1148,8 +1840,8 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) } /* argv -> const wasm_val_t params[] */ - if (!(argc = argv_to_params( - argv, wasm_functype_params(wasm_func_type(func)), params))) { + if (!(argc = argv_to_params(argv, wasm_functype_params(func->type), + params))) { goto failed; } } @@ -1173,15 +1865,16 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) } if (trap) { - wasm_name_t *message = malloc_internal(sizeof(wasm_name_t)); - if (message) { - wasm_trap_message(trap, message); - if (message->data) { - LOG_WARNING("got a trap %s", message->data); - wasm_name_delete(message); - } - FREEIF(message); + wasm_byte_vec_t message = { 0 }; + wasm_trap_message(trap, &message); + if (message.data) { + LOG_WARNING("got a trap %s", message.data); + wasm_runtime_set_exception(exec_env->module_inst, + "call failed, meet a wasm_trap_t"); } + wasm_byte_vec_delete(&message); + + cur_trap = trap; } if (argv) { @@ -1192,7 +1885,7 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) if (!trap && result_count) { /* wasm_val_t results[] -> argv */ if (!(argc = results_to_argv( - results, wasm_functype_results(wasm_func_type(func)), argv))) { + results, wasm_functype_results(func->type), argv))) { goto failed; } } @@ -1203,52 +1896,39 @@ native_func_trampoline(wasm_exec_env_t exec_env, uint64 *argv) return; } -wasm_func_t * -wasm_func_new(wasm_store_t *store, - const wasm_functype_t *func_type, - wasm_func_callback_t callback) +static wasm_func_t * +wasm_func_new_basic(const wasm_functype_t *type, + wasm_func_callback_t func_callback) { wasm_func_t *func = NULL; + bh_assert(type); - check_engine_and_store(singleton_engine, store); - bh_assert(func_type); - - func = malloc_internal(sizeof(wasm_func_t)); - if (!func) { + if (!(func = malloc_internal(sizeof(wasm_func_t)))) { goto failed; } func->kind = WASM_EXTERN_FUNC; func->with_env = false; - func->u.cb = callback; + func->u.cb = func_callback; - func->func_type = wasm_functype_copy((wasm_functype_t *)func_type); - if (!func->func_type) { + if (!(func->type = wasm_functype_copy(type))) { goto failed; } - return func; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_func_delete(func); - return NULL; + RETURN_OBJ(func, wasm_func_delete) } -wasm_func_t * -wasm_func_new_with_env(wasm_store_t *store, - const wasm_functype_t *func_type, - wasm_func_callback_with_env_t callback, - void *env, - void (*finalizer)(void *)) +static wasm_func_t * +wasm_func_new_with_env_basic(const wasm_functype_t *type, + wasm_func_callback_with_env_t callback, + void *env, + void (*finalizer)(void *)) { wasm_func_t *func = NULL; - check_engine_and_store(singleton_engine, store); - bh_assert(func_type); - - func = malloc_internal(sizeof(wasm_func_t)); - if (!func) { + bh_assert(type); + + if (!(func = malloc_internal(sizeof(wasm_func_t)))) { goto failed; } @@ -1258,17 +1938,31 @@ wasm_func_new_with_env(wasm_store_t *store, func->u.cb_env.env = env; func->u.cb_env.finalizer = finalizer; - func->func_type = wasm_functype_copy((wasm_functype_t *)func_type); - if (!func->func_type) { + if (!(func->type = wasm_functype_copy(type))) { goto failed; } - return func; + RETURN_OBJ(func, wasm_func_delete) +} -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_func_delete(func); - return NULL; +wasm_func_t * +wasm_func_new(wasm_store_t *store, + const wasm_functype_t *type, + wasm_func_callback_t callback) +{ + check_engine_and_store(singleton_engine, store); + return wasm_func_new_basic(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 *)) +{ + check_engine_and_store(singleton_engine, store); + return wasm_func_new_with_env_basic(type, callback, env, finalizer); } static wasm_func_t * @@ -1289,7 +1983,7 @@ wasm_func_new_internal(wasm_store_t *store, func->kind = WASM_EXTERN_FUNC; - if (INTERP_MODE == current_runtime_mode()) { + if (run_with_bytecode_module_inst(inst_comm_rt)) { #if WASM_ENABLE_INTERP != 0 bh_assert(func_idx_rt < ((WASMModuleInstance *)inst_comm_rt)->function_count); @@ -1303,11 +1997,17 @@ wasm_func_new_internal(wasm_store_t *store, else { #if WASM_ENABLE_AOT != 0 /* use same index to trace the function type in AOTFuncType **func_types */ - AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; - AOTFunctionInstance *func_aot = - (AOTFunctionInstance *)inst_aot->export_funcs.ptr + func_idx_rt; - type_rt = func_aot->is_import_func ? func_aot->u.func_import->func_type - : func_aot->u.func.func_type; + AOTModule *module_aot = + ((AOTModuleInstance *)inst_comm_rt)->aot_module.ptr; + if (func_idx_rt < module_aot->import_func_count) { + type_rt = (module_aot->import_funcs + func_idx_rt)->func_type; + } + else { + func_idx_rt -= module_aot->import_func_count; + type_rt = + module_aot + ->func_types[module_aot->func_type_indexes[func_idx_rt]]; + } #endif } @@ -1315,8 +2015,8 @@ wasm_func_new_internal(wasm_store_t *store, goto failed; } - func->func_type = wasm_functype_new_internal(type_rt); - if (!func->func_type) { + func->type = wasm_functype_new_internal(type_rt); + if (!func->type) { goto failed; } @@ -1340,9 +2040,9 @@ wasm_func_delete(wasm_func_t *func) return; } - if (func->func_type) { - wasm_functype_delete(func->func_type); - func->func_type = NULL; + if (func->type) { + wasm_functype_delete(func->type); + func->type = NULL; } if (func->with_env) { @@ -1356,49 +2056,32 @@ wasm_func_delete(wasm_func_t *func) wasm_runtime_free(func); } -wasm_func_t * +own wasm_func_t * wasm_func_copy(const wasm_func_t *func) { wasm_func_t *cloned = NULL; bh_assert(func); - cloned = malloc_internal(sizeof(wasm_func_t)); - if (!cloned) { + if (!(cloned = func->with_env + ? wasm_func_new_with_env_basic( + func->type, func->u.cb_env.cb, func->u.cb_env.env, + func->u.cb_env.finalizer) + : wasm_func_new_basic(func->type, func->u.cb))) { goto failed; } - cloned->kind = func->kind; - cloned->with_env = func->with_env; - if (cloned->with_env) { - cloned->u.cb_env.cb = func->u.cb_env.cb; - cloned->u.cb_env.env = func->u.cb_env.env; - cloned->u.cb_env.finalizer = func->u.cb_env.finalizer; - } - else { - cloned->u.cb = func->u.cb; - } - cloned->func_idx_rt = func->func_idx_rt; cloned->inst_comm_rt = func->inst_comm_rt; - cloned->func_type = wasm_functype_copy(func->func_type); - if (!cloned->func_type) { - goto failed; - } - return cloned; - -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_func_delete(cloned); - return NULL; + RETURN_OBJ(cloned, wasm_func_delete) } -wasm_functype_t * +own wasm_functype_t * wasm_func_type(const wasm_func_t *func) { bh_assert(func); - return func->func_type; + return wasm_functype_copy(func->type); } static uint32 @@ -1479,27 +2162,36 @@ argv_to_results(const uint32 *results, switch (def->kind) { case WASM_I32: + { out->kind = WASM_I32; out->of.i32 = *(int32 *)result; result += 1; break; + } case WASM_I64: + { out->kind = WASM_I64; out->of.i64 = *(int64 *)result; result += 2; break; + } case WASM_F32: + { out->kind = WASM_F32; out->of.f32 = *(float32 *)result; result += 1; break; + } case WASM_F64: + { out->kind = WASM_F64; out->of.f64 = *(float64 *)result; result += 2; break; + } default: - LOG_DEBUG("unexpected parameter val type %d", def->kind); + LOG_WARNING("%s meets unsupported type: %d", __FUNCTION__, + def->kind); goto failed; } out++; @@ -1526,9 +2218,13 @@ wasm_func_call(const wasm_func_t *func, WASMFunctionInstanceCommon *func_comm_rt = NULL; size_t param_count, result_count, alloc_count; - bh_assert(func && func->func_type && func->inst_comm_rt); + bh_assert(func && func->type && func->inst_comm_rt); + + /* TODO: how to check whether its store still exists */ - if (INTERP_MODE == current_runtime_mode()) { + cur_trap = NULL; + + if (run_with_bytecode_module_inst(func->inst_comm_rt)) { #if WASM_ENABLE_INTERP != 0 func_comm_rt = ((WASMModuleInstance *)func->inst_comm_rt)->functions + func->func_idx_rt; @@ -1556,54 +2252,58 @@ wasm_func_call(const wasm_func_t *func, /* copy parametes */ if (param_count - && !(argc = params_to_argv(params, - wasm_functype_params(wasm_func_type(func)), - wasm_func_param_arity(func), argv))) { + && !(argc = params_to_argv(params, wasm_functype_params(func->type), + param_count, argv))) { goto failed; } if (!wasm_runtime_create_exec_env_and_call_wasm( func->inst_comm_rt, func_comm_rt, argc, argv)) { - LOG_DEBUG("wasm_runtime_create_exec_env_and_call_wasm failed"); - goto failed; + 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 - && !(argc = argv_to_results( - argv, wasm_functype_results(wasm_func_type(func)), - wasm_func_result_arity(func), results))) { - goto failed; + if (result_count) { + if (!(argc = argv_to_results(argv, wasm_functype_results(func->type), + result_count, results))) { + goto failed; + } } FREEIF(argv); - /* should return trap */ return NULL; failed: - LOG_DEBUG("%s failed", __FUNCTION__); FREEIF(argv); - return NULL; + if (cur_trap) { + return cur_trap; + } + else { + if (wasm_runtime_get_exception(func->inst_comm_rt)) { + return wasm_trap_new_internal( + wasm_runtime_get_exception(func->inst_comm_rt)); + } + else { + return wasm_trap_new_internal("wasm_func_call failed"); + } + } } size_t wasm_func_param_arity(const wasm_func_t *func) { - bh_assert(func && func->func_type && func->func_type->params); - return func->func_type->params->num_elems; + bh_assert(func && func->type && func->type->params); + return func->type->params->num_elems; } size_t wasm_func_result_arity(const wasm_func_t *func) { - bh_assert(func && func->func_type && func->func_type->results); - return func->func_type->results->num_elems; -} - -wasm_extern_t * -wasm_func_as_extern(wasm_func_t *func) -{ - return (wasm_extern_t *)func; + bh_assert(func && func->type && func->type->results); + return func->type->results->num_elems; } wasm_global_t * @@ -1622,7 +2322,7 @@ wasm_global_new(wasm_store_t *store, } global->kind = WASM_EXTERN_GLOBAL; - global->type = wasm_globaltype_copy((wasm_globaltype_t *)global_type); + global->type = wasm_globaltype_copy(global_type); if (!global->type) { goto failed; } @@ -1657,7 +2357,7 @@ wasm_global_copy(const wasm_global_t *src) } global->kind = WASM_EXTERN_GLOBAL; - global->type = wasm_globaltype_copy((wasm_globaltype_t *)src->type); + global->type = wasm_globaltype_copy(src->type); if (!global->type) { goto failed; } @@ -1689,7 +2389,6 @@ wasm_global_delete(wasm_global_t *global) if (global->init) { wasm_val_delete(global->init); - wasm_runtime_free(global->init); global->init = NULL; } @@ -1901,155 +2600,388 @@ aot_global_get(const AOTModuleInstance *inst_aot, } return ret; } -#endif +#endif + +void +wasm_global_set(wasm_global_t *global, const wasm_val_t *v) +{ + bh_assert(global && v); + + if (run_with_bytecode_module_inst(global->inst_comm_rt)) { +#if WASM_ENABLE_INTERP != 0 + (void)interp_global_set((WASMModuleInstance *)global->inst_comm_rt, + global->global_idx_rt, v); +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + (void)aot_global_set((AOTModuleInstance *)global->inst_comm_rt, + global->global_idx_rt, v); +#endif + } +} + +void +wasm_global_get(const wasm_global_t *global, wasm_val_t *out) +{ + bh_assert(global && out); + + memset(out, 0, sizeof(wasm_val_t)); + + if (run_with_bytecode_module_inst(global->inst_comm_rt)) { +#if WASM_ENABLE_INTERP != 0 + (void)interp_global_get((WASMModuleInstance *)global->inst_comm_rt, + global->global_idx_rt, out); +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + (void)aot_global_get((AOTModuleInstance *)global->inst_comm_rt, + global->global_idx_rt, out); +#endif + } + + bh_assert(global->init->kind == out->kind); +} + +static 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; + + check_engine_and_store(singleton_engine, store); + bh_assert(inst_comm_rt); + + global = malloc_internal(sizeof(wasm_global_t)); + if (!global) { + goto failed; + } + + /* + * global->module_name = NULL; + * global->name = NULL; + */ + global->kind = WASM_EXTERN_GLOBAL; + + if (run_with_bytecode_module_inst(inst_comm_rt)) { +#if WASM_ENABLE_INTERP != 0 + WASMGlobalInstance *global_interp = + ((WASMModuleInstance *)inst_comm_rt)->globals + global_idx_rt; + val_type_rt = global_interp->type; + is_mutable = global_interp->is_mutable; +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; + AOTModule *module_aot = inst_aot->aot_module.ptr; + 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 + } + + 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 (run_with_bytecode_module_inst(inst_comm_rt)) { +#if WASM_ENABLE_INTERP != 0 + interp_global_get((WASMModuleInstance *)inst_comm_rt, global_idx_rt, + global->init); +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + 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) +{ + bh_assert(global); + return wasm_globaltype_copy(global->type); +} + +static wasm_table_t * +wasm_table_new_basic(const wasm_tabletype_t *type) +{ + wasm_table_t *table = NULL; + + bh_assert(type); + + if (!(table = malloc_internal(sizeof(wasm_table_t)))) { + goto failed; + } + + table->kind = WASM_EXTERN_TABLE; + + if (!(table->type = wasm_tabletype_copy(type))) { + goto failed; + } + + RETURN_OBJ(table, wasm_table_delete); +} + +static 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; + + check_engine_and_store(singleton_engine, store); + bh_assert(inst_comm_rt); + + if (!(table = malloc_internal(sizeof(wasm_table_t)))) { + goto failed; + } + + table->kind = WASM_EXTERN_TABLE; + + if (run_with_bytecode_module_inst(inst_comm_rt)) { +#if WASM_ENABLE_INTERP != 0 + WASMTableInstance *table_interp = + ((WASMModuleInstance *)inst_comm_rt)->tables[table_idx_rt]; + val_type_rt = table_interp->elem_type; + init_size = table_interp->cur_size; + max_size = table_interp->max_size; +#endif + } + else { +#if WASM_ENABLE_AOT != 0 + AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; + AOTModule *module_aot = (AOTModule *)inst_aot->aot_module.ptr; + + if (table_idx_rt < module_aot->import_table_count) { + AOTImportTable *table_aot = + module_aot->import_tables + table_idx_rt; + val_type_rt = VALUE_TYPE_FUNCREF; + init_size = table_aot->table_init_size; + max_size = table_aot->table_max_size; + } + else { + AOTTable *table_aot = + module_aot->tables + + (table_idx_rt - module_aot->import_table_count); + val_type_rt = VALUE_TYPE_FUNCREF; + init_size = table_aot->table_init_size; + max_size = table_aot->table_max_size; + } +#endif + } + + 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); +} + +wasm_table_t * +wasm_table_new(wasm_store_t *store, + const wasm_tabletype_t *table_type, + wasm_ref_t *init) +{ + (void)init; + check_engine_and_store(singleton_engine, store); + return wasm_table_new_basic(table_type); +} + +wasm_table_t * +wasm_table_copy(const wasm_table_t *src) +{ + return wasm_table_new_basic(src->type); +} + +void +wasm_table_delete(wasm_table_t *table) +{ + if (!table) { + return; + } + + if (table->type) { + wasm_tabletype_delete(table->type); + table->type = NULL; + } + + wasm_runtime_free(table); +} + +wasm_tabletype_t * +wasm_table_type(const wasm_table_t *table) +{ + bh_assert(table); + return wasm_tabletype_copy(table->type); +} -void -wasm_global_set(wasm_global_t *global, const wasm_val_t *v) +static wasm_memory_t * +wasm_memory_new_basic(const wasm_memorytype_t *type) { - bh_assert(global && v); + wasm_memory_t *memory = NULL; - if (INTERP_MODE == current_runtime_mode()) { -#if WASM_ENABLE_INTERP != 0 - (void)interp_global_set((WASMModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, v); -#endif - } - else { -#if WASM_ENABLE_AOT != 0 - (void)aot_global_set((AOTModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, v); -#endif + bh_assert(type); + + if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) { + goto failed; } + + memory->kind = WASM_EXTERN_MEMORY; + memory->type = wasm_memorytype_copy(type); + + RETURN_OBJ(memory, wasm_memory_delete) } -void -wasm_global_get(const wasm_global_t *global, wasm_val_t *out) +wasm_memory_t * +wasm_memory_new(wasm_store_t *store, const wasm_memorytype_t *type) { - bh_assert(global && out); + check_engine_and_store(singleton_engine, store); + return wasm_memory_new_basic(type); +} - memset(out, 0, sizeof(wasm_val_t)); +wasm_memory_t * +wasm_memory_copy(const wasm_memory_t *src) +{ + wasm_memory_t *dst = NULL; - if (INTERP_MODE == current_runtime_mode()) { -#if WASM_ENABLE_INTERP != 0 - (void)interp_global_get((WASMModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, out); -#endif - } - else { -#if WASM_ENABLE_AOT != 0 - (void)aot_global_get((AOTModuleInstance *)global->inst_comm_rt, - global->global_idx_rt, out); -#endif + bh_assert(src); + + if (!(dst = wasm_memory_new_basic(src->type))) { + goto failed; } - bh_assert(global->init->kind == out->kind); + dst->memory_idx_rt = src->memory_idx_rt; + dst->inst_comm_rt = src->inst_comm_rt; + + RETURN_OBJ(dst, wasm_memory_delete) } -static wasm_global_t * -wasm_global_new_internal(wasm_store_t *store, - uint16 global_idx_rt, +static wasm_memory_t * +wasm_memory_new_internal(wasm_store_t *store, + uint16 memory_idx_rt, WASMModuleInstanceCommon *inst_comm_rt) { - wasm_global_t *global = NULL; - uint8 val_type_rt = 0; - bool is_mutable = 0; + wasm_memory_t *memory = NULL; + uint32 min_pages = 0, max_pages = 0; check_engine_and_store(singleton_engine, store); bh_assert(inst_comm_rt); - global = malloc_internal(sizeof(wasm_global_t)); - if (!global) { + if (!(memory = malloc_internal(sizeof(wasm_memory_t)))) { goto failed; } - /* - * global->module_name = NULL; - * global->name = NULL; - */ - global->kind = WASM_EXTERN_GLOBAL; + memory->kind = WASM_EXTERN_MEMORY; - if (INTERP_MODE == current_runtime_mode()) { + if (run_with_bytecode_module_inst(inst_comm_rt)) { #if WASM_ENABLE_INTERP != 0 - WASMGlobalInstance *global_interp = - ((WASMModuleInstance *)inst_comm_rt)->globals + global_idx_rt; - val_type_rt = global_interp->type; - is_mutable = global_interp->is_mutable; + 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; #endif } else { #if WASM_ENABLE_AOT != 0 AOTModuleInstance *inst_aot = (AOTModuleInstance *)inst_comm_rt; - AOTModule *module_aot = inst_aot->aot_module.ptr; - 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; + AOTModule *module_aot = (AOTModule *)(inst_aot->aot_module.ptr); + + 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 { - 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; + min_pages = module_aot->memories->mem_init_page_count; + max_pages = module_aot->memories->mem_max_page_count; } #endif } - global->type = wasm_globaltype_new_internal(val_type_rt, is_mutable); - if (!global->type) { + if (!(memory->type = wasm_memorytype_new_internal(min_pages, max_pages))) { goto failed; } - global->init = malloc_internal(sizeof(wasm_val_t)); - if (!global->init) { - goto failed; - } + memory->inst_comm_rt = inst_comm_rt; + memory->memory_idx_rt = memory_idx_rt; - if (INTERP_MODE == current_runtime_mode()) { -#if WASM_ENABLE_INTERP != 0 - interp_global_get((WASMModuleInstance *)inst_comm_rt, global_idx_rt, - global->init); -#endif - } - else { -#if WASM_ENABLE_AOT != 0 - aot_global_get((AOTModuleInstance *)inst_comm_rt, global_idx_rt, - global->init); -#endif - } + RETURN_OBJ(memory, wasm_memory_delete); +} - global->inst_comm_rt = inst_comm_rt; - global->global_idx_rt = global_idx_rt; +void +wasm_memory_delete(wasm_memory_t *memory) +{ + if (!memory) { + return; + } - return global; + if (memory->type) { + wasm_memorytype_delete(memory->type); + memory->type = NULL; + } -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_global_delete(global); - return NULL; + wasm_runtime_free(memory); } -wasm_globaltype_t * -wasm_global_type(const wasm_global_t *global) +wasm_memorytype_t * +wasm_memory_type(const wasm_memory_t *memory) { - bh_assert(global); - return global->type; + bh_assert(memory); + return wasm_memorytype_copy(memory->type); } -wasm_extern_t * -wasm_global_as_extern(wasm_global_t *global) +byte_t * +wasm_memory_data(wasm_memory_t *memory) { - return (wasm_extern_t *)global; + return (byte_t *)wasm_runtime_get_memory_data(memory->inst_comm_rt, + memory->memory_idx_rt); } -void -wasm_table_delete(wasm_table_t *table) -{} - -void -wasm_memory_delete(wasm_memory_t *memory) -{} +size_t +wasm_memory_data_size(const wasm_memory_t *memory) +{ + return wasm_runtime_get_memory_data_size(memory->inst_comm_rt, + memory->memory_idx_rt); +} #if WASM_ENABLE_INTERP != 0 static bool @@ -2068,8 +3000,12 @@ interp_link_func(const wasm_instance_t *inst, imported_func_interp = module_interp->import_functions + func_idx_rt; bh_assert(imported_func_interp); - cloned = wasm_func_copy(import); - if (!cloned || !bh_vector_append((Vector *)inst->imports, &cloned)) { + if (!(cloned = wasm_func_copy(import))) { + return false; + } + + if (!bh_vector_append((Vector *)inst->imports, &cloned)) { + wasm_func_delete(cloned); return false; } @@ -2127,22 +3063,6 @@ interp_link_global(const WASMModule *module_interp, return true; } -static bool -interp_link_memory(const WASMModule *module_interp, - uint16 memory_inst_index, - wasm_memory_t *import) -{ - return false; -} - -static bool -interp_link_table(const WASMModule *module_interp, - uint16 table_inst_index, - wasm_table_t *import) -{ - return false; -} - static uint32 interp_link(const wasm_instance_t *inst, const WASMModule *module_interp, @@ -2151,10 +3071,6 @@ interp_link(const wasm_instance_t *inst, uint32 i = 0; uint32 import_func_i = 0; uint32 import_global_i = 0; - uint32 import_table_i = 0; - uint32 import_memory_i = 0; - wasm_func_t *func = NULL; - wasm_global_t *global = NULL; bh_assert(inst && module_interp && imports); @@ -2164,40 +3080,35 @@ interp_link(const wasm_instance_t *inst, switch (import_rt->kind) { case IMPORT_KIND_FUNC: - func = wasm_extern_as_func(import); + { if (!interp_link_func(inst, module_interp, import_func_i++, - func)) { + wasm_extern_as_func(import))) { goto failed; } break; + } case IMPORT_KIND_GLOBAL: - global = wasm_extern_as_global(import); + { if (!interp_link_global(module_interp, import_global_i++, - global)) { + wasm_extern_as_global(import))) { goto failed; } break; + } case IMPORT_KIND_MEMORY: - if (!interp_link_memory(module_interp, import_memory_i++, - wasm_extern_as_memory(import))) { - goto failed; - }; - break; case IMPORT_KIND_TABLE: - if (!interp_link_table(module_interp, import_table_i++, - wasm_extern_as_table(import))) { - goto failed; - } + ASSERT_NOT_IMPLEMENTED(); break; default: - NOT_REACHED(); - break; + LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, + import_rt->kind); + goto failed; } } - return module_interp->import_count; + return i; failed: LOG_DEBUG("%s failed", __FUNCTION__); @@ -2211,8 +3122,6 @@ interp_process_export(wasm_store_t *store, { WASMExport *exports = NULL; WASMExport *export = NULL; - wasm_func_t *func = NULL; - wasm_global_t *global = NULL; wasm_extern_t *external = NULL; uint32 export_cnt = 0; uint32 i = 0; @@ -2227,30 +3136,56 @@ interp_process_export(wasm_store_t *store, switch (export->kind) { case EXPORT_KIND_FUNC: - func = wasm_func_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp); - if (!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: - global = wasm_global_new_internal( - store, export->index, - (WASMModuleInstanceCommon *)inst_interp); - if (!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_MEMORY: + } case EXPORT_KIND_TABLE: - /* TODO: */ + { + 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; } @@ -2262,7 +3197,7 @@ interp_process_export(wasm_store_t *store, return true; failed: - LOG_DEBUG("%s failed", __FUNCTION__); + wasm_extern_delete(external); return false; } #endif /* WASM_ENABLE_INTERP */ @@ -2282,13 +3217,12 @@ aot_link_func(const wasm_instance_t *inst, import_aot_func = module_aot->import_funcs + import_func_idx_rt; bh_assert(import_aot_func); - cloned = wasm_func_copy(import); - if (!cloned || !bh_vector_append((Vector *)inst->imports, &cloned)) { + if (!(cloned = wasm_func_copy(import))) { return false; } import_aot_func->call_conv_raw = true; - import_aot_func->attachment = wasm_func_copy(import); + import_aot_func->attachment = cloned; import_aot_func->func_ptr_linked = native_func_trampoline; import->func_idx_rt = import_func_idx_rt; @@ -2308,6 +3242,7 @@ aot_link_global(const AOTModule *module_aot, import_aot_global = module_aot->import_globals + global_idx_rt; bh_assert(import_aot_global); + //TODO: import->type ? val_type = wasm_globaltype_content(wasm_global_type(import)); bh_assert(val_type); @@ -2378,8 +3313,8 @@ aot_link(const wasm_instance_t *inst, break; case WASM_EXTERN_MEMORY: - break; case WASM_EXTERN_TABLE: + ASSERT_NOT_IMPLEMENTED(); break; default: goto failed; @@ -2398,8 +3333,7 @@ aot_process_export(wasm_store_t *store, const AOTModuleInstance *inst_aot, wasm_extern_vec_t *externals) { - uint32 i = 0; - uint32 export_func_i = 0; + uint32 i; wasm_extern_t *external = NULL; AOTModule *module_aot = NULL; @@ -2410,34 +3344,59 @@ aot_process_export(wasm_store_t *store, for (i = 0; i < module_aot->export_count; ++i) { AOTExport *export = module_aot->exports + i; - wasm_func_t *func = NULL; - wasm_global_t *global = NULL; switch (export->kind) { case EXPORT_KIND_FUNC: - func = - wasm_func_new_internal(store, export_func_i++, - (WASMModuleInstanceCommon *)inst_aot); - if (!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: - global = wasm_global_new_internal( - store, export->index, (WASMModuleInstanceCommon *)inst_aot); - if (!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_MEMORY: + } 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: - NOT_REACHED(); + LOG_WARNING("%s meets unsupported kind: %d", __FUNCTION__, + export->kind); goto failed; } @@ -2449,7 +3408,7 @@ aot_process_export(wasm_store_t *store, return true; failed: - LOG_DEBUG("%s failed", __FUNCTION__); + wasm_extern_delete(external); return false; } #endif /* WASM_ENABLE_AOT */ @@ -2458,7 +3417,7 @@ wasm_instance_t * wasm_instance_new(wasm_store_t *store, const wasm_module_t *module, const wasm_extern_t *const imports[], - wasm_trap_t **traps) + own wasm_trap_t **traps) { char error[128] = { 0 }; const uint32 stack_size = 16 * 1024; @@ -2477,18 +3436,19 @@ wasm_instance_new(wasm_store_t *store, /* link module and imports */ if (imports) { - if (INTERP_MODE == current_runtime_mode()) { + if (run_with_bytecode_module(module)) { #if WASM_ENABLE_INTERP != 0 - import_count = ((WASMModule *)*module)->import_count; - INIT_VEC(instance->imports, wasm_extern_vec, import_count); - if (!instance->imports) { - goto failed; - } + import_count = MODULE_INTERP(module)->import_count; + + INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized, + import_count); if (import_count) { - import_count = interp_link(instance, (WASMModule *)*module, - (wasm_extern_t **)imports); - if ((int32)import_count < 0) { + uint32 actual_link_import_count = interp_link( + instance, MODULE_INTERP(module), (wasm_extern_t **)imports); + /* make sure a complete import list */ + if ((int32)import_count < 0 + || import_count != actual_link_import_count) { goto failed; } } @@ -2496,17 +3456,16 @@ wasm_instance_new(wasm_store_t *store, } else { #if WASM_ENABLE_AOT != 0 - import_count = ((AOTModule *)*module)->import_func_count - + ((AOTModule *)*module)->import_global_count - + ((AOTModule *)*module)->import_memory_count - + ((AOTModule *)*module)->import_table_count; - INIT_VEC(instance->imports, wasm_extern_vec, import_count); - if (!instance->imports) { - goto failed; - } + import_count = MODULE_AOT(module)->import_func_count + + MODULE_AOT(module)->import_global_count + + MODULE_AOT(module)->import_memory_count + + MODULE_AOT(module)->import_table_count; + + INIT_VEC(instance->imports, wasm_extern_vec_new_uninitialized, + import_count); if (import_count) { - import_count = aot_link(instance, (AOTModule *)*module, + import_count = aot_link(instance, MODULE_AOT(module), (wasm_extern_t **)imports); if ((int32)import_count < 0) { goto failed; @@ -2523,8 +3482,8 @@ wasm_instance_new(wasm_store_t *store, goto failed; } - /* fill in inst */ - for (i = 0; i < (uint32)import_count; ++i) { + /* fill with inst */ + for (i = 0; imports && i < (uint32)import_count; ++i) { wasm_extern_t *import = (wasm_extern_t *)imports[i]; switch (import->kind) { case WASM_EXTERN_FUNC: @@ -2549,12 +3508,13 @@ wasm_instance_new(wasm_store_t *store, } /* build the exports list */ - if (INTERP_MODE == current_runtime_mode()) { + if (run_with_bytecode_module_inst(instance->inst_comm_rt)) { #if WASM_ENABLE_INTERP != 0 uint32 export_cnt = ((WASMModuleInstance *)instance->inst_comm_rt)->module->export_count; - INIT_VEC(instance->exports, wasm_extern_vec, export_cnt); + INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized, + export_cnt); if (!interp_process_export( store, (WASMModuleInstance *)instance->inst_comm_rt, @@ -2566,9 +3526,13 @@ wasm_instance_new(wasm_store_t *store, else { #if WASM_ENABLE_AOT != 0 uint32 export_cnt = - ((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count; + ((AOTModuleInstance *)instance->inst_comm_rt)->export_func_count + + ((AOTModuleInstance *)instance->inst_comm_rt)->export_global_count + + ((AOTModuleInstance *)instance->inst_comm_rt)->export_tab_count + + ((AOTModuleInstance *)instance->inst_comm_rt)->export_mem_count; - INIT_VEC(instance->exports, wasm_extern_vec, export_cnt); + INIT_VEC(instance->exports, wasm_extern_vec_new_uninitialized, + export_cnt); if (!aot_process_export(store, (AOTModuleInstance *)instance->inst_comm_rt, @@ -2591,7 +3555,7 @@ wasm_instance_new(wasm_store_t *store, return NULL; } -void +static void wasm_instance_delete_internal(wasm_instance_t *instance) { if (!instance) { @@ -2608,58 +3572,46 @@ wasm_instance_delete_internal(wasm_instance_t *instance) wasm_runtime_free(instance); } -/* will release instance when releasing the store */ void wasm_instance_delete(wasm_instance_t *module) { - /* pass */ + /* will release instance when releasing the store */ } void -wasm_instance_exports(const wasm_instance_t *instance, wasm_extern_vec_t *out) +wasm_instance_exports(const wasm_instance_t *instance, + own wasm_extern_vec_t *out) { bh_assert(instance && out); wasm_extern_vec_copy(out, instance->exports); } -void -wasm_instance_vec_new_uninitialized(wasm_instance_vec_t *out, size_t size) -{ - generic_vec_init_data((Vector *)out, size, sizeof(wasm_instance_t *)); -} - -void -wasm_instance_vec_delete(wasm_instance_vec_t *instance_vec) -{ - size_t i = 0; - if (!instance_vec || !instance_vec->data) { - return; - } - - FREE_VEC_ELEMS(instance_vec, wasm_instance_delete_internal); - bh_vector_destroy((Vector *)instance_vec); -} - wasm_extern_t * wasm_extern_copy(const wasm_extern_t *src) { wasm_extern_t *dst = NULL; - wasm_func_t *func = NULL; - wasm_global_t *global = NULL; bh_assert(src); switch (wasm_extern_kind(src)) { case WASM_EXTERN_FUNC: - func = wasm_func_copy(wasm_extern_as_func_const(src)); - dst = wasm_func_as_extern(func); + dst = wasm_func_as_extern( + wasm_func_copy(wasm_extern_as_func_const(src))); break; case WASM_EXTERN_GLOBAL: - global = wasm_global_copy(wasm_extern_as_global_const(src)); - dst = wasm_global_as_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; } @@ -2690,8 +3642,14 @@ wasm_extern_delete(wasm_extern_t *external) 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; } } @@ -2699,102 +3657,73 @@ wasm_extern_delete(wasm_extern_t *external) wasm_externkind_t wasm_extern_kind(const wasm_extern_t *extrenal) { - return (wasm_externkind_t)extrenal->kind; -} - -wasm_func_t * -wasm_extern_as_func(wasm_extern_t *external) -{ - return (wasm_func_t *)external; -} - -const wasm_func_t * -wasm_extern_as_func_const(const wasm_extern_t *external) -{ - return (const wasm_func_t *)external; -} - -wasm_global_t * -wasm_extern_as_global(wasm_extern_t *external) -{ - return (wasm_global_t *)external; -} - -const wasm_global_t * -wasm_extern_as_global_const(const wasm_extern_t *external) -{ - return (const wasm_global_t *)external; -} - -wasm_memory_t * -wasm_extern_as_memory(wasm_extern_t *external) -{ - return (wasm_memory_t *)external; -} - -const wasm_memory_t * -wasm_extern_as_memory_const(const wasm_extern_t *external) -{ - return (const wasm_memory_t *)external; -} - -wasm_table_t * -wasm_extern_as_table(wasm_extern_t *external) -{ - return (wasm_table_t *)external; + return extrenal->kind; } -const wasm_table_t * -wasm_extern_as_table_const(const wasm_extern_t *external) +own wasm_externtype_t * +wasm_extern_type(const wasm_extern_t *external) { - return (const wasm_table_t *)external; + 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; } -void -wasm_extern_vec_copy(wasm_extern_vec_t *out, const wasm_extern_vec_t *src) -{ - size_t i = 0; - bh_assert(out && src); +#define BASIC_FOUR_LIST(V) \ + V(func) \ + V(global) \ + V(memory) \ + V(table) - generic_vec_init_data((Vector *)out, src->size, sizeof(wasm_extern_t *)); - if (!out->data) { - goto failed; +#define WASM_EXTERN_AS_OTHER(name) \ + wasm_##name##_t *wasm_extern_as_##name(wasm_extern_t *external) \ + { \ + return (wasm_##name##_t *)external; \ } - for (i = 0; i < src->num_elems; ++i) { - wasm_extern_t *orig = *(src->data + i); - wasm_extern_t *cloned = wasm_extern_copy(orig); - if (!cloned) { - goto failed; - } +BASIC_FOUR_LIST(WASM_EXTERN_AS_OTHER) +#undef WASM_EXTERN_AS_OTHER - if (!bh_vector_append((Vector *)out, &cloned)) { - goto failed; - } +#define WASM_OTHER_AS_EXTERN(name) \ + wasm_extern_t *wasm_##name##_as_extern(wasm_##name##_t *other) \ + { \ + return (wasm_extern_t *)other; \ } - return; +BASIC_FOUR_LIST(WASM_OTHER_AS_EXTERN) +#undef WASM_OTHER_AS_EXTERN -failed: - LOG_DEBUG("%s failed", __FUNCTION__); - wasm_extern_vec_delete(out); - return; -} +#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; \ + } -void -wasm_extern_vec_new_uninitialized(wasm_extern_vec_t *out, size_t size) -{ - generic_vec_init_data((Vector *)out, size, sizeof(wasm_extern_t *)); -} +BASIC_FOUR_LIST(WASM_EXTERN_AS_OTHER_CONST) +#undef WASM_EXTERN_AS_OTHER_CONST -void -wasm_extern_vec_delete(wasm_extern_vec_t *extern_vec) -{ - size_t i = 0; - if (!extern_vec || !extern_vec->data) { - return; +#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; \ } - FREE_VEC_ELEMS(extern_vec, wasm_extern_delete); - bh_vector_destroy((Vector *)extern_vec); -} +BASIC_FOUR_LIST(WASM_OTHER_AS_EXTERN_CONST) +#undef WASM_OTHER_AS_EXTERN_CONST diff --git a/core/iwasm/common/wasm_c_api_internal.h b/core/iwasm/common/wasm_c_api_internal.h index f2d5c65f8a..b308968be0 100644 --- a/core/iwasm/common/wasm_c_api_internal.h +++ b/core/iwasm/common/wasm_c_api_internal.h @@ -24,17 +24,9 @@ WASM_DECLARE_VEC(module, *) WASM_DECLARE_VEC(instance, *) /* Runtime Environment */ -typedef enum runtime_mode_e { - INTERP_MODE = 0, - JIT_MODE, - AOT_MODE -} runtime_mode_e; - struct wasm_engine_t { /* support one store for now */ wasm_store_vec_t *stores; - /* Interpreter by deault */ - runtime_mode_e mode; }; struct wasm_store_t { @@ -64,13 +56,13 @@ struct wasm_globaltype_t { struct wasm_tabletype_t { uint32 extern_kind; /* always be WASM_FUNCREF */ - wasm_valtype_t *type; - wasm_limits_t *limits; + wasm_valtype_t *val_type; + wasm_limits_t limits; }; struct wasm_memorytype_t { uint32 extern_kind; - wasm_limits_t *limits; + wasm_limits_t limits; }; struct wasm_externtype_t { @@ -78,16 +70,15 @@ struct wasm_externtype_t { uint8 data[1]; }; -struct wasm_import_type_t { - uint32 extern_kind; +struct wasm_importtype_t { wasm_name_t *module_name; wasm_name_t *name; + wasm_externtype_t *extern_type; }; -struct wasm_export_type_t { - uint32 extern_kind; - wasm_name_t *module_name; +struct wasm_exporttype_t { wasm_name_t *name; + wasm_externtype_t *extern_type; }; /* Runtime Objects */ @@ -104,7 +95,7 @@ struct wasm_func_t { wasm_name_t *name; uint16 kind; - wasm_functype_t *func_type; + wasm_functype_t *type; bool with_env; union { @@ -169,7 +160,7 @@ struct wasm_table_t { struct wasm_extern_t { wasm_name_t *module_name; wasm_name_t *name; - uint16 kind; + wasm_externkind_t kind; uint8 data[1]; }; diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 8e122906c1..5c63336045 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -454,14 +454,16 @@ wasm_runtime_destroy_registered_module_list() bh_list_remove(registered_module_list, reg_module); /* now, it is time to release every module in the runtime */ + if (reg_module->module->module_type == Wasm_Module_Bytecode) { #if WASM_ENABLE_INTERP != 0 - if (reg_module->module->module_type == Wasm_Module_Bytecode) wasm_unload((WASMModule *)reg_module->module); #endif + } + else { #if WASM_ENABLE_AOT != 0 - if (reg_module->module->module_type == Wasm_Module_AoT) aot_unload((AOTModule *)reg_module->module); #endif + } /* destroy the file buffer */ if (destroyer && reg_module->orig_file_buf) { @@ -4318,3 +4320,244 @@ wasm_runtime_dump_call_stack(WASMExecEnv *exec_env) } #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */ +bool +wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + WASMType **out) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_comm->module_type == Wasm_Module_Bytecode) { + WASMModule *module = (WASMModule *)module_comm; + + if (export->index < module->import_function_count) { + *out = + module->import_functions[export->index].u.function.func_type; + } + else { + *out = + module->functions[export->index - module->import_function_count] + ->func_type; + } + return true; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module_comm->module_type == Wasm_Module_AoT) { + AOTModule *module = (AOTModule *)module_comm; + + if (export->index < module->import_func_count) { + *out = module->func_types[module->import_funcs[export->index] + .func_type_index]; + } + else { + *out = + module->func_types[module->func_type_indexes + [export->index - module->import_func_count]]; + } + return true; + } +#endif + return false; +} + +bool +wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint8 *out_val_type, + bool *out_mutability) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_comm->module_type == Wasm_Module_Bytecode) { + WASMModule *module = (WASMModule *)module_comm; + + if (export->index < module->import_global_count) { + WASMGlobalImport *import_global = + &((module->import_globals + export->index)->u.global); + *out_val_type = import_global->type; + *out_mutability = import_global->is_mutable; + } + else { + WASMGlobal *global = + module->globals + (export->index - module->import_global_count); + *out_val_type = global->type; + *out_mutability = global->is_mutable; + } + return true; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module_comm->module_type == Wasm_Module_AoT) { + AOTModule *module = (AOTModule *)module_comm; + + if (export->index < module->import_global_count) { + AOTImportGlobal *import_global = + module->import_globals + export->index; + *out_val_type = import_global->type; + *out_mutability = import_global->is_mutable; + } + else { + AOTGlobal *global = + module->globals + (export->index - module->import_global_count); + *out_val_type = global->type; + *out_mutability = global->is_mutable; + } + return true; + } +#endif + return false; +} + +bool +wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint32 *out_min_page, + uint32 *out_max_page) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_comm->module_type == Wasm_Module_Bytecode) { + WASMModule *module = (WASMModule *)module_comm; + + if (export->index < module->import_memory_count) { + WASMMemoryImport *import_memory = + &((module->import_memories + export->index)->u.memory); + *out_min_page = import_memory->init_page_count; + *out_max_page = import_memory->max_page_count; + } + else { + WASMMemory *memory = + module->memories + (export->index - module->import_memory_count); + *out_min_page = memory->init_page_count; + *out_max_page = memory->max_page_count; + } + return true; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module_comm->module_type == Wasm_Module_AoT) { + AOTModule *module = (AOTModule *)module_comm; + + if (export->index < module->import_memory_count) { + AOTImportMemory *import_memory = + module->import_memories + export->index; + *out_min_page = import_memory->mem_init_page_count; + *out_max_page = import_memory->mem_max_page_count; + } + else { + AOTMemory *memory = + module->memories + (export->index - module->import_memory_count); + *out_min_page = memory->mem_init_page_count; + *out_max_page = memory->mem_max_page_count; + } + return true; + } +#endif + return false; +} + +bool +wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint8 *out_elem_type, + uint32 *out_min_size, + uint32 *out_max_size) +{ +#if WASM_ENABLE_INTERP != 0 + if (module_comm->module_type == Wasm_Module_Bytecode) { + WASMModule *module = (WASMModule *)module_comm; + + if (export->index < module->import_table_count) { + WASMTableImport *import_table = + &((module->import_tables + export->index)->u.table); + *out_elem_type = import_table->elem_type; + *out_min_size = import_table->init_size; + *out_max_size = import_table->max_size; + } + else { + WASMTable *table = + module->tables + (export->index - module->import_table_count); + *out_elem_type = table->elem_type; + *out_min_size = table->init_size; + *out_max_size = table->max_size; + } + return true; + } +#endif + +#if WASM_ENABLE_AOT != 0 + if (module_comm->module_type == Wasm_Module_AoT) { + AOTModule *module = (AOTModule *)module_comm; + + if (export->index < module->import_table_count) { + AOTImportTable *import_table = + module->import_tables + export->index; + *out_elem_type = VALUE_TYPE_FUNCREF; + *out_min_size = import_table->table_init_size; + *out_max_size = import_table->table_max_size; + } + else { + AOTTable *table = + module->tables + (export->index - module->import_table_count); + *out_elem_type = table->elem_type; + *out_min_size = table->table_init_size; + *out_max_size = table->table_max_size; + } + return true; + } +#endif + return false; +} + +uint8 * +wasm_runtime_get_memory_data(const WASMModuleInstanceCommon *module_inst_comm, + uint32 memory_inst_idx) +{ +#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_inst_idx]; + return 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.ptr + memory_inst_idx; + return memory_inst->memory_data.ptr; + } +#endif + return NULL; +} + +uint32 +wasm_runtime_get_memory_data_size( + const WASMModuleInstanceCommon *module_inst_comm, + uint32 memory_inst_idx) +{ +#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_inst_idx]; + return 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.ptr + memory_inst_idx; + return memory_inst->cur_page_count * memory_inst->num_bytes_per_page; + } +#endif + return 0; +} + diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 01a0c21bee..6be32fae11 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -744,6 +744,38 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env, bool ret, uint32 *argv); #endif +bool +wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + WASMType **out); + +bool +wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint8 *out_val_type, + bool *out_mutability); + +bool +wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint32 *out_min_page, + uint32 *out_max_page); + +bool +wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm, + const WASMExport *export, + uint8 *out_elem_type, + uint32 *out_min_size, + uint32 *out_max_size); + +uint8 * +wasm_runtime_get_memory_data(const WASMModuleInstanceCommon *module_inst_comm, + uint32 memory_inst_idx); + +uint32 +wasm_runtime_get_memory_data_size(const WASMModuleInstanceCommon *module_inst_comm, + uint32 memory_inst_idx); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/include/wasm_c_api.h b/core/iwasm/include/wasm_c_api.h index 6f1a9c519a..88e514be02 100644 --- a/core/iwasm/include/wasm_c_api.h +++ b/core/iwasm/include/wasm_c_api.h @@ -29,15 +29,15 @@ extern "C" { // Auxiliaries // Machine types -#if (__STDC_VERSION__ > 199901L) -inline void assertions() { +#if (__STDC_VERSION__) > 199901L +inline void assertions(void) { static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type"); static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type"); static_assert(sizeof(intptr_t) == sizeof(uint32_t) || sizeof(intptr_t) == sizeof(uint64_t), "incompatible pointer type"); } -#endif /* __STDC_VERSION__ > 199901L */ +#endif typedef char byte_t; typedef float float32_t; @@ -79,7 +79,7 @@ typedef double float64_t; // Vectors // size: capacity // num_elems: current number of elements -// size_of_elem: size of one element +// size_of_elem: size of one elemen #define WASM_DECLARE_VEC(name, ptr_or_none) \ typedef struct wasm_##name##_vec_t { \ size_t size; \ @@ -115,6 +115,12 @@ typedef wasm_byte_vec_t wasm_name_t; static inline void wasm_name_new_from_string( own wasm_name_t* out, const char* s +) { + wasm_name_new(out, strlen(s), s); +} + +static inline void wasm_name_new_from_string_nt( + own wasm_name_t* out, const char* s ) { wasm_name_new(out, strlen(s) + 1, s); } @@ -123,11 +129,21 @@ static inline void wasm_name_new_from_string( /////////////////////////////////////////////////////////////////////////////// // Runtime Environment +// Configuration + +WASM_DECLARE_OWN(config) + +WASM_API_EXTERN own wasm_config_t* wasm_config_new(void); + +// Embedders may provide custom functions for manipulating configs. + + // Engine WASM_DECLARE_OWN(engine) -WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(); +WASM_API_EXTERN own wasm_engine_t* wasm_engine_new(void); +WASM_API_EXTERN own wasm_engine_t* wasm_engine_new_with_config(own wasm_config_t*); // Store @@ -162,7 +178,7 @@ static const uint32_t wasm_limits_max_default = 0xffffffff; WASM_DECLARE_OWN(name) \ WASM_DECLARE_VEC(name, *) \ \ - WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*); + WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); // Value Types @@ -334,7 +350,12 @@ WASM_DECLARE_VEC(val, ) WASM_DECLARE_OWN(name) \ \ WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \ - WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); + WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \ + \ + WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \ + WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \ + WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \ + wasm_##name##_t*, void*, void (*)(void*)); #define WASM_DECLARE_REF(name) \ WASM_DECLARE_REF_BASE(name) \ @@ -354,17 +375,42 @@ WASM_DECLARE_VEC(val, ) WASM_DECLARE_REF_BASE(ref) + +// Frames + +WASM_DECLARE_OWN(frame) +WASM_DECLARE_VEC(frame, *) +WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*); + +WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*); +WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*); +WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*); +WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*); + + // Traps typedef wasm_name_t wasm_message_t; // null terminated -WASM_DECLARE_REF_BASE(trap) +WASM_DECLARE_REF(trap) WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*); WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out); +WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*); +WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out); + + +// Foreign Objects + +WASM_DECLARE_REF(foreign) + +WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*); + // Modules +// WASM_DECLARE_SHARABLE_REF(module) + #ifndef WASM_MODULE_T_DEFINED #define WASM_MODULE_T_DEFINED struct WASMModuleCommon; @@ -374,12 +420,9 @@ typedef struct WASMModuleCommon *wasm_module_t; WASM_API_EXTERN own wasm_module_t* wasm_module_new( wasm_store_t*, const wasm_byte_vec_t* binary); -WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary); - WASM_API_EXTERN void wasm_module_delete(own wasm_module_t*); -WASM_API_EXTERN own wasm_module_t* wasm_module_copy(const wasm_module_t*); -WASM_API_EXTERN bool wasm_module_same(const wasm_module_t*, const wasm_module_t*); +WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary); WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out); WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out); @@ -393,7 +436,7 @@ WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const WASM_DECLARE_REF(func) typedef own wasm_trap_t* (*wasm_func_callback_t)( - const wasm_val_t args[], wasm_val_t results[]); + const wasm_val_t args[], own wasm_val_t results[]); typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( void* env, const wasm_val_t args[], wasm_val_t results[]); @@ -413,7 +456,7 @@ WASM_API_EXTERN own wasm_trap_t* wasm_func_call( // Global Instances -WASM_DECLARE_REF_BASE(global) +WASM_DECLARE_REF(global) WASM_API_EXTERN own wasm_global_t* wasm_global_new( wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*); @@ -426,7 +469,7 @@ WASM_API_EXTERN void wasm_global_set(wasm_global_t*, const wasm_val_t*); // Table Instances -WASM_DECLARE_REF_BASE(table) +WASM_DECLARE_REF(table) typedef uint32_t wasm_table_size_t; @@ -444,7 +487,7 @@ WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, was // Memory Instances -WASM_DECLARE_REF_BASE(memory) +WASM_DECLARE_REF(memory) typedef uint32_t wasm_memory_pages_t; @@ -463,7 +506,7 @@ WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta) // Externals -WASM_DECLARE_REF_BASE(extern) +WASM_DECLARE_REF(extern) WASM_DECLARE_VEC(extern, *) WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*); @@ -492,10 +535,10 @@ WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_exte // Module Instances -WASM_DECLARE_REF_BASE(instance) +WASM_DECLARE_REF(instance) WASM_API_EXTERN own wasm_instance_t* wasm_instance_new( - wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[], + wasm_store_t*, const wasm_module_t*, const wasm_extern_t *const imports[], own wasm_trap_t** ); @@ -505,32 +548,38 @@ WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_exte /////////////////////////////////////////////////////////////////////////////// // Convenience +// Vectors + +#define WASM_EMPTY_VEC {0, NULL, 0, 0} +#define WASM_ARRAY_VEC(array) {sizeof(array)/sizeof(*(array)), array, sizeof(array)/sizeof(*(array)), sizeof(*(array))} + + // Value Type construction short-hands -static inline own wasm_valtype_t* wasm_valtype_new_i32() { +static inline own wasm_valtype_t* wasm_valtype_new_i32(void) { return wasm_valtype_new(WASM_I32); } -static inline own wasm_valtype_t* wasm_valtype_new_i64() { +static inline own wasm_valtype_t* wasm_valtype_new_i64(void) { return wasm_valtype_new(WASM_I64); } -static inline own wasm_valtype_t* wasm_valtype_new_f32() { +static inline own wasm_valtype_t* wasm_valtype_new_f32(void) { return wasm_valtype_new(WASM_F32); } -static inline own wasm_valtype_t* wasm_valtype_new_f64() { +static inline own wasm_valtype_t* wasm_valtype_new_f64(void) { return wasm_valtype_new(WASM_F64); } -static inline own wasm_valtype_t* wasm_valtype_new_anyref() { +static inline own wasm_valtype_t* wasm_valtype_new_anyref(void) { return wasm_valtype_new(WASM_ANYREF); } -static inline own wasm_valtype_t* wasm_valtype_new_funcref() { +static inline own wasm_valtype_t* wasm_valtype_new_funcref(void) { return wasm_valtype_new(WASM_FUNCREF); } // Function Types construction short-hands -static inline own wasm_functype_t* wasm_functype_new_0_0() { +static inline own wasm_functype_t* wasm_functype_new_0_0(void) { wasm_valtype_vec_t params, results; wasm_valtype_vec_new_empty(¶ms); wasm_valtype_vec_new_empty(&results); @@ -677,6 +726,13 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) { #endif } +#define WASM_I32_VAL(i) {.kind = WASM_I32, .of = {.i32 = i}} +#define WASM_I64_VAL(i) {.kind = WASM_I64, .of = {.i64 = i}} +#define WASM_F32_VAL(z) {.kind = WASM_F32, .of = {.f32 = z}} +#define WASM_F64_VAL(z) {.kind = WASM_F64, .of = {.f64 = z}} +#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}} +#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}} + /////////////////////////////////////////////////////////////////////////////// diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 3861376a53..3a02888081 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -3417,21 +3417,18 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, if (function->is_import_func) { #if WASM_ENABLE_MULTI_MODULE != 0 if (function->import_module_inst) { - LOG_DEBUG("it is a function of a sub module"); wasm_interp_call_func_import(module_inst, exec_env, function, frame); } else #endif { - LOG_DEBUG("it is an native function"); /* it is a native function */ wasm_interp_call_func_native(module_inst, exec_env, function, frame); } } else { - LOG_DEBUG("it is a function of the module itself"); wasm_interp_call_func_bytecode(module_inst, exec_env, function, frame); } @@ -3440,13 +3437,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, for (i = 0; i < function->ret_cell_num; i++) { argv[i] = *(frame->sp + i - function->ret_cell_num); } - - if (function->ret_cell_num) { - LOG_DEBUG("first return value argv[0]=%d", argv[0]); - } - else { - LOG_DEBUG("no return value"); - } } else { #if WASM_ENABLE_DUMP_CALL_STACK != 0 diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index c1af8a8fd2..edcf15f441 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -377,7 +377,6 @@ const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, } if (node) { - LOG_DEBUG("reuse %s", node->str); return node->str; } @@ -703,7 +702,8 @@ wasm_loader_resolve_function(const char *module_name, module_reg = wasm_runtime_find_module_registered(module_name); if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) { - LOG_DEBUG("can not find a module named %s for function", module_name); + LOG_DEBUG("can not find a module named %s for function %s", + module_name, function_name); set_error_buf(error_buf, error_buf_size, "unknown import"); return NULL; } @@ -1722,8 +1722,6 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, /* 0x00/0x01/0x02/0x03 */ kind = read_uint8(p); - LOG_DEBUG("import #%d: (%s, %s), kind: %d", - i, sub_module_name, field_name, kind); switch (kind) { case IMPORT_KIND_FUNC: /* import function */ bh_assert(import_functions); @@ -2947,7 +2945,6 @@ load_from_sections(WASMModule *module, WASMSection *sections, while (section) { buf = section->section_body; buf_end = buf + section->section_body_size; - LOG_DEBUG("load section, type: %d", section->section_type); switch (section->section_type) { case SECTION_TYPE_USER: /* unsupported user section, ignore it. */ diff --git a/samples/simple/profiles/arm-interp/toolchain.cmake b/samples/simple/profiles/arm-interp/toolchain.cmake index 2bd47b420c..604141d0af 100644 --- a/samples/simple/profiles/arm-interp/toolchain.cmake +++ b/samples/simple/profiles/arm-interp/toolchain.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception INCLUDE(CMakeForceCompiler) SET(CMAKE_SYSTEM_NAME Linux) # this one is important diff --git a/samples/simple/profiles/arm-interp/wamr_config_simple.cmake b/samples/simple/profiles/arm-interp/wamr_config_simple.cmake index db33d5f60c..90bb2f8d1c 100644 --- a/samples/simple/profiles/arm-interp/wamr_config_simple.cmake +++ b/samples/simple/profiles/arm-interp/wamr_config_simple.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_TARGET ARM) set (WAMR_BUILD_INTERP 1) diff --git a/samples/simple/profiles/arm64-aot/toolchain.cmake b/samples/simple/profiles/arm64-aot/toolchain.cmake index 6d674ce706..182504fea3 100644 --- a/samples/simple/profiles/arm64-aot/toolchain.cmake +++ b/samples/simple/profiles/arm64-aot/toolchain.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception INCLUDE(CMakeForceCompiler) SET(CMAKE_SYSTEM_NAME Linux) # this one is important diff --git a/samples/simple/profiles/arm64-aot/wamr_config_simple.cmake b/samples/simple/profiles/arm64-aot/wamr_config_simple.cmake index 81d8103ea7..7e6604885e 100644 --- a/samples/simple/profiles/arm64-aot/wamr_config_simple.cmake +++ b/samples/simple/profiles/arm64-aot/wamr_config_simple.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_TARGET AARCH64) set (WAMR_BUILD_INTERP 1) diff --git a/samples/simple/profiles/arm64-interp/toolchain.cmake b/samples/simple/profiles/arm64-interp/toolchain.cmake index 6d674ce706..182504fea3 100644 --- a/samples/simple/profiles/arm64-interp/toolchain.cmake +++ b/samples/simple/profiles/arm64-interp/toolchain.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception INCLUDE(CMakeForceCompiler) SET(CMAKE_SYSTEM_NAME Linux) # this one is important diff --git a/samples/simple/profiles/arm64-interp/wamr_config_simple.cmake b/samples/simple/profiles/arm64-interp/wamr_config_simple.cmake index 804e71cba9..13fb9ac132 100644 --- a/samples/simple/profiles/arm64-interp/wamr_config_simple.cmake +++ b/samples/simple/profiles/arm64-interp/wamr_config_simple.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_TARGET AARCH64) set (WAMR_BUILD_INTERP 1) diff --git a/samples/simple/profiles/host-aot/wamr_config_simple.cmake b/samples/simple/profiles/host-aot/wamr_config_simple.cmake index a3317f0372..1f8cf9f8ff 100644 --- a/samples/simple/profiles/host-aot/wamr_config_simple.cmake +++ b/samples/simple/profiles/host-aot/wamr_config_simple.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_TARGET X86_64) set (WAMR_BUILD_INTERP 1) diff --git a/samples/simple/profiles/host-interp/wamr_config_simple.cmake b/samples/simple/profiles/host-interp/wamr_config_simple.cmake index a3317f0372..1f8cf9f8ff 100644 --- a/samples/simple/profiles/host-interp/wamr_config_simple.cmake +++ b/samples/simple/profiles/host-interp/wamr_config_simple.cmake @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception set (WAMR_BUILD_PLATFORM "linux") set (WAMR_BUILD_TARGET X86_64) set (WAMR_BUILD_INTERP 1) diff --git a/samples/simple/src/iwasm_main.c b/samples/simple/src/iwasm_main.c index 4d0a355fbf..31d897ab9c 100644 --- a/samples/simple/src/iwasm_main.c +++ b/samples/simple/src/iwasm_main.c @@ -1,3 +1,7 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ #ifndef CONNECTION_UART #include diff --git a/samples/simple/src/main.c b/samples/simple/src/main.c index 5bf24ce67d..26de7eecd5 100644 --- a/samples/simple/src/main.c +++ b/samples/simple/src/main.c @@ -1,3 +1,8 @@ +/* + * Copyright (C) 2019 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + extern void iwasm_main(); int main(int argc, char *argv[]) { diff --git a/samples/wasm-c-api/CMakeLists.txt b/samples/wasm-c-api/CMakeLists.txt index 93235eaff5..144bfa89cf 100644 --- a/samples/wasm-c-api/CMakeLists.txt +++ b/samples/wasm-c-api/CMakeLists.txt @@ -31,10 +31,10 @@ if(NOT DEFINED WAMR_BUILD_INTERP) endif() if(NOT DEFINED WAMR_BUILD_AOT) - set(WAMR_BUILD_AOT 0) + set(WAMR_BUILD_AOT 1) endif() -if(NOT DEFINED WAMR_BUILD_JOT) +if(NOT DEFINED WAMR_BUILD_JIT) set(WAMR_BUILD_JIT 0) endif() @@ -43,7 +43,7 @@ set(WAMR_BUILD_LIBC_WASI 0) set(WAMR_BUILD_MULTI_MODULE 1) if(NOT DEFINED WAMR_BUILD_FAST_INTERP) - set(WAMR_BUILD_FAST_INTERP 0) + set(WAMR_BUILD_FAST_INTERP 1) endif() if (NOT MSVC) @@ -68,6 +68,7 @@ add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE}) if (MSVC) target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=) endif() +target_link_libraries (vmlib ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread) ################################################ ################ application related ################ @@ -86,29 +87,54 @@ include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake) set(MM_UTIL src/utils/multi_module_utils.c) # build executable for each .c -file(GLOB SOURCES src/*.c) -foreach(SRC ${SOURCES}) - get_filename_component(APPNAME ${SRC} NAME_WE) +set(EXAMPLES + hello + callback + global + reflect + trap + # multi # AOT/JIT return multiple values + # globalexportimport # AOT/JIT doesn't suppport MULTI_MODULE +) + +foreach(EX ${EXAMPLES}) + set(SRC ${CMAKE_CURRENT_LIST_DIR}/src/${EX}.c) - add_executable(${APPNAME} ${SRC} ${UNCOMMON_SHARED_SOURCE} ${MM_UTIL}) - target_include_directories(${APPNAME} PRIVATE ${UNCOMMON_SHARED_DIR}) - target_link_libraries(${APPNAME} vmlib -lpthread -lm) + add_executable(${EX} ${SRC} ${UNCOMMON_SHARED_SOURCE} ${MM_UTIL}) + target_include_directories(${EX} PRIVATE ${UNCOMMON_SHARED_DIR}) + target_link_libraries(${EX} vmlib -lpthread -lm) if (MSVC) - target_compile_definitions(${APPNAME} PRIVATE WASM_API_EXTERN=) + target_compile_definitions(${EX} PRIVATE WASM_API_EXTERN=) endif() endforeach() # wat to wasm -file(GLOB WAT_FILES src/*.wat) -foreach(WAT_FILE ${WAT_FILES}) - get_filename_component(WATNAME ${WAT_FILE} NAME_WE) - - add_custom_target(${WATNAME}_WASM ALL - COMMAND ${WAT2WASM} ${WAT_FILE} -o ${PROJECT_BINARY_DIR}/${WATNAME}.wasm - DEPENDS ${WAT_FILE} - BYPRODUCTS ${PROJECT_BINARY_DIR}/${WATNAME}.wasm +foreach(EX ${EXAMPLES}) + set(SRC ${CMAKE_CURRENT_LIST_DIR}/src/${EX}.wat) + + add_custom_target(${EX}_WASM ALL + COMMAND ${WAT2WASM} ${SRC} -o ${PROJECT_BINARY_DIR}/${EX}.wasm + DEPENDS ${SRC} + BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.wasm VERBATIM - SOURCES ${WAT_FILE} + SOURCES ${SRC} ) endforeach() -################################################ + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + find_program(VALGRIND + valgrind + REQUIRED + ) + + if(VALGRIND) + foreach(EX ${EXAMPLES}) + add_custom_target(${EX}_LEAK_TEST + COMMAND ${VALGRIND} --tool=memcheck --leak-check=yes --show-reachable=yes ./${EX} + DEPENDS ${EX} ${EX}_WASM + VERBATIM + SOURCES ${EX} + ) + endforeach() + endif (VALGRIND) +endif (CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/samples/wasm-c-api/src/LICENSE b/samples/wasm-c-api/src/LICENSE new file mode 100644 index 0000000000..8f71f43fee --- /dev/null +++ b/samples/wasm-c-api/src/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/samples/wasm-c-api/src/callback.c b/samples/wasm-c-api/src/callback.c index 52349c3309..ed0b60df5f 100644 --- a/samples/wasm-c-api/src/callback.c +++ b/samples/wasm-c-api/src/callback.c @@ -4,14 +4,6 @@ #include #include "wasm_c_api.h" -#include "wasm_export.h" -#include "bh_platform.h" - -extern bool -reader(const char *module_name, uint8 **p_buffer, uint32 *p_size); - -extern void -destroyer(uint8 *buffer, uint32 size); #define own @@ -69,8 +61,6 @@ own wasm_trap_t* closure_callback( int main(int argc, const char* argv[]) { - wasm_runtime_set_module_reader(reader, destroyer); - // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); @@ -78,11 +68,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); -#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0 - FILE* file = fopen("callback.aot", "rb"); -#else FILE* file = fopen("callback.wasm", "rb"); -#endif if (!file) { printf("> Error loading module!\n"); return 1; @@ -154,12 +140,8 @@ int main(int argc, const char* argv[]) { // Call. printf("Calling export...\n"); - wasm_val_t args[2]; - args[0].kind = WASM_I32; - args[0].of.i32 = 3; - args[1].kind = WASM_I32; - args[1].of.i32 = 4; - wasm_val_t results[1]; + wasm_val_t args[2] = { WASM_I32_VAL(3), WASM_I32_VAL(4) }; + wasm_val_t results[1] = { WASM_INIT_VAL }; if (wasm_func_call(run_func, args, results)) { printf("> Error calling function!\n"); return 1; diff --git a/samples/wasm-c-api/src/global.c b/samples/wasm-c-api/src/global.c index a7b5c16af9..053fef7109 100644 --- a/samples/wasm-c-api/src/global.c +++ b/samples/wasm-c-api/src/global.c @@ -4,14 +4,6 @@ #include #include "wasm_c_api.h" -#include "wasm_export.h" -#include "bh_platform.h" - -extern bool -reader(const char *module_name, uint8 **p_buffer, uint32 *p_size); - -extern void -destroyer(uint8 *buffer, uint32 size); #define own @@ -54,8 +46,6 @@ wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) { int main(int argc, const char* argv[]) { - wasm_runtime_set_module_reader(reader, destroyer); - // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); @@ -63,11 +53,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); -#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0 - FILE* file = fopen("global.aot", "rb"); -#else FILE* file = fopen("global.wasm", "rb"); -#endif if (!file) { printf("> Error loading module!\n"); return 1; @@ -104,16 +90,16 @@ int main(int argc, const char* argv[]) { own wasm_globaltype_t* var_i64_type = wasm_globaltype_new( wasm_valtype_new(WASM_I64), WASM_VAR); - wasm_val_t val_f32_1 = {.kind = WASM_F32, .of = {.f32 = 1}}; + wasm_val_t val_f32_1 = WASM_F32_VAL(1); own wasm_global_t* const_f32_import = wasm_global_new(store, const_f32_type, &val_f32_1); - wasm_val_t val_i64_2 = {.kind = WASM_I64, .of = {.i64 = 2}}; + wasm_val_t val_i64_2 = WASM_I64_VAL(2); own wasm_global_t* const_i64_import = wasm_global_new(store, const_i64_type, &val_i64_2); - wasm_val_t val_f32_3 = {.kind = WASM_F32, .of = {.f32 = 3}}; + wasm_val_t val_f32_3 = WASM_F32_VAL(3); own wasm_global_t* var_f32_import = wasm_global_new(store, var_f32_type, &val_f32_3); - wasm_val_t val_i64_4 = {.kind = WASM_I64, .of = {.i64 = 4}}; + wasm_val_t val_i64_4 = WASM_I64_VAL(4); own wasm_global_t* var_i64_import = wasm_global_new(store, var_i64_type, &val_i64_4); @@ -189,13 +175,13 @@ int main(int argc, const char* argv[]) { check_call(get_var_i64_export, i64, 8); // Modify variables through API and check again. - wasm_val_t val33 = {.kind = WASM_F32, .of = {.f32 = 33}}; + wasm_val_t val33 = WASM_F32_VAL(33); wasm_global_set(var_f32_import, &val33); - wasm_val_t val34 = {.kind = WASM_I64, .of = {.i64 = 34}}; + wasm_val_t val34 = WASM_I64_VAL(34); wasm_global_set(var_i64_import, &val34); - wasm_val_t val37 = {.kind = WASM_F32, .of = {.f32 = 37}}; + wasm_val_t val37 = WASM_F32_VAL(37); wasm_global_set(var_f32_export, &val37); - wasm_val_t val38 = {.kind = WASM_I64, .of = {.i64 = 38}}; + wasm_val_t val38 = WASM_I64_VAL(38); wasm_global_set(var_i64_export, &val38); check_global(var_f32_import, f32, 33); @@ -209,13 +195,13 @@ int main(int argc, const char* argv[]) { check_call(get_var_i64_export, i64, 38); // Modify variables through calls and check again. - wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} }; + wasm_val_t args73[] = { WASM_F32_VAL(73) }; wasm_func_call(set_var_f32_import, args73, NULL); - wasm_val_t args74[] = { {.kind = WASM_I64, .of = {.i64 = 74}} }; + wasm_val_t args74[] = { WASM_I64_VAL(74) }; wasm_func_call(set_var_i64_import, args74, NULL); - wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} }; + wasm_val_t args77[] = { WASM_F32_VAL(77) }; wasm_func_call(set_var_f32_export, args77, NULL); - wasm_val_t args78[] = { {.kind = WASM_I64, .of = {.i64 = 78}} }; + wasm_val_t args78[] = { WASM_I64_VAL(78) }; wasm_func_call(set_var_i64_export, args78, NULL); check_global(var_f32_import, f32, 73); diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index db8281c362..1ea538b0dc 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -4,14 +4,6 @@ #include #include "wasm_c_api.h" -#include "wasm_export.h" -#include "bh_platform.h" - -extern bool -reader(const char *module_name, uint8 **p_buffer, uint32 *p_size); - -extern void -destroyer(uint8 *buffer, uint32 size); #define own @@ -26,8 +18,6 @@ own wasm_trap_t* hello_callback( int main(int argc, const char* argv[]) { - wasm_runtime_set_module_reader(reader, destroyer); - // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); @@ -35,11 +25,7 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); -#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0 - FILE* file = fopen("hello.aot", "rb"); -#else FILE* file = fopen("hello.wasm", "rb"); -#endif if (!file) { printf("> Error loading module!\n"); return 1; @@ -65,26 +51,15 @@ int main(int argc, const char* argv[]) { wasm_byte_vec_delete(&binary); - // Create external print functions. - printf("Creating callback...\n"); - own wasm_functype_t* hello_type = wasm_functype_new_0_0(); - own wasm_func_t* hello_func = - wasm_func_new(store, hello_type, hello_callback); - - wasm_functype_delete(hello_type); - // Instantiate. printf("Instantiating module...\n"); - const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_func) }; own wasm_instance_t* instance = - wasm_instance_new(store, module, imports, NULL); + wasm_instance_new(store, module, NULL, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; } - wasm_func_delete(hello_func); - // Extract export. printf("Extracting export...\n"); own wasm_extern_vec_t exports; @@ -93,22 +68,10 @@ int main(int argc, const char* argv[]) { printf("> Error accessing exports!\n"); return 1; } - const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]); - if (run_func == NULL) { - printf("> Error accessing export!\n"); - return 1; - } wasm_module_delete(module); wasm_instance_delete(instance); - // Call. - printf("Calling export...\n"); - if (wasm_func_call(run_func, NULL, NULL)) { - printf("> Error calling function!\n"); - return 1; - } - wasm_extern_vec_delete(&exports); // Shut down. diff --git a/samples/wasm-c-api/src/multi.c b/samples/wasm-c-api/src/multi.c new file mode 100644 index 0000000000..8291ff9b53 --- /dev/null +++ b/samples/wasm-c-api/src/multi.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include + +#include "wasm_c_api.h" + +#define own + +// A function to be called from Wasm code. +own wasm_trap_t* callback( + const wasm_val_t args[], wasm_val_t results[] +) { + printf("Calling back...\n> "); + printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", + args[0].of.i32, args[1].of.i64, + args[2].of.i64, args[3].of.i32); + printf("\n"); + + wasm_val_copy(&results[0], &args[3]); + wasm_val_copy(&results[1], &args[1]); + wasm_val_copy(&results[2], &args[2]); + wasm_val_copy(&results[3], &args[0]); + return NULL; +} + + +// A function closure. +own wasm_trap_t* closure_callback( + void* env, const wasm_val_t args[], wasm_val_t results[] +) { + int i = *(int*)env; + printf("Calling back closure...\n"); + printf("> %d\n", i); + + results[0].kind = WASM_I32; + results[0].of.i32 = (int32_t)i; + return NULL; +} + + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("multi.wasm", "rb"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // Create external print functions. + printf("Creating callback...\n"); + wasm_valtype_t* types[4] = { + wasm_valtype_new_i32(), wasm_valtype_new_i64(), + wasm_valtype_new_i64(), wasm_valtype_new_i32() + }; + own wasm_valtype_vec_t tuple1, tuple2; + wasm_valtype_vec_new(&tuple1, 4, types); + wasm_valtype_vec_copy(&tuple2, &tuple1); + own wasm_functype_t* callback_type = wasm_functype_new(&tuple1, &tuple2); + own wasm_func_t* callback_func = + wasm_func_new(store, callback_type, callback); + + wasm_functype_delete(callback_type); + + // Instantiate. + printf("Instantiating module...\n"); + const wasm_extern_t* imports[] = { wasm_func_as_extern(callback_func) }; + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); + if (!instance) { + printf("> Error instantiating module!\n"); + return 1; + } + + wasm_func_delete(callback_func); + + // Extract export. + printf("Extracting export...\n"); + own wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + if (exports.size == 0) { + printf("> Error accessing exports!\n"); + return 1; + } + const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]); + if (run_func == NULL) { + printf("> Error accessing export!\n"); + return 1; + } + + wasm_module_delete(module); + wasm_instance_delete(instance); + + // Call. + printf("Calling export...\n"); + wasm_val_t args[4] = { + WASM_I32_VAL(1), WASM_I64_VAL(2), WASM_I64_VAL(3), WASM_I32_VAL(4) + }; + wasm_val_t results[4] = { + WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL, WASM_INIT_VAL + }; + if (wasm_func_call(run_func, args, results)) { + printf("> Error calling function!\n"); + return 1; + } + + wasm_extern_vec_delete(&exports); + + // Print result. + printf("Printing result...\n"); + printf("> %"PRIu32" %"PRIu64" %"PRIu64" %"PRIu32"\n", + results[0].of.i32, results[1].of.i64, results[2].of.i64, results[3].of.i32); + + assert(results[0].of.i32 == 1); + assert(results[1].of.i64 == 2); + assert(results[2].of.i64 == 3); + assert(results[3].of.i32 == 4); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/samples/wasm-c-api/src/multi.wat b/samples/wasm-c-api/src/multi.wat new file mode 100644 index 0000000000..e7fb331125 --- /dev/null +++ b/samples/wasm-c-api/src/multi.wat @@ -0,0 +1,7 @@ +(module + (func $f (import "" "f") (param i32 i64 i64 i32) (result i32 i64 i64 i32)) + + (func $g (export "g") (param i32 i64 i64 i32) (result i32 i64 i64 i32) + (call $f (local.get 0) (local.get 2) (local.get 1) (local.get 3)) + ) +) diff --git a/samples/wasm-c-api/src/reflect.c b/samples/wasm-c-api/src/reflect.c new file mode 100644 index 0000000000..f2e41869c5 --- /dev/null +++ b/samples/wasm-c-api/src/reflect.c @@ -0,0 +1,170 @@ +#include +#include +#include +#include + +#include "wasm_c_api.h" + +#define own + +void print_mutability(wasm_mutability_t mut) { + switch (mut) { + case WASM_VAR: printf("var"); break; + case WASM_CONST: printf("const"); break; + } +} + +void print_limits(const wasm_limits_t* limits) { + printf("%ud", limits->min); + if (limits->max < wasm_limits_max_default) printf(" %ud", limits->max); +} + +void print_valtype(const wasm_valtype_t* type) { + switch (wasm_valtype_kind(type)) { + case WASM_I32: printf("i32"); break; + case WASM_I64: printf("i64"); break; + case WASM_F32: printf("f32"); break; + case WASM_F64: printf("f64"); break; + case WASM_ANYREF: printf("anyref"); break; + case WASM_FUNCREF: printf("funcref"); break; + } +} + +void print_valtypes(const wasm_valtype_vec_t* types) { + bool first = true; + for (size_t i = 0; i < types->size; ++i) { + if (first) { + first = false; + } else { + printf(" "); + } + print_valtype(types->data[i]); + } +} + +void print_externtype(const wasm_externtype_t* type) { + switch (wasm_externtype_kind(type)) { + case WASM_EXTERN_FUNC: { + const wasm_functype_t* functype = + wasm_externtype_as_functype_const(type); + printf("func "); + print_valtypes(wasm_functype_params(functype)); + printf(" -> "); + print_valtypes(wasm_functype_results(functype)); + } break; + case WASM_EXTERN_GLOBAL: { + const wasm_globaltype_t* globaltype = + wasm_externtype_as_globaltype_const(type); + printf("global "); + print_mutability(wasm_globaltype_mutability(globaltype)); + printf(" "); + print_valtype(wasm_globaltype_content(globaltype)); + } break; + case WASM_EXTERN_TABLE: { + const wasm_tabletype_t* tabletype = + wasm_externtype_as_tabletype_const(type); + printf("table "); + print_limits(wasm_tabletype_limits(tabletype)); + printf(" "); + print_valtype(wasm_tabletype_element(tabletype)); + } break; + case WASM_EXTERN_MEMORY: { + const wasm_memorytype_t* memorytype = + wasm_externtype_as_memorytype_const(type); + printf("memory "); + print_limits(wasm_memorytype_limits(memorytype)); + } break; + } +} + +void print_name(const wasm_name_t* name) { + printf("\"%.*s\"", (int)name->size, name->data); +} + + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("reflect.wasm", "rb"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // Instantiate. + printf("Instantiating module...\n"); + own wasm_instance_t* instance = + wasm_instance_new(store, module, NULL, NULL); + if (!instance) { + printf("> Error instantiating module!\n"); + return 1; + } + + // Extract export. + printf("Extracting export...\n"); + own wasm_exporttype_vec_t export_types; + own wasm_extern_vec_t exports; + wasm_module_exports(module, &export_types); + wasm_instance_exports(instance, &exports); + assert(exports.size == export_types.size); + + for (size_t i = 0; i < exports.size; ++i) { + assert(wasm_extern_kind(exports.data[i]) == + wasm_externtype_kind(wasm_exporttype_type(export_types.data[i]))); + printf("> export %zu ", i); + print_name(wasm_exporttype_name(export_types.data[i])); + printf("\n"); + printf(">> initial: "); + print_externtype(wasm_exporttype_type(export_types.data[i])); + printf("\n"); + printf(">> current: "); + own wasm_externtype_t* current = wasm_extern_type(exports.data[i]); + print_externtype(current); + wasm_externtype_delete(current); + printf("\n"); + if (wasm_extern_kind(exports.data[i]) == WASM_EXTERN_FUNC) { + wasm_func_t* func = wasm_extern_as_func(exports.data[i]); + printf(">> in-arity: %zu", wasm_func_param_arity(func)); + printf(", out-arity: %zu\n", wasm_func_result_arity(func)); + } + } + + wasm_module_delete(module); + wasm_instance_delete(instance); + wasm_extern_vec_delete(&exports); + wasm_exporttype_vec_delete(&export_types); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/samples/wasm-c-api/src/reflect.wat b/samples/wasm-c-api/src/reflect.wat new file mode 100644 index 0000000000..261dfd3c33 --- /dev/null +++ b/samples/wasm-c-api/src/reflect.wat @@ -0,0 +1,6 @@ +(module + (func (export "func") (param i32 f64 f32) (result i32) (unreachable)) + (global (export "global") f64 (f64.const 0)) + (table (export "table") 0 50 anyfunc) + (memory (export "memory") 1) +) diff --git a/samples/wasm-c-api/src/trap.c b/samples/wasm-c-api/src/trap.c new file mode 100644 index 0000000000..60ff0654be --- /dev/null +++ b/samples/wasm-c-api/src/trap.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#include "wasm_c_api.h" + +#define own + +// A function to be called from Wasm code. +own wasm_trap_t* fail_callback( + void* env, const wasm_val_t args[], wasm_val_t results[] +) { + printf("Calling back...\n"); + own wasm_name_t message; + wasm_name_new_from_string_nt(&message, "callback abort"); + own wasm_trap_t* trap = wasm_trap_new((wasm_store_t*)env, &message); + wasm_name_delete(&message); + return trap; +} + +int main(int argc, const char* argv[]) { + // Initialize. + printf("Initializing...\n"); + wasm_engine_t* engine = wasm_engine_new(); + wasm_store_t* store = wasm_store_new(engine); + + // Load binary. + printf("Loading binary...\n"); + FILE* file = fopen("trap.wasm", "rb"); + if (!file) { + printf("> Error loading module!\n"); + return 1; + } + fseek(file, 0L, SEEK_END); + size_t file_size = ftell(file); + fseek(file, 0L, SEEK_SET); + wasm_byte_vec_t binary; + wasm_byte_vec_new_uninitialized(&binary, file_size); + if (fread(binary.data, file_size, 1, file) != 1) { + printf("> Error loading module!\n"); + return 1; + } + fclose(file); + + // Compile. + printf("Compiling module...\n"); + own wasm_module_t* module = wasm_module_new(store, &binary); + if (!module) { + printf("> Error compiling module!\n"); + return 1; + } + + wasm_byte_vec_delete(&binary); + + // Create external print functions. + printf("Creating callback...\n"); + own wasm_functype_t* fail_type = + wasm_functype_new_0_1(wasm_valtype_new_i32()); + own wasm_func_t* fail_func = + wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL); + + wasm_functype_delete(fail_type); + + // Instantiate. + printf("Instantiating module...\n"); + const wasm_extern_t* imports[] = { wasm_func_as_extern(fail_func) }; + own wasm_instance_t* instance = + wasm_instance_new(store, module, imports, NULL); + if (!instance) { + printf("> Error instantiating module!\n"); + return 1; + } + + wasm_func_delete(fail_func); + + // Extract export. + printf("Extracting exports...\n"); + own wasm_extern_vec_t exports; + wasm_instance_exports(instance, &exports); + if (exports.size < 2) { + printf("> Error accessing exports!\n"); + return 1; + } + + wasm_module_delete(module); + wasm_instance_delete(instance); + + // Call. + for (int i = 0; i < 2; ++i) { + const wasm_func_t* func = wasm_extern_as_func(exports.data[i]); + if (func == NULL) { + printf("> Error accessing export!\n"); + return 1; + } + + printf("Calling export %d...\n", i); + wasm_val_t results[1]; \ + own wasm_trap_t* trap = wasm_func_call(func, NULL, results); + if (!trap) { + printf("> Error calling function, expected trap!\n"); + return 1; + } + + printf("Printing message...\n"); + own wasm_name_t message; + wasm_trap_message(trap, &message); + printf("> %s\n", message.data); + + wasm_trap_delete(trap); + wasm_name_delete(&message); + } + + wasm_extern_vec_delete(&exports); + + // Shut down. + printf("Shutting down...\n"); + wasm_store_delete(store); + wasm_engine_delete(engine); + + // All done. + printf("Done.\n"); + return 0; +} diff --git a/samples/wasm-c-api/src/trap.wat b/samples/wasm-c-api/src/trap.wat new file mode 100644 index 0000000000..dfd20fb12a --- /dev/null +++ b/samples/wasm-c-api/src/trap.wat @@ -0,0 +1,5 @@ +(module + (func $callback (import "" "callback") (result i32)) + (func (export "callback") (result i32) (call $callback)) + (func (export "unreachable") (result i32) (unreachable) (i32.const 1)) +) diff --git a/samples/workload/XNNPACK/CMakeLists.txt b/samples/workload/XNNPACK/CMakeLists.txt index 86a784cbbd..3e00f20f59 100644 --- a/samples/workload/XNNPACK/CMakeLists.txt +++ b/samples/workload/XNNPACK/CMakeLists.txt @@ -20,85 +20,72 @@ include(ExternalProject) ExternalProject_Add(xnnpack PREFIX xnnpack GIT_REPOSITORY https://github.com/google/XNNPACK.git - GIT_TAG 2da0de89960b829c6fae74204a102db524e73047 + GIT_TAG master GIT_PROGRESS ON SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack - UPDATE_COMMAND git checkout .bazelrc BUILD.bazel emscripten.bzl + UPDATE_COMMAND git checkout . && git apply ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack.patch - && cmake -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/toolchain ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack/toolchain - # replace string "$ENV{HOME}" with actual home directory - && sed -i "s|\$ENV{HOME}|$ENV{HOME}|g" ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack/toolchain/emscripten_toolchain_config.bzl CONFIGURE_COMMAND "" BUILD_COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack - && bazel build -c opt --sandbox_writable_path=$ENV{HOME} --config=emscripten_wasm - //:qs8_gemm_bench.wasm - //:qs8_requantization_bench.wasm - //:qu8_gemm_bench.wasm - //:qu8_requantization_bench.wasm - //:f16_igemm_bench.wasm - //:f16_gemm_bench.wasm - //:f16_spmm_bench.wasm - //:f32_igemm_bench.wasm - //:f16_relu_bench.wasm - //:f32_conv_hwc_bench.wasm - //:f32_conv_hwc2chw_bench.wasm - //:f16_dwconv_bench.wasm - //:f32_dwconv_bench.wasm - //:f32_dwconv2d_chw_bench.wasm - //:f32_gemm_bench.wasm - //:f32_hswish_bench.wasm - //:f32_raddexpminusmax_bench.wasm - //:f32_raddextexp_bench.wasm - //:f32_raddstoreexpminusmax_bench.wasm - //:f32_relu_bench.wasm - //:f32_rmax_bench.wasm - //:f32_sigmoid_bench.wasm - //:f32_spmm_bench.wasm - //:f32_softmax_bench.wasm - //:f32_vscaleexpminusmax_bench.wasm - //:f32_vscaleextexp_bench.wasm - //:f32_vsqrt_bench.wasm - //:f32_im2col_gemm_bench.wasm - //:rounding_bench.wasm - //:average_pooling_bench.wasm - //:bankers_rounding_bench.wasm - //:ceiling_bench.wasm - //:channel_shuffle_bench.wasm - //:convolution_bench.wasm - //:deconvolution_bench.wasm - //:floor_bench.wasm - //:global_average_pooling_bench.wasm - //:hardswish_bench.wasm - //:max_pooling_bench.wasm - //:sigmoid_bench.wasm - //:prelu_bench.wasm - //:softmax_bench.wasm - //:square_root_bench.wasm - //:truncation_bench.wasm - //:fp32_mobilenet_v1.wasm - //:fp16_mobilenet_v1.wasm - //:qs8_mobilenet_v1.wasm - //:qs8_mobilenet_v2.wasm - //:fp32_mobilenet_v2.wasm - //:fp16_mobilenet_v2.wasm - //:fp32_mobilenet_v3_large.wasm - //:fp16_mobilenet_v3_large.wasm - //:fp32_mobilenet_v3_small.wasm - //:fp16_mobilenet_v3_small.wasm - //:f32_dwconv_e2e_bench.wasm - //:f32_gemm_e2e_bench.wasm - //:end2end_bench.wasm - //:f32_exp_eval.wasm - //:f32_expminus_eval.wasm - //:f32_extexp_eval.wasm - //:f32_roundne_eval.wasm - //:f32_roundd_eval.wasm - //:f32_roundu_eval.wasm - //:f32_roundz_eval.wasm - //:f32_sigmoid_eval.wasm - //:f32_sqrt_eval.wasm + && bazel --output_user_root=build_user_output build -c opt --config=wasm + //:qs8_gemm_bench + //:qs8_requantization_bench + //:qu8_gemm_bench + //:qu8_requantization_bench + //:f16_igemm_bench + //:f16_gemm_bench + //:f16_spmm_bench + //:f32_igemm_bench + //:f16_relu_bench + //:f32_conv_hwc_bench + //:f32_conv_hwc2chw_bench + //:f16_dwconv_bench + //:f32_dwconv_bench + //:f32_dwconv2d_chw_bench + //:f32_gemm_bench + //:f32_hswish_bench + //:f32_raddexpminusmax_bench + //:f32_raddextexp_bench + //:f32_raddstoreexpminusmax_bench + //:f32_relu_bench + //:f32_rmax_bench + //:f32_sigmoid_bench + //:f32_spmm_bench + //:f32_softmax_bench + //:f32_velu_bench + //:f32_vscaleexpminusmax_bench + //:f32_vscaleextexp_bench + //:f32_vsqrt_bench + //:f32_im2col_gemm_bench + //:rounding_bench + //:average_pooling_bench + //:bankers_rounding_bench + //:ceiling_bench + //:channel_shuffle_bench + //:convolution_bench + //:deconvolution_bench + //:elu_bench + //:floor_bench + //:global_average_pooling_bench + //:hardswish_bench + //:max_pooling_bench + //:sigmoid_bench + //:prelu_bench + //:softmax_bench + //:square_root_bench + //:truncation_bench + //:f32_dwconv_e2e_bench + //:f32_gemm_e2e_bench + //:qs8_gemm_e2e_bench + //:end2end_bench + //:f32_exp_ulp_eval + //:f32_expminus_ulp_eval + //:f32_expm1minus_ulp_eval + //:f32_extexp_ulp_eval + //:f32_sigmoid_ulp_eval + //:f32_sqrt_ulp_eval #--sandbox_debug - INSTALL_COMMAND ${CMAKE_COMMAND} -E create_symlink + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/xnnpack/bazel-out/wasm-opt/bin/ ${CMAKE_CURRENT_SOURCE_DIR}/build/wasm-opt ) diff --git a/samples/workload/XNNPACK/toolchain/BUILD.bazel b/samples/workload/XNNPACK/toolchain/BUILD.bazel deleted file mode 100644 index 9cf9b96931..0000000000 --- a/samples/workload/XNNPACK/toolchain/BUILD.bazel +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (C) 2019 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -package(default_visibility = ['//visibility:public']) - -load(":emscripten_toolchain_config.bzl", "emsdk_toolchain_config") - -cc_toolchain_suite( - name = "emscripten", - toolchains = { - "wasm": ":emsdk_toolchain", - }, -) - -filegroup(name = "empty") - -emsdk_toolchain_config(name = "emsdk_toolchain_config") - -cc_toolchain( - name = "emsdk_toolchain", - toolchain_identifier = "emsdk-toolchain", - toolchain_config = ":emsdk_toolchain_config", - all_files = ":empty", - compiler_files = ":empty", - dwp_files = ":empty", - linker_files = ":empty", - objcopy_files = ":empty", - strip_files = ":empty", - supports_param_files = 0, -) diff --git a/samples/workload/XNNPACK/toolchain/emscripten_toolchain_config.bzl b/samples/workload/XNNPACK/toolchain/emscripten_toolchain_config.bzl deleted file mode 100644 index d3e440590c..0000000000 --- a/samples/workload/XNNPACK/toolchain/emscripten_toolchain_config.bzl +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (C) 2019 Intel Corporation. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") -load( - "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", - "feature", - "flag_group", - "flag_set", - "tool_path", -) - -all_compile_actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, -] - -all_link_actions = [ - ACTION_NAMES.cpp_link_executable, - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.cpp_link_nodeps_dynamic_library, -] - -def _impl(ctx): - tool_paths = [ - tool_path( - name = "gcc", - path = "/opt/emsdk/upstream/emscripten/emcc", - ), - tool_path( - name = "ld", - path = "/opt/emsdk/upstream/emscripten/emcc", - ), - tool_path( - name = "ar", - path = "/opt/emsdk/upstream/emscripten/emar", - ), - tool_path( - name = "cpp", - path = "/opt/emsdk/upstream/emscripten/em++", - ), - tool_path( - name = "gcov", - path = "/bin/false", - ), - tool_path( - name = "nm", - path = "/bin/false", - ), - tool_path( - name = "objdump", - path = "/bin/false", - ), - tool_path( - name = "strip", - path = "/bin/false", - ), - ] - - features = [ # NEW - feature( - name = "default_compile_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_compile_actions, - flag_groups = ([ - flag_group( - flags = [ - "-O3", - "-msimd128", - "-s", - "USE_PTHREADS=0", - "-s", - "ERROR_ON_UNDEFINED_SYMBOLS=0", - "-s", - "STANDALONE_WASM=1", - ], - ), - ]), - ), - ], - ), - feature( - name = "default_linker_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_link_actions, - flag_groups = ([ - flag_group( - flags = [ - "-O3", - "-msimd128", - "-s", - "USE_PTHREADS=0", - "-s", - "ERROR_ON_UNDEFINED_SYMBOLS=0", - "-s", - "STANDALONE_WASM=1", - "-Wl,--export=__heap_base", - "-Wl,--export=__data_end", - "-Wl,--export=malloc", - "-Wl,--export=free", - ], - ), - ]), - ), - ], - ), - ] - - return cc_common.create_cc_toolchain_config_info( - ctx = ctx, - features = features, # NEW - cxx_builtin_include_directories = [ - "/opt/emsdk/upstream/emscripten/system/include", - "/opt/emsdk/upstream/emscripten/system/lib/libc/include", - "/opt/emsdk/upstream/emscripten/system/lib/libcxx/include", - "/opt/emsdk/upstream/emscripten/system/lib/libcxxabi/include", - "/opt/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten", - "/opt/emsdk/upstream/emscripten/system/include/compat", - "/opt/emsdk/upstream/emscripten/cache/sysroot/include", - "/opt/emsdk/upstream/lib/clang/13.0.0/include", - "$ENV{HOME}/.emscripten_cache/sysroot/include", - ], - toolchain_identifier = "wasm-emsdk", - host_system_name = "i686-unknown-linux-gnu", - target_system_name = "wasm32-unknown-emscripten", - target_cpu = "wasm32", - target_libc = "unknown", - compiler = "emsdk", - abi_version = "unknown", - abi_libc_version = "unknown", - tool_paths = tool_paths, - ) - -emsdk_toolchain_config = rule( - implementation = _impl, - attrs = {}, - provides = [CcToolchainConfigInfo], -) diff --git a/samples/workload/XNNPACK/xnnpack.patch b/samples/workload/XNNPACK/xnnpack.patch index b58cbc7953..17dafbf2e2 100644 --- a/samples/workload/XNNPACK/xnnpack.patch +++ b/samples/workload/XNNPACK/xnnpack.patch @@ -1,742 +1,137 @@ diff --git a/.bazelrc b/.bazelrc -index ea28201..ffd4ed4 100644 +index ec740f38..2c193244 100644 --- a/.bazelrc +++ b/.bazelrc -@@ -44,3 +44,7 @@ build:ios_arm64e --watchos_cpus=armv7k - build:ios_fat --config=ios - build:ios_fat --ios_multi_cpus=armv7,arm64 - build:ios_fat --watchos_cpus=armv7k +@@ -49,4 +49,10 @@ build:ios_fat --watchos_cpus=armv7k + build:macos --apple_platform_type=macos + + build:macos_arm64 --config=macos +-build:macos_arm64 --cpu=darwin_arm64 +\ No newline at end of file ++build:macos_arm64 --cpu=darwin_arm64 ++ ++build:wasm --copt=-msimd128 ++build:wasm --cpu=wasm ++build:wasm --crosstool_top=@emsdk//emscripten_toolchain:everything ++build:wasm --host_crosstool_top=@bazel_tools//tools/cpp:toolchain + -+# WASM configs -+build:emscripten_wasm --cpu=wasm -+build:emscripten_wasm --crosstool_top=//toolchain:emscripten diff --git a/BUILD.bazel b/BUILD.bazel -index d38ef1e..f261eb5 100644 +index ae4108bc..1c11fac2 100644 --- a/BUILD.bazel +++ b/BUILD.bazel -@@ -3228,13 +3228,19 @@ xnnpack_cc_library( - hdrs = INTERNAL_HDRS, - gcc_copts = xnnpack_gcc_std_copts(), - msvc_copts = xnnpack_msvc_std_copts(), -- wasm_srcs = WASM_UKERNELS, -- wasmsimd_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS, -+ optimized_copts = [ -+ "-ffast-math", -+ ], -+ wasm_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS + -+ PSIMD_FASTMATH_UKERNELS + PSIMD_ACCMATH_UKERNELS, -+ wasmsimd_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS + -+ PSIMD_FASTMATH_UKERNELS + PSIMD_ACCMATH_UKERNELS, - deps = [ - ":tables", - "@FP16", - "@FXdiv", - "@pthreadpool", -+ "@psimd", - ], - ) - -@@ -3247,13 +3253,19 @@ xnnpack_cc_library( - ], - gcc_copts = xnnpack_gcc_std_copts(), - msvc_copts = xnnpack_msvc_std_copts(), -- wasm_srcs = WASM_UKERNELS, -- wasmsimd_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS, -+ optimized_copts = [ -+ "-ffast-math", -+ ], -+ wasm_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS + -+ PSIMD_FASTMATH_UKERNELS + PSIMD_ACCMATH_UKERNELS, -+ wasmsimd_srcs = WASM_UKERNELS + WASMSIMD_UKERNELS + -+ PSIMD_FASTMATH_UKERNELS + PSIMD_ACCMATH_UKERNELS, - deps = [ - ":tables", - "@FP16", - "@FXdiv", - "@pthreadpool", -+ "@psimd", - ], - ) - -@@ -4495,7 +4507,7 @@ xnnpack_cc_library( - ######################### Benchmarks for micro-kernels ######################### - - xnnpack_benchmark( -- name = "qs8_gemm_bench", -+ name = "qs8_gemm_bench.wasm", - srcs = [ - "bench/gemm.h", - "bench/qs8-gemm.cc", -@@ -4506,7 +4518,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "qs8_requantization_bench", -+ name = "qs8_requantization_bench.wasm", - srcs = [ - "bench/qs8-requantization.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4516,7 +4528,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "qu8_gemm_bench", -+ name = "qu8_gemm_bench.wasm", - srcs = [ - "bench/gemm.h", - "bench/qu8-gemm.cc", -@@ -4527,7 +4539,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "qu8_requantization_bench", -+ name = "qu8_requantization_bench.wasm", - srcs = [ - "bench/qu8-requantization.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4537,11 +4549,11 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f16_igemm_bench", -+ name = "f16_igemm_bench.wasm", +@@ -5038,7 +5038,6 @@ xnnpack_benchmark( srcs = [ "bench/f16-igemm.cc", "bench/conv.h", - "bench/google/conv.h", -+ #"bench/google/conv.h", "src/xnnpack/AlignedAllocator.h", ] + MICROKERNEL_BENCHMARK_HDRS, deps = MICROKERNEL_BENCHMARK_DEPS + [ -@@ -4551,7 +4563,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f16_gemm_bench", -+ name = "f16_gemm_bench.wasm", - srcs = [ - "bench/f16-gemm.cc", - "bench/gemm.h", -@@ -4563,7 +4575,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f16_spmm_bench", -+ name = "f16_spmm_bench.wasm", - srcs = [ - "bench/f16-spmm.cc", - "bench/gemm.h", -@@ -4573,7 +4585,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_igemm_bench", -+ name = "f32_igemm_bench.wasm", - srcs = [ - "bench/f32-igemm.cc", - "bench/conv.h", -@@ -4586,7 +4598,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f16_relu_bench", -+ name = "f16_relu_bench.wasm", - srcs = [ - "bench/f16-relu.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4595,7 +4607,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_conv_hwc_bench", -+ name = "f32_conv_hwc_bench.wasm", - srcs = [ - "bench/f32-conv-hwc.cc", - "bench/dconv.h", -@@ -4607,7 +4619,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_conv_hwc2chw_bench", -+ name = "f32_conv_hwc2chw_bench.wasm", - srcs = [ - "bench/f32-conv-hwc2chw.cc", - "bench/dconv.h", -@@ -4619,11 +4631,11 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f16_dwconv_bench", -+ name = "f16_dwconv_bench.wasm", +@@ -5120,7 +5119,6 @@ xnnpack_benchmark( srcs = [ "bench/f16-dwconv.cc", "bench/dwconv.h", - "bench/google/dwconv.h", -+ #"bench/google/dwconv.h", "src/xnnpack/AlignedAllocator.h", ] + MICROKERNEL_BENCHMARK_HDRS, deps = MICROKERNEL_BENCHMARK_DEPS + [ -@@ -4633,7 +4645,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_dwconv_bench", -+ name = "f32_dwconv_bench.wasm", - srcs = [ - "bench/f32-dwconv.cc", - "bench/dwconv.h", -@@ -4646,7 +4658,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_dwconv2d_chw_bench", -+ name = "f32_dwconv2d_chw_bench.wasm", - srcs = [ - "bench/f32-dwconv2d-chw.cc", - "bench/dwconv.h", -@@ -4659,7 +4671,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_gemm_bench", -+ name = "f32_gemm_bench.wasm", - srcs = [ - "bench/f32-gemm.cc", - "bench/gemm.h", -@@ -4670,7 +4682,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_hswish_bench", -+ name = "f32_hswish_bench.wasm", - srcs = [ - "bench/f32-hswish.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4679,7 +4691,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_raddexpminusmax_bench", -+ name = "f32_raddexpminusmax_bench.wasm", - srcs = [ - "bench/f32-raddexpminusmax.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4688,7 +4700,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_raddextexp_bench", -+ name = "f32_raddextexp_bench.wasm", - srcs = [ - "bench/f32-raddextexp.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4697,7 +4709,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_raddstoreexpminusmax_bench", -+ name = "f32_raddstoreexpminusmax_bench.wasm", - srcs = [ - "bench/f32-raddstoreexpminusmax.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4706,7 +4718,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_relu_bench", -+ name = "f32_relu_bench.wasm", - srcs = [ - "bench/f32-relu.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4715,7 +4727,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_rmax_bench", -+ name = "f32_rmax_bench.wasm", - srcs = [ - "bench/f32-rmax.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4724,7 +4736,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_sigmoid_bench", -+ name = "f32_sigmoid_bench.wasm", - srcs = [ - "bench/f32-sigmoid.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4733,7 +4745,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_spmm_bench", -+ name = "f32_spmm_bench.wasm", - srcs = [ - "bench/f32-spmm.cc", - "bench/gemm.h", -@@ -4743,7 +4755,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_softmax_bench", -+ name = "f32_softmax_bench.wasm", - srcs = [ - "bench/f32-softmax.cc", - ] + MICROKERNEL_BENCHMARK_HDRS, -@@ -4752,7 +4764,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_vscaleexpminusmax_bench", -+ name = "f32_vscaleexpminusmax_bench.wasm", - srcs = [ - "bench/f32-vscaleexpminusmax.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4761,7 +4773,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_vscaleextexp_bench", -+ name = "f32_vscaleextexp_bench.wasm", - srcs = [ - "bench/f32-vscaleextexp.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4770,7 +4782,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_vsqrt_bench", -+ name = "f32_vsqrt_bench.wasm", - srcs = [ - "bench/f32-vsqrt.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4779,7 +4791,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_im2col_gemm_bench", -+ name = "f32_im2col_gemm_bench.wasm", - srcs = [ - "bench/f32-im2col-gemm.cc", - "bench/conv.h", -@@ -4792,7 +4804,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "rounding_bench", -+ name = "rounding_bench.wasm", - srcs = [ - "bench/rounding.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -4804,7 +4816,7 @@ xnnpack_benchmark( - ########################### Benchmarks for operators ########################### - - xnnpack_benchmark( -- name = "average_pooling_bench", -+ name = "average_pooling_bench.wasm", - srcs = ["bench/average-pooling.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4812,7 +4824,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "bankers_rounding_bench", -+ name = "bankers_rounding_bench.wasm", - srcs = ["bench/bankers-rounding.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4820,7 +4832,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "ceiling_bench", -+ name = "ceiling_bench.wasm", - srcs = ["bench/ceiling.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4828,13 +4840,13 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "channel_shuffle_bench", -+ name = "channel_shuffle_bench.wasm", - srcs = ["bench/channel-shuffle.cc"], - deps = OPERATOR_BENCHMARK_DEPS, - ) - - xnnpack_benchmark( -- name = "convolution_bench", -+ name = "convolution_bench.wasm", - srcs = ["bench/convolution.cc"], - copts = xnnpack_optional_tflite_copts() + xnnpack_optional_armcl_copts(), - tags = ["nowin32"], -@@ -4842,7 +4854,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "deconvolution_bench", -+ name = "deconvolution_bench.wasm", - srcs = ["bench/deconvolution.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4850,7 +4862,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "floor_bench", -+ name = "floor_bench.wasm", - srcs = ["bench/floor.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4858,13 +4870,13 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "global_average_pooling_bench", -+ name = "global_average_pooling_bench.wasm", - srcs = ["bench/global-average-pooling.cc"], - deps = OPERATOR_BENCHMARK_DEPS, - ) - - xnnpack_benchmark( -- name = "hardswish_bench", -+ name = "hardswish_bench.wasm", - srcs = ["bench/hardswish.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4872,13 +4884,13 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "max_pooling_bench", -+ name = "max_pooling_bench.wasm", - srcs = ["bench/max-pooling.cc"], - deps = OPERATOR_BENCHMARK_DEPS, - ) - - xnnpack_benchmark( -- name = "sigmoid_bench", -+ name = "sigmoid_bench.wasm", - srcs = ["bench/sigmoid.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4886,7 +4898,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "prelu_bench", -+ name = "prelu_bench.wasm", - srcs = ["bench/prelu.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4894,7 +4906,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "softmax_bench", -+ name = "softmax_bench.wasm", - srcs = ["bench/softmax.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4902,7 +4914,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "square_root_bench", -+ name = "square_root_bench.wasm", - srcs = ["bench/square-root.cc"], - copts = xnnpack_optional_tflite_copts(), - tags = ["nowin32"], -@@ -4910,7 +4922,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "truncation_bench", -+ name = "truncation_bench.wasm", - srcs = ["bench/truncation.cc"], - deps = OPERATOR_BENCHMARK_DEPS, - ) -@@ -4918,7 +4930,7 @@ xnnpack_benchmark( - ############################# End-to-end benchmarks ############################ - - cc_library( -- name = "fp32_mobilenet_v1", -+ name = "fp32_mobilenet_v1.wasm", - srcs = ["models/fp32-mobilenet-v1.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4930,7 +4942,7 @@ cc_library( - ) - - cc_library( -- name = "fp16_mobilenet_v1", -+ name = "fp16_mobilenet_v1.wasm", - srcs = ["models/fp16-mobilenet-v1.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4943,7 +4955,7 @@ cc_library( - ) - - cc_library( -- name = "qs8_mobilenet_v1", -+ name = "qs8_mobilenet_v1.wasm", - srcs = ["models/qs8-mobilenet-v1.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4955,7 +4967,7 @@ cc_library( - ) - - cc_library( -- name = "qs8_mobilenet_v2", -+ name = "qs8_mobilenet_v2.wasm", - srcs = ["models/qs8-mobilenet-v2.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4967,7 +4979,7 @@ cc_library( - ) - - cc_library( -- name = "fp32_mobilenet_v2", -+ name = "fp32_mobilenet_v2.wasm", - srcs = ["models/fp32-mobilenet-v2.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4979,7 +4991,7 @@ cc_library( - ) - - cc_library( -- name = "fp16_mobilenet_v2", -+ name = "fp16_mobilenet_v2.wasm", - srcs = ["models/fp16-mobilenet-v2.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -4992,7 +5004,7 @@ cc_library( - ) - - cc_library( -- name = "fp32_mobilenet_v3_large", -+ name = "fp32_mobilenet_v3_large.wasm", - srcs = ["models/fp32-mobilenet-v3-large.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -5004,7 +5016,7 @@ cc_library( - ) - - cc_library( -- name = "fp16_mobilenet_v3_large", -+ name = "fp16_mobilenet_v3_large.wasm", - srcs = ["models/fp16-mobilenet-v3-large.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -5017,7 +5029,7 @@ cc_library( - ) - - cc_library( -- name = "fp32_mobilenet_v3_small", -+ name = "fp32_mobilenet_v3_small.wasm", - srcs = ["models/fp32-mobilenet-v3-small.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -5029,7 +5041,7 @@ cc_library( - ) - - cc_library( -- name = "fp16_mobilenet_v3_small", -+ name = "fp16_mobilenet_v3_small.wasm", - srcs = ["models/fp16-mobilenet-v3-small.cc"], - hdrs = ["models/models.h"], - copts = xnnpack_std_cxxopts(), -@@ -5042,51 +5054,51 @@ cc_library( - ) - - xnnpack_benchmark( -- name = "f32_dwconv_e2e_bench", -+ name = "f32_dwconv_e2e_bench.wasm", - srcs = [ - "bench/f32-dwconv-e2e.cc", - "bench/end2end.h", - ] + MICROKERNEL_BENCHMARK_HDRS, - deps = MICROKERNEL_BENCHMARK_DEPS + [ - ":XNNPACK", -- ":fp32_mobilenet_v1", -- ":fp32_mobilenet_v2", -- ":fp32_mobilenet_v3_large", -- ":fp32_mobilenet_v3_small", -+ ":fp32_mobilenet_v1.wasm", -+ ":fp32_mobilenet_v2.wasm", -+ ":fp32_mobilenet_v3_large.wasm", -+ ":fp32_mobilenet_v3_small.wasm", - ], - ) - - xnnpack_benchmark( -- name = "f32_gemm_e2e_bench", -+ name = "f32_gemm_e2e_bench.wasm", - srcs = [ - "bench/f32-gemm-e2e.cc", - "bench/end2end.h", - ] + MICROKERNEL_BENCHMARK_HDRS, - deps = MICROKERNEL_BENCHMARK_DEPS + [ - ":XNNPACK", -- ":fp32_mobilenet_v1", -- ":fp32_mobilenet_v2", -- ":fp32_mobilenet_v3_large", -- ":fp32_mobilenet_v3_small", -+ ":fp32_mobilenet_v1.wasm", -+ ":fp32_mobilenet_v2.wasm", -+ ":fp32_mobilenet_v3_large.wasm", -+ ":fp32_mobilenet_v3_small.wasm", - ], - ) - - xnnpack_benchmark( -- name = "end2end_bench", -+ name = "end2end_bench.wasm", - srcs = ["bench/end2end.cc"], - deps = [ - ":XNNPACK", - ":bench_utils", -- ":fp16_mobilenet_v1", -- ":fp16_mobilenet_v2", -- ":fp16_mobilenet_v3_large", -- ":fp16_mobilenet_v3_small", -- ":fp32_mobilenet_v1", -- ":fp32_mobilenet_v2", -- ":fp32_mobilenet_v3_large", -- ":fp32_mobilenet_v3_small", -- ":qs8_mobilenet_v1", -- ":qs8_mobilenet_v2", -+ ":fp16_mobilenet_v1.wasm", -+ ":fp16_mobilenet_v2.wasm", -+ ":fp16_mobilenet_v3_large.wasm", -+ ":fp16_mobilenet_v3_small.wasm", -+ ":fp32_mobilenet_v1.wasm", -+ ":fp32_mobilenet_v2.wasm", -+ ":fp32_mobilenet_v3_large.wasm", -+ ":fp32_mobilenet_v3_small.wasm", -+ ":qs8_mobilenet_v1.wasm", -+ ":qs8_mobilenet_v2.wasm", - "@pthreadpool", - ], - ) -@@ -5094,7 +5106,7 @@ xnnpack_benchmark( - #################### Accuracy evaluation for math functions #################### - - xnnpack_benchmark( -- name = "f32_exp_eval", -+ name = "f32_exp_eval.wasm", - srcs = [ - "eval/f32-exp.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5103,7 +5115,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_expminus_eval", -+ name = "f32_expminus_eval.wasm", - srcs = [ - "eval/f32-expminus.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5112,7 +5124,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_extexp_eval", -+ name = "f32_extexp_eval.wasm", - srcs = [ - "eval/f32-extexp.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5121,7 +5133,7 @@ xnnpack_benchmark( - ) - - xnnpack_unit_test( -- name = "f32_roundne_eval", -+ name = "f32_roundne_eval.wasm", - srcs = [ - "eval/f32-roundne.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5132,7 +5144,7 @@ xnnpack_unit_test( - ) - - xnnpack_unit_test( -- name = "f32_roundd_eval", -+ name = "f32_roundd_eval.wasm", - srcs = [ - "eval/f32-roundd.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5143,7 +5155,7 @@ xnnpack_unit_test( - ) - - xnnpack_unit_test( -- name = "f32_roundu_eval", -+ name = "f32_roundu_eval.wasm", - srcs = [ - "eval/f32-roundu.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5154,7 +5166,7 @@ xnnpack_unit_test( - ) - - xnnpack_unit_test( -- name = "f32_roundz_eval", -+ name = "f32_roundz_eval.wasm", - srcs = [ - "eval/f32-roundz.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5165,7 +5177,7 @@ xnnpack_unit_test( - ) - - xnnpack_benchmark( -- name = "f32_sigmoid_eval", -+ name = "f32_sigmoid_eval.wasm", - srcs = [ - "eval/f32-sigmoid.cc", - "src/xnnpack/AlignedAllocator.h", -@@ -5174,7 +5186,7 @@ xnnpack_benchmark( - ) - - xnnpack_benchmark( -- name = "f32_sqrt_eval", -+ name = "f32_sqrt_eval.wasm", - srcs = [ - "eval/f32-sqrt.cc", - "src/xnnpack/AlignedAllocator.h", +diff --git a/WORKSPACE b/WORKSPACE +index 4fa1aa2f..86040d42 100644 +--- a/WORKSPACE ++++ b/WORKSPACE +@@ -89,3 +89,18 @@ android_ndk_repository(name = "androidndk") + + # Android SDK location and API is auto-detected from $ANDROID_HOME environment variable + android_sdk_repository(name = "androidsdk") ++ ++# emscripten library ++http_archive( ++ name = "emsdk", ++ strip_prefix = "emsdk-c1589b55641787d55d53e883852035beea9aec3f/bazel", ++ url = "https://github.com/emscripten-core/emsdk/archive/c1589b55641787d55d53e883852035beea9aec3f.tar.gz", ++ sha256 = "7a58a9996b113d3e0675df30b5f17e28aa47de2e684a844f05394fe2f6f12e8e", ++) ++ ++load("@emsdk//:deps.bzl", emsdk_deps = "deps") ++emsdk_deps() ++ ++load("@emsdk//:emscripten_deps.bzl", emsdk_emscripten_deps = "emscripten_deps") ++emsdk_emscripten_deps() ++ +diff --git a/build_defs.bzl b/build_defs.bzl +index 10345032..0e926fca 100644 +--- a/build_defs.bzl ++++ b/build_defs.bzl +@@ -1,6 +1,6 @@ + """Build definitions and rules for XNNPACK.""" + +-load(":emscripten.bzl", "xnnpack_emscripten_benchmark_linkopts", "xnnpack_emscripten_deps", "xnnpack_emscripten_minimal_linkopts", "xnnpack_emscripten_test_linkopts") ++load(":emscripten.bzl", "xnnpack_emscripten_benchmark_linkopts", "xnnpack_emscripten_deps", "xnnpack_emscripten_minimal_linkopts", "xnnpack_emscripten_test_linkopts", "xnnpack_emscripten_benchmark_copts") + + def xnnpack_visibility(): + """Visibility of :XNNPACK target. +@@ -424,10 +424,15 @@ def xnnpack_benchmark(name, srcs, copts = [], deps = [], tags = []): + ":windows_x86_64_mingw": ["-Wno-unused-function"], + ":windows_x86_64_msys": ["-Wno-unused-function"], + ":windows_x86_64": [], ++ ":emscripten": xnnpack_emscripten_benchmark_copts(), ++ ":emscripten_wasm": xnnpack_emscripten_benchmark_copts(), ++ ":emscripten_wasmsimd": xnnpack_emscripten_benchmark_copts(), + "//conditions:default": ["-Wno-unused-function"], + }) + copts, + linkopts = select({ + ":emscripten": xnnpack_emscripten_benchmark_linkopts(), ++ ":emscripten_wasm": xnnpack_emscripten_benchmark_linkopts(), ++ ":emscripten_wasmsimd": xnnpack_emscripten_benchmark_linkopts(), + ":windows_x86_64_mingw": ["-lshlwapi"], + ":windows_x86_64_msys": ["-lshlwapi"], + "//conditions:default": [], diff --git a/emscripten.bzl b/emscripten.bzl -index faad087..2b4763f 100644 +index 0a0caedf..d28afa30 100644 --- a/emscripten.bzl +++ b/emscripten.bzl -@@ -4,30 +4,25 @@ def xnnpack_emscripten_minimal_linkopts(): - """Minimal Emscripten-specific linkopts for binaries.""" +@@ -23,15 +23,28 @@ def xnnpack_emscripten_benchmark_linkopts(): + """Emscripten-specific linkopts for benchmarks.""" return [ - "-s ASSERTIONS=0", + "-s ASSERTIONS=1", - "-s ERROR_ON_UNDEFINED_SYMBOLS=1", - "-s EXIT_RUNTIME=1", +- "-s ALLOW_MEMORY_GROWTH=1", + "-s ERROR_ON_UNDEFINED_SYMBOLS=0", - ] - - def xnnpack_emscripten_test_linkopts(): - """Emscripten-specific linkopts for unit tests.""" - return [ - "-s ASSERTIONS=2", -- "-s ERROR_ON_UNDEFINED_SYMBOLS=1", -+ "-s ERROR_ON_UNDEFINED_SYMBOLS=0", - "-s DEMANGLE_SUPPORT=1", -- "-s EXIT_RUNTIME=1", - "-s ALLOW_MEMORY_GROWTH=1", ++ "-s ALLOW_MEMORY_GROWTH=0", + "-s TOTAL_MEMORY=436207616", # 416M - "--pre-js $(location :preamble.js.lds)", ++ "-s USE_PTHREADS=0", ++ "-s STANDALONE_WASM=1", ++ "-Wno-unused", ++ "-Wl,--export=__heap_base", ++ "-Wl,--export=__data_end", ++ "-Wl,--export=malloc", ++ "-Wl,--export=free", ] - def xnnpack_emscripten_benchmark_linkopts(): - """Emscripten-specific linkopts for benchmarks.""" + def xnnpack_emscripten_deps(): + """Emscripten-specific dependencies for unit tests and benchmarks.""" ++ return [] ++ ++def xnnpack_emscripten_benchmark_copts(): return [ - "-s ASSERTIONS=1", -- "-s ERROR_ON_UNDEFINED_SYMBOLS=1", -- "-s EXIT_RUNTIME=1", +- ":preamble.js.lds", ++ "-s ASSERTIONS=1", + "-s ERROR_ON_UNDEFINED_SYMBOLS=0", - "-s ALLOW_MEMORY_GROWTH=1", - "-s TOTAL_MEMORY=268435456", # 256M -- "--pre-js $(location :preamble.js.lds)", ++ "-s ALLOW_MEMORY_GROWTH=0", ++ "-s USE_PTHREADS=0", ++ "-s STANDALONE_WASM=1", ++ "-Wno-unused", ] +diff --git a/third_party/cpuinfo.BUILD b/third_party/cpuinfo.BUILD +index 128d683e..f6c287c4 100644 +--- a/third_party/cpuinfo.BUILD ++++ b/third_party/cpuinfo.BUILD +@@ -343,5 +343,5 @@ config_setting( - def xnnpack_emscripten_deps(): + config_setting( + name = "emscripten", +- values = {"crosstool_top": "//toolchain:emscripten"}, ++ values = {"crosstool_top": "@emsdk//emscripten_toolchain:everything"}, + ) diff --git a/samples/workload/docker/Dockerfile b/samples/workload/docker/Dockerfile index 4c57c668b2..9906920dd7 100644 --- a/samples/workload/docker/Dockerfile +++ b/samples/workload/docker/Dockerfile @@ -17,7 +17,6 @@ ARG WASI_SDK_VER=12 ARG WABT_VER=1.0.20 ARG CMAKE_VER=3.16.2 ARG BINARYEN_VER=version_97 -ARG BAZEL_VER=3.7.0 # # install wasi-sdk @@ -66,13 +65,13 @@ RUN cd /opt \ && rm ${BINARYEN_FILE} \ && ln -sf /opt/binaryen-${BINARYEN_VER} /opt/binaryen -# # -# # install bazel -# ARG BAZEL_FILE=bazel-${BAZEL_VER}-installer-linux-x86_64.sh -# COPY ${BAZEL_FILE} /tmp -# RUN cd /tmp \ -# && chmod a+x ${BAZEL_FILE} \ -# && ./${BAZEL_FILE} +# +# install bazelisk +ARG BAZEL_FILE="bazelisk-linux-amd64" +COPY ${BAZEL_FILE} /opt/bazelisk/bin/bazelisk +RUN cd /opt/bazelisk/bin/ \ + && chmod a+x bazelisk \ + && ln -sf /opt/bazelisk/bin/bazelisk /usr/local/bin/bazel # # Clean up diff --git a/samples/workload/docker/docker_build.sh b/samples/workload/docker/docker_build.sh index ec502d55a1..d4cb10a334 100755 --- a/samples/workload/docker/docker_build.sh +++ b/samples/workload/docker/docker_build.sh @@ -13,7 +13,7 @@ readonly WASI_SDK_VER=12 readonly WABT_VER=1.0.20 readonly CMAKE_VER=3.16.2 readonly BINARYEN_VER=version_97 -readonly BAZEL_VER=3.7.0 +readonly BAZELISK_VER=1.7.5 cd ${BUILD_CONTENT} || exit if [[ ! -f wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz ]]; then @@ -36,24 +36,22 @@ if [[ ! -f binaryen-${BINARYEN_VER}-x86_64-linux.tar.gz ]]; then wget https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VER}/binaryen-${BINARYEN_VER}-x86_64-linux.tar.gz fi -if [[ ! -f bazel-${BAZEL_VER}-installer-linux-x86_64.sh ]]; then - wget https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VER}/bazel-${BAZEL_VER}-installer-linux-x86_64.sh +if [[ ! -f bazelisk-linux-amd64.sh ]]; then + wget https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 fi cd - > /dev/null || exit DOCKERFILE_PATH=$(dirname "$(realpath "$0")") docker build \ - --build-arg WASI_SDK_VER=${WASI_SDK_VER} \ - --build-arg WABT_VER=${WABT_VER} \ - --build-arg CMAKE_VER=${CMAKE_VER} \ - --build-arg BINARYEN_VER=${BINARYEN_VER} \ - --build-arg BAZEL_VER=${BAZEL_VER} \ - -t clang_env:0.1 -f "${DOCKERFILE_PATH}"/Dockerfile ${BUILD_CONTENT} - -docker run --rm -it \ - --name workload_w_clang \ - --mount type=bind,source="$(pwd)",target=/data/project \ - -w /data/project \ - clang_env:0.1 \ - /bin/bash -c /build.sh + --build-arg WASI_SDK_VER=${WASI_SDK_VER} \ + --build-arg WABT_VER=${WABT_VER} \ + --build-arg CMAKE_VER=${CMAKE_VER} \ + --build-arg BINARYEN_VER=${BINARYEN_VER} \ + -t clang_env:0.1 -f "${DOCKERFILE_PATH}"/Dockerfile ${BUILD_CONTENT} \ + && docker run --rm \ + --name workload_w_clang \ + --mount type=bind,source="$(pwd)",target=/data/project \ + -w /data/project \ + clang_env:0.1 \ + /bin/bash -c /build.sh