Merge branch main into dev/shared_heap

This commit is contained in:
Wenyong Huang
2024-09-20 14:34:00 +08:00
20 changed files with 1024 additions and 338 deletions

View File

@ -2246,60 +2246,6 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name,
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
static WASMFunction *
wasm_loader_resolve_function(const char *module_name, const char *function_name,
const WASMFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size)
{
WASMModuleCommon *module_reg;
WASMFunction *function = NULL;
WASMExport *export = NULL;
WASMModule *module = NULL;
WASMFuncType *target_function_type = NULL;
module_reg = wasm_runtime_find_module_registered(module_name);
if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) {
LOG_DEBUG("can not find a module named %s for function %s", module_name,
function_name);
set_error_buf(error_buf, error_buf_size, "unknown import");
return NULL;
}
module = (WASMModule *)module_reg;
export =
wasm_loader_find_export(module, module_name, function_name,
EXPORT_KIND_FUNC, error_buf, error_buf_size);
if (!export) {
return NULL;
}
/* resolve function type and function */
if (export->index < module->import_function_count) {
target_function_type =
module->import_functions[export->index].u.function.func_type;
function = module->import_functions[export->index]
.u.function.import_func_linked;
}
else {
target_function_type =
module->functions[export->index - module->import_function_count]
->func_type;
function =
module->functions[export->index - module->import_function_count];
}
/* check function type */
if (!wasm_type_equal((WASMType *)expected_function_type,
(WASMType *)target_function_type, module->types,
module->type_count)) {
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
set_error_buf(error_buf, error_buf_size, "incompatible import type");
return NULL;
}
return function;
}
static WASMTable *
wasm_loader_resolve_table(const char *module_name, const char *table_name,
uint32 init_size, uint32 max_size, char *error_buf,
@ -2494,21 +2440,11 @@ static bool
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)
WASMFunctionImport *function, bool no_resolve,
char *error_buf, uint32 error_buf_size)
{
const uint8 *p = *p_buf, *p_end = buf_end;
uint32 declare_type_index = 0;
WASMFuncType *declare_func_type = NULL;
WASMFunction *linked_func = NULL;
#if WASM_ENABLE_MULTI_MODULE != 0
WASMModule *sub_module = NULL;
bool is_built_in_module = false;
#endif
const char *linked_signature = NULL;
void *linked_attachment = NULL;
bool linked_call_conv_raw = false;
bool is_native_symbol = false;
read_leb_uint32(p, p_end, declare_type_index);
*p_buf = p;
@ -2527,43 +2463,19 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end,
parent_module->types, parent_module->type_count, declare_type_index);
#endif
declare_func_type =
function->func_type =
(WASMFuncType *)parent_module->types[declare_type_index];
/* 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 (!(is_built_in_module =
wasm_runtime_is_built_in_module(sub_module_name))) {
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
}
if (is_built_in_module || sub_module)
linked_func = wasm_loader_resolve_function(
sub_module_name, function_name, declare_func_type, error_buf,
error_buf_size);
}
#endif
function->module_name = (char *)sub_module_name;
function->field_name = (char *)function_name;
function->func_type = declare_func_type;
/* 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_native_symbol ? NULL : sub_module;
function->import_func_linked = is_native_symbol ? NULL : linked_func;
#endif
function->attachment = NULL;
function->signature = NULL;
function->call_conv_raw = false;
/* lookup registered native symbols first */
if (!no_resolve) {
wasm_resolve_import_func(parent_module, function);
}
return true;
fail:
return false;
@ -3258,8 +3170,8 @@ fail:
static bool
load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
bool is_load_from_file_buf, bool no_resolve,
char *error_buf, uint32 error_buf_size)
{
const uint8 *p = buf, *p_end = buf_end, *p_old;
uint32 import_count, name_len, type_index, i, u32, flags;
@ -3442,9 +3354,10 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
case IMPORT_KIND_FUNC: /* import function */
bh_assert(import_functions);
import = import_functions++;
if (!load_function_import(
&p, p_end, module, sub_module_name, field_name,
&import->u.function, error_buf, error_buf_size)) {
if (!load_function_import(&p, p_end, module,
sub_module_name, field_name,
&import->u.function, no_resolve,
error_buf, error_buf_size)) {
return false;
}
break;
@ -5760,7 +5673,7 @@ static void **handle_table;
static bool
load_from_sections(WASMModule *module, WASMSection *sections,
bool is_load_from_file_buf, bool wasm_binary_freeable,
char *error_buf, uint32 error_buf_size)
bool no_resolve, char *error_buf, uint32 error_buf_size)
{
WASMExport *export;
WASMSection *section = sections;
@ -5817,8 +5730,8 @@ load_from_sections(WASMModule *module, WASMSection *sections,
break;
case SECTION_TYPE_IMPORT:
if (!load_import_section(buf, buf_end, module,
reuse_const_strings, error_buf,
error_buf_size))
reuse_const_strings, no_resolve,
error_buf, error_buf_size))
return false;
break;
case SECTION_TYPE_FUNC:
@ -6343,7 +6256,7 @@ wasm_loader_load_from_sections(WASMSection *section_list, char *error_buf,
if (!module)
return NULL;
if (!load_from_sections(module, section_list, false, true, error_buf,
if (!load_from_sections(module, section_list, false, true, false, error_buf,
error_buf_size)) {
wasm_loader_unload(module);
return NULL;
@ -6488,7 +6401,8 @@ static union {
static bool
load(const uint8 *buf, uint32 size, WASMModule *module,
bool wasm_binary_freeable, char *error_buf, uint32 error_buf_size)
bool wasm_binary_freeable, bool no_resolve, char *error_buf,
uint32 error_buf_size)
{
const uint8 *buf_end = buf + size;
const uint8 *p = buf, *p_end = buf_end;
@ -6519,7 +6433,7 @@ load(const uint8 *buf, uint32 size, WASMModule *module,
if (!create_sections(buf, size, &section_list, error_buf, error_buf_size)
|| !load_from_sections(module, section_list, true, wasm_binary_freeable,
error_buf, error_buf_size)) {
no_resolve, error_buf, error_buf_size)) {
destroy_sections(section_list);
return false;
}
@ -6695,8 +6609,8 @@ wasm_loader_load(uint8 *buf, uint32 size,
module->load_size = size;
#endif
if (!load(buf, size, module, args->wasm_binary_freeable, error_buf,
error_buf_size)) {
if (!load(buf, size, module, args->wasm_binary_freeable, args->no_resolve,
error_buf, error_buf_size)) {
goto fail;
}

View File

@ -83,6 +83,124 @@ wasm_unload(WASMModule *module)
wasm_loader_unload(module);
}
bool
wasm_resolve_symbols(WASMModule *module)
{
bool ret = true;
uint32 idx;
for (idx = 0; idx < module->import_function_count; ++idx) {
WASMFunctionImport *import = &module->import_functions[idx].u.function;
bool linked = import->func_ptr_linked;
#if WASM_ENABLE_MULTI_MODULE != 0
if (import->import_func_linked) {
linked = true;
}
#endif
if (!linked && !wasm_resolve_import_func(module, import)) {
ret = false;
}
}
return ret;
}
#if WASM_ENABLE_MULTI_MODULE != 0
static WASMFunction *
wasm_resolve_function(const char *module_name, const char *function_name,
const WASMFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size)
{
WASMModuleCommon *module_reg;
WASMFunction *function = NULL;
WASMExport *export = NULL;
WASMModule *module = NULL;
WASMFuncType *target_function_type = NULL;
module_reg = wasm_runtime_find_module_registered(module_name);
if (!module_reg || module_reg->module_type != Wasm_Module_Bytecode) {
LOG_DEBUG("can not find a module named %s for function %s", module_name,
function_name);
set_error_buf(error_buf, error_buf_size, "unknown import");
return NULL;
}
module = (WASMModule *)module_reg;
export = loader_find_export((WASMModuleCommon *)module, module_name,
function_name, EXPORT_KIND_FUNC, error_buf,
error_buf_size);
if (!export) {
return NULL;
}
/* resolve function type and function */
if (export->index < module->import_function_count) {
target_function_type =
module->import_functions[export->index].u.function.func_type;
function = module->import_functions[export->index]
.u.function.import_func_linked;
}
else {
target_function_type =
module->functions[export->index - module->import_function_count]
->func_type;
function =
module->functions[export->index - module->import_function_count];
}
/* check function type */
if (!wasm_type_equal((WASMType *)expected_function_type,
(WASMType *)target_function_type, module->types,
module->type_count)) {
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
set_error_buf(error_buf, error_buf_size, "incompatible import type");
return NULL;
}
return function;
}
#endif
bool
wasm_resolve_import_func(const WASMModule *module, WASMFunctionImport *function)
{
#if WASM_ENABLE_MULTI_MODULE != 0
char error_buf[128];
WASMModule *sub_module = NULL;
#endif
function->func_ptr_linked = wasm_native_resolve_symbol(
function->module_name, function->field_name, function->func_type,
&function->signature, &function->attachment, &function->call_conv_raw);
if (function->func_ptr_linked) {
return true;
}
#if WASM_ENABLE_MULTI_MODULE != 0
if (!wasm_runtime_is_built_in_module(function->module_name)) {
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)module, function->module_name, error_buf,
sizeof(error_buf));
if (!sub_module) {
LOG_WARNING("failed to load sub module: %s", error_buf);
return false;
}
}
function->import_func_linked = wasm_resolve_function(
function->module_name, function->field_name, function->func_type,
error_buf, sizeof(error_buf));
if (function->import_func_linked) {
function->import_module = sub_module;
return true;
}
else {
LOG_WARNING("failed to link function (%s, %s): %s",
function->module_name, function->field_name, error_buf);
}
#endif
return false;
}
static void *
runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
{
@ -1323,42 +1441,6 @@ export_tags_instantiate(const WASMModule *module,
}
#endif /* end of WASM_ENABLE_TAGS != 0 */
#if WASM_ENABLE_MULTI_MODULE != 0
static void
export_globals_deinstantiate(WASMExportGlobInstance *globals)
{
if (globals)
wasm_runtime_free(globals);
}
static WASMExportGlobInstance *
export_globals_instantiate(const WASMModule *module,
WASMModuleInstance *module_inst,
uint32 export_glob_count, char *error_buf,
uint32 error_buf_size)
{
WASMExportGlobInstance *export_globals, *export_global;
WASMExport *export = module->exports;
uint32 i;
uint64 total_size =
sizeof(WASMExportGlobInstance) * (uint64)export_glob_count;
if (!(export_global = export_globals =
runtime_malloc(total_size, error_buf, error_buf_size))) {
return NULL;
}
for (i = 0; i < module->export_count; i++, export ++)
if (export->kind == EXPORT_KIND_GLOBAL) {
export_global->name = export->name;
export_global->global = &module_inst->e->globals[export->index];
export_global++;
}
bh_assert((uint32)(export_global - export_globals) == export_glob_count);
return export_globals;
}
#if WASM_ENABLE_MULTI_MEMORY != 0
static void
export_memories_deinstantiate(WASMExportMemInstance *memories)
@ -1396,6 +1478,42 @@ export_memories_instantiate(const WASMModule *module,
}
#endif /* end of if WASM_ENABLE_MULTI_MEMORY != 0 */
#if WASM_ENABLE_MULTI_MODULE != 0
static void
export_globals_deinstantiate(WASMExportGlobInstance *globals)
{
if (globals)
wasm_runtime_free(globals);
}
static WASMExportGlobInstance *
export_globals_instantiate(const WASMModule *module,
WASMModuleInstance *module_inst,
uint32 export_glob_count, char *error_buf,
uint32 error_buf_size)
{
WASMExportGlobInstance *export_globals, *export_global;
WASMExport *export = module->exports;
uint32 i;
uint64 total_size =
sizeof(WASMExportGlobInstance) * (uint64)export_glob_count;
if (!(export_global = export_globals =
runtime_malloc(total_size, error_buf, error_buf_size))) {
return NULL;
}
for (i = 0; i < module->export_count; i++, export ++)
if (export->kind == EXPORT_KIND_GLOBAL) {
export_global->name = export->name;
export_global->global = &module_inst->e->globals[export->index];
export_global++;
}
bh_assert((uint32)(export_global - export_globals) == export_glob_count);
return export_globals;
}
#endif /* end of if WASM_ENABLE_MULTI_MODULE != 0 */
static WASMFunctionInstance *
@ -2388,11 +2506,13 @@ 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);
module_inst->export_memory_count =
get_export_count(module, EXPORT_KIND_MEMORY);
#if WASM_ENABLE_TAGS != 0
module_inst->e->export_tag_count =
get_export_count(module, EXPORT_KIND_TAG);
@ -2432,7 +2552,7 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
module, module_inst, module_inst->export_global_count,
error_buf, error_buf_size)))
#endif
#if WASM_ENABLE_MULTI_MODULE != 0 && WASM_ENABLE_MULTI_MEMORY != 0
#if WASM_ENABLE_MULTI_MEMORY != 0
|| (module_inst->export_memory_count > 0
&& !(module_inst->export_memories = export_memories_instantiate(
module, module_inst, module_inst->export_memory_count,
@ -3240,7 +3360,7 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
export_globals_deinstantiate(module_inst->export_globals);
#endif
#if WASM_ENABLE_MULTI_MODULE != 0 && WASM_ENABLE_MULTI_MEMORY != 0
#if WASM_ENABLE_MULTI_MEMORY != 0
export_memories_deinstantiate(module_inst->export_memories);
#endif
@ -3292,17 +3412,6 @@ wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name)
return NULL;
}
#if WASM_ENABLE_MULTI_MODULE != 0
WASMGlobalInstance *
wasm_lookup_global(const WASMModuleInstance *module_inst, const char *name)
{
uint32 i;
for (i = 0; i < module_inst->export_global_count; i++)
if (!strcmp(module_inst->export_globals[i].name, name))
return module_inst->export_globals[i].global;
return NULL;
}
WASMMemoryInstance *
wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name)
{
@ -3314,10 +3423,23 @@ wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name)
return NULL;
#else
(void)module_inst->export_memories;
if (!module_inst->memories)
return NULL;
return module_inst->memories[0];
#endif
}
#if WASM_ENABLE_MULTI_MODULE != 0
WASMGlobalInstance *
wasm_lookup_global(const WASMModuleInstance *module_inst, const char *name)
{
uint32 i;
for (i = 0; i < module_inst->export_global_count; i++)
if (!strcmp(module_inst->export_globals[i].name, name))
return module_inst->export_globals[i].global;
return NULL;
}
WASMTableInstance *
wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
{

View File

@ -528,6 +528,13 @@ wasm_load_from_sections(WASMSection *section_list, char *error_buf,
void
wasm_unload(WASMModule *module);
bool
wasm_resolve_symbols(WASMModule *module);
bool
wasm_resolve_import_func(const WASMModule *module,
WASMFunctionImport *function);
WASMModuleInstance *
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
WASMExecEnv *exec_env_main, uint32 stack_size,
@ -554,13 +561,13 @@ wasm_set_running_mode(WASMModuleInstance *module_inst,
WASMFunctionInstance *
wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name);
WASMMemoryInstance *
wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name);
#if WASM_ENABLE_MULTI_MODULE != 0
WASMGlobalInstance *
wasm_lookup_global(const WASMModuleInstance *module_inst, const char *name);
WASMMemoryInstance *
wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name);
WASMTableInstance *
wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name);