Merge branch main into dev/shared_heap
This commit is contained in:
@ -75,6 +75,10 @@
|
||||
#define WASM_ENABLE_AOT 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_DYNAMIC_AOT_DEBUG
|
||||
#define WASM_ENABLE_DYNAMIC_AOT_DEBUG 0
|
||||
#endif
|
||||
|
||||
#ifndef WASM_ENABLE_WORD_ALIGN_READ
|
||||
#define WASM_ENABLE_WORD_ALIGN_READ 0
|
||||
#endif
|
||||
|
||||
@ -634,73 +634,6 @@ str2uint32(const char *buf, uint32 *p_res);
|
||||
static bool
|
||||
str2uint64(const char *buf, uint64 *p_res);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
static void *
|
||||
aot_loader_resolve_function(const AOTModule *module, const char *function_name,
|
||||
const AOTFuncType *expected_function_type,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
static void *
|
||||
aot_loader_resolve_function_ex(const char *module_name,
|
||||
const char *function_name,
|
||||
const AOTFuncType *expected_function_type,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *module_reg;
|
||||
|
||||
module_reg = wasm_runtime_find_module_registered(module_name);
|
||||
if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
|
||||
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;
|
||||
}
|
||||
return aot_loader_resolve_function((AOTModule *)module_reg, function_name,
|
||||
expected_function_type, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
static void *
|
||||
aot_loader_resolve_function(const AOTModule *module, const char *function_name,
|
||||
const AOTFuncType *expected_function_type,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
void *function = NULL;
|
||||
AOTExport *export = NULL;
|
||||
AOTFuncType *target_function_type = NULL;
|
||||
|
||||
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_func_count) {
|
||||
target_function_type = module->import_funcs[export->index].func_type;
|
||||
function = module->import_funcs[export->index].func_ptr_linked;
|
||||
}
|
||||
else {
|
||||
target_function_type =
|
||||
(AOTFuncType *)module
|
||||
->types[module->func_type_indexes[export->index
|
||||
- module->import_func_count]];
|
||||
function =
|
||||
(module->func_ptrs[export->index - module->import_func_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 /* end of WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
static bool
|
||||
load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
|
||||
AOTModule *module, bool is_load_from_file_buf,
|
||||
@ -2285,19 +2218,13 @@ destroy_import_funcs(AOTImportFunc *import_funcs)
|
||||
|
||||
static bool
|
||||
load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
bool is_load_from_file_buf, char *error_buf,
|
||||
bool is_load_from_file_buf, bool no_resolve, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
char *module_name, *field_name;
|
||||
const uint8 *buf = *p_buf;
|
||||
AOTImportFunc *import_funcs;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
AOTModule *sub_module = NULL;
|
||||
AOTFunc *linked_func = NULL;
|
||||
AOTFuncType *declare_func_type = NULL;
|
||||
#endif
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportFunc) * (uint64)module->import_func_count;
|
||||
@ -2314,53 +2241,17 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
declare_func_type =
|
||||
(AOTFuncType *)module->types[import_funcs[i].func_type_index];
|
||||
read_string(buf, buf_end, module_name);
|
||||
read_string(buf, buf_end, field_name);
|
||||
|
||||
import_funcs[i].module_name = module_name;
|
||||
import_funcs[i].func_name = field_name;
|
||||
linked_func = wasm_native_resolve_symbol(
|
||||
module_name, field_name, declare_func_type,
|
||||
&import_funcs[i].signature, &import_funcs[i].attachment,
|
||||
&import_funcs[i].call_conv_raw);
|
||||
if (!linked_func) {
|
||||
sub_module = NULL;
|
||||
if (!wasm_runtime_is_built_in_module(module_name)) {
|
||||
sub_module = (AOTModule *)wasm_runtime_load_depended_module(
|
||||
(WASMModuleCommon *)module, module_name, error_buf,
|
||||
error_buf_size);
|
||||
if (!sub_module) {
|
||||
LOG_ERROR("failed to load sub module: %s", error_buf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!sub_module)
|
||||
linked_func = aot_loader_resolve_function_ex(
|
||||
module_name, field_name, declare_func_type, error_buf,
|
||||
error_buf_size);
|
||||
else
|
||||
linked_func = aot_loader_resolve_function(
|
||||
sub_module, field_name, declare_func_type, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
import_funcs[i].func_ptr_linked = linked_func;
|
||||
import_funcs[i].func_type = declare_func_type;
|
||||
|
||||
#else
|
||||
import_funcs[i].func_type =
|
||||
(AOTFuncType *)module->types[import_funcs[i].func_type_index];
|
||||
read_string(buf, buf_end, import_funcs[i].module_name);
|
||||
read_string(buf, buf_end, import_funcs[i].func_name);
|
||||
module_name = import_funcs[i].module_name;
|
||||
field_name = import_funcs[i].func_name;
|
||||
import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol(
|
||||
module_name, field_name, import_funcs[i].func_type,
|
||||
&import_funcs[i].signature, &import_funcs[i].attachment,
|
||||
&import_funcs[i].call_conv_raw);
|
||||
#endif
|
||||
import_funcs[i].attachment = NULL;
|
||||
import_funcs[i].signature = NULL;
|
||||
import_funcs[i].call_conv_raw = false;
|
||||
|
||||
if (!no_resolve) {
|
||||
aot_resolve_import_func(module, &import_funcs[i]);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
|
||||
@ -2378,7 +2269,7 @@ fail:
|
||||
static bool
|
||||
load_import_func_info(const uint8 **p_buf, const uint8 *buf_end,
|
||||
AOTModule *module, bool is_load_from_file_buf,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
bool no_resolve, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *buf = *p_buf;
|
||||
|
||||
@ -2387,7 +2278,7 @@ load_import_func_info(const uint8 **p_buf, const uint8 *buf_end,
|
||||
/* load import funcs */
|
||||
if (module->import_func_count > 0
|
||||
&& !load_import_funcs(&buf, buf_end, module, is_load_from_file_buf,
|
||||
error_buf, error_buf_size))
|
||||
no_resolve, error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
*p_buf = buf;
|
||||
@ -2514,7 +2405,7 @@ fail:
|
||||
static bool
|
||||
load_init_data_section(const uint8 *buf, const uint8 *buf_end,
|
||||
AOTModule *module, bool is_load_from_file_buf,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
bool no_resolve, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
|
||||
@ -2525,7 +2416,7 @@ load_init_data_section(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size)
|
||||
|| !load_global_info(&p, p_end, module, error_buf, error_buf_size)
|
||||
|| !load_import_func_info(&p, p_end, module, is_load_from_file_buf,
|
||||
error_buf, error_buf_size))
|
||||
no_resolve, error_buf, error_buf_size))
|
||||
return false;
|
||||
|
||||
/* load function count and start function index */
|
||||
@ -3819,7 +3710,7 @@ has_module_memory64(AOTModule *module)
|
||||
|
||||
static bool
|
||||
load_from_sections(AOTModule *module, AOTSection *sections,
|
||||
bool is_load_from_file_buf, char *error_buf,
|
||||
bool is_load_from_file_buf, bool no_resolve, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
AOTSection *section = sections;
|
||||
@ -3852,8 +3743,8 @@ load_from_sections(AOTModule *module, AOTSection *sections,
|
||||
break;
|
||||
case AOT_SECTION_TYPE_INIT_DATA:
|
||||
if (!load_init_data_section(buf, buf_end, module,
|
||||
is_load_from_file_buf, error_buf,
|
||||
error_buf_size))
|
||||
is_load_from_file_buf, no_resolve,
|
||||
error_buf, error_buf_size))
|
||||
return false;
|
||||
break;
|
||||
case AOT_SECTION_TYPE_TEXT:
|
||||
@ -4076,7 +3967,7 @@ aot_load_from_sections(AOTSection *section_list, char *error_buf,
|
||||
if (!module)
|
||||
return NULL;
|
||||
|
||||
if (!load_from_sections(module, section_list, false, error_buf,
|
||||
if (!load_from_sections(module, section_list, false, false, error_buf,
|
||||
error_buf_size)) {
|
||||
aot_unload(module);
|
||||
return NULL;
|
||||
@ -4246,7 +4137,8 @@ fail:
|
||||
|
||||
static bool
|
||||
load(const uint8 *buf, uint32 size, AOTModule *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;
|
||||
@ -4273,7 +4165,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module,
|
||||
return false;
|
||||
|
||||
ret = load_from_sections(module, section_list, !wasm_binary_freeable,
|
||||
error_buf, error_buf_size);
|
||||
no_resolve, error_buf, error_buf_size);
|
||||
if (!ret) {
|
||||
/* If load_from_sections() fails, then aot text is destroyed
|
||||
in destroy_sections() */
|
||||
@ -4321,8 +4213,8 @@ aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
|
||||
return NULL;
|
||||
|
||||
os_thread_jit_write_protect_np(false); /* Make memory writable */
|
||||
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)) {
|
||||
aot_unload(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1058,7 +1058,24 @@ fail1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static AOTMemoryInstance *
|
||||
AOTMemoryInstance *
|
||||
aot_lookup_memory(AOTModuleInstance *module_inst, char const *name)
|
||||
{
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_memory_count; i++)
|
||||
if (!strcmp(module_inst->export_memories[i].name, name))
|
||||
return module_inst->export_memories[i].memory;
|
||||
return NULL;
|
||||
#else
|
||||
(void)module_inst->export_memories;
|
||||
if (!module_inst->memories)
|
||||
return NULL;
|
||||
return module_inst->memories[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
AOTMemoryInstance *
|
||||
aot_get_default_memory(AOTModuleInstance *module_inst)
|
||||
{
|
||||
if (module_inst->memories)
|
||||
@ -1067,6 +1084,14 @@ aot_get_default_memory(AOTModuleInstance *module_inst)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AOTMemoryInstance *
|
||||
aot_get_memory_with_index(AOTModuleInstance *module_inst, uint32 index)
|
||||
{
|
||||
if ((index >= module_inst->memory_count) || !module_inst->memories)
|
||||
return NULL;
|
||||
return module_inst->memories[index];
|
||||
}
|
||||
|
||||
static bool
|
||||
memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
|
||||
AOTModule *module, uint32 heap_size,
|
||||
@ -1388,6 +1413,36 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
static WASMExportMemInstance *
|
||||
export_memories_instantiate(const AOTModule *module,
|
||||
AOTModuleInstance *module_inst,
|
||||
uint32 export_mem_count, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMExportMemInstance *export_memories, *export_memory;
|
||||
AOTExport *export = module->exports;
|
||||
uint32 i;
|
||||
uint64 total_size =
|
||||
sizeof(WASMExportMemInstance) * (uint64)export_mem_count;
|
||||
|
||||
if (!(export_memory = export_memories =
|
||||
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_MEMORY) {
|
||||
export_memory->name = export->name;
|
||||
export_memory->memory = module_inst->memories[export->index];
|
||||
export_memory++;
|
||||
}
|
||||
|
||||
bh_assert((uint32)(export_memory - export_memories) == export_mem_count);
|
||||
return export_memories;
|
||||
}
|
||||
#endif /* end of if WASM_ENABLE_MULTI_MEMORY != 0 */
|
||||
|
||||
static bool
|
||||
create_exports(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
@ -1414,6 +1469,19 @@ create_exports(AOTModuleInstance *module_inst, AOTModule *module,
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MEMORY == 0
|
||||
bh_assert(module_inst->export_memory_count <= 1);
|
||||
#else
|
||||
if (module_inst->export_memory_count) {
|
||||
module_inst->export_memories = export_memories_instantiate(
|
||||
module, module_inst, module_inst->export_memory_count, error_buf,
|
||||
error_buf_size);
|
||||
if (!module_inst->export_memories) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return create_export_funcs(module_inst, module, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
@ -2057,6 +2125,11 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||
if (module_inst->export_functions)
|
||||
wasm_runtime_free(module_inst->export_functions);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
if (module_inst->export_memories)
|
||||
wasm_runtime_free(module_inst->export_memories);
|
||||
#endif
|
||||
|
||||
if (extra->functions) {
|
||||
uint32 func_idx;
|
||||
for (func_idx = 0; func_idx < extra->function_count; ++func_idx) {
|
||||
@ -4999,6 +5072,18 @@ aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
|
||||
return c_str;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DYNAMIC_AOT_DEBUG != 0
|
||||
AOTModule *g_dynamic_aot_module = NULL;
|
||||
|
||||
void __attribute__((noinline)) __enable_dynamic_aot_debug(void)
|
||||
{
|
||||
/* empty implementation. */
|
||||
}
|
||||
|
||||
void (*__enable_dynamic_aot_debug_ptr)(void)
|
||||
__attribute__((visibility("default"))) = __enable_dynamic_aot_debug;
|
||||
#endif
|
||||
|
||||
bool
|
||||
aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
|
||||
uint32_t error_buf_size)
|
||||
@ -5012,6 +5097,12 @@ aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
|
||||
false,
|
||||
#endif
|
||||
error_buf, error_buf_size);
|
||||
#if WASM_ENABLE_DYNAMIC_AOT_DEBUG != 0
|
||||
/* export g_dynamic_aot_module for dynamic aot debug */
|
||||
g_dynamic_aot_module = module;
|
||||
/* trigger breakpoint __enable_dynamic_aot_debug */
|
||||
(*__enable_dynamic_aot_debug_ptr)();
|
||||
#endif
|
||||
return module->name != NULL;
|
||||
}
|
||||
|
||||
@ -5020,3 +5111,125 @@ aot_get_module_name(AOTModule *module)
|
||||
{
|
||||
return module->name;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_resolve_symbols(AOTModule *module)
|
||||
{
|
||||
bool ret = true;
|
||||
uint32 idx;
|
||||
for (idx = 0; idx < module->import_func_count; ++idx) {
|
||||
AOTImportFunc *aot_import_func = &module->import_funcs[idx];
|
||||
if (!aot_import_func->func_ptr_linked) {
|
||||
if (!aot_resolve_import_func(module, aot_import_func)) {
|
||||
LOG_WARNING("Failed to link function (%s, %s)",
|
||||
aot_import_func->module_name,
|
||||
aot_import_func->func_name);
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
static void *
|
||||
aot_resolve_function(const AOTModule *module, const char *function_name,
|
||||
const AOTFuncType *expected_function_type, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
static void *
|
||||
aot_resolve_function_ex(const char *module_name, const char *function_name,
|
||||
const AOTFuncType *expected_function_type,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *module_reg;
|
||||
|
||||
module_reg = wasm_runtime_find_module_registered(module_name);
|
||||
if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
|
||||
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;
|
||||
}
|
||||
return aot_resolve_function((AOTModule *)module_reg, function_name,
|
||||
expected_function_type, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
static void *
|
||||
aot_resolve_function(const AOTModule *module, const char *function_name,
|
||||
const AOTFuncType *expected_function_type, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
void *function = NULL;
|
||||
AOTExport *export = NULL;
|
||||
AOTFuncType *target_function_type = NULL;
|
||||
|
||||
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_func_count) {
|
||||
target_function_type = module->import_funcs[export->index].func_type;
|
||||
function = module->import_funcs[export->index].func_ptr_linked;
|
||||
}
|
||||
else {
|
||||
target_function_type =
|
||||
(AOTFuncType *)module
|
||||
->types[module->func_type_indexes[export->index
|
||||
- module->import_func_count]];
|
||||
function =
|
||||
(module->func_ptrs[export->index - module->import_func_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 /* end of WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
bool
|
||||
aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func)
|
||||
{
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
char error_buf[128];
|
||||
AOTModule *sub_module = NULL;
|
||||
#endif
|
||||
import_func->func_ptr_linked = wasm_native_resolve_symbol(
|
||||
import_func->module_name, import_func->func_name,
|
||||
import_func->func_type, &import_func->signature,
|
||||
&import_func->attachment, &import_func->call_conv_raw);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (!import_func->func_ptr_linked) {
|
||||
if (!wasm_runtime_is_built_in_module(import_func->module_name)) {
|
||||
sub_module = (AOTModule *)wasm_runtime_load_depended_module(
|
||||
(WASMModuleCommon *)module, import_func->module_name, error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!sub_module) {
|
||||
LOG_WARNING("Failed to load sub module: %s", error_buf);
|
||||
}
|
||||
if (!sub_module)
|
||||
import_func->func_ptr_linked = aot_resolve_function_ex(
|
||||
import_func->module_name, import_func->func_name,
|
||||
import_func->func_type, error_buf, sizeof(error_buf));
|
||||
else
|
||||
import_func->func_ptr_linked = aot_resolve_function(
|
||||
sub_module, import_func->func_name, import_func->func_type,
|
||||
error_buf, sizeof(error_buf));
|
||||
if (!import_func->func_ptr_linked) {
|
||||
LOG_WARNING("Failed to link function: %s", error_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return import_func->func_ptr_linked != NULL;
|
||||
}
|
||||
|
||||
@ -496,6 +496,18 @@ aot_load_from_sections(AOTSection *section_list, char *error_buf,
|
||||
void
|
||||
aot_unload(AOTModule *module);
|
||||
|
||||
/**
|
||||
* Resolve symbols for an AOT module
|
||||
*/
|
||||
bool
|
||||
aot_resolve_symbols(AOTModule *module);
|
||||
|
||||
/**
|
||||
* Helper function to resolve a single function
|
||||
*/
|
||||
bool
|
||||
aot_resolve_import_func(AOTModule *module, AOTImportFunc *import_func);
|
||||
|
||||
/**
|
||||
* Instantiate a AOT module.
|
||||
*
|
||||
@ -536,6 +548,15 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst);
|
||||
AOTFunctionInstance *
|
||||
aot_lookup_function(const AOTModuleInstance *module_inst, const char *name);
|
||||
|
||||
AOTMemoryInstance *
|
||||
aot_lookup_memory(AOTModuleInstance *module_inst, char const *name);
|
||||
|
||||
AOTMemoryInstance *
|
||||
aot_get_default_memory(AOTModuleInstance *module_inst);
|
||||
|
||||
AOTMemoryInstance *
|
||||
aot_get_memory_with_index(AOTModuleInstance *module_inst, uint32 index);
|
||||
|
||||
/**
|
||||
* Get a function in the AOT module instance.
|
||||
*
|
||||
|
||||
@ -1102,11 +1102,9 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
|
||||
WASMMemoryInstance *
|
||||
wasm_get_memory_with_idx(WASMModuleInstance *module_inst, uint32 index)
|
||||
{
|
||||
bh_assert(index < module_inst->memory_count);
|
||||
if (module_inst->memories)
|
||||
return module_inst->memories[index];
|
||||
else
|
||||
if ((index >= module_inst->memory_count) || !module_inst->memories)
|
||||
return NULL;
|
||||
return module_inst->memories[index];
|
||||
}
|
||||
|
||||
void
|
||||
@ -1185,20 +1183,13 @@ wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size)
|
||||
return wasm_mremap_linear_memory(NULL, 0, map_size, commit_size);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
|
||||
uint32 memidx)
|
||||
static bool
|
||||
wasm_enlarge_memory_internal(WASMModuleInstanceCommon *module,
|
||||
WASMMemoryInstance *memory, uint32 inc_page_count)
|
||||
{
|
||||
#if WASM_ENABLE_MULTI_MEMORY != 0
|
||||
WASMMemoryInstance *memory = wasm_get_memory_with_idx(module, memidx);
|
||||
#else
|
||||
WASMMemoryInstance *memory = wasm_get_default_memory(module);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_SHARED_HEAP != 0
|
||||
WASMSharedHeap *shared_heap;
|
||||
#endif
|
||||
|
||||
uint8 *memory_data_old, *memory_data_new, *heap_data_old;
|
||||
uint32 num_bytes_per_page, heap_size;
|
||||
uint32 cur_page_count, max_page_count, total_page_count;
|
||||
@ -1231,8 +1222,23 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
|
||||
total_page_count = inc_page_count + cur_page_count;
|
||||
total_size_new = num_bytes_per_page * (uint64)total_page_count;
|
||||
|
||||
if (inc_page_count <= 0)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < cur_page_count) { /* integer overflow */
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
if (total_page_count > max_page_count) {
|
||||
failure_reason = MAX_SIZE_REACHED;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_SHARED_HEAP != 0
|
||||
shared_heap = get_shared_heap((WASMModuleInstanceCommon *)module);
|
||||
shared_heap = get_shared_heap(module);
|
||||
if (shared_heap) {
|
||||
if (memory->is_memory64
|
||||
&& total_size_new > shared_heap->start_off_mem64) {
|
||||
@ -1248,20 +1254,6 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (inc_page_count <= 0)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < cur_page_count) { /* integer overflow */
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
if (total_page_count > max_page_count) {
|
||||
failure_reason = MAX_SIZE_REACHED;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
bh_assert(total_size_new
|
||||
<= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
|
||||
@ -1364,7 +1356,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
|
||||
wasm_runtime_set_mem_bound_check_bytes(memory, total_size_new);
|
||||
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
if (!ret && module && enlarge_memory_error_cb) {
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
@ -1377,8 +1369,7 @@ return_func:
|
||||
#endif
|
||||
|
||||
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
|
||||
failure_reason,
|
||||
(WASMModuleInstanceCommon *)module, exec_env,
|
||||
failure_reason, module, exec_env,
|
||||
enlarge_memory_error_user_data);
|
||||
}
|
||||
|
||||
@ -1422,15 +1413,16 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (module->memory_count > 0) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module->memory_count > 0)
|
||||
shared_memory_lock(module->memories[0]);
|
||||
#endif
|
||||
ret = wasm_enlarge_memory_internal(module, inc_page_count, 0);
|
||||
ret = wasm_enlarge_memory_internal((WASMModuleInstanceCommon *)module,
|
||||
module->memories[0], inc_page_count);
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module->memory_count > 0)
|
||||
shared_memory_unlock(module->memories[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1441,15 +1433,117 @@ wasm_enlarge_memory_with_idx(WASMModuleInstance *module, uint32 inc_page_count,
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (memidx < module->memory_count) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memidx < module->memory_count)
|
||||
shared_memory_lock(module->memories[memidx]);
|
||||
#endif
|
||||
ret = wasm_enlarge_memory_internal(module, inc_page_count, memidx);
|
||||
ret = wasm_enlarge_memory_internal((WASMModuleInstanceCommon *)module,
|
||||
module->memories[memidx],
|
||||
inc_page_count);
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memidx < module->memory_count)
|
||||
shared_memory_unlock(module->memories[memidx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_runtime_lookup_memory(WASMModuleInstanceCommon *module_inst,
|
||||
const char *name)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_lookup_memory((WASMModuleInstance *)module_inst, name);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_lookup_memory((WASMModuleInstance *)module_inst, name);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_runtime_get_default_memory(WASMModuleInstanceCommon *module_inst)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_get_default_memory((WASMModuleInstance *)module_inst);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_get_default_memory((AOTModuleInstance *)module_inst);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WASMMemoryInstance *
|
||||
wasm_runtime_get_memory(WASMModuleInstanceCommon *module_inst, uint32 index)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode)
|
||||
return wasm_get_memory_with_idx((WASMModuleInstance *)module_inst,
|
||||
index);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT)
|
||||
return aot_get_memory_with_index((AOTModuleInstance *)module_inst,
|
||||
index);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64
|
||||
wasm_memory_get_cur_page_count(WASMMemoryInstance *memory)
|
||||
{
|
||||
return memory->cur_page_count;
|
||||
}
|
||||
|
||||
uint64
|
||||
wasm_memory_get_max_page_count(WASMMemoryInstance *memory)
|
||||
{
|
||||
return memory->max_page_count;
|
||||
}
|
||||
|
||||
uint64
|
||||
wasm_memory_get_bytes_per_page(WASMMemoryInstance *memory)
|
||||
{
|
||||
return memory->num_bytes_per_page;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_memory_get_shared(WASMMemoryInstance *memory)
|
||||
{
|
||||
return memory->is_shared_memory;
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_memory_get_base_address(WASMMemoryInstance *memory)
|
||||
{
|
||||
return memory->memory_data;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_memory_enlarge(WASMMemoryInstance *memory, uint64 inc_page_count)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (memory) {
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
shared_memory_lock(memory);
|
||||
#endif
|
||||
ret =
|
||||
wasm_enlarge_memory_internal(NULL, memory, (uint32)inc_page_count);
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
shared_memory_unlock(memory);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1484,6 +1484,22 @@ wasm_runtime_load_ex(uint8 *buf, uint32 size, const LoadArgs *args,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_resolve_symbols(WASMModuleCommon *module)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
return wasm_resolve_symbols((WASMModule *)module);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
return aot_resolve_symbols((AOTModule *)module);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
@ -4505,7 +4521,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
||||
#endif
|
||||
typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *);
|
||||
NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr;
|
||||
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64;
|
||||
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size;
|
||||
uint32 *argv_src = argv, i, argc1, ptr_len;
|
||||
uint32 arg_i32;
|
||||
bool ret = false;
|
||||
@ -4568,6 +4584,8 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
|
||||
case VALUE_TYPE_I64:
|
||||
#if WASM_ENABLE_MEMORY64 != 0
|
||||
{
|
||||
uint64 arg_i64;
|
||||
|
||||
PUT_I64_TO_ADDR((uint32 *)argv_dst,
|
||||
GET_I64_FROM_ADDR(argv_src));
|
||||
argv_src += 2;
|
||||
|
||||
@ -1407,7 +1407,9 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef *param_values = NULL, value_ret = NULL, func;
|
||||
LLVMValueRef import_func_idx, res;
|
||||
LLVMValueRef ext_ret, ext_ret_ptr, ext_ret_idx;
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0
|
||||
LLVMValueRef func_idx_ref;
|
||||
#endif
|
||||
int32 i, j = 0, param_count, result_count, ext_ret_count;
|
||||
uint64 total_size;
|
||||
uint8 wasm_ret_type;
|
||||
|
||||
@ -534,6 +534,10 @@ typedef struct LoadArgs {
|
||||
bool clone_wasm_binary;
|
||||
/* This option is only used by the AOT/wasm loader (see wasm_export.h) */
|
||||
bool wasm_binary_freeable;
|
||||
/* false by default, if true, don't resolve the symbols yet. The
|
||||
wasm_runtime_load_ex has to be followed by a wasm_runtime_resolve_symbols
|
||||
call */
|
||||
bool no_resolve;
|
||||
/* TODO: more fields? */
|
||||
} LoadArgs;
|
||||
#endif /* LOAD_ARGS_OPTION_DEFINED */
|
||||
|
||||
@ -120,6 +120,10 @@ typedef struct WASMModuleInstanceCommon *wasm_module_inst_t;
|
||||
typedef void WASMFunctionInstanceCommon;
|
||||
typedef WASMFunctionInstanceCommon *wasm_function_inst_t;
|
||||
|
||||
/* Memory instance */
|
||||
struct WASMMemoryInstance;
|
||||
typedef struct WASMMemoryInstance *wasm_memory_inst_t;
|
||||
|
||||
/* WASM section */
|
||||
typedef struct wasm_section_t {
|
||||
struct wasm_section_t *next;
|
||||
@ -251,6 +255,11 @@ typedef struct LoadArgs {
|
||||
const strings), making it possible to free the wasm binary buffer after
|
||||
loading. */
|
||||
bool wasm_binary_freeable;
|
||||
|
||||
/* false by default, if true, don't resolve the symbols yet. The
|
||||
wasm_runtime_load_ex has to be followed by a wasm_runtime_resolve_symbols
|
||||
call */
|
||||
bool no_resolve;
|
||||
/* TODO: more fields? */
|
||||
} LoadArgs;
|
||||
#endif /* LOAD_ARGS_OPTION_DEFINED */
|
||||
@ -572,6 +581,12 @@ WASM_RUNTIME_API_EXTERN wasm_module_t
|
||||
wasm_runtime_load_ex(uint8_t *buf, uint32_t size, const LoadArgs *args,
|
||||
char *error_buf, uint32_t error_buf_size);
|
||||
|
||||
/**
|
||||
* Resolve symbols for a previously loaded WASM module. Only useful when the
|
||||
* module was loaded with LoadArgs::no_resolve set to true
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_resolve_symbols(wasm_module_t module);
|
||||
/**
|
||||
* Load a WASM module from a specified WASM or AOT section list.
|
||||
*
|
||||
@ -946,6 +961,100 @@ WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_module_inst(wasm_exec_env_t exec_env,
|
||||
const wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* @brief Lookup a memory instance by name
|
||||
*
|
||||
* @param module_inst The module instance
|
||||
* @param name The name of the memory instance
|
||||
*
|
||||
* @return The memory instance if found, NULL otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_memory_inst_t
|
||||
wasm_runtime_lookup_memory(const wasm_module_inst_t module_inst,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* @brief Get the default memory instance
|
||||
*
|
||||
* @param module_inst The module instance
|
||||
*
|
||||
* @return The memory instance if found, NULL otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_memory_inst_t
|
||||
wasm_runtime_get_default_memory(const wasm_module_inst_t module_inst);
|
||||
|
||||
/**
|
||||
* @brief Get a memory instance by index
|
||||
*
|
||||
* @param module_inst The module instance
|
||||
* @param index The index of the memory instance
|
||||
*
|
||||
* @return The memory instance if found, NULL otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN wasm_memory_inst_t
|
||||
wasm_runtime_get_memory(const wasm_module_inst_t module_inst, uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief Get the current number of pages for a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
*
|
||||
* @return The current number of pages
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint64_t
|
||||
wasm_memory_get_cur_page_count(const wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Get the maximum number of pages for a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
*
|
||||
* @return The maximum number of pages
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint64_t
|
||||
wasm_memory_get_max_page_count(const wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Get the number of bytes per page for a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
*
|
||||
* @return The number of bytes per page
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN uint64_t
|
||||
wasm_memory_get_bytes_per_page(const wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Get the shared status for a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
*
|
||||
* @return True if shared, false otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_memory_get_shared(const wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Get the base address for a memory instance
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
*
|
||||
* @return The base address on success, false otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_memory_get_base_address(const wasm_memory_inst_t memory_inst);
|
||||
|
||||
/**
|
||||
* @brief Enlarge a memory instance by a number of pages
|
||||
*
|
||||
* @param memory_inst The memory instance
|
||||
* @param inc_page_count The number of pages to add
|
||||
*
|
||||
* @return True if successful, false otherwise
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_memory_enlarge(wasm_memory_inst_t memory_inst, uint64_t inc_page_count);
|
||||
|
||||
/**
|
||||
* Call the given WASM function of a WASM module instance with
|
||||
* arguments (bytecode and AoT).
|
||||
|
||||
@ -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, §ion_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;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user