Skip to content

Commit

Permalink
Refactor import handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lum1n0us committed Oct 21, 2024
1 parent 18398a0 commit 0b87486
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 90 deletions.
89 changes: 89 additions & 0 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -7742,3 +7742,92 @@ wasm_runtime_is_underlying_binary_freeable(WASMModuleCommon *const module)

return true;
}

void
wasm_runtime_release_imports(struct WasmExternInstance *extern_inst)
{
if (extern_inst == NULL)
return;

wasm_runtime_free(extern_inst);
}

static struct WasmExternInstance *
wasm_runtime_create_imports(WASMModuleCommon *const module)
{
int32_t import_count = wasm_runtime_get_import_count(module);
struct WasmExternInstance *imports = NULL;

imports =
wasm_runtime_malloc(sizeof(struct WasmExternInstance) * import_count);
if (!imports) {
LOG_ERROR("allocate memory failed: %s", strerror(errno));
return NULL;
}

for (int32_t i = 0; i < import_count; i++) {
wasm_import_t import_type = { 0 };
wasm_runtime_get_import_type(module, i, &import_type);

struct WasmExternInstance *extern_instance = imports + i;
extern_instance->module_name = import_type.module_name;
extern_instance->field_name = import_type.name;
extern_instance->kind = import_type.kind;

if (import_type.kind == WASM_IMPORT_EXPORT_KIND_MEMORY) {
extern_instance->u.memory =
wasm_runtime_create_memory(NULL, import_type.u.memory_type, 0);
}
else {
LOG_DEBUG("unimplemented import(%s,%s) kind %d\n",
import_type.module_name, import_type.name,
import_type.kind);
}
}

return imports;
}

#if WASM_ENABLE_SPEC_TEST != 0
struct WasmExternInstance *
wasm_runtime_create_spec_test_imports(WASMModuleCommon *const module)
{
LOG_DEBUG("create spec test imports\n");
#ifndef NDEBUG
int32_t import_count = wasm_runtime_get_import_count(module);
for (int32_t i = 0; i < import_count; i++) {

wasm_import_t import_type = { 0 };
wasm_runtime_get_import_type(module, i, &import_type);
if (strncmp(import_type.module_name, "spectest", 8) != 0) {
LOG_WARNING("import module name %s is not spectest\n",
import_type.module_name);
}
}
#endif
return wasm_runtime_create_imports(module);
}
#endif

#if WASM_ENABLE_WASI_TEST != 0
struct WasmExternInstance *
wasm_runtime_create_wasi_test_imports(WASMModuleCommon *const module)
{
LOG_DEBUG("create wasi test imports\n");
#ifndef NDEBUG
int32_t import_count = wasm_runtime_get_import_count(module);
for (int32_t i = 0; i < import_count; i++) {

wasm_import_t import_type = { 0 };
wasm_runtime_get_import_type(module, i, &import_type);
if (strncmp(import_type.module_name, "foo", 3) != 0
&& strncmp(import_type.module_name, "env", 3) != 0) {
LOG_WARNING("import module name %s is not expected(foo or env) in "
"wasitest\n",
import_type.module_name);
}
}
#endif
return wasm_runtime_create_imports(module);
}
#endif
13 changes: 13 additions & 0 deletions core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,19 @@ void
wasm_runtime_set_linux_perf(bool flag);
#endif

#if WASM_ENABLE_SPEC_TEST != 0
struct WasmExternInstance *
wasm_runtime_create_spec_test_imports(WASMModuleCommon *const);
#endif

#if WASM_ENABLE_WASI_TEST != 0
struct WasmExternInstance *
wasm_runtime_create_wasi_test_imports(WASMModuleCommon *const);
#endif

void
wasm_runtime_release_imports(struct WasmExternInstance *);

#ifdef __cplusplus
}
#endif
Expand Down
44 changes: 31 additions & 13 deletions core/iwasm/interpreter/wasm_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,6 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
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;
Expand All @@ -536,9 +535,9 @@ 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++) {
#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;
Expand All @@ -557,10 +556,9 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
return NULL;
}
}
else
#endif
{
#if WASM_ENABLE_MULTI_MODULE != 0
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;
Expand All @@ -578,12 +576,20 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
return NULL;
}
mem_index++;
#endif
}
}

/* instantiate memories from memory section */
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,
Expand Down Expand Up @@ -1930,6 +1936,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)
Expand Down Expand Up @@ -5112,15 +5124,19 @@ wasm_get_module_name(WASMModule *module)
}

#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
bool
/*
* The function is used to create a new struct WasmExternInstance list
* for a spawned thread.
*/
int32
wasm_runtime_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
struct WasmExternInstance *out, int32_t out_len)
{
int32_t 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 false;
return -1;
}

for (int32_t i = 0, import_memory_index = 0; i < spawned_import_count;
Expand All @@ -5136,7 +5152,9 @@ wasm_runtime_inherit_imports(WASMModule *module, WASMModuleInstance *inst,

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 {
Expand All @@ -5146,6 +5164,6 @@ wasm_runtime_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
}
}

return true;
return 0;
}
#endif
#endif
2 changes: 1 addition & 1 deletion core/iwasm/interpreter/wasm_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ const char *
wasm_get_module_name(WASMModule *module);

#if WASM_ENABLE_LIB_WASI_THREADS != 0 || WASM_ENABLE_THREAD_MGR != 0
bool
int32
wasm_runtime_inherit_imports(WASMModule *module, WASMModuleInstance *inst,
struct WasmExternInstance *out, int32_t out_len);
#endif
Expand Down
38 changes: 34 additions & 4 deletions core/iwasm/libraries/lib-pthread/lib_pthread_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_t spawned_import_count = ((WASMModule *)module)->import_count;
struct WasmExternInstance *spawned_imports = NULL;

bh_assert(module);
bh_assert(module_inst);
Expand All @@ -579,12 +581,37 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
}
#endif

/*
* build a imports list(struct WASMExternInstance[]) from parent's imports
*/
spawned_imports = wasm_runtime_malloc(sizeof(struct WasmExternInstance)
* spawned_import_count);
if (spawned_imports == NULL) {
LOG_ERROR("Failed to allocate memory for imports");
goto fail;
}

#if WASM_ENABLE_INTERP != 0
ret = wasm_runtime_inherit_imports((WASMModule *)module,
(WASMModuleInstance *)module_inst,
spawned_imports, spawned_import_count);
if (ret != 0) {
LOG_ERROR("Failed to inherit imports");
goto fail;
}
#endif

#if WASM_ENABLE_AOT != 0
// TODO:
// bh_assert(false && "Unsupported operation");
#endif

if (!(new_module_inst = wasm_runtime_instantiate_internal(
module, module_inst, exec_env, stack_size,
0, // heap_size
0, // max_memory_pages
0, // import_count
NULL, // imports
0, // heap_size
0, // max_memory_pages
spawned_import_count, // import_count
spawned_imports, // imports
NULL, 0)))
return -1;

Expand Down Expand Up @@ -646,9 +673,12 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
if (thread)
*thread = thread_handle;

wasm_runtime_free(spawned_imports);
return 0;

fail:
if (spawned_imports)
wasm_runtime_free(spawned_imports);
if (new_module_inst)
wasm_runtime_deinstantiate_internal(new_module_inst, true);
if (info_node)
Expand Down
31 changes: 22 additions & 9 deletions core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ 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_t spawned_import_count = ((WASMModule *)module)->import_count;
struct WasmExternInstance *spawned_imports = NULL;

bh_assert(module);
bh_assert(module_inst);
Expand All @@ -89,18 +91,26 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
/*
* build a imports list(struct WASMExternInstance[]) from parent's imports
*/
int32_t spawned_import_count = ((WASMModule *)module)->import_count;
struct WasmExternInstance *spawned_imports = wasm_runtime_malloc(
sizeof(struct WasmExternInstance) * spawned_import_count);
spawned_imports = wasm_runtime_malloc(sizeof(struct WasmExternInstance)
* spawned_import_count);
if (spawned_imports == NULL) {
LOG_ERROR("Failed to allocate memory for imports");
return -1;
}

#if WASM_ENABLE_INTERP != 0
wasm_runtime_inherit_imports((WASMModule *)module,
(WASMModuleInstance *)module_inst,
spawned_imports, spawned_import_count);
ret = wasm_runtime_inherit_imports((WASMModule *)module,
(WASMModuleInstance *)module_inst,
spawned_imports, spawned_import_count);
if (ret != 0) {
LOG_ERROR("Failed to inherit imports");
goto free_imports;
}
#endif

#if WASM_ENABLE_AOT != 0
// TODO:
// bh_assert(false && "Unsupported operation");
#endif

new_module_inst = wasm_runtime_instantiate_internal(
Expand All @@ -110,9 +120,9 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
spawned_import_count, // import_count
spawned_imports, // imports
NULL, 0);
wasm_runtime_free(spawned_imports);
if (new_module_inst == NULL) {
return -1;
LOG_ERROR("Failed to instantiate new module");
goto free_imports;
}

wasm_runtime_set_custom_data_internal(
Expand Down Expand Up @@ -151,6 +161,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
goto thread_spawn_fail;
}

wasm_runtime_free(spawned_imports);
return thread_id;

thread_spawn_fail:
Expand All @@ -160,6 +171,8 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
wasm_runtime_deinstantiate_internal(new_module_inst, true);
if (thread_start_arg)
wasm_runtime_free(thread_start_arg);
free_imports:
wasm_runtime_free(spawned_imports);

return -1;
}
Expand Down
Loading

0 comments on commit 0b87486

Please sign in to comment.