mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +00:00
Fix loader fail to lookup registered native symbol issue (#529)
This commit is contained in:
parent
3849ece496
commit
370cc83fbd
|
@ -539,12 +539,6 @@ wasm_runtime_destroy_loading_module_list()
|
|||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
bool
|
||||
wasm_runtime_is_host_module(const char *module_name)
|
||||
{
|
||||
return strlen(module_name) == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_is_built_in_module(const char *module_name)
|
||||
{
|
||||
|
@ -552,7 +546,7 @@ wasm_runtime_is_built_in_module(const char *module_name)
|
|||
|| !strcmp("wasi_unstable", module_name)
|
||||
|| !strcmp("wasi_snapshot_preview1", module_name)
|
||||
|| !strcmp("spectest", module_name)
|
||||
);
|
||||
|| !strcmp("", module_name));
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
|
|
|
@ -369,9 +369,6 @@ void
|
|||
wasm_runtime_destroy_loading_module_list();
|
||||
#endif /* WASM_ENALBE_MULTI_MODULE */
|
||||
|
||||
bool
|
||||
wasm_runtime_is_host_module(const char *module_name);
|
||||
|
||||
bool
|
||||
wasm_runtime_is_built_in_module(const char *module_name);
|
||||
|
||||
|
|
|
@ -598,7 +598,7 @@ wasm_loader_resolve_function(const char *module_name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* run a function type check */
|
||||
/* resolve function type and function */
|
||||
if (export->index < module->import_function_count) {
|
||||
target_function_type =
|
||||
module->import_functions[export->index].u.function.func_type;
|
||||
|
@ -613,6 +613,7 @@ wasm_loader_resolve_function(const char *module_name,
|
|||
module->functions[export->index - module->import_function_count];
|
||||
}
|
||||
|
||||
/* check function type */
|
||||
if (!wasm_type_equal(expected_function_type, target_function_type)) {
|
||||
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
|
||||
set_error_buf(error_buf, error_buf_size, "incompatible import type");
|
||||
|
@ -650,7 +651,7 @@ wasm_loader_resolve_table(const char *module_name, const char *table_name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* run a table type check */
|
||||
/* resolve table and check the init/max size */
|
||||
if (export->index < module->import_table_count) {
|
||||
table =
|
||||
module->import_tables[export->index].u.table.import_table_linked;
|
||||
|
@ -698,7 +699,7 @@ wasm_loader_resolve_memory(const char *module_name, const char *memory_name,
|
|||
}
|
||||
|
||||
|
||||
/* run a memory check */
|
||||
/* resolve memory and check the init/max page count */
|
||||
if (export->index < module->import_memory_count) {
|
||||
memory =
|
||||
module->import_memories[export->index].u.memory.import_memory_linked;
|
||||
|
@ -747,7 +748,7 @@ wasm_loader_resolve_global(const char *module_name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* run a global check */
|
||||
/* resolve and check the global */
|
||||
if (export->index < module->import_global_count) {
|
||||
global =
|
||||
module->import_globals[export->index].u.global.import_global_linked;
|
||||
|
@ -764,12 +765,164 @@ wasm_loader_resolve_global(const char *module_name,
|
|||
}
|
||||
return global;
|
||||
}
|
||||
|
||||
static WASMModule *
|
||||
search_sub_module(const WASMModule *parent_module, const char *sub_module_name)
|
||||
{
|
||||
WASMRegisteredModule *node =
|
||||
bh_list_first_elem(parent_module->import_module_list);
|
||||
while (node && strcmp(sub_module_name, node->module_name)) {
|
||||
node = bh_list_elem_next(node);
|
||||
}
|
||||
return node ? (WASMModule*)node->module : NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
register_sub_module(const WASMModule *parent_module,
|
||||
const char *sub_module_name, WASMModule *sub_module)
|
||||
{
|
||||
/* register sub_module into its parent sub module list */
|
||||
WASMRegisteredModule *node = NULL;
|
||||
bh_list_status ret;
|
||||
|
||||
if (search_sub_module(parent_module, sub_module_name)) {
|
||||
LOG_DEBUG("%s has been registered in its parent", sub_module_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
node = wasm_runtime_malloc(sizeof(WASMRegisteredModule));
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node->module_name = sub_module_name;
|
||||
node->module = (WASMModuleCommon*)sub_module;
|
||||
ret = bh_list_insert(parent_module->import_module_list, node);
|
||||
bh_assert(BH_LIST_SUCCESS == ret);
|
||||
(void)ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static WASMModule *
|
||||
load_depended_module(const WASMModule *parent_module,
|
||||
const char *sub_module_name, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *sub_module = NULL;
|
||||
bool ret = false;
|
||||
uint8 *buffer = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
const module_reader reader = wasm_runtime_get_module_reader();
|
||||
const module_destroyer destroyer = wasm_runtime_get_module_destroyer();
|
||||
|
||||
/* check the registered module list of the parent */
|
||||
sub_module = search_sub_module(parent_module, sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded before", sub_module_name);
|
||||
return sub_module;
|
||||
}
|
||||
|
||||
/* check the global registered module list */
|
||||
sub_module =
|
||||
(WASMModule *)wasm_runtime_find_module_registered(sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded", sub_module_name);
|
||||
goto register_sub_module;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("loading %s", sub_module_name);
|
||||
|
||||
if (!reader) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"no sub module reader to load %s",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* start to maintain a loading module list */
|
||||
ret = wasm_runtime_is_loading_module(sub_module_name);
|
||||
if (ret) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"found circular dependency on %s",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_add_loading_module(sub_module_name, error_buf,
|
||||
error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("can not add %s into loading module list\n",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = reader(sub_module_name, &buffer, &buffer_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("read the file of %s failed", sub_module_name);
|
||||
set_error_buf_v(error_buf, error_buf_size, "unknown import",
|
||||
sub_module_name);
|
||||
goto delete_loading_module;
|
||||
}
|
||||
|
||||
sub_module =
|
||||
wasm_loader_load(buffer, buffer_size, error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
LOG_DEBUG("error: can not load the sub_module %s", sub_module_name);
|
||||
/* others will be destroyed in runtime_destroy() */
|
||||
goto destroy_file_buffer;
|
||||
}
|
||||
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
|
||||
/* register on a global list */
|
||||
ret = wasm_runtime_register_module_internal(sub_module_name,
|
||||
(WASMModuleCommon*)sub_module,
|
||||
buffer, buffer_size, error_buf,
|
||||
error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("error: can not register module %s globally\n", sub_module_name);
|
||||
/* others will be unloaded in runtime_destroy() */
|
||||
goto unload_module;
|
||||
}
|
||||
|
||||
/* register into its parent list */
|
||||
register_sub_module:
|
||||
ret = register_sub_module(parent_module, sub_module_name, sub_module);
|
||||
if (!ret) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"failed to register sub module %s",
|
||||
sub_module_name);
|
||||
/* since it is in the global module list, no need to
|
||||
* unload the module. the runtime_destroy() will do it
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sub_module;
|
||||
|
||||
unload_module:
|
||||
wasm_loader_unload(sub_module);
|
||||
|
||||
destroy_file_buffer:
|
||||
if (destroyer) {
|
||||
destroyer(buffer, buffer_size);
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("need to release the reading buffer of %s manually",
|
||||
sub_module_name);
|
||||
}
|
||||
|
||||
delete_loading_module:
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
static bool
|
||||
load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
||||
char *sub_module_name, char *function_name,
|
||||
const uint8 **p_buf, const uint8 *buf_end,
|
||||
load_function_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
const WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *function_name,
|
||||
WASMFunctionImport *function,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
|
@ -777,10 +930,14 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
uint32 declare_type_index = 0;
|
||||
WASMType *declare_func_type = NULL;
|
||||
WASMFunction *linked_func = NULL;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *sub_module = NULL;
|
||||
#endif
|
||||
const char *linked_signature = NULL;
|
||||
void *linked_attachment = NULL;
|
||||
bool linked_call_conv_raw = false;
|
||||
bool is_built_in_module = false;
|
||||
bool is_native_symbol = false;
|
||||
|
||||
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
read_leb_uint32(p, p_end, declare_type_index);
|
||||
|
@ -799,21 +956,25 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
|
||||
declare_func_type = parent_module->types[declare_type_index];
|
||||
|
||||
if (wasm_runtime_is_host_module(sub_module_name)) {
|
||||
/* do nothing, wait for injecting host created fuctions */
|
||||
}
|
||||
else if ((is_built_in_module =
|
||||
wasm_runtime_is_built_in_module(sub_module_name))) {
|
||||
/* check built-in modules */
|
||||
linked_func = wasm_native_resolve_symbol(sub_module_name,
|
||||
function_name,
|
||||
declare_func_type,
|
||||
&linked_signature,
|
||||
&linked_attachment,
|
||||
&linked_call_conv_raw);
|
||||
/* lookup registered native symbols first */
|
||||
linked_func = wasm_native_resolve_symbol(sub_module_name,
|
||||
function_name,
|
||||
declare_func_type,
|
||||
&linked_signature,
|
||||
&linked_attachment,
|
||||
&linked_call_conv_raw);
|
||||
if (linked_func) {
|
||||
is_native_symbol = true;
|
||||
}
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
else {
|
||||
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
sub_module = load_depended_module(parent_module, sub_module_name,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
linked_func = wasm_loader_resolve_function(sub_module_name,
|
||||
function_name,
|
||||
declare_func_type,
|
||||
|
@ -822,18 +983,17 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
}
|
||||
#endif
|
||||
|
||||
function->module_name = sub_module_name;
|
||||
function->field_name = function_name;
|
||||
function->module_name = (char *)sub_module_name;
|
||||
function->field_name = (char *)function_name;
|
||||
function->func_type = declare_func_type;
|
||||
/* func_ptr_linked is for built-in functions */
|
||||
function->func_ptr_linked = is_built_in_module ? linked_func : NULL;
|
||||
/* func_ptr_linked is for native registered symbol */
|
||||
function->func_ptr_linked = is_native_symbol ? linked_func : NULL;
|
||||
function->signature = linked_signature;
|
||||
function->attachment = linked_attachment;
|
||||
function->call_conv_raw = linked_call_conv_raw;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
function->import_module = is_built_in_module ? NULL : sub_module;
|
||||
/* can not set both func_ptr_linked and import_func_linked not NULL */
|
||||
function->import_func_linked = is_built_in_module ? NULL : linked_func;
|
||||
function->import_module = is_native_symbol ? NULL : sub_module;
|
||||
function->import_func_linked = is_native_symbol ? NULL : linked_func;
|
||||
#endif
|
||||
return true;
|
||||
fail:
|
||||
|
@ -853,9 +1013,11 @@ check_table_max_size(uint32 init_size, uint32 max_size,
|
|||
}
|
||||
|
||||
static bool
|
||||
load_table_import(WASMModule *sub_module, const char *sub_module_name,
|
||||
const char *table_name, const uint8 **p_buf,
|
||||
const uint8 *buf_end, WASMTableImport *table,
|
||||
load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *table_name,
|
||||
WASMTableImport *table,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
|
@ -864,6 +1026,7 @@ load_table_import(WASMModule *sub_module, const char *sub_module_name,
|
|||
uint32 declare_init_size = 0;
|
||||
uint32 declare_max_size = 0;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *sub_module = NULL;
|
||||
WASMTable *linked_table = NULL;
|
||||
#endif
|
||||
|
||||
|
@ -889,19 +1052,21 @@ load_table_import(WASMModule *sub_module, const char *sub_module_name,
|
|||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
linked_table = wasm_loader_resolve_table(
|
||||
sub_module_name, table_name,
|
||||
declare_init_size, declare_max_size,
|
||||
error_buf, error_buf_size);
|
||||
if (!linked_table) {
|
||||
LOG_DEBUG("(%s, %s) is not an exported from one of modules",
|
||||
table_name, sub_module_name);
|
||||
sub_module = load_depended_module(parent_module, sub_module_name,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset with linked table limit
|
||||
*/
|
||||
linked_table = wasm_loader_resolve_table(
|
||||
sub_module_name, table_name,
|
||||
declare_init_size, declare_max_size,
|
||||
error_buf, error_buf_size);
|
||||
if (!linked_table) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* reset with linked table limit */
|
||||
declare_elem_type = linked_table->elem_type;
|
||||
declare_init_size = linked_table->init_size;
|
||||
declare_max_size = linked_table->max_size;
|
||||
|
@ -977,9 +1142,11 @@ check_memory_max_size(uint32 init_size, uint32 max_size,
|
|||
}
|
||||
|
||||
static bool
|
||||
load_memory_import(WASMModule *sub_module, const char *sub_module_name,
|
||||
const char *memory_name, const uint8 **p_buf,
|
||||
const uint8 *buf_end, WASMMemoryImport *memory,
|
||||
load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *memory_name,
|
||||
WASMMemoryImport *memory,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
|
@ -994,6 +1161,7 @@ load_memory_import(WASMModule *sub_module, const char *sub_module_name,
|
|||
uint32 declare_init_page_count = 0;
|
||||
uint32 declare_max_page_count = 0;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *sub_module = NULL;
|
||||
WASMMemory *linked_memory = NULL;
|
||||
#endif
|
||||
|
||||
|
@ -1022,6 +1190,12 @@ load_memory_import(WASMModule *sub_module, const char *sub_module_name,
|
|||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
sub_module = load_depended_module(parent_module, sub_module_name,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
|
||||
linked_memory = wasm_loader_resolve_memory(
|
||||
sub_module_name, memory_name,
|
||||
declare_init_page_count, declare_max_page_count,
|
||||
|
@ -1075,16 +1249,19 @@ fail:
|
|||
}
|
||||
|
||||
static bool
|
||||
load_global_import(const WASMModule *parent_module,
|
||||
WASMModule *sub_module,
|
||||
load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
const WASMModule *parent_module,
|
||||
char *sub_module_name, char *global_name,
|
||||
const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMGlobalImport *global,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
uint8 declare_type = 0;
|
||||
uint8 declare_mutable = 0;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModule *sub_module = NULL;
|
||||
WASMGlobal *linked_global = NULL;
|
||||
#endif
|
||||
|
||||
CHECK_BUF(p, p_end, 2);
|
||||
declare_type = read_uint8(p);
|
||||
|
@ -1096,20 +1273,21 @@ load_global_import(const WASMModule *parent_module,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (wasm_runtime_is_host_module(sub_module_name)) {
|
||||
/* do nothing, let host inject the symbol */
|
||||
}
|
||||
#if WASM_ENABLE_LIBC_BUILTIN != 0
|
||||
else if (wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
/* check built-in modules */
|
||||
global->is_linked = wasm_native_lookup_libc_builtin_global(
|
||||
sub_module_name, global_name, global);
|
||||
}
|
||||
global->is_linked = wasm_native_lookup_libc_builtin_global(
|
||||
sub_module_name, global_name, global);
|
||||
#endif
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
else {
|
||||
if (!global->is_linked
|
||||
&& !wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
sub_module = load_depended_module(parent_module, sub_module_name,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check sub modules */
|
||||
WASMGlobal *linked_global =
|
||||
linked_global =
|
||||
wasm_loader_resolve_global(sub_module_name, global_name,
|
||||
declare_type, declare_mutable,
|
||||
error_buf, error_buf_size);
|
||||
|
@ -1236,170 +1414,6 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
static WASMModule *
|
||||
search_sub_module(const WASMModule *parent_module, const char *sub_module_name)
|
||||
{
|
||||
WASMRegisteredModule *node =
|
||||
bh_list_first_elem(parent_module->import_module_list);
|
||||
while (node && strcmp(sub_module_name, node->module_name)) {
|
||||
node = bh_list_elem_next(node);
|
||||
}
|
||||
return node ? (WASMModule*)node->module : NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
register_sub_module(const WASMModule *parent_module,
|
||||
const char *sub_module_name, WASMModule *sub_module)
|
||||
{
|
||||
/* register a sub_module on its parent sub module list */
|
||||
WASMRegisteredModule *node = NULL;
|
||||
bh_list_status ret;
|
||||
|
||||
if (search_sub_module(parent_module, sub_module_name)) {
|
||||
LOG_DEBUG("%s has been registered in its parent", sub_module_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
node = wasm_runtime_malloc(sizeof(WASMRegisteredModule));
|
||||
if (!node) {
|
||||
LOG_DEBUG("malloc WASMRegisteredModule failed. SZ %d\n",
|
||||
sizeof(WASMRegisteredModule));
|
||||
return false;
|
||||
}
|
||||
|
||||
node->module_name = sub_module_name;
|
||||
node->module = (WASMModuleCommon*)sub_module;
|
||||
ret = bh_list_insert(parent_module->import_module_list, node);
|
||||
bh_assert(BH_LIST_SUCCESS == ret);
|
||||
(void)ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
static WASMModule *
|
||||
load_depended_module(const WASMModule *parent_module,
|
||||
const char *sub_module_name, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *sub_module = NULL;
|
||||
bool ret = false;
|
||||
uint8 *buffer = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
const module_reader reader = wasm_runtime_get_module_reader();
|
||||
const module_destroyer destroyer = wasm_runtime_get_module_destroyer();
|
||||
|
||||
/* check the registered module list of the parent */
|
||||
sub_module = search_sub_module(parent_module, sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded before", sub_module_name);
|
||||
return sub_module;
|
||||
}
|
||||
|
||||
/* check the global registered module list */
|
||||
sub_module =
|
||||
(WASMModule *)wasm_runtime_find_module_registered(sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded", sub_module_name);
|
||||
goto REGISTER_SUB_MODULE;
|
||||
}
|
||||
|
||||
LOG_VERBOSE("to load %s", sub_module_name);
|
||||
|
||||
if (!reader) {
|
||||
LOG_DEBUG("error: there is no sub_module reader to load %s",
|
||||
sub_module_name);
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"no sub module reader to load %s",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* start to maintain a loading module list */
|
||||
ret = wasm_runtime_is_loading_module(sub_module_name);
|
||||
if (ret) {
|
||||
LOG_DEBUG("find a circular dependency on %s", sub_module_name);
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"found circular dependency on %s",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = wasm_runtime_add_loading_module(sub_module_name, error_buf,
|
||||
error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("can not add %s into loading module list\n",
|
||||
sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = reader(sub_module_name, &buffer, &buffer_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("read the file of %s failed", sub_module_name);
|
||||
set_error_buf_v(error_buf, error_buf_size, "unknown import",
|
||||
sub_module_name);
|
||||
goto DELETE_FROM_LOADING_LIST;
|
||||
}
|
||||
|
||||
sub_module =
|
||||
wasm_loader_load(buffer, buffer_size, error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
LOG_DEBUG("error: can not load the sub_module %s", sub_module_name);
|
||||
/*
|
||||
* others will be destroyed in runtime_destroy()
|
||||
*/
|
||||
goto DESTROY_FILE_BUFFER;
|
||||
}
|
||||
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
|
||||
/* register on a global list */
|
||||
ret = wasm_runtime_register_module_internal(sub_module_name,
|
||||
(WASMModuleCommon*)sub_module,
|
||||
buffer, buffer_size, error_buf,
|
||||
error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("error: can not register module %s globally\n",
|
||||
sub_module_name);
|
||||
/*
|
||||
* others will be unload in runtime_destroy()
|
||||
*/
|
||||
goto UNLOAD_MODULE;
|
||||
}
|
||||
|
||||
/* register on its parent list */
|
||||
REGISTER_SUB_MODULE:
|
||||
ret = register_sub_module(parent_module, sub_module_name, sub_module);
|
||||
if (!ret) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"failed to register sub module %s",
|
||||
sub_module_name);
|
||||
/*
|
||||
* since it is in the global module list, there is no need to
|
||||
* unload the module. the runtime_destroy() will do it
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sub_module;
|
||||
|
||||
UNLOAD_MODULE:
|
||||
wasm_loader_unload(sub_module);
|
||||
|
||||
DESTROY_FILE_BUFFER:
|
||||
if (destroyer) {
|
||||
destroyer(buffer, buffer_size);
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("need to release the reading buffer of %s manually",
|
||||
sub_module_name);
|
||||
}
|
||||
|
||||
DELETE_FROM_LOADING_LIST:
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
static bool
|
||||
load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
|
@ -1413,6 +1427,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
char *sub_module_name, *field_name;
|
||||
uint8 u8, kind;
|
||||
|
||||
/* insert builtin module names into const str list */
|
||||
if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module,
|
||||
error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_snapshot_preview1", 22, module,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, import_count);
|
||||
|
||||
if (import_count) {
|
||||
|
@ -1504,20 +1527,8 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
|
||||
p = p_old;
|
||||
|
||||
/* TODO: move it out of the loop */
|
||||
/* insert "env", "wasi_unstable" and "wasi_snapshot_preview1" to const str list */
|
||||
if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module,
|
||||
error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_snapshot_preview1", 22, module,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Scan again to read the data */
|
||||
/* Scan again to resolve the data */
|
||||
for (i = 0; i < import_count; i++) {
|
||||
WASMModule *sub_module = NULL;
|
||||
|
||||
/* load module name */
|
||||
read_leb_uint32(p, p_end, name_len);
|
||||
CHECK_BUF(p, p_end, name_len);
|
||||
|
@ -1536,36 +1547,19 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
}
|
||||
p += name_len;
|
||||
|
||||
LOG_DEBUG("import #%d: (%s, %s)", i, sub_module_name, field_name);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
/* assume built-in modules have been loaded */
|
||||
if (!wasm_runtime_is_host_module(sub_module_name)
|
||||
&& !wasm_runtime_is_built_in_module(sub_module_name)) {
|
||||
LOG_DEBUG("%s is an exported field of a %s", field_name,
|
||||
sub_module_name);
|
||||
/*
|
||||
* if it returns well, guarantee that
|
||||
* the sub_module_name and its dependencies
|
||||
* have been loaded well
|
||||
*/
|
||||
sub_module = load_depended_module(module, sub_module_name,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
/* 0x00/0x01/0x02/0x03 */
|
||||
kind = read_uint8(p);
|
||||
|
||||
LOG_DEBUG("import #%d: (%s, %s), kind: %d",
|
||||
i, sub_module_name, field_name, kind);
|
||||
switch (kind) {
|
||||
case IMPORT_KIND_FUNC: /* import function */
|
||||
bh_assert(import_functions);
|
||||
import = import_functions++;
|
||||
if (!load_function_import(module, sub_module,
|
||||
sub_module_name, field_name, &p,
|
||||
p_end, &import->u.function,
|
||||
if (!load_function_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.function,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1574,14 +1568,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_TABLE: /* import table */
|
||||
bh_assert(import_tables);
|
||||
import = import_tables++;
|
||||
if (!load_table_import(sub_module,
|
||||
sub_module_name,
|
||||
field_name,
|
||||
&p,
|
||||
p_end,
|
||||
if (!load_table_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.table,
|
||||
error_buf,
|
||||
error_buf_size)) {
|
||||
error_buf, error_buf_size)) {
|
||||
LOG_DEBUG("can not import such a table (%s,%s)",
|
||||
sub_module_name, field_name);
|
||||
return false;
|
||||
|
@ -1591,14 +1581,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_MEMORY: /* import memory */
|
||||
bh_assert(import_memories);
|
||||
import = import_memories++;
|
||||
if (!load_memory_import(sub_module,
|
||||
sub_module_name,
|
||||
field_name,
|
||||
&p,
|
||||
p_end,
|
||||
if (!load_memory_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.memory,
|
||||
error_buf,
|
||||
error_buf_size)) {
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -1606,9 +1592,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_GLOBAL: /* import global */
|
||||
bh_assert(import_globals);
|
||||
import = import_globals++;
|
||||
if (!load_global_import(module, sub_module,
|
||||
if (!load_global_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&p, p_end, &import->u.global,
|
||||
&import->u.global,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1622,7 +1608,6 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
import->kind = kind;
|
||||
import->u.names.module_name = sub_module_name;
|
||||
import->u.names.field_name = field_name;
|
||||
(void)sub_module;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
|
@ -2043,7 +2028,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
export->index = index;
|
||||
|
||||
switch(export->kind) {
|
||||
/*function index*/
|
||||
/* function index */
|
||||
case EXPORT_KIND_FUNC:
|
||||
if (index >= module->function_count
|
||||
+ module->import_function_count) {
|
||||
|
@ -2058,7 +2043,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
#endif
|
||||
#endif
|
||||
break;
|
||||
/*table index*/
|
||||
/* table index */
|
||||
case EXPORT_KIND_TABLE:
|
||||
if (index >= module->table_count
|
||||
+ module->import_table_count) {
|
||||
|
@ -2067,7 +2052,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
/*memory index*/
|
||||
/* memory index */
|
||||
case EXPORT_KIND_MEMORY:
|
||||
if (index >= module->memory_count
|
||||
+ module->import_memory_count) {
|
||||
|
@ -2076,7 +2061,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
/*global index*/
|
||||
/* global index */
|
||||
case EXPORT_KIND_GLOBAL:
|
||||
if (index >= module->global_count
|
||||
+ module->import_global_count) {
|
||||
|
@ -2561,7 +2546,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
while (section) {
|
||||
buf = section->section_body;
|
||||
buf_end = buf + section->section_body_size;
|
||||
LOG_DEBUG("to section %d", section->section_type);
|
||||
LOG_DEBUG("load section, type: %d", section->section_type);
|
||||
switch (section->section_type) {
|
||||
case SECTION_TYPE_USER:
|
||||
/* unsupported user section, ignore it. */
|
||||
|
|
|
@ -320,9 +320,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
}
|
||||
|
||||
static bool
|
||||
load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
||||
char *sub_module_name, char *function_name,
|
||||
const uint8 **p_buf, const uint8 *buf_end,
|
||||
load_function_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
const WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *function_name,
|
||||
WASMFunctionImport *function,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
|
@ -333,7 +334,6 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
const char *linked_signature = NULL;
|
||||
void *linked_attachment = NULL;
|
||||
bool linked_call_conv_raw = false;
|
||||
bool is_built_in_module = false;
|
||||
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
read_leb_uint32(p, p_end, declare_type_index);
|
||||
|
@ -343,24 +343,18 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
|
||||
declare_func_type = parent_module->types[declare_type_index];
|
||||
|
||||
is_built_in_module = wasm_runtime_is_built_in_module(sub_module_name);
|
||||
if (is_built_in_module) {
|
||||
LOG_DEBUG("%s is a function of a built-in module %s",
|
||||
function_name, sub_module_name);
|
||||
/* check built-in modules */
|
||||
linked_func = wasm_native_resolve_symbol(sub_module_name,
|
||||
function_name,
|
||||
declare_func_type,
|
||||
&linked_signature,
|
||||
&linked_attachment,
|
||||
&linked_call_conv_raw);
|
||||
}
|
||||
/* check built-in modules */
|
||||
linked_func = wasm_native_resolve_symbol(sub_module_name,
|
||||
function_name,
|
||||
declare_func_type,
|
||||
&linked_signature,
|
||||
&linked_attachment,
|
||||
&linked_call_conv_raw);
|
||||
|
||||
function->module_name = sub_module_name;
|
||||
function->field_name = function_name;
|
||||
function->module_name = (char *)sub_module_name;
|
||||
function->field_name = (char *)function_name;
|
||||
function->func_type = declare_func_type;
|
||||
/* func_ptr_linked is for built-in functions */
|
||||
function->func_ptr_linked = is_built_in_module ? linked_func : NULL;
|
||||
function->func_ptr_linked = linked_func;
|
||||
function->signature = linked_signature;
|
||||
function->attachment = linked_attachment;
|
||||
function->call_conv_raw = linked_call_conv_raw;
|
||||
|
@ -368,9 +362,11 @@ load_function_import(const WASMModule *parent_module, WASMModule *sub_module,
|
|||
}
|
||||
|
||||
static bool
|
||||
load_table_import(WASMModule *sub_module, const char *sub_module_name,
|
||||
const char *table_name, const uint8 **p_buf,
|
||||
const uint8 *buf_end, WASMTableImport *table,
|
||||
load_table_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *table_name,
|
||||
WASMTableImport *table,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
|
@ -409,9 +405,11 @@ unsigned
|
|||
wasm_runtime_memory_pool_size();
|
||||
|
||||
static bool
|
||||
load_memory_import(WASMModule *sub_module, const char *sub_module_name,
|
||||
const char *memory_name, const uint8 **p_buf,
|
||||
const uint8 *buf_end, WASMMemoryImport *memory,
|
||||
load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMModule *parent_module,
|
||||
const char *sub_module_name,
|
||||
const char *memory_name,
|
||||
WASMMemoryImport *memory,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
|
@ -454,10 +452,9 @@ load_memory_import(WASMModule *sub_module, const char *sub_module_name,
|
|||
}
|
||||
|
||||
static bool
|
||||
load_global_import(const WASMModule *parent_module,
|
||||
WASMModule *sub_module,
|
||||
load_global_import(const uint8 **p_buf, const uint8 *buf_end,
|
||||
const WASMModule *parent_module,
|
||||
char *sub_module_name, char *global_name,
|
||||
const uint8 **p_buf, const uint8 *buf_end,
|
||||
WASMGlobalImport *global,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
|
@ -477,12 +474,9 @@ load_global_import(const WASMModule *parent_module,
|
|||
is_mutable = declare_mutable & 1 ? true : false;
|
||||
|
||||
#if WASM_ENABLE_LIBC_BUILTIN != 0
|
||||
ret = wasm_runtime_is_built_in_module(sub_module_name);
|
||||
if (ret) {
|
||||
/* check built-in modules */
|
||||
ret = wasm_native_lookup_libc_builtin_global(sub_module_name,
|
||||
global_name, global);
|
||||
}
|
||||
/* check built-in modules */
|
||||
ret = wasm_native_lookup_libc_builtin_global(sub_module_name,
|
||||
global_name, global);
|
||||
#endif /* WASM_ENABLE_LIBC_BUILTIN */
|
||||
|
||||
global->is_linked = ret;
|
||||
|
@ -581,6 +575,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
char *sub_module_name, *field_name;
|
||||
uint8 u8, kind;
|
||||
|
||||
/* insert builtin module names into const str list */
|
||||
if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module,
|
||||
error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_snapshot_preview1", 22, module,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read_leb_uint32(p, p_end, import_count);
|
||||
|
||||
if (import_count) {
|
||||
|
@ -663,17 +666,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
|
||||
p = p_old;
|
||||
|
||||
/* TODO: move it out of the loop */
|
||||
/* insert "env", "wasi_unstable" and "wasi_snapshot_preview1" to const str list */
|
||||
if (!const_str_list_insert((uint8*)"env", 3, module, error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_unstable", 13, module,
|
||||
error_buf, error_buf_size)
|
||||
|| !const_str_list_insert((uint8*)"wasi_snapshot_preview1", 22, module,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Scan again to read the data */
|
||||
/* Scan again to resolve the data */
|
||||
for (i = 0; i < import_count; i++) {
|
||||
WASMModule *sub_module = NULL;
|
||||
|
||||
|
@ -695,18 +688,19 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
}
|
||||
p += name_len;
|
||||
|
||||
LOG_DEBUG("import #%d: (%s, %s)", i, sub_module_name, field_name);
|
||||
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
/* 0x00/0x01/0x02/0x03 */
|
||||
kind = read_uint8(p);
|
||||
|
||||
LOG_DEBUG("import #%d: (%s, %s), kind: %d",
|
||||
i, sub_module_name, field_name, kind);
|
||||
switch (kind) {
|
||||
case IMPORT_KIND_FUNC: /* import function */
|
||||
bh_assert(import_functions);
|
||||
import = import_functions++;
|
||||
if (!load_function_import(module, sub_module,
|
||||
sub_module_name, field_name, &p,
|
||||
p_end, &import->u.function,
|
||||
if (!load_function_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.function,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -715,14 +709,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_TABLE: /* import table */
|
||||
bh_assert(import_tables);
|
||||
import = import_tables++;
|
||||
if (!load_table_import(sub_module,
|
||||
sub_module_name,
|
||||
field_name,
|
||||
&p,
|
||||
p_end,
|
||||
if (!load_table_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.table,
|
||||
error_buf,
|
||||
error_buf_size)) {
|
||||
error_buf, error_buf_size)) {
|
||||
LOG_DEBUG("can not import such a table (%s,%s)",
|
||||
sub_module_name, field_name);
|
||||
return false;
|
||||
|
@ -732,14 +722,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_MEMORY: /* import memory */
|
||||
bh_assert(import_memories);
|
||||
import = import_memories++;
|
||||
if (!load_memory_import(sub_module,
|
||||
sub_module_name,
|
||||
field_name,
|
||||
&p,
|
||||
p_end,
|
||||
if (!load_memory_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&import->u.memory,
|
||||
error_buf,
|
||||
error_buf_size)) {
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -747,9 +733,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
case IMPORT_KIND_GLOBAL: /* import global */
|
||||
bh_assert(import_globals);
|
||||
import = import_globals++;
|
||||
if (!load_global_import(module, sub_module,
|
||||
if (!load_global_import(&p, p_end, module,
|
||||
sub_module_name, field_name,
|
||||
&p, p_end, &import->u.global,
|
||||
&import->u.global,
|
||||
error_buf, error_buf_size)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1098,22 +1084,22 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
export->index = index;
|
||||
|
||||
switch(export->kind) {
|
||||
/*function index*/
|
||||
/* function index */
|
||||
case EXPORT_KIND_FUNC:
|
||||
bh_assert(index < module->function_count
|
||||
+ module->import_function_count);
|
||||
break;
|
||||
/*table index*/
|
||||
/* table index */
|
||||
case EXPORT_KIND_TABLE:
|
||||
bh_assert(index < module->table_count
|
||||
+ module->import_table_count);
|
||||
break;
|
||||
/*memory index*/
|
||||
/* memory index */
|
||||
case EXPORT_KIND_MEMORY:
|
||||
bh_assert(index < module->memory_count
|
||||
+ module->import_memory_count);
|
||||
break;
|
||||
/*global index*/
|
||||
/* global index */
|
||||
case EXPORT_KIND_GLOBAL:
|
||||
bh_assert(index < module->global_count
|
||||
+ module->import_global_count);
|
||||
|
@ -1491,7 +1477,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
|||
while (section) {
|
||||
buf = section->section_body;
|
||||
buf_end = buf + section->section_body_size;
|
||||
LOG_DEBUG("to section %d", section->section_type);
|
||||
LOG_DEBUG("load section, type: %d", section->section_type);
|
||||
switch (section->section_type) {
|
||||
case SECTION_TYPE_USER:
|
||||
/* unsupported user section, ignore it. */
|
||||
|
|
Loading…
Reference in New Issue
Block a user