mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
[instantiation linking] create and import WASMMemoryInstance for interp (#3845)
APIs to create and import WASMMemoryInstance for Interp - add a demo (sample/linking/raw) for APIs test - new APIs for instances of spawned threads to build imports list from parents'
This commit is contained in:
parent
217ba3b10c
commit
e030350bd7
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -21,9 +21,10 @@ core/iwasm/libraries/lib-wasi-threads/test/*.wasm
|
|||
core/iwasm/libraries/lib-socket/test/*.wasm
|
||||
|
||||
product-mini/app-samples/hello-world/test.wasm
|
||||
product-mini/platforms/linux-sgx/enclave-sample/App/
|
||||
product-mini/platforms/linux-sgx/enclave-sample/Enclave/
|
||||
product-mini/platforms/linux-sgx/enclave-sample/iwasm
|
||||
product-mini/platforms/linux-sgx/enclave-sample/App/*.o
|
||||
product-mini/platforms/linux-sgx/enclave-sample/Enclave/*.o
|
||||
product-mini/platforms/linux-sgx/enclave-sample/
|
||||
!product-mini/platforms/linux-sgx/enclave-sample/Makefile*
|
||||
|
||||
build_out
|
||||
tests/wamr-test-suites/workspace
|
||||
|
|
|
@ -3384,7 +3384,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
|||
AOTModuleInstance *inst_aot =
|
||||
(AOTModuleInstance *)func->inst_comm_rt;
|
||||
AOTModule *module_aot = (AOTModule *)inst_aot->module;
|
||||
uint32 export_i = 0, export_func_j = 0;
|
||||
uint32 export_i = 0;
|
||||
|
||||
for (; export_i < module_aot->export_count; ++export_i) {
|
||||
AOTExport *export = module_aot->exports + export_i;
|
||||
|
@ -3395,7 +3395,6 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params,
|
|||
((wasm_func_t *)func)->func_comm_rt = func_comm_rt;
|
||||
break;
|
||||
}
|
||||
export_func_j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1535,6 +1535,48 @@ wasm_enlarge_memory_with_idx(WASMModuleInstance *module, uint32 inc_page_count,
|
|||
return ret;
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_runtime_create_memory(WASMModuleCommon *module, WASMMemoryType *type)
|
||||
{
|
||||
if (!module)
|
||||
return NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_create_memory((WASMModule *)module, type);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
bh_assert(false && "Unsupported operation");
|
||||
#endif
|
||||
|
||||
LOG_ERROR("create memory failed, invalid module type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_memory(WASMModuleCommon *const module,
|
||||
WASMMemoryInstance *memory)
|
||||
{
|
||||
if (!module)
|
||||
return;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
wasm_destroy_memory(memory);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
bh_assert(false && "Unsupported operation");
|
||||
#endif
|
||||
|
||||
LOG_ERROR("destroy memory failed, invalid module type");
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_runtime_lookup_memory(WASMModuleInstanceCommon *module_inst,
|
||||
const char *name)
|
||||
|
|
|
@ -1351,6 +1351,7 @@ wasm_runtime_destroy_loading_module_list()
|
|||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
/*TODO: may need to merge with wasm_native. Even do more classification work */
|
||||
bool
|
||||
wasm_runtime_is_built_in_module(const char *module_name)
|
||||
{
|
||||
|
@ -1360,7 +1361,7 @@ wasm_runtime_is_built_in_module(const char *module_name)
|
|||
|| !strcmp("spectest", module_name)
|
||||
#endif
|
||||
#if WASM_ENABLE_WASI_TEST != 0
|
||||
|| !strcmp("foo", module_name)
|
||||
|| !strcmp("foo", module_name) || !strncmp("wasi", module_name, 4)
|
||||
#endif
|
||||
|| !strcmp("", module_name));
|
||||
}
|
||||
|
@ -1622,13 +1623,16 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
const WASMExternInstance *imports,
|
||||
uint32 import_count, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
return (WASMModuleInstanceCommon *)wasm_instantiate(
|
||||
(WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
|
||||
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
|
||||
stack_size, heap_size, max_memory_pages, imports, import_count,
|
||||
error_buf, error_buf_size);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
|
@ -1647,8 +1651,11 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
|
|||
uint32 error_buf_size)
|
||||
{
|
||||
return wasm_runtime_instantiate_internal(module, NULL, NULL, stack_size,
|
||||
heap_size, 0, error_buf,
|
||||
error_buf_size);
|
||||
heap_size,
|
||||
0, // max_memory_pages
|
||||
NULL, // imports
|
||||
0, // import_count
|
||||
error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
WASMModuleInstanceCommon *
|
||||
|
@ -1658,8 +1665,8 @@ wasm_runtime_instantiate_ex(WASMModuleCommon *module,
|
|||
{
|
||||
return wasm_runtime_instantiate_internal(
|
||||
module, NULL, NULL, args->default_stack_size,
|
||||
args->host_managed_heap_size, args->max_memory_pages, error_buf,
|
||||
error_buf_size);
|
||||
args->host_managed_heap_size, args->max_memory_pages, args->imports,
|
||||
args->import_count, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7474,6 +7481,8 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *sub_module_inst = NULL;
|
||||
sub_module_inst = wasm_runtime_instantiate_internal(
|
||||
sub_module, NULL, NULL, stack_size, heap_size, max_memory_pages,
|
||||
NULL, // imports
|
||||
0, // import_count
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module_inst) {
|
||||
LOG_DEBUG("instantiate %s failed",
|
||||
|
@ -7739,3 +7748,198 @@ wasm_runtime_is_underlying_binary_freeable(WASMModuleCommon *const module)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*TODO: take us(below) out when have a linker */
|
||||
bool
|
||||
wasm_runtime_create_extern_inst(WASMModuleCommon *module,
|
||||
wasm_import_t import_type,
|
||||
WASMExternInstance *out)
|
||||
{
|
||||
if (!out)
|
||||
return false;
|
||||
|
||||
LOG_DEBUG("create import(%s,%s) kind %d", import_type.module_name,
|
||||
import_type.name, import_type.kind);
|
||||
|
||||
out->module_name = import_type.module_name;
|
||||
out->field_name = import_type.name;
|
||||
out->kind = import_type.kind;
|
||||
|
||||
if (import_type.kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
out->u.memory =
|
||||
wasm_runtime_create_memory(module, import_type.u.memory_type);
|
||||
if (!out->u.memory) {
|
||||
LOG_ERROR("create memory failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_DEBUG("unimplemented import(%s,%s) kind %d",
|
||||
import_type.module_name, import_type.name, import_type.kind);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_extern_inst(WASMModuleCommon *module,
|
||||
WASMExternInstance *extern_inst)
|
||||
{
|
||||
if (!extern_inst)
|
||||
return;
|
||||
|
||||
if (extern_inst->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
wasm_runtime_destroy_memory(module, extern_inst->u.memory);
|
||||
extern_inst->u.memory = NULL;
|
||||
}
|
||||
else {
|
||||
LOG_DEBUG("unimplemented import(%s,%s) kind %d",
|
||||
extern_inst->module_name, extern_inst->field_name,
|
||||
extern_inst->kind);
|
||||
}
|
||||
|
||||
extern_inst->module_name = NULL;
|
||||
extern_inst->field_name = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* willn't take the ownership of new_extern_inst
|
||||
* take the ownership of the content of new_extern_inst
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_overwirte_imports(WASMModuleCommon *module,
|
||||
WASMExternInstance *orig_extern_inst_list,
|
||||
WASMExternInstance *new_extern_inst, int32 index)
|
||||
{
|
||||
// argument check
|
||||
if (!module || !orig_extern_inst_list || !new_extern_inst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check index with the import count of the module
|
||||
if (index < 0 || index >= wasm_runtime_get_import_count(module)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the targeted extern_inst. allow to be NULL
|
||||
WASMExternInstance *old_extern_inst = orig_extern_inst_list + index;
|
||||
|
||||
// release the targeted extern_inst if not NULL
|
||||
wasm_runtime_destroy_extern_inst(module, old_extern_inst);
|
||||
|
||||
// overwrite the targeted extern_inst
|
||||
bh_memcpy_s(old_extern_inst, sizeof(WASMExternInstance), new_extern_inst,
|
||||
sizeof(WASMExternInstance));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Be aware that it will remove all items in the list, regardless of whether
|
||||
* they were created by the runtime (for built-ins) or by users.
|
||||
*/
|
||||
void
|
||||
wasm_runtime_destroy_imports(WASMModuleCommon *module,
|
||||
WASMExternInstance *extern_inst_list)
|
||||
{
|
||||
if (!module || !extern_inst_list)
|
||||
return;
|
||||
|
||||
for (int32 i = 0, import_count = wasm_runtime_get_import_count(module);
|
||||
i < import_count; i++) {
|
||||
wasm_runtime_destroy_extern_inst(module, extern_inst_list + i);
|
||||
}
|
||||
|
||||
wasm_runtime_free(extern_inst_list);
|
||||
}
|
||||
|
||||
WASMExternInstance *
|
||||
wasm_runtime_create_imports(WASMModuleCommon *module,
|
||||
bool (*module_name_filter)(const char *))
|
||||
{
|
||||
int32 import_count = wasm_runtime_get_import_count(module);
|
||||
WASMExternInstance *imports = NULL;
|
||||
|
||||
if (import_count == 0)
|
||||
return NULL;
|
||||
|
||||
imports = runtime_malloc(sizeof(WASMExternInstance) * import_count,
|
||||
NULL, // module_inst
|
||||
NULL, 0);
|
||||
if (!imports) {
|
||||
LOG_ERROR("allocate memory failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < import_count; i++) {
|
||||
wasm_import_t import_type = { 0 };
|
||||
wasm_runtime_get_import_type(module, i, &import_type);
|
||||
|
||||
if (module_name_filter
|
||||
&& !module_name_filter(import_type.module_name)) {
|
||||
LOG_DEBUG("skip import(%s,%s)", import_type.module_name,
|
||||
import_type.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
WASMExternInstance *extern_instance = imports + i;
|
||||
if (!wasm_runtime_create_extern_inst(module, import_type,
|
||||
extern_instance)) {
|
||||
wasm_runtime_destroy_imports(module, imports);
|
||||
LOG_ERROR("create import failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
WASMExternInstance *
|
||||
wasm_runtime_create_imports_with_builtin(WASMModuleCommon *module)
|
||||
{
|
||||
LOG_DEBUG("create imports with builtin");
|
||||
return wasm_runtime_create_imports(module, wasm_runtime_is_built_in_module);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
|
||||
/*
|
||||
* The function is used to create a new WASMExternInstance list
|
||||
* for a spawned thread.
|
||||
*/
|
||||
int32
|
||||
wasm_runtime_inherit_imports(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *inst,
|
||||
WASMExternInstance *out, int32 out_len)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
return wasm_inherit_imports((WASMModule *)module,
|
||||
(WASMModuleInstance *)inst, out, out_len);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
bh_assert(false && "Unsupported operation");
|
||||
}
|
||||
#endif
|
||||
LOG_ERROR("inherit imports failed, invalid module type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_disinherit_imports(WASMModuleCommon *module,
|
||||
WASMExternInstance *imports, int32 import_count)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
wasm_disinherit_imports((WASMModule *)module, imports, import_count);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
bh_assert(false && "Unsupported operation");
|
||||
}
|
||||
#endif
|
||||
LOG_ERROR("disinherit imports failed, invalid module type");
|
||||
}
|
||||
#endif /* WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0 */
|
||||
|
|
|
@ -575,7 +575,9 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
const WASMExternInstance *imports,
|
||||
uint32 import_count, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
/* Internal API */
|
||||
void
|
||||
|
@ -1215,6 +1217,22 @@ void
|
|||
wasm_runtime_set_linux_perf(bool flag);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
|
||||
/*
|
||||
* The function is used to create a new WASMExternInstance list
|
||||
* for a spawned thread.
|
||||
*/
|
||||
int32
|
||||
wasm_runtime_inherit_imports(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *inst,
|
||||
WASMExternInstance *out, int32 out_len);
|
||||
|
||||
void
|
||||
wasm_runtime_disinherit_imports(WASMModuleCommon *module,
|
||||
WASMExternInstance *imports,
|
||||
int32 import_count);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -199,6 +199,8 @@ typedef struct InstantiationArgs {
|
|||
uint32_t default_stack_size;
|
||||
uint32_t host_managed_heap_size;
|
||||
uint32_t max_memory_pages;
|
||||
const struct WasmExternInstance *imports;
|
||||
uint32_t import_count;
|
||||
} InstantiationArgs;
|
||||
#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
|
||||
|
||||
|
|
|
@ -264,6 +264,15 @@ typedef struct LoadArgs {
|
|||
} LoadArgs;
|
||||
#endif /* LOAD_ARGS_OPTION_DEFINED */
|
||||
|
||||
typedef struct WASMExternInstance {
|
||||
const char *module_name;
|
||||
const char *field_name;
|
||||
wasm_import_export_kind_t kind;
|
||||
union {
|
||||
wasm_memory_inst_t memory;
|
||||
} u;
|
||||
} WASMExternInstance, *wasm_extern_inst_t;
|
||||
|
||||
#ifndef INSTANTIATION_ARGS_OPTION_DEFINED
|
||||
#define INSTANTIATION_ARGS_OPTION_DEFINED
|
||||
/* WASM module instantiation arguments */
|
||||
|
@ -271,6 +280,8 @@ typedef struct InstantiationArgs {
|
|||
uint32_t default_stack_size;
|
||||
uint32_t host_managed_heap_size;
|
||||
uint32_t max_memory_pages;
|
||||
const wasm_extern_inst_t imports;
|
||||
uint32_t import_count;
|
||||
} InstantiationArgs;
|
||||
#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
|
||||
|
||||
|
@ -961,6 +972,25 @@ WASM_RUNTIME_API_EXTERN void
|
|||
wasm_runtime_set_module_inst(wasm_exec_env_t exec_env,
|
||||
const wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* Create a memory instance.
|
||||
* don't have a app heap
|
||||
*
|
||||
* @return The created memory instance if successful, NULL otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_memory_inst_t
|
||||
wasm_runtime_create_memory(const wasm_module_t module,
|
||||
const wasm_memory_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Destroy a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance to destroy
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_destroy_memory(const wasm_module_t module,
|
||||
wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Lookup a memory instance by name
|
||||
*
|
||||
|
@ -2300,6 +2330,20 @@ wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64_t size,
|
|||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64_t ptr);
|
||||
|
||||
/*TODO: take me out when have a linker */
|
||||
/**
|
||||
* @return NULL if failed and if there is no import
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_extern_inst_t
|
||||
wasm_runtime_create_imports_with_builtin(wasm_module_t module);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_destroy_imports(wasm_module_t module, wasm_extern_inst_t imports);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN wasm_extern_inst_t
|
||||
wasm_runtime_create_imports(wasm_module_t module,
|
||||
bool (*module_name_filter)(const char *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -6580,7 +6580,7 @@ check_wasi_abi_compatibility(const WASMModule *module,
|
|||
*/
|
||||
/* clang-format on */
|
||||
|
||||
WASMExport *initialize = NULL, *memory = NULL, *start = NULL;
|
||||
WASMExport *initialize = NULL, *start = NULL;
|
||||
uint32 import_function_count = module->import_function_count;
|
||||
WASMFuncType *func_type;
|
||||
|
||||
|
@ -6655,32 +6655,6 @@ check_wasi_abi_compatibility(const WASMModule *module,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* it is ok a reactor acts as a main module,
|
||||
* so skip the check about (with `_initialize`)
|
||||
*/
|
||||
|
||||
memory = wasm_loader_find_export(module, "", "memory", EXPORT_KIND_MEMORY,
|
||||
error_buf, error_buf_size);
|
||||
if (!memory
|
||||
#if WASM_ENABLE_LIB_WASI_THREADS != 0
|
||||
/*
|
||||
* with wasi-threads, it's still an open question if a memory
|
||||
* should be exported.
|
||||
*
|
||||
* https://github.com/WebAssembly/wasi-threads/issues/22
|
||||
* https://github.com/WebAssembly/WASI/issues/502
|
||||
*
|
||||
* Note: this code assumes the number of memories is at most 1.
|
||||
*/
|
||||
&& module->import_memory_count == 0
|
||||
#endif
|
||||
) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"a module with WASI apis must export memory by default");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -233,74 +233,89 @@ get_sub_module_inst(const WASMModuleInstance *parent_module_inst,
|
|||
/**
|
||||
* Destroy memory instances.
|
||||
*/
|
||||
|
||||
static void
|
||||
memory_deinstantiate(WASMMemoryInstance *memory)
|
||||
{
|
||||
if (!memory)
|
||||
return;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (shared_memory_is_shared(memory)) {
|
||||
uint32 ref_count = shared_memory_dec_reference(memory);
|
||||
/* if the reference count is not zero,
|
||||
don't free the memory */
|
||||
if (ref_count > 0)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (memory->heap_handle) {
|
||||
mem_allocator_destroy(memory->heap_handle);
|
||||
wasm_runtime_free(memory->heap_handle);
|
||||
memory->heap_handle = NULL;
|
||||
}
|
||||
|
||||
if (memory->memory_data) {
|
||||
wasm_deallocate_linear_memory(memory);
|
||||
memory->memory_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
memories_deinstantiate(WASMModuleInstance *module_inst,
|
||||
WASMMemoryInstance **memories, uint32 count)
|
||||
{
|
||||
uint32 i;
|
||||
if (memories) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (memories[i]) {
|
||||
WASMModule *module = module_inst->module;
|
||||
|
||||
if (!memories)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If created by host or linker, import memories should also be released by
|
||||
* host or linker
|
||||
*/
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
if (i < module->import_memory_count
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *module = module_inst->module;
|
||||
if (i < module->import_memory_count
|
||||
&& module->import_memories[i].u.memory.import_module) {
|
||||
continue;
|
||||
}
|
||||
&& module->import_memories[i].u.memory.import_module
|
||||
#endif
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (shared_memory_is_shared(memories[i])) {
|
||||
uint32 ref_count = shared_memory_dec_reference(memories[i]);
|
||||
/* if the reference count is not zero,
|
||||
don't free the memory */
|
||||
if (ref_count > 0)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (memories[i]->heap_handle) {
|
||||
mem_allocator_destroy(memories[i]->heap_handle);
|
||||
wasm_runtime_free(memories[i]->heap_handle);
|
||||
memories[i]->heap_handle = NULL;
|
||||
}
|
||||
if (memories[i]->memory_data) {
|
||||
wasm_deallocate_linear_memory(memories[i]);
|
||||
}
|
||||
}
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
wasm_runtime_free(memories);
|
||||
|
||||
memory_deinstantiate(memories[i]);
|
||||
}
|
||||
|
||||
wasm_runtime_free(memories);
|
||||
(void)module_inst;
|
||||
}
|
||||
|
||||
static WASMMemoryInstance *
|
||||
memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||
WASMMemoryInstance *memory, uint32 memory_idx,
|
||||
uint32 num_bytes_per_page, uint32 init_page_count,
|
||||
uint32 max_page_count, uint32 heap_size, uint32 flags,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
memory_instantiate(const WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMMemoryInstance *memory,
|
||||
WASMMemoryInstance *parent_memory, uint32 num_bytes_per_page,
|
||||
uint32 init_page_count, uint32 max_page_count,
|
||||
uint32 heap_size, uint32 flags,
|
||||
uint8 *aux_heap_base_global_data, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module = module_inst->module;
|
||||
uint32 inc_page_count, global_idx, default_max_page;
|
||||
uint32 bytes_of_last_page, bytes_to_page_end;
|
||||
uint64 aux_heap_base,
|
||||
heap_offset = (uint64)num_bytes_per_page * init_page_count;
|
||||
uint64 memory_data_size, max_memory_data_size;
|
||||
uint8 *global_addr;
|
||||
|
||||
bool is_shared_memory = false;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
is_shared_memory = flags & SHARED_MEMORY_FLAG ? true : false;
|
||||
|
||||
bh_assert(memory != NULL);
|
||||
|
||||
/* shared memory */
|
||||
if (is_shared_memory && parent != NULL) {
|
||||
bh_assert(parent->memory_count > memory_idx);
|
||||
memory = parent->memories[memory_idx];
|
||||
bh_assert(parent->memory_count > 0);
|
||||
memory = parent_memory;
|
||||
shared_memory_inc_reference(memory);
|
||||
return memory;
|
||||
}
|
||||
#else
|
||||
(void)parent;
|
||||
(void)memory_idx;
|
||||
(void)parent_memory;
|
||||
(void)flags;
|
||||
#endif /* end of WASM_ENABLE_SHARED_MEMORY */
|
||||
|
||||
|
@ -309,13 +324,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
memory->is_memory64 = 1;
|
||||
}
|
||||
#endif
|
||||
default_max_page =
|
||||
memory->is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES;
|
||||
|
||||
/* The app heap should be in the default memory */
|
||||
if (memory_idx == 0) {
|
||||
if (heap_size > 0 && module_inst->module->malloc_function != (uint32)-1
|
||||
&& module_inst->module->free_function != (uint32)-1) {
|
||||
/* adjust heap_size, heap_offset and num_bytes_per_page */
|
||||
uint64 heap_offset = (uint64)num_bytes_per_page * init_page_count;
|
||||
{
|
||||
if (heap_size > 0 && module->malloc_function != (uint32)-1
|
||||
&& module->free_function != (uint32)-1) {
|
||||
/* Disable app heap, use malloc/free function exported
|
||||
by wasm app to allocate/free memory instead */
|
||||
heap_size = 0;
|
||||
|
@ -345,6 +359,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
}
|
||||
}
|
||||
else if (heap_size > 0) {
|
||||
uint32 inc_page_count = 0;
|
||||
if (init_page_count == max_page_count && init_page_count == 0) {
|
||||
/* If the memory data size is always 0, we resize it to
|
||||
one page for app heap */
|
||||
|
@ -356,11 +371,12 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
&& module->aux_heap_base
|
||||
< (uint64)num_bytes_per_page * init_page_count) {
|
||||
/* Insert app heap before __heap_base */
|
||||
aux_heap_base = module->aux_heap_base;
|
||||
bytes_of_last_page = aux_heap_base % num_bytes_per_page;
|
||||
uint64 aux_heap_base = module->aux_heap_base;
|
||||
uint32 bytes_of_last_page = aux_heap_base % num_bytes_per_page;
|
||||
if (bytes_of_last_page == 0)
|
||||
bytes_of_last_page = num_bytes_per_page;
|
||||
bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
|
||||
uint32 bytes_to_page_end =
|
||||
num_bytes_per_page - bytes_of_last_page;
|
||||
inc_page_count =
|
||||
(heap_size - bytes_to_page_end + num_bytes_per_page - 1)
|
||||
/ num_bytes_per_page;
|
||||
|
@ -377,21 +393,24 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
}
|
||||
|
||||
/* Adjust __heap_base global value */
|
||||
global_idx = module->aux_heap_base_global_index;
|
||||
bh_assert(module_inst->e->globals
|
||||
&& global_idx < module_inst->e->global_count);
|
||||
global_addr = module_inst->global_data
|
||||
+ module_inst->e->globals[global_idx].data_offset;
|
||||
if (aux_heap_base_global_data == NULL) {
|
||||
set_error_buf(
|
||||
error_buf, error_buf_size,
|
||||
"auxiliary heap base global data should not be NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
if (memory->is_memory64) {
|
||||
/* For memory64, the global value should be i64 */
|
||||
*(uint64 *)global_addr = aux_heap_base;
|
||||
*(uint64 *)aux_heap_base_global_data = aux_heap_base;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* For memory32, the global value should be i32 */
|
||||
*(uint32 *)global_addr = (uint32)aux_heap_base;
|
||||
*(uint32 *)aux_heap_base_global_data =
|
||||
(uint32)aux_heap_base;
|
||||
}
|
||||
LOG_VERBOSE("Reset __heap_base global to %" PRIu64,
|
||||
aux_heap_base);
|
||||
|
@ -405,6 +424,10 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
if (heap_size > 0)
|
||||
heap_size -= 1 * BH_KB;
|
||||
}
|
||||
|
||||
uint32 default_max_page = memory->is_memory64
|
||||
? DEFAULT_MEM64_MAX_PAGES
|
||||
: DEFAULT_MAX_PAGES;
|
||||
init_page_count += inc_page_count;
|
||||
max_page_count += inc_page_count;
|
||||
if (init_page_count > default_max_page) {
|
||||
|
@ -422,17 +445,18 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
LOG_VERBOSE("Memory instantiate:");
|
||||
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
|
||||
num_bytes_per_page, init_page_count, max_page_count);
|
||||
if (memory_idx == 0)
|
||||
LOG_VERBOSE(" heap offset: %" PRIu64 ", heap size: %u\n", heap_offset,
|
||||
heap_size);
|
||||
|
||||
max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
|
||||
bh_assert(max_memory_data_size
|
||||
<= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
|
||||
(void)max_memory_data_size;
|
||||
|
||||
bh_assert(memory != NULL);
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
uint64 max_memory_data_size =
|
||||
(uint64)num_bytes_per_page * max_page_count;
|
||||
bh_assert(max_memory_data_size
|
||||
<= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
|
||||
(void)max_memory_data_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64 memory_data_size = 0;
|
||||
if (wasm_allocate_linear_memory(&memory->memory_data, is_shared_memory,
|
||||
memory->is_memory64, num_bytes_per_page,
|
||||
init_page_count, max_page_count,
|
||||
|
@ -448,21 +472,24 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
memory->cur_page_count = init_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
memory->memory_data_size = memory_data_size;
|
||||
|
||||
if (memory_idx == 0) {
|
||||
memory->heap_data = memory->memory_data + heap_offset;
|
||||
memory->heap_data_end = memory->heap_data + heap_size;
|
||||
memory->memory_data_end = memory->memory_data + memory_data_size;
|
||||
}
|
||||
memory->heap_data = memory->memory_data + heap_offset;
|
||||
memory->heap_data_end = memory->heap_data + heap_size;
|
||||
memory->memory_data_end = memory->memory_data + memory->memory_data_size;
|
||||
|
||||
/* Initialize heap */
|
||||
if (memory_idx == 0 && heap_size > 0) {
|
||||
if (heap_size > 0) {
|
||||
LOG_VERBOSE(" heap offset: %" PRIu64 ", heap size: %u\n", heap_offset,
|
||||
heap_size);
|
||||
|
||||
uint32 heap_struct_size = mem_allocator_get_heap_struct_size();
|
||||
|
||||
if (!(memory->heap_handle = runtime_malloc(
|
||||
(uint64)heap_struct_size, error_buf, error_buf_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"allocate app heap failed");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
if (!mem_allocator_create_with_struct_and_pool(
|
||||
memory->heap_handle, heap_struct_size, memory->heap_data,
|
||||
heap_size)) {
|
||||
|
@ -486,11 +513,14 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
|||
return memory;
|
||||
|
||||
fail2:
|
||||
if (memory_idx == 0 && heap_size > 0)
|
||||
if (heap_size > 0) {
|
||||
wasm_runtime_free(memory->heap_handle);
|
||||
memory->heap_handle = NULL;
|
||||
}
|
||||
fail1:
|
||||
if (memory->memory_data)
|
||||
if (memory->memory_data) {
|
||||
wasm_deallocate_linear_memory(memory);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -501,10 +531,9 @@ fail1:
|
|||
static WASMMemoryInstance **
|
||||
memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
WASMModuleInstance *parent, uint32 heap_size,
|
||||
uint32 max_memory_pages, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
uint32 max_memory_pages, uint8 *aux_heap_base_global_data,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMImport *import;
|
||||
uint32 mem_index = 0, i,
|
||||
memory_count = module->import_memory_count + module->memory_count;
|
||||
uint64 total_size;
|
||||
|
@ -519,18 +548,10 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
|||
memory = module_inst->global_table_data.memory_instances;
|
||||
|
||||
/* instantiate memories from import section */
|
||||
import = module->import_memories;
|
||||
for (i = 0; i < module->import_memory_count; i++, import++, memory++) {
|
||||
uint32 num_bytes_per_page =
|
||||
import->u.memory.mem_type.num_bytes_per_page;
|
||||
uint32 init_page_count = import->u.memory.mem_type.init_page_count;
|
||||
uint32 max_page_count = wasm_runtime_get_max_mem(
|
||||
max_memory_pages, import->u.memory.mem_type.init_page_count,
|
||||
import->u.memory.mem_type.max_page_count);
|
||||
uint32 flags = import->u.memory.mem_type.flags;
|
||||
uint32 actual_heap_size = heap_size;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMImport *import = module->import_memories;
|
||||
for (i = 0; i < module->import_memory_count; i++, import++, memory++) {
|
||||
// TODO: ? make sure import->u.memory.import_module is set properly
|
||||
if (import->u.memory.import_module != NULL) {
|
||||
WASMModuleInstance *module_inst_linked;
|
||||
|
||||
|
@ -548,13 +569,24 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
// TODO: Although it is for inherited memory, it misses a situation
|
||||
// where the memory is imported from host or other modules
|
||||
uint32 num_bytes_per_page =
|
||||
import->u.memory.mem_type.num_bytes_per_page;
|
||||
uint32 init_page_count = import->u.memory.mem_type.init_page_count;
|
||||
uint32 max_page_count = wasm_runtime_get_max_mem(
|
||||
max_memory_pages, import->u.memory.mem_type.init_page_count,
|
||||
import->u.memory.mem_type.max_page_count);
|
||||
uint32 flags = import->u.memory.mem_type.flags;
|
||||
|
||||
if (!(memories[mem_index] = memory_instantiate(
|
||||
module_inst, parent, memory, mem_index,
|
||||
module, parent, memory,
|
||||
parent ? parent->memories[mem_index] : NULL,
|
||||
num_bytes_per_page, init_page_count, max_page_count,
|
||||
actual_heap_size, flags, error_buf, error_buf_size))) {
|
||||
/* only inst->memories[0] will have an app heap */
|
||||
mem_index == 0 ? heap_size : 0, flags,
|
||||
aux_heap_base_global_data, error_buf, error_buf_size))) {
|
||||
memories_deinstantiate(module_inst, memories, memory_count);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -562,17 +594,29 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
|||
}
|
||||
}
|
||||
|
||||
bh_assert(mem_index == module->import_memory_count);
|
||||
bh_assert(memory
|
||||
== module_inst->global_table_data.memory_instances
|
||||
+ module->import_memory_count);
|
||||
#else
|
||||
mem_index = module->import_memory_count;
|
||||
memory = module_inst->global_table_data.memory_instances
|
||||
+ module->import_memory_count;
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE != 0 */
|
||||
|
||||
/* instantiate memories from memory section */
|
||||
for (i = 0; i < module->memory_count; i++, memory++) {
|
||||
uint32 max_page_count = wasm_runtime_get_max_mem(
|
||||
max_memory_pages, module->memories[i].init_page_count,
|
||||
module->memories[i].max_page_count);
|
||||
if (!(memories[mem_index] = memory_instantiate(
|
||||
module_inst, parent, memory, mem_index,
|
||||
module, parent, memory,
|
||||
parent ? parent->memories[mem_index] : NULL,
|
||||
module->memories[i].num_bytes_per_page,
|
||||
module->memories[i].init_page_count, max_page_count,
|
||||
heap_size, module->memories[i].flags, error_buf,
|
||||
error_buf_size))) {
|
||||
/* only inst->memories[0] will have a app heap */
|
||||
mem_index == 0 ? heap_size : 0, module->memories[i].flags,
|
||||
aux_heap_base_global_data, error_buf, error_buf_size))) {
|
||||
memories_deinstantiate(module_inst, memories, memory_count);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -584,6 +628,50 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
|||
return memories;
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_create_memory(const WASMModule *module, const WASMMemoryType *type)
|
||||
{
|
||||
WASMMemoryInstance *memory = NULL;
|
||||
char error_buf[64] = { 0 };
|
||||
|
||||
memory = runtime_malloc(sizeof(WASMMemoryInstance), error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!memory) {
|
||||
LOG_ERROR("Failed to create WASMMemoryInstance: %s", error_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* use provided max_page_count of type instead of adjusting with
|
||||
* wasm_runtime_get_max_mem()
|
||||
*/
|
||||
if (!memory_instantiate(module,
|
||||
NULL, // parent
|
||||
memory,
|
||||
NULL, // parent_memory
|
||||
type->num_bytes_per_page, type->init_page_count,
|
||||
type->max_page_count,
|
||||
0, // no heap_size from host side
|
||||
type->flags,
|
||||
NULL, // aux_heap_base_global_data
|
||||
error_buf, sizeof(error_buf))) {
|
||||
wasm_runtime_free(memory);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_destroy_memory(WASMMemoryInstance *memory)
|
||||
{
|
||||
if (!memory)
|
||||
return;
|
||||
|
||||
memory_deinstantiate(memory);
|
||||
wasm_runtime_free(memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy table instances.
|
||||
*/
|
||||
|
@ -1879,6 +1967,12 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* all imported WASMXXXInstance shall be linked and NOT NULL
|
||||
*
|
||||
* TODO: not sure if MULTI_MODULE can be used under the same conditions
|
||||
* for checking.
|
||||
*/
|
||||
static bool
|
||||
check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
|
@ -1932,16 +2026,19 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf,
|
|||
}
|
||||
|
||||
for (i = 0; i < module->import_memory_count; i++) {
|
||||
WASMMemoryImport *memory = &((module->import_memories + i)->u.memory);
|
||||
|
||||
if (!wasm_runtime_is_built_in_module(memory->module_name)
|
||||
WASMMemoryImport *type = &((module->import_memories + i)->u.memory);
|
||||
WASMMemoryInstance *memory = module_inst->memories[i];
|
||||
if (
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
&& !memory->import_memory_linked
|
||||
!wasm_runtime_is_built_in_module(type->module_name)
|
||||
&& !type->import_memory_linked
|
||||
#else
|
||||
!memory
|
||||
#endif
|
||||
) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"failed to link import memory (%s, %s)",
|
||||
memory->module_name, memory->field_name);
|
||||
type->module_name, type->field_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2340,8 +2437,9 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
|
|||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
const WASMExternInstance *imports, uint32 import_count,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMGlobalInstance *globals = NULL, *global;
|
||||
|
@ -2362,6 +2460,18 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
if (!module)
|
||||
return NULL;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
if (module->import_count > 0 && !imports) {
|
||||
/*
|
||||
* TODO: might be too strict
|
||||
* might wasm_runtime_create_imports_with_builtin() here by default
|
||||
*/
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"argument imports is NULL while module has imports");
|
||||
// return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check the heap size */
|
||||
heap_size = align_uint(heap_size, 8);
|
||||
if (heap_size > APP_HEAP_SIZE_MAX)
|
||||
|
@ -2502,6 +2612,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
#endif
|
||||
|
||||
/* Instantiate global firstly to get the mutable data size */
|
||||
/*
|
||||
* memory_instantiate() might change the value of __heap_base
|
||||
* so, globals_instantiate() has to be called firstly
|
||||
*/
|
||||
global_count = module->import_global_count + module->global_count;
|
||||
if (global_count
|
||||
&& !(globals = globals_instantiate(module, module_inst, error_buf,
|
||||
|
@ -2527,11 +2641,8 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
|
||||
/* export */
|
||||
module_inst->export_func_count = get_export_count(module, EXPORT_KIND_FUNC);
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
module_inst->export_memory_count =
|
||||
get_export_count(module, EXPORT_KIND_MEMORY);
|
||||
#endif
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module_inst->export_table_count =
|
||||
get_export_count(module, EXPORT_KIND_TABLE);
|
||||
#if WASM_ENABLE_TAGS != 0
|
||||
|
@ -2540,13 +2651,22 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
#endif
|
||||
module_inst->export_global_count =
|
||||
get_export_count(module, EXPORT_KIND_GLOBAL);
|
||||
#endif
|
||||
|
||||
/* __heap_base */
|
||||
uint8 *aux_heap_base_global_data = NULL;
|
||||
if (module_inst->e->globals
|
||||
&& module->aux_heap_base_global_index < module->global_count) {
|
||||
aux_heap_base_global_data =
|
||||
module_inst->global_data
|
||||
+ module_inst->e->globals[module->aux_heap_base_global_index]
|
||||
.data_offset;
|
||||
}
|
||||
|
||||
/* Instantiate memories/tables/functions/tags */
|
||||
if ((module_inst->memory_count > 0
|
||||
&& !(module_inst->memories = memories_instantiate(
|
||||
module, module_inst, parent, heap_size, max_memory_pages,
|
||||
error_buf, error_buf_size)))
|
||||
aux_heap_base_global_data, error_buf, error_buf_size)))
|
||||
|| (module_inst->table_count > 0
|
||||
&& !(module_inst->tables =
|
||||
tables_instantiate(module, module_inst, first_table,
|
||||
|
@ -2590,6 +2710,36 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
/* imports */
|
||||
/*
|
||||
* const WASMExternInstance *imports should have the same order
|
||||
* with import section content in .wasm.
|
||||
*/
|
||||
{
|
||||
uint32 import_memory_index = 0;
|
||||
uint32 import_index = 0;
|
||||
for (; import_index < import_count; import_index++) {
|
||||
/* TODO: remove me if the entire instantiation linking feature is
|
||||
* complete */
|
||||
if (imports == NULL)
|
||||
break;
|
||||
|
||||
const WASMExternInstance *import = imports + import_index;
|
||||
if (import->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
if (import_memory_index >= module->import_memory_count) {
|
||||
LOG_ERROR("provided import memory not match requirement");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
module_inst->memories[import_memory_index] = import->u.memory;
|
||||
import_memory_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (global_count > 0) {
|
||||
/* Initialize the global data */
|
||||
global_data = module_inst->global_data;
|
||||
|
@ -3366,9 +3516,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
|||
(WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->memory_count > 0)
|
||||
if (module_inst->memory_count > 0) {
|
||||
memories_deinstantiate(module_inst, module_inst->memories,
|
||||
module_inst->memory_count);
|
||||
}
|
||||
|
||||
if (module_inst->import_func_ptrs) {
|
||||
wasm_runtime_free(module_inst->import_func_ptrs);
|
||||
|
@ -5032,3 +5183,82 @@ wasm_get_module_name(WASMModule *module)
|
|||
{
|
||||
return module->name;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
|
||||
/*
|
||||
* The function is used to create a new WASMExternInstance list
|
||||
* for a spawned thread.
|
||||
*/
|
||||
int32
|
||||
wasm_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
|
||||
WASMExternInstance *out, int32 out_len)
|
||||
{
|
||||
if (!module || !inst || !out)
|
||||
return -1;
|
||||
|
||||
int32 spawned_import_count = module->import_count;
|
||||
if (spawned_import_count > out_len) {
|
||||
LOG_WARNING("The number of imported functions is more than the "
|
||||
"length of provided buffer ");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32 i = 0, import_memory_index = 0; i < spawned_import_count; i++) {
|
||||
wasm_import_t import_type = { 0 };
|
||||
|
||||
wasm_runtime_get_import_type((WASMModuleCommon *)module, i,
|
||||
&import_type);
|
||||
|
||||
out[i].module_name = import_type.module_name;
|
||||
out[i].field_name = import_type.name;
|
||||
out[i].kind = import_type.kind;
|
||||
|
||||
if (import_type.kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
out[i].u.memory = inst->memories[import_memory_index];
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
shared_memory_inc_reference(inst->memories[import_memory_index]);
|
||||
#endif
|
||||
import_memory_index++;
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("for spawned, inherit() import(%s,%s) kind %d",
|
||||
import_type.module_name, import_type.name,
|
||||
import_type.kind);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_disinherit_imports(WASMModule *module, WASMExternInstance *imports,
|
||||
int32 import_count)
|
||||
{
|
||||
if (!module || !imports)
|
||||
return;
|
||||
|
||||
int32 spawned_import_count = module->import_count;
|
||||
if (spawned_import_count > import_count) {
|
||||
LOG_WARNING("The number of imported functions is more than the "
|
||||
"length of provided buffer ");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < import_count; i++) {
|
||||
WASMExternInstance *import = imports + i;
|
||||
|
||||
if (import->kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
if (!import->u.memory)
|
||||
continue;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
shared_memory_dec_reference(import->u.memory);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("for spawned, disinherit() import(%s,%s) kind %d",
|
||||
import->module_name, import->field_name, import->kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0 */
|
||||
|
|
|
@ -546,8 +546,9 @@ wasm_resolve_import_func(const WASMModule *module,
|
|||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
const WASMExternInstance *imports, uint32 import_count,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
void
|
||||
wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
|
||||
|
@ -566,6 +567,9 @@ bool
|
|||
wasm_set_running_mode(WASMModuleInstance *module_inst,
|
||||
RunningMode running_mode);
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_create_memory(const WASMModule *module, const WASMMemoryType *type);
|
||||
|
||||
WASMFunctionInstance *
|
||||
wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name);
|
||||
|
||||
|
@ -584,8 +588,10 @@ WASMTagInstance *
|
|||
wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name,
|
||||
const char *signature);
|
||||
#endif
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE != 0 */
|
||||
|
||||
#endif
|
||||
void
|
||||
wasm_destroy_memory(WASMMemoryInstance *memory);
|
||||
|
||||
bool
|
||||
wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
|
||||
|
@ -889,6 +895,16 @@ wasm_set_module_name(WASMModule *module, const char *name, char *error_buf,
|
|||
const char *
|
||||
wasm_get_module_name(WASMModule *module);
|
||||
|
||||
#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
|
||||
int32
|
||||
wasm_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
|
||||
WASMExternInstance *out, int32 out_len);
|
||||
|
||||
void
|
||||
wasm_disinherit_imports(WASMModule *module, WASMExternInstance *imports,
|
||||
int32 import_count);
|
||||
#endif /* WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -561,6 +561,8 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
|||
uint32 aux_stack_size;
|
||||
uint64 aux_stack_start = 0;
|
||||
int32 ret = -1;
|
||||
int32 spawned_import_count = ((WASMModule *)module)->import_count;
|
||||
WASMExternInstance *spawned_imports = NULL;
|
||||
|
||||
bh_assert(module);
|
||||
bh_assert(module_inst);
|
||||
|
@ -579,9 +581,31 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* build a imports list(WASMExternInstance[]) from parent's imports
|
||||
*/
|
||||
spawned_imports =
|
||||
wasm_runtime_malloc(sizeof(WASMExternInstance) * spawned_import_count);
|
||||
if (spawned_imports == NULL) {
|
||||
LOG_ERROR("Failed to allocate memory for imports");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_inherit_imports(module, module_inst, spawned_imports,
|
||||
spawned_import_count);
|
||||
if (ret != 0) {
|
||||
LOG_ERROR("Failed to inherit imports");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
|
||||
return -1;
|
||||
module, module_inst, exec_env, stack_size,
|
||||
0, // heap_size
|
||||
0, // max_memory_pages
|
||||
spawned_imports, // imports
|
||||
spawned_import_count, // import_count
|
||||
NULL, 0)))
|
||||
goto fail;
|
||||
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
|
@ -641,9 +665,17 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
|||
if (thread)
|
||||
*thread = thread_handle;
|
||||
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
wasm_runtime_free(spawned_imports);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (spawned_imports) {
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
wasm_runtime_free(spawned_imports);
|
||||
}
|
||||
if (new_module_inst)
|
||||
wasm_runtime_deinstantiate_internal(new_module_inst, true);
|
||||
if (info_node)
|
||||
|
|
|
@ -77,18 +77,45 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
|
|||
wasm_module_inst_t new_module_inst = NULL;
|
||||
ThreadStartArg *thread_start_arg = NULL;
|
||||
wasm_function_inst_t start_func;
|
||||
int32 thread_id;
|
||||
int32 thread_id = -1;
|
||||
uint32 stack_size = 8192;
|
||||
int32 ret = -1;
|
||||
int32 spawned_import_count = ((WASMModule *)module)->import_count;
|
||||
WASMExternInstance *spawned_imports = NULL;
|
||||
|
||||
bh_assert(module);
|
||||
bh_assert(module_inst);
|
||||
|
||||
stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
|
||||
/*
|
||||
* build a imports list(WASMExternInstance[]) from parent's imports
|
||||
*/
|
||||
spawned_imports =
|
||||
wasm_runtime_malloc(sizeof(WASMExternInstance) * spawned_import_count);
|
||||
if (spawned_imports == NULL) {
|
||||
LOG_ERROR("Failed to allocate memory for imports");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_inherit_imports(module, module_inst, spawned_imports,
|
||||
spawned_import_count);
|
||||
if (ret != 0) {
|
||||
LOG_ERROR("Failed to inherit imports");
|
||||
goto free_imports;
|
||||
}
|
||||
|
||||
new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size,
|
||||
0, // heap_size
|
||||
0, // max_memory_pages
|
||||
spawned_imports, // imports
|
||||
spawned_import_count, // import_count
|
||||
NULL, 0);
|
||||
if (new_module_inst == NULL) {
|
||||
LOG_ERROR("Failed to instantiate new module");
|
||||
goto free_imports;
|
||||
}
|
||||
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
@ -126,16 +153,22 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
|
|||
goto thread_spawn_fail;
|
||||
}
|
||||
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
wasm_runtime_free(spawned_imports);
|
||||
return thread_id;
|
||||
|
||||
thread_spawn_fail:
|
||||
deallocate_thread_id(thread_id);
|
||||
|
||||
thread_preparation_fail:
|
||||
if (new_module_inst)
|
||||
wasm_runtime_deinstantiate_internal(new_module_inst, true);
|
||||
if (thread_start_arg)
|
||||
wasm_runtime_free(thread_start_arg);
|
||||
free_imports:
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
wasm_runtime_free(spawned_imports);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -500,16 +500,42 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
uint32 aux_stack_size;
|
||||
uint64 aux_stack_start;
|
||||
uint32 stack_size = 8192;
|
||||
int32 ret = -1;
|
||||
int32 spawned_import_count = 0;
|
||||
WASMExternInstance *spawned_imports = NULL;
|
||||
|
||||
if (!module_inst || !(module = wasm_exec_env_get_module(exec_env))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0))) {
|
||||
/*
|
||||
* build a imports list(WASMExternInstance[]) from parent's imports
|
||||
*/
|
||||
spawned_import_count = ((WASMModule *)module)->import_count;
|
||||
spawned_imports =
|
||||
wasm_runtime_malloc(sizeof(WASMExternInstance) * spawned_import_count);
|
||||
if (spawned_imports == NULL) {
|
||||
LOG_ERROR("Failed to allocate memory for imports");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_inherit_imports(module, module_inst, spawned_imports,
|
||||
spawned_import_count);
|
||||
if (ret != 0) {
|
||||
LOG_ERROR("Failed to inherit imports");
|
||||
goto release_imports;
|
||||
}
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size,
|
||||
0, // heap_size
|
||||
0, // max_memory_pages
|
||||
spawned_imports, // imports
|
||||
spawned_import_count, // import_count
|
||||
NULL, 0))) {
|
||||
goto disinherit_imports;
|
||||
}
|
||||
|
||||
/* Set custom_data to new module instance */
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
@ -570,6 +596,9 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
|
||||
os_mutex_unlock(&cluster->lock);
|
||||
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
wasm_runtime_free(spawned_imports);
|
||||
return new_exec_env;
|
||||
|
||||
fail3:
|
||||
|
@ -580,6 +609,11 @@ fail2:
|
|||
wasm_cluster_free_aux_stack(exec_env, aux_stack_start);
|
||||
fail1:
|
||||
wasm_runtime_deinstantiate_internal(new_module_inst, true);
|
||||
disinherit_imports:
|
||||
wasm_runtime_disinherit_imports(module, spawned_imports,
|
||||
spawned_import_count);
|
||||
release_imports:
|
||||
wasm_runtime_free(spawned_imports);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -377,17 +377,56 @@ handle_cmd_instantiate_module(uint64 *args, uint32 argc)
|
|||
|
||||
bh_assert(argc == 5);
|
||||
|
||||
*(void **)args_org = NULL;
|
||||
|
||||
if (!runtime_inited) {
|
||||
*(void **)args_org = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
{
|
||||
int32_t import_count =
|
||||
wasm_runtime_get_import_count(enclave_module->module);
|
||||
WASMExternInstance *imports = NULL;
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 \
|
||||
|| WASM_ENABLE_LIBC_BUILTIN != 0 || WASM_ENABLE_LIBC_WASI != 0
|
||||
imports =
|
||||
wasm_runtime_create_imports_with_builtin(enclave_module->module);
|
||||
#endif
|
||||
if (import_count > 0 && imports == NULL) {
|
||||
LOG_WARNING("Need to provide necessary imported objects");
|
||||
return;
|
||||
}
|
||||
|
||||
InstantiationArgs inst_args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.imports = imports,
|
||||
.import_count = (uint32_t)import_count,
|
||||
};
|
||||
|
||||
module_inst = wasm_runtime_instantiate_ex(
|
||||
enclave_module->module, &inst_args, error_buf, error_buf_size);
|
||||
if (!module_inst) {
|
||||
wasm_runtime_destroy_imports(enclave_module->module, imports);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: how to relese imports.
|
||||
* if there will be spawned thread, need to release when the thread is
|
||||
* done.
|
||||
*/
|
||||
}
|
||||
#else /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
if (!(module_inst =
|
||||
wasm_runtime_instantiate(enclave_module->module, stack_size,
|
||||
heap_size, error_buf, error_buf_size))) {
|
||||
*(void **)args_org = NULL;
|
||||
return;
|
||||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
|
||||
*(wasm_module_inst_t *)args_org = module_inst;
|
||||
|
||||
|
@ -763,6 +802,11 @@ ecall_iwasm_main(uint8_t *wasm_file_buf, uint32_t wasm_file_size)
|
|||
RuntimeInitArgs init_args;
|
||||
char error_buf[128];
|
||||
const char *exception;
|
||||
uint32 stack_size = 16 * 1024;
|
||||
uint32 heap_size = 16 * 1024;
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
WASMExternInstance *imports = NULL;
|
||||
#endif
|
||||
|
||||
/* avoid duplicated init */
|
||||
if (runtime_inited) {
|
||||
|
@ -797,13 +841,45 @@ ecall_iwasm_main(uint8_t *wasm_file_buf, uint32_t wasm_file_size)
|
|||
}
|
||||
|
||||
/* instantiate the module */
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
{
|
||||
int32_t import_count = wasm_runtime_get_import_count(wasm_module);
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 \
|
||||
|| WASM_ENABLE_LIBC_BUILTIN != 0 || WASM_ENABLE_LIBC_WASI != 0
|
||||
imports = wasm_runtime_create_imports_with_builtin(wasm_module);
|
||||
#endif
|
||||
if (import_count > 0 && imports == NULL) {
|
||||
enclave_print("Need to provide necessary imported objects");
|
||||
enclave_print("\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
InstantiationArgs inst_args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.imports = imports,
|
||||
.import_count = (uint32_t)import_count,
|
||||
};
|
||||
|
||||
wasm_module_inst = wasm_runtime_instantiate_ex(
|
||||
wasm_module, &inst_args, error_buf, sizeof(error_buf));
|
||||
if (!wasm_module_inst) {
|
||||
enclave_print(error_buf);
|
||||
enclave_print("\n");
|
||||
goto fail3;
|
||||
}
|
||||
}
|
||||
#else /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
if (!(wasm_module_inst =
|
||||
wasm_runtime_instantiate(wasm_module, 16 * 1024, 16 * 1024,
|
||||
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
enclave_print(error_buf);
|
||||
enclave_print("\n");
|
||||
goto fail2;
|
||||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
|
||||
/* execute the main function of wasm app */
|
||||
wasm_application_execute_main(wasm_module_inst, 0, NULL);
|
||||
|
@ -815,6 +891,12 @@ ecall_iwasm_main(uint8_t *wasm_file_buf, uint32_t wasm_file_size)
|
|||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
fail3:
|
||||
/* destory imports */
|
||||
wasm_runtime_destroy_imports(wasm_module, imports);
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE == 0*/
|
||||
|
||||
fail2:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
|
|
|
@ -885,7 +885,7 @@ main(int argc, char *argv[])
|
|||
/* load WASM byte buffer from WASM bin file */
|
||||
if (!(wasm_file_buf =
|
||||
(uint8 *)bh_read_file_to_buffer(wasm_file, &wasm_file_size)))
|
||||
goto fail1;
|
||||
goto unregister_native;
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (wasm_runtime_is_xip_file(wasm_file_buf, wasm_file_size)) {
|
||||
|
@ -898,7 +898,7 @@ main(int argc, char *argv[])
|
|||
map_flags, os_get_invalid_handle()))) {
|
||||
printf("mmap memory failed\n");
|
||||
wasm_runtime_free(wasm_file_buf);
|
||||
goto fail1;
|
||||
goto unregister_native;
|
||||
}
|
||||
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
|
@ -925,7 +925,7 @@ main(int argc, char *argv[])
|
|||
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail2;
|
||||
goto unmap_file;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DYNAMIC_AOT_DEBUG != 0
|
||||
|
@ -933,7 +933,7 @@ main(int argc, char *argv[])
|
|||
sizeof(error_buf))) {
|
||||
printf("set aot module name failed in dynamic aot debug mode, %s\n",
|
||||
error_buf);
|
||||
goto fail3;
|
||||
goto unload_module;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -942,12 +942,42 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
int32_t import_count = wasm_runtime_get_import_count(wasm_module);
|
||||
WASMExternInstance *imports = NULL;
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 \
|
||||
|| WASM_ENABLE_LIBC_BUILTIN != 0 || WASM_ENABLE_LIBC_WASI != 0
|
||||
imports = wasm_runtime_create_imports_with_builtin(wasm_module);
|
||||
#endif
|
||||
|
||||
if (import_count > 0 && imports == NULL) {
|
||||
printf("Need to provide %" PRId32 " imported objects:\n", import_count);
|
||||
goto unload_module;
|
||||
}
|
||||
|
||||
InstantiationArgs inst_args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.imports = imports,
|
||||
.import_count = import_count,
|
||||
};
|
||||
|
||||
wasm_module_inst = wasm_runtime_instantiate_ex(
|
||||
wasm_module, &inst_args, error_buf, sizeof(error_buf));
|
||||
if (!wasm_module_inst) {
|
||||
printf("%s\n", error_buf);
|
||||
goto destroy_imports;
|
||||
}
|
||||
#else
|
||||
if (!(wasm_module_inst =
|
||||
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
goto unload_module;
|
||||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
|
||||
#if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
|
||||
if (disable_bounds_checks) {
|
||||
|
@ -1037,21 +1067,27 @@ fail5:
|
|||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
fail4:
|
||||
#endif
|
||||
|
||||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
|
||||
fail3:
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
destroy_imports:
|
||||
wasm_runtime_destroy_imports(wasm_module, imports);
|
||||
#endif
|
||||
|
||||
unload_module:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
|
||||
fail2:
|
||||
unmap_file:
|
||||
/* free the file buffer */
|
||||
if (!is_xip_file)
|
||||
wasm_runtime_free(wasm_file_buf);
|
||||
else
|
||||
os_munmap(wasm_file_buf, wasm_file_size);
|
||||
|
||||
fail1:
|
||||
unregister_native:
|
||||
#if BH_HAS_DLFCN
|
||||
/* unload the native libraries */
|
||||
unregister_and_unload_native_libs(native_lib_loaded_count,
|
||||
|
|
|
@ -540,12 +540,41 @@ main(int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
int32_t import_count = wasm_runtime_get_import_count(wasm_module);
|
||||
WASMExternInstance *imports = NULL;
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 \
|
||||
|| WASM_ENABLE_LIBC_BUILTIN != 0 || WASM_ENABLE_LIBC_WASI != 0
|
||||
imports = wasm_runtime_create_imports_with_builtin(wasm_module);
|
||||
#endif
|
||||
if (import_count > 0 && imports == NULL) {
|
||||
printf("Need to provide %d imported objects:\n", import_count);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
InstantiationArgs inst_args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.imports = imports,
|
||||
.import_count = import_count,
|
||||
};
|
||||
|
||||
wasm_module_inst = wasm_runtime_instantiate_ex(
|
||||
wasm_module, &inst_args, error_buf, sizeof(error_buf));
|
||||
if (!wasm_module_inst) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail4;
|
||||
}
|
||||
#else
|
||||
if (!(wasm_module_inst =
|
||||
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE == 0 */
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
if (ip_addr != NULL) {
|
||||
|
@ -554,12 +583,12 @@ main(int argc, char *argv[])
|
|||
uint32_t debug_port;
|
||||
if (exec_env == NULL) {
|
||||
printf("%s\n", wasm_runtime_get_exception(wasm_module_inst));
|
||||
goto fail4;
|
||||
goto fail5;
|
||||
}
|
||||
debug_port = wasm_runtime_start_debug_instance(exec_env);
|
||||
if (debug_port == 0) {
|
||||
printf("Failed to start debug instance\n");
|
||||
goto fail4;
|
||||
goto fail5;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -595,11 +624,16 @@ main(int argc, char *argv[])
|
|||
printf("%s\n", exception);
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
fail4:
|
||||
fail5:
|
||||
#endif
|
||||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
fail4:
|
||||
wasm_runtime_destroy_imports(wasm_module, imports);
|
||||
#endif
|
||||
|
||||
fail3:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
|
|
|
@ -18,7 +18,7 @@ int
|
|||
main(int argc, char *argv_main[])
|
||||
{
|
||||
static char global_heap_buf[512 * 1024];
|
||||
char *buffer, error_buf[128];
|
||||
char *buffer, error_buf[128] = { 0 };
|
||||
const char *wasm_path = NULL, *wasi_dir = NULL;
|
||||
int opt, main_result = 1;
|
||||
|
||||
|
@ -27,6 +27,10 @@ main(int argc, char *argv_main[])
|
|||
wasm_exec_env_t exec_env = NULL;
|
||||
uint32 buf_size, stack_size = 8092, heap_size = 8092;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
WASMExternInstance *imports = NULL;
|
||||
#endif
|
||||
|
||||
RuntimeInitArgs init_args;
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
|
@ -76,8 +80,37 @@ main(int argc, char *argv_main[])
|
|||
wasm_runtime_set_wasi_args_ex(module, &wasi_dir, 1, NULL, 0, NULL, 0, NULL,
|
||||
0, 0, 1, 2);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
int32_t import_count = wasm_runtime_get_import_count(module);
|
||||
|
||||
#if WASM_ENABLE_SPEC_TEST != 0 || WASM_ENABLE_WASI_TEST != 0 \
|
||||
|| WASM_ENABLE_LIBC_BUILTIN != 0 || WASM_ENABLE_LIBC_WASI != 0
|
||||
imports = wasm_runtime_create_imports_with_builtin(module);
|
||||
#endif
|
||||
|
||||
if (import_count > 0 && imports == NULL) {
|
||||
printf("Need to provide %" PRId32 " imported objects:\n", import_count);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
InstantiationArgs inst_args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.imports = imports,
|
||||
.import_count = import_count,
|
||||
};
|
||||
|
||||
module_inst = wasm_runtime_instantiate_ex(module, &inst_args, error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!module_inst) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
module_inst = wasm_runtime_instantiate(module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf));
|
||||
#endif
|
||||
|
||||
if (!module_inst) {
|
||||
printf("Instantiate wasm module failed. error: %s\n", error_buf);
|
||||
|
@ -104,6 +137,10 @@ fail:
|
|||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
if (module_inst)
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
#if WASM_ENABLE_MULTI_MODULE == 0
|
||||
if (imports)
|
||||
wasm_runtime_destroy_imports(module, imports);
|
||||
#endif
|
||||
if (module)
|
||||
wasm_runtime_unload(module);
|
||||
if (buffer)
|
||||
|
|
51
samples/linking/CMakeLists.txt
Normal file
51
samples/linking/CMakeLists.txt
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(linking_samples)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
find_package(WASISDK REQUIRED)
|
||||
|
||||
################ runtime settings ################
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
include(CheckPIESupported)
|
||||
|
||||
# AOT and JIT byd default
|
||||
set(WAMR_BUILD_AOT 0)
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
# wasm32-wasi
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
# mvp
|
||||
set(WAMR_BUILD_BULK_MEMORY 1)
|
||||
set(WAMR_BUILD_REF_TYPES 1)
|
||||
set(WAMR_BUILD_SIMD 1)
|
||||
set(WAMR_BUILD_TAIL_CALL 1)
|
||||
set(WAMR_BUILD_THREAD_MGR 0)
|
||||
set(WAMR_BUILD_LIB_WASI_THREADS 0)
|
||||
|
||||
# vmlib
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib SHARED ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
target_include_directories(vmlib INTERFACE ${WAMR_ROOT_DIR}/core/iwasm/include)
|
||||
target_link_libraries (vmlib ${LLVM_AVAILABLE_LIBS} -lm -ldl)
|
||||
|
||||
################ samples ################
|
||||
add_subdirectory(raw)
|
||||
|
||||
################ wasm and/or aot ################
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(wasm
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm"
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm -B build
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
|
||||
EXCLUDE_FROM_ALL NO
|
||||
)
|
23
samples/linking/cmake/FindWASISDK.cmake
Normal file
23
samples/linking/cmake/FindWASISDK.cmake
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
file(GLOB WASISDK_SEARCH_PATH "/opt/wasi-sdk-*")
|
||||
find_path(WASISDK_HOME
|
||||
NAMES share/wasi-sysroot
|
||||
PATHS ${WASISDK_SEARCH_PATH}
|
||||
NO_DEFAULT_PATH
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
string(REGEX MATCH [0-9]+\.[0-9]+\.*[0-9]* WASISDK_VERSION ${WASISDK_HOME})
|
||||
|
||||
find_package_handle_standard_args(WASISDK REQUIRED_VARS WASISDK_HOME VERSION_VAR WASISDK_VERSION)
|
||||
|
||||
if(WASISDK_FOUND)
|
||||
set(WASISDK_CC_COMMAND ${WASISDK_HOME}/bin/clang)
|
||||
set(WASISDK_CXX_COMMAND ${WASISDK_HOME}/bin/clang++)
|
||||
set(WASISDK_TOOLCHAIN ${WASISDK_HOME}/share/cmake/wasi-sdk.cmake)
|
||||
set(WASISDK_SYSROOT ${WASISDK_HOME}/share/wasi-sysroot)
|
||||
endif()
|
21
samples/linking/lib/CMakeLists.txt
Normal file
21
samples/linking/lib/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
# compilation options
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
set(WAMR_BUILD_AOT 1)
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 0)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
|
||||
include(${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
|
||||
# # workaround for missing headers
|
||||
include(${WAMR_ROOT_DIR}/core/shared/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
get_property(WAMR_INCLUDE_PATHS_OUT DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
|
||||
include(CMakePrintHelpers)
|
||||
set(WAMR_INCLUDE_PATHS ${WAMR_INCLUDE_PATHS_OUT} PARENT_SCOPE)
|
||||
cmake_print_variables(WAMR_INCLUDE_PATHS_OUT)
|
6
samples/linking/raw/CMakeLists.txt
Normal file
6
samples/linking/raw/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
add_executable(raw main.c ${UNCOMMON_SHARED_SOURCE})
|
||||
target_link_libraries(raw PRIVATE vmlib)
|
119
samples/linking/raw/main.c
Normal file
119
samples/linking/raw/main.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
#include "wasm_export.h"
|
||||
#include "bh_read_file.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv_main[])
|
||||
{
|
||||
int exit_code = EXIT_FAILURE;
|
||||
|
||||
/* runtime */
|
||||
if (!wasm_runtime_init()) {
|
||||
printf("Init runtime failed.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
wasm_runtime_set_log_level(WASM_LOG_LEVEL_VERBOSE);
|
||||
|
||||
/* wasm module file */
|
||||
char *buffer;
|
||||
uint32 buf_size;
|
||||
buffer = bh_read_file_to_buffer("import_memory.wasm", &buf_size);
|
||||
if (!buffer) {
|
||||
printf("Open wasm file failed.\n");
|
||||
goto destroy_runtime;
|
||||
}
|
||||
|
||||
/* wasm module */
|
||||
char error_buf[128];
|
||||
wasm_module_t module = wasm_runtime_load((uint8 *)buffer, buf_size,
|
||||
error_buf, sizeof(error_buf));
|
||||
if (!module) {
|
||||
printf("Load wasm file failed: %s\n", error_buf);
|
||||
goto release_file_buffer;
|
||||
}
|
||||
|
||||
/* import type */
|
||||
int32_t import_count = wasm_runtime_get_import_count(module);
|
||||
wasm_import_t import_type = { 0 };
|
||||
int32_t import_memory_index = -1;
|
||||
for (int i = 0; i < import_count; i++) {
|
||||
wasm_runtime_get_import_type(module, i, &import_type);
|
||||
if (import_type.kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
|
||||
import_memory_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (import_memory_index == -1) {
|
||||
printf("No memory import found.\n");
|
||||
goto unload_module;
|
||||
}
|
||||
|
||||
/* host memory */
|
||||
wasm_memory_type_t memory_type = import_type.u.memory_type;
|
||||
wasm_memory_inst_t memory = wasm_runtime_create_memory(module, memory_type);
|
||||
if (!memory) {
|
||||
printf("Create memory failed.\n");
|
||||
goto unload_module;
|
||||
}
|
||||
|
||||
/* import list */
|
||||
WASMExternInstance import_list[10] = { 0 };
|
||||
import_list[import_memory_index].module_name = "env";
|
||||
import_list[import_memory_index].field_name = "memory";
|
||||
import_list[import_memory_index].kind = WASM_IMPORT_EXPORT_KIND_MEMORY;
|
||||
import_list[import_memory_index].u.memory = memory;
|
||||
|
||||
/* wasm instance */
|
||||
InstantiationArgs inst_args = {
|
||||
.imports = import_list,
|
||||
.import_count = 10,
|
||||
};
|
||||
wasm_module_inst_t inst = wasm_runtime_instantiate_ex(
|
||||
module, &inst_args, error_buf, sizeof(error_buf));
|
||||
if (!inst) {
|
||||
printf("Instantiate wasm file failed: %s\n", error_buf);
|
||||
goto destroy_memory;
|
||||
}
|
||||
|
||||
/* export function */
|
||||
wasm_function_inst_t func =
|
||||
wasm_runtime_lookup_function(inst, "goodhart_law");
|
||||
if (!func) {
|
||||
printf("The function goodhart_law is not found.\n");
|
||||
goto destroy_inst;
|
||||
}
|
||||
|
||||
wasm_exec_env_t exec_env = wasm_runtime_create_exec_env(inst, 8192);
|
||||
if (!exec_env) {
|
||||
printf("Create wasm execution environment failed.\n");
|
||||
goto destroy_inst;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_call_wasm(exec_env, func, 0, NULL)) {
|
||||
printf("call wasm function goodhart_law failed. %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
goto destroy_exec_env;
|
||||
}
|
||||
|
||||
exit_code = EXIT_SUCCESS;
|
||||
|
||||
destroy_exec_env:
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
destroy_inst:
|
||||
wasm_runtime_deinstantiate(inst);
|
||||
destroy_memory:
|
||||
wasm_runtime_destroy_memory(module, memory);
|
||||
unload_module:
|
||||
wasm_runtime_unload(module);
|
||||
release_file_buffer:
|
||||
wasm_runtime_free(buffer);
|
||||
destroy_runtime:
|
||||
wasm_runtime_destroy();
|
||||
|
||||
return exit_code;
|
||||
}
|
18
samples/linking/wasm/CMakeLists.txt
Normal file
18
samples/linking/wasm/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
project(linking_samples_wasm)
|
||||
|
||||
add_executable(import_memory import_memory.c)
|
||||
target_link_options(import_memory
|
||||
PRIVATE
|
||||
LINKER:--import-memory
|
||||
# (memory 3 5) for test
|
||||
LINKER:--initial-memory=196608
|
||||
LINKER:--max-memory=327680
|
||||
LINKER:--initial-heap=65536
|
||||
)
|
||||
set_target_properties(import_memory PROPERTIES SUFFIX .wasm)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/import_memory.wasm DESTINATION .)
|
83
samples/linking/wasm/import_memory.c
Normal file
83
samples/linking/wasm/import_memory.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Buffer {
|
||||
int size;
|
||||
char *data;
|
||||
};
|
||||
|
||||
struct Buffer *
|
||||
new_buffer(int size)
|
||||
{
|
||||
struct Buffer *buffer = calloc(1, sizeof(struct Buffer));
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->size = size;
|
||||
buffer->data = calloc(1, size);
|
||||
if (!buffer->data) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void
|
||||
release_buffer(struct Buffer *buffer)
|
||||
{
|
||||
buffer->size = 0;
|
||||
free(buffer->data);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
__attribute__((export_name("goodhart_law"))) void
|
||||
goodhart_law()
|
||||
{
|
||||
struct Buffer *buffer = new_buffer(64);
|
||||
assert(buffer);
|
||||
|
||||
snprintf(buffer->data, 60, "%s",
|
||||
"When a measure becomes a target, it ceases to be a good measure");
|
||||
assert(buffer->data[10] == 's');
|
||||
|
||||
release_buffer(buffer);
|
||||
|
||||
printf("-> pass basic\n");
|
||||
fflush(stdout);
|
||||
|
||||
// alloc a huge buffer
|
||||
struct Buffer *huge_buffer = new_buffer(60000);
|
||||
assert(huge_buffer->data != NULL);
|
||||
|
||||
memset(huge_buffer->data, 0xEE, 60000);
|
||||
assert((uint8_t)(huge_buffer->data[50000]) == 0xEE);
|
||||
|
||||
release_buffer(huge_buffer);
|
||||
|
||||
printf("-> pass huge allocations\n");
|
||||
fflush(stdout);
|
||||
|
||||
int ret = __builtin_wasm_memory_grow(0, 1);
|
||||
// sync with the value assigned by `--initial-memory`
|
||||
assert(ret == 3);
|
||||
|
||||
printf("-> pass manually memory.grow\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
goodhart_law();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -28,11 +28,13 @@ To run a single GC case case:
|
|||
--aot-compiler wamrc --gc spec/test/core/xxx.wast
|
||||
"""
|
||||
|
||||
|
||||
def exe_file_path(base_path: str) -> str:
|
||||
if platform.system().lower() == "windows":
|
||||
base_path += ".exe"
|
||||
return base_path
|
||||
|
||||
|
||||
def get_iwasm_cmd(platform: str) -> str:
|
||||
build_path = "../../../product-mini/platforms/" + platform + "/build/"
|
||||
exe_name = "iwasm"
|
||||
|
@ -42,6 +44,7 @@ def get_iwasm_cmd(platform: str) -> str:
|
|||
|
||||
return exe_file_path(build_path + exe_name)
|
||||
|
||||
|
||||
PLATFORM_NAME = platform.uname().system.lower()
|
||||
IWASM_CMD = get_iwasm_cmd(PLATFORM_NAME)
|
||||
IWASM_SGX_CMD = "../../../product-mini/platforms/linux-sgx/enclave-sample/iwasm"
|
||||
|
@ -69,6 +72,7 @@ AVAILABLE_TARGETS = [
|
|||
"XTENSA",
|
||||
]
|
||||
|
||||
|
||||
def ignore_the_case(
|
||||
case_name,
|
||||
target,
|
||||
|
@ -84,11 +88,23 @@ def ignore_the_case(
|
|||
eh_flag=False,
|
||||
qemu_flag=False,
|
||||
):
|
||||
|
||||
if case_name in ["comments", "inline-module", "names"]:
|
||||
return True
|
||||
|
||||
if not multi_module_flag and case_name in ["imports", "linking", "simd_linking"]:
|
||||
if not multi_module_flag and case_name in [
|
||||
"imports",
|
||||
"linking",
|
||||
"simd_linking",
|
||||
# from multi-memory
|
||||
"imports0",
|
||||
"imports1",
|
||||
"imports2",
|
||||
"imports4",
|
||||
"linking0",
|
||||
"linking1",
|
||||
"linking2",
|
||||
"linking3",
|
||||
]:
|
||||
return True
|
||||
|
||||
# Note: x87 doesn't preserve sNaN and makes some relevant tests fail.
|
||||
|
@ -96,7 +112,7 @@ def ignore_the_case(
|
|||
return True
|
||||
|
||||
# esp32s3 qemu doesn't have PSRAM emulation
|
||||
if qemu_flag and target == 'xtensa' and case_name in ["memory_size"]:
|
||||
if qemu_flag and target == "xtensa" and case_name in ["memory_size"]:
|
||||
return True
|
||||
|
||||
if gc_flag:
|
||||
|
@ -170,7 +186,7 @@ def test_case(
|
|||
qemu_flag=False,
|
||||
qemu_firmware="",
|
||||
log="",
|
||||
no_pty=False
|
||||
no_pty=False,
|
||||
):
|
||||
CMD = [sys.executable, "runtest.py"]
|
||||
CMD.append("--wast2wasm")
|
||||
|
@ -238,6 +254,7 @@ def test_case(
|
|||
CMD.append(str(case_path))
|
||||
# print(f"============> use {' '.join(CMD)}")
|
||||
print(f"============> run {case_name} ", end="")
|
||||
|
||||
with subprocess.Popen(
|
||||
CMD,
|
||||
bufsize=1,
|
||||
|
@ -319,7 +336,11 @@ def test_suite(
|
|||
|
||||
if eh_flag:
|
||||
eh_case_list = sorted(suite_path.glob("*.wast"))
|
||||
eh_case_list_include = [test for test in eh_case_list if test.stem in ["throw", "tag", "try_catch", "rethrow", "try_delegate"]]
|
||||
eh_case_list_include = [
|
||||
test
|
||||
for test in eh_case_list
|
||||
if test.stem in ["throw", "tag", "try_catch", "rethrow", "try_delegate"]
|
||||
]
|
||||
case_list.extend(eh_case_list_include)
|
||||
|
||||
if multi_memory_flag:
|
||||
|
@ -573,8 +594,9 @@ def main():
|
|||
nargs="*",
|
||||
help=f"Specify all wanted cases. If not the script will go through all cases under {SPEC_TEST_DIR}",
|
||||
)
|
||||
parser.add_argument('--no-pty', action='store_true',
|
||||
help="Use direct pipes instead of pseudo-tty")
|
||||
parser.add_argument(
|
||||
"--no-pty", action="store_true", help="Use direct pipes instead of pseudo-tty"
|
||||
)
|
||||
|
||||
options = parser.parse_args()
|
||||
|
||||
|
@ -616,7 +638,7 @@ def main():
|
|||
options.qemu_flag,
|
||||
options.qemu_firmware,
|
||||
options.log,
|
||||
options.no_pty
|
||||
options.no_pty,
|
||||
)
|
||||
end = time.time_ns()
|
||||
print(
|
||||
|
|
Loading…
Reference in New Issue
Block a user