Implement memory64 for classic interpreter (#3266)

Adding a new cmake flag (cache variable) `WAMR_BUILD_MEMORY64` to enable
the memory64 feature, it can only be enabled on the 64-bit platform/target and
can only use software boundary check. And when it is enabled, it can support both
i32 and i64 linear memory types. The main modifications are:

- wasm loader & mini-loader: loading and bytecode validating process 
- wasm runtime: memory instantiating process
- classic-interpreter: wasm code executing process
- Support memory64 memory in related runtime APIs
- Modify main function type check when it's memory64 wasm file
- Modify `wasm_runtime_invoke_native` and `wasm_runtime_invoke_native_raw` to
  handle registered native function pointer argument when memory64 is enabled
- memory64 classic-interpreter spec test in `test_wamr.sh` and in CI

Currently, it supports memory64 memory wasm file that uses core spec
(including bulk memory proposal) opcodes and threads opcodes.

ps.
https://github.com/bytecodealliance/wasm-micro-runtime/issues/3091
https://github.com/bytecodealliance/wasm-micro-runtime/pull/3240
https://github.com/bytecodealliance/wasm-micro-runtime/pull/3260
This commit is contained in:
Wenyong Huang
2024-04-02 15:22:07 +08:00
committed by GitHub
parent 6b0b5de1c5
commit a23fa9f86c
22 changed files with 1084 additions and 342 deletions

View File

@ -286,6 +286,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
@ -299,9 +300,13 @@ wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail;
}
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check */
if (size > MAX_LINEAR_MEMORY_SIZE
|| app_offset > MAX_LINEAR_MEMORY_SIZE - size) {
if (size > max_linear_memory_size
|| app_offset > max_linear_memory_size - size) {
goto fail;
}
@ -324,7 +329,7 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
uint64 app_str_offset)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
uint64 app_end_offset;
uint64 app_end_offset, max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
char *str, *str_end;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
@ -338,10 +343,14 @@ wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
&app_end_offset))
goto fail;
#if WASM_ENABLE_MEMORY64 != 0
if (module_inst->memories[0]->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check, max start offset can only be size - 1, while end
* offset can be size */
if (app_str_offset >= MAX_LINEAR_MEMORY_SIZE
|| app_end_offset > MAX_LINEAR_MEMORY_SIZE)
if (app_str_offset >= max_linear_memory_size
|| app_end_offset > max_linear_memory_size)
goto fail;
str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
@ -364,6 +373,7 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
WASMMemoryInstance *memory_inst;
uint8 *addr = (uint8 *)native_ptr;
uint64 max_linear_memory_size = MAX_LINEAR_MEMORY_SIZE;
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|| module_inst_comm->module_type == Wasm_Module_AoT);
@ -377,8 +387,12 @@ wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
goto fail;
}
#if WASM_ENABLE_MEMORY64 != 0
if (memory_inst->is_memory64)
max_linear_memory_size = MAX_LINEAR_MEM64_MEMORY_SIZE;
#endif
/* boundary overflow check */
if (size > MAX_LINEAR_MEMORY_SIZE || (uintptr_t)addr > UINTPTR_MAX - size) {
if (size > max_linear_memory_size || (uintptr_t)addr > UINTPTR_MAX - size) {
goto fail;
}
@ -748,12 +762,13 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
goto return_func;
}
bh_assert(total_size_new <= MAX_LINEAR_MEMORY_SIZE);
bh_assert(total_size_new
<= GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64));
if (full_size_mmaped) {
#ifdef BH_PLATFORM_WINDOWS
if (!os_mem_commit(memory->memory_data_end,
(uint32)(total_size_new - total_size_old),
(mem_offset_t)(total_size_new - total_size_old),
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
ret = false;
goto return_func;
@ -761,12 +776,12 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
#endif
if (os_mprotect(memory->memory_data_end,
(uint32)(total_size_new - total_size_old),
(mem_offset_t)(total_size_new - total_size_old),
MMAP_PROT_READ | MMAP_PROT_WRITE)
!= 0) {
#ifdef BH_PLATFORM_WINDOWS
os_mem_decommit(memory->memory_data_end,
(uint32)(total_size_new - total_size_old));
(mem_offset_t)(total_size_new - total_size_old));
#endif
ret = false;
goto return_func;
@ -895,8 +910,9 @@ wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
int
wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
uint64 num_bytes_per_page, uint64 init_page_count,
uint64 max_page_count, uint64 *memory_data_size)
bool is_memory64, uint64 num_bytes_per_page,
uint64 init_page_count, uint64 max_page_count,
uint64 *memory_data_size)
{
uint64 map_size, page_size;
@ -925,7 +941,16 @@ wasm_allocate_linear_memory(uint8 **data, bool is_shared_memory,
page_size = os_getpagesize();
*memory_data_size = init_page_count * num_bytes_per_page;
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
#if WASM_ENABLE_MEMORY64 != 0
if (is_memory64) {
bh_assert(*memory_data_size <= MAX_LINEAR_MEM64_MEMORY_SIZE);
}
else
#endif
{
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
}
align_as_and_cast(*memory_data_size, page_size);
if (map_size > 0) {