Add memory instance support apis (#3786)

Now that WAMR supports multiple memory instances, this PR adds some APIs
to access them in a standard way.

This involves moving some existing utility functions out from the
`WASM_ENABLE_MULTI_MODULE` blocks they were nested in, but multi-memory
and multi-module seem independent as far as I can tell so I assume that's okay.

APIs added:
```C
wasm_runtime_lookup_memory
wasm_runtime_get_default_memory
wasm_runtime_get_memory
wasm_memory_get_cur_page_count
wasm_memory_get_max_page_count
wasm_memory_get_bytes_per_page
wasm_memory_get_shared
wasm_memory_get_base_address
wasm_memory_enlarge
```
This commit is contained in:
Benbuck Nason 2024-09-13 19:31:13 -07:00 committed by GitHub
parent 9aadbfee29
commit 926f662231
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 307 additions and 76 deletions

View File

@ -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,

View File

@ -532,6 +532,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.
*

View File

@ -673,11 +673,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
@ -756,15 +754,10 @@ 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
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;
@ -913,7 +906,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
@ -926,8 +919,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);
}
@ -971,15 +963,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;
}
@ -990,15 +983,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;
}

View File

@ -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;
@ -939,6 +943,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).

View File

@ -1323,42 +1323,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 +1360,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 +2388,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 +2434,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 +3242,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 +3294,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 +3305,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

@ -539,13 +539,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);