Add support for multi-memory proposal in classic interpreter (#3742)

Implement multi-memory for classic-interpreter. Support core spec (and bulk memory) opcodes now,
and will support atomic opcodes, and add multi-memory export APIs in the future. 

PS: Multi-memory spec test patched a lot for linking test to adapt for multi-module implementation.
This commit is contained in:
Wenyong Huang 2024-08-21 12:22:23 +08:00 committed by GitHub
parent f4383a9e62
commit 1329e1d3e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 1658 additions and 262 deletions

View File

@ -68,6 +68,7 @@ env:
WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -S -b -P" WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -S -b -P"
GC_TEST_OPTIONS: "-s spec -G -b -P" GC_TEST_OPTIONS: "-s spec -G -b -P"
MEMORY64_TEST_OPTIONS: "-s spec -W -b -P" MEMORY64_TEST_OPTIONS: "-s spec -W -b -P"
MULTI_MEMORY_TEST_OPTIONS: "-s spec -E -b -P"
jobs: jobs:
build_llvm_libraries_on_ubuntu_2204: build_llvm_libraries_on_ubuntu_2204:
@ -148,6 +149,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1", "-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
] ]
os: [ubuntu-22.04] os: [ubuntu-22.04]
platform: [android, linux] platform: [android, linux]
@ -206,11 +208,9 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
# Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform # Memory64 only on CLASSIC INTERP and AOT mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1" - make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
@ -221,6 +221,21 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Multi memory only on CLASSIC INTERP mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
# Fast-JIT and Multi-Tier-JIT mode don't support android # Fast-JIT and Multi-Tier-JIT mode don't support android
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
platform: android platform: android
@ -593,6 +608,7 @@ jobs:
$WASI_TEST_OPTIONS, $WASI_TEST_OPTIONS,
$GC_TEST_OPTIONS, $GC_TEST_OPTIONS,
$MEMORY64_TEST_OPTIONS, $MEMORY64_TEST_OPTIONS,
$MULTI_MEMORY_TEST_OPTIONS,
] ]
wasi_sdk_release: wasi_sdk_release:
[ [
@ -640,18 +656,30 @@ jobs:
test_option: $MEMORY64_TEST_OPTIONS test_option: $MEMORY64_TEST_OPTIONS
- running_mode: "multi-tier-jit" - running_mode: "multi-tier-jit"
test_option: $MEMORY64_TEST_OPTIONS test_option: $MEMORY64_TEST_OPTIONS
# aot, fast-interp, fast-jit, llvm-jit, multi-tier-jit don't support Multi Memory
- running_mode: "aot"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "fast-interp"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "fast-jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS
steps: steps:
- name: checkout - name: checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set-up OCaml - name: Set-up OCaml
uses: ocaml/setup-ocaml@v3 uses: ocaml/setup-ocaml@v3
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS' if: matrix.test_option == '$GC_TEST_OPTIONS'
with: with:
ocaml-compiler: 4.13 ocaml-compiler: 4.13
- name: Set-up Ocamlbuild - name: Set-up Ocamlbuild
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS' if: matrix.test_option == '$GC_TEST_OPTIONS'
run: opam install ocamlbuild dune menhir run: opam install ocamlbuild dune menhir
- name: download and install wasi-sdk - name: download and install wasi-sdk
@ -717,13 +745,13 @@ jobs:
- name: run tests - name: run tests
timeout-minutes: 30 timeout-minutes: 30
if: matrix.test_option != '$GC_TEST_OPTIONS' && matrix.test_option != '$MEMORY64_TEST_OPTIONS' if: matrix.test_option != '$GC_TEST_OPTIONS'
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites working-directory: ./tests/wamr-test-suites
- name: run gc or memory64 tests - name: run gc tests
timeout-minutes: 20 timeout-minutes: 20
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS' if: matrix.test_option == '$GC_TEST_OPTIONS'
run: | run: |
eval $(opam env) eval $(opam env)
./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }} ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}

View File

@ -132,6 +132,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1", "-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
] ]
os: [ubuntu-20.04] os: [ubuntu-20.04]
platform: [android, linux] platform: [android, linux]
@ -190,11 +191,9 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1" make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
# Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform # Memory64 only on CLASSIC INTERP and AOT mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1" - make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS - make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
@ -205,6 +204,21 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS - make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Multi memory only on CLASSIC INTERP mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
# Fast-JIT and Multi-Tier-JIT mode don't support android # Fast-JIT and Multi-Tier-JIT mode don't support android
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
platform: android platform: android
@ -289,6 +303,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1", "-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
] ]
exclude: exclude:
# incompatible feature and platform # incompatible feature and platform
@ -322,6 +337,11 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS - make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1" make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Memory64 only on CLASSIC INTERP mode
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
steps: steps:
- name: Install dependencies - name: Install dependencies
run: | run: |

View File

@ -265,6 +265,11 @@ if (WAMR_BUILD_MEMORY64 EQUAL 1)
set (WAMR_DISABLE_HW_BOUND_CHECK 1) set (WAMR_DISABLE_HW_BOUND_CHECK 1)
message (" Memory64 memory enabled") message (" Memory64 memory enabled")
endif () endif ()
if (WAMR_BUILD_MULTI_MEMORY EQUAL 1)
add_definitions (-DWASM_ENABLE_MULTI_MEMORY=1)
message (" Multi memory enabled")
set (WAMR_BUILD_DEBUG_INTERP 0)
endif ()
if (WAMR_BUILD_THREAD_MGR EQUAL 1) if (WAMR_BUILD_THREAD_MGR EQUAL 1)
message (" Thread manager enabled") message (" Thread manager enabled")
endif () endif ()

View File

@ -664,6 +664,11 @@
#define WASM_ENABLE_MEMORY64 0 #define WASM_ENABLE_MEMORY64 0
#endif #endif
/* Disable multi-memory by default */
#ifndef WASM_ENABLE_MULTI_MEMORY
#define WASM_ENABLE_MULTI_MEMORY 0
#endif
#ifndef WASM_TABLE_MAX_SIZE #ifndef WASM_TABLE_MAX_SIZE
#define WASM_TABLE_MAX_SIZE 1024 #define WASM_TABLE_MAX_SIZE 1024
#endif #endif

View File

@ -2817,6 +2817,13 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
return wasm_enlarge_memory(module_inst, inc_page_count); return wasm_enlarge_memory(module_inst, inc_page_count);
} }
bool
aot_enlarge_memory_with_idx(AOTModuleInstance *module_inst,
uint32 inc_page_count, uint32 memidx)
{
return wasm_enlarge_memory_with_idx(module_inst, inc_page_count, memidx);
}
bool bool
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc, aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
uint32 *argv) uint32 *argv)

View File

@ -605,6 +605,10 @@ aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
bool bool
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count); aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count);
bool
aot_enlarge_memory_with_idx(AOTModuleInstance *module_inst,
uint32 inc_page_count, uint32 memidx);
/** /**
* Invoke native function from aot code * Invoke native function from aot code
*/ */

View File

@ -670,6 +670,16 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
return NULL; return NULL;
} }
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
return NULL;
}
void void
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory, wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
uint64 memory_data_size) uint64 memory_data_size)
@ -747,9 +757,14 @@ wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size)
} }
bool bool
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count) wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
uint32 memidx)
{ {
#if WASM_ENABLE_MULTI_MEMORY != 0
WASMMemoryInstance *memory = wasm_get_memory_with_idx(module, memidx);
#else
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
#endif
uint8 *memory_data_old, *memory_data_new, *heap_data_old; uint8 *memory_data_old, *memory_data_new, *heap_data_old;
uint32 num_bytes_per_page, heap_size; uint32 num_bytes_per_page, heap_size;
uint32 cur_page_count, max_page_count, total_page_count; uint32 cur_page_count, max_page_count, total_page_count;
@ -960,7 +975,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
if (module->memory_count > 0) if (module->memory_count > 0)
shared_memory_lock(module->memories[0]); shared_memory_lock(module->memories[0]);
#endif #endif
ret = wasm_enlarge_memory_internal(module, inc_page_count); ret = wasm_enlarge_memory_internal(module, inc_page_count, 0);
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (module->memory_count > 0) if (module->memory_count > 0)
shared_memory_unlock(module->memories[0]); shared_memory_unlock(module->memories[0]);
@ -969,6 +984,25 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return ret; return ret;
} }
bool
wasm_enlarge_memory_with_idx(WASMModuleInstance *module, uint32 inc_page_count,
uint32 memidx)
{
bool ret = false;
#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);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (memidx < module->memory_count)
shared_memory_unlock(module->memories[memidx]);
#endif
return ret;
}
void void
wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst) wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
{ {

View File

@ -181,15 +181,36 @@ static RunningMode runtime_running_mode = Mode_Default;
of signal handler */ of signal handler */
static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL; static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
static bool
is_sig_addr_in_guard_pages(void *sig_addr, WASMModuleInstance *module_inst)
{
WASMMemoryInstance *memory_inst;
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
uint32 i;
for (i = 0; i < module_inst->memory_count; ++i) {
/* To be compatible with multi memory, get the ith memory instance */
memory_inst = wasm_get_memory_with_idx(module_inst, i);
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
if (mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr) {
/* The address which causes segmentation fault is inside
the memory instance's guard regions */
return true;
}
}
return false;
}
#ifndef BH_PLATFORM_WINDOWS #ifndef BH_PLATFORM_WINDOWS
static void static void
runtime_signal_handler(void *sig_addr) runtime_signal_handler(void *sig_addr)
{ {
WASMModuleInstance *module_inst; WASMModuleInstance *module_inst;
WASMMemoryInstance *memory_inst;
WASMJmpBuf *jmpbuf_node; WASMJmpBuf *jmpbuf_node;
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
uint32 page_size = os_getpagesize(); uint32 page_size = os_getpagesize();
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
uint8 *stack_min_addr; uint8 *stack_min_addr;
@ -201,23 +222,13 @@ runtime_signal_handler(void *sig_addr)
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) { && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
/* Get mapped mem info of current instance */ /* Get mapped mem info of current instance */
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst; module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
/* Get the default memory instance */
memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst) {
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
}
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
/* Get stack info of current thread */ /* Get stack info of current thread */
stack_min_addr = os_thread_get_stack_boundary(); stack_min_addr = os_thread_get_stack_boundary();
#endif #endif
if (memory_inst if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) {
&& (mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr)) {
/* The address which causes segmentation fault is inside
the memory instance's guard regions */
wasm_set_exception(module_inst, "out of bounds memory access"); wasm_set_exception(module_inst, "out of bounds memory access");
os_longjmp(jmpbuf_node->jmpbuf, 1); os_longjmp(jmpbuf_node->jmpbuf, 1);
} }
@ -340,16 +351,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) { && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst; module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
/* Get the default memory instance */ if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) {
memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst) {
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr =
memory_inst->memory_data + 8 * (uint64)BH_GB;
}
if (memory_inst && mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr) {
/* The address which causes segmentation fault is inside /* The address which causes segmentation fault is inside
the memory instance's guard regions. the memory instance's guard regions.
Set exception and let the wasm func continue to run, when Set exception and let the wasm func continue to run, when

View File

@ -540,6 +540,7 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
/* TODO: create import memories */ /* TODO: create import memories */
/* Allocate memory for memory array, reserve one AOTMemory space at least */ /* Allocate memory for memory array, reserve one AOTMemory space at least */
/* TODO: multi-memory */
if (!comp_data->memory_count) if (!comp_data->memory_count)
comp_data->memory_count = 1; comp_data->memory_count = 1;

View File

@ -895,6 +895,7 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
POP_PAGE_COUNT(delta); POP_PAGE_COUNT(delta);
/* TODO: multi-memory aot_enlarge_memory_with_idx() */
/* Function type of aot_enlarge_memory() */ /* Function type of aot_enlarge_memory() */
param_types[0] = INT8_PTR_TYPE; param_types[0] = INT8_PTR_TYPE;
param_types[1] = I32_TYPE; param_types[1] = I32_TYPE;

View File

@ -602,6 +602,7 @@ jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
args[0] = get_module_inst_reg(cc->jit_frame); args[0] = get_module_inst_reg(cc->jit_frame);
args[1] = inc_page_count; args[1] = inc_page_count;
/* TODO: multi-memory wasm_enlarge_memory_with_idx() */
if (!jit_emit_callnative(cc, wasm_enlarge_memory, grow_res, args, 2)) { if (!jit_emit_callnative(cc, wasm_enlarge_memory, grow_res, args, 2)) {
goto fail; goto fail;
} }

View File

@ -94,6 +94,14 @@ extern "C" {
#define SHARED_MEMORY_FLAG 0x02 #define SHARED_MEMORY_FLAG 0x02
#define MEMORY64_FLAG 0x04 #define MEMORY64_FLAG 0x04
/**
* In the multi-memory proposal, the memarg in loads and stores are
* reinterpreted as a bitfield, bit 6 serves as a flag indicating the presence
* of the optional memory index, if it is set, then an i32 memory index follows
* after the alignment bitfield
*/
#define OPT_MEMIDX_FLAG 0x40
#define DEFAULT_NUM_BYTES_PER_PAGE 65536 #define DEFAULT_NUM_BYTES_PER_PAGE 65536
#define DEFAULT_MAX_PAGES 65536 #define DEFAULT_MAX_PAGES 65536
#define DEFAULT_MEM64_MAX_PAGES UINT32_MAX #define DEFAULT_MEM64_MAX_PAGES UINT32_MAX

View File

@ -697,6 +697,44 @@ wasm_interp_get_frame_ref(WASMInterpFrame *frame)
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res) #define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
#endif #endif
#if WASM_ENABLE_MULTI_MEMORY != 0
/* If the current memidx differs than the last cached one,
* update memory related information */
#define read_leb_memidx(p, p_end, res) \
do { \
read_leb_uint32(p, p_end, res); \
if (res != memidx_cached) { \
memory = wasm_get_memory_with_idx(module, res); \
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); \
memidx_cached = res; \
} \
} while (0)
/* First read the alignment, then if it has flag indicating following memidx,
* read and update memory related information, if it differs than the
* last(cached) one. If it doesn't have flag reset the
* memory instance to the default memories[0] */
#define read_leb_memarg(p, p_end, res) \
do { \
read_leb_uint32(p, p_end, res); \
if (!(res & OPT_MEMIDX_FLAG)) \
memidx = 0; \
else \
read_leb_uint32(p, p_end, memidx); \
if (memidx != memidx_cached) { \
memory = wasm_get_memory_with_idx(module, memidx); \
linear_mem_size = GET_LINEAR_MEMORY_SIZE(memory); \
memidx_cached = memidx; \
} \
} while (0)
#else
#define read_leb_memarg(p, p_end, res) \
do { \
read_leb_uint32(p, p_end, res); \
(void)res; \
} while (0)
#define read_leb_memidx(p, p_end, res) read_leb_memarg(p, p_end, res)
#endif
#if WASM_ENABLE_LABELS_AS_VALUES == 0 #if WASM_ENABLE_LABELS_AS_VALUES == 0
#define RECOVER_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func) #define RECOVER_FRAME_IP_END() frame_ip_end = wasm_get_func_code_end(cur_func)
#else #else
@ -1567,6 +1605,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
if (memory) if (memory)
is_memory64 = memory->is_memory64; is_memory64 = memory->is_memory64;
#endif #endif
#if WASM_ENABLE_MULTI_MEMORY != 0
uint32 memidx = 0;
uint32 memidx_cached = (uint32)-1;
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0 #if WASM_ENABLE_DEBUG_INTERP != 0
uint8 *frame_ip_orig = NULL; uint8 *frame_ip_orig = NULL;
@ -4292,13 +4334,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
PUSH_I32(LOAD_I32(maddr)); PUSH_I32(LOAD_I32(maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4308,13 +4349,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(8); CHECK_MEMORY_OVERFLOW(8);
PUSH_I64(LOAD_I64(maddr)); PUSH_I64(LOAD_I64(maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4323,13 +4363,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
PUSH_I32(sign_ext_8_32(*(int8 *)maddr)); PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4338,13 +4377,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
PUSH_I32((uint32)(*(uint8 *)maddr)); PUSH_I32((uint32)(*(uint8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4353,13 +4391,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
PUSH_I32(sign_ext_16_32(LOAD_I16(maddr))); PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4368,13 +4405,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
PUSH_I32((uint32)(LOAD_U16(maddr))); PUSH_I32((uint32)(LOAD_U16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4383,13 +4419,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
PUSH_I64(sign_ext_8_64(*(int8 *)maddr)); PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4398,13 +4433,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(1); CHECK_MEMORY_OVERFLOW(1);
PUSH_I64((uint64)(*(uint8 *)maddr)); PUSH_I64((uint64)(*(uint8 *)maddr));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4413,13 +4447,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
PUSH_I64(sign_ext_16_64(LOAD_I16(maddr))); PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4428,13 +4461,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(2); CHECK_MEMORY_OVERFLOW(2);
PUSH_I64((uint64)(LOAD_U16(maddr))); PUSH_I64((uint64)(LOAD_U16(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4443,14 +4475,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
opcode = *(frame_ip - 1); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_uint32(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
PUSH_I64(sign_ext_32_64(LOAD_I32(maddr))); PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4459,13 +4489,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
CHECK_MEMORY_OVERFLOW(4); CHECK_MEMORY_OVERFLOW(4);
PUSH_I64((uint64)(LOAD_U32(maddr))); PUSH_I64((uint64)(LOAD_U32(maddr)));
CHECK_READ_WATCHPOINT(addr, offset); CHECK_READ_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4476,7 +4505,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp--; frame_sp--;
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4491,7 +4520,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
STORE_U32(maddr, frame_sp[1]); STORE_U32(maddr, frame_sp[1]);
} }
CHECK_WRITE_WATCHPOINT(addr, offset); CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4501,7 +4529,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 flags; uint32 flags;
mem_offset_t offset, addr; mem_offset_t offset, addr;
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
frame_sp -= 2; frame_sp -= 2;
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4519,7 +4547,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
GET_I64_FROM_ADDR(frame_sp + 1)); GET_I64_FROM_ADDR(frame_sp + 1));
} }
CHECK_WRITE_WATCHPOINT(addr, offset); CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4531,7 +4558,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint32 sval; uint32 sval;
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint32)POP_I32(); sval = (uint32)POP_I32();
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4545,7 +4572,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
STORE_U16(maddr, (uint16)sval); STORE_U16(maddr, (uint16)sval);
} }
CHECK_WRITE_WATCHPOINT(addr, offset); CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -4558,7 +4584,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint64 sval; uint64 sval;
opcode = *(frame_ip - 1); opcode = *(frame_ip - 1);
read_leb_uint32(frame_ip, frame_ip_end, flags); read_leb_memarg(frame_ip, frame_ip_end, flags);
read_leb_mem_offset(frame_ip, frame_ip_end, offset); read_leb_mem_offset(frame_ip, frame_ip_end, offset);
sval = (uint64)POP_I64(); sval = (uint64)POP_I64();
addr = POP_MEM_OFFSET(); addr = POP_MEM_OFFSET();
@ -4576,29 +4602,27 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
STORE_U32(maddr, (uint32)sval); STORE_U32(maddr, (uint32)sval);
} }
CHECK_WRITE_WATCHPOINT(addr, offset); CHECK_WRITE_WATCHPOINT(addr, offset);
(void)flags;
HANDLE_OP_END(); HANDLE_OP_END();
} }
/* memory size and memory grow instructions */ /* memory size and memory grow instructions */
HANDLE_OP(WASM_OP_MEMORY_SIZE) HANDLE_OP(WASM_OP_MEMORY_SIZE)
{ {
uint32 reserved; uint32 mem_idx;
read_leb_uint32(frame_ip, frame_ip_end, reserved); read_leb_memidx(frame_ip, frame_ip_end, mem_idx);
PUSH_PAGE_COUNT(memory->cur_page_count); PUSH_PAGE_COUNT(memory->cur_page_count);
(void)reserved;
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_MEMORY_GROW) HANDLE_OP(WASM_OP_MEMORY_GROW)
{ {
uint32 reserved, delta, uint32 mem_idx, delta, prev_page_count;
prev_page_count = memory->cur_page_count;
read_leb_uint32(frame_ip, frame_ip_end, reserved); read_leb_memidx(frame_ip, frame_ip_end, mem_idx);
prev_page_count = memory->cur_page_count;
delta = (uint32)POP_PAGE_COUNT(); delta = (uint32)POP_PAGE_COUNT();
if (!wasm_enlarge_memory(module, delta)) { if (!wasm_enlarge_memory_with_idx(module, delta, mem_idx)) {
/* failed to memory.grow, return -1 */ /* failed to memory.grow, return -1 */
PUSH_PAGE_COUNT(-1); PUSH_PAGE_COUNT(-1);
} }
@ -4614,7 +4638,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#endif #endif
} }
(void)reserved;
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -5610,8 +5633,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
uint8 *data; uint8 *data;
read_leb_uint32(frame_ip, frame_ip_end, segment); read_leb_uint32(frame_ip, frame_ip_end, segment);
#if WASM_ENABLE_MULTI_MEMORY != 0
read_leb_memidx(frame_ip, frame_ip_end, memidx);
#else
/* skip memory index */ /* skip memory index */
frame_ip++; frame_ip++;
#endif
bytes = (uint64)(uint32)POP_I32(); bytes = (uint64)(uint32)POP_I32();
offset = (uint64)(uint32)POP_I32(); offset = (uint64)(uint32)POP_I32();
@ -5660,33 +5687,54 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
mem_offset_t dst, src, len; mem_offset_t dst, src, len;
uint8 *mdst, *msrc; uint8 *mdst, *msrc;
uint64 dlen;
frame_ip += 2;
len = POP_MEM_OFFSET(); len = POP_MEM_OFFSET();
src = POP_MEM_OFFSET(); src = POP_MEM_OFFSET();
dst = POP_MEM_OFFSET(); dst = POP_MEM_OFFSET();
#if WASM_ENABLE_MULTI_MEMORY != 0
/* dst memidx */
read_leb_memidx(frame_ip, frame_ip_end, memidx);
#else
/* skip dst memidx */
frame_ip += 1;
#endif
#if WASM_ENABLE_THREAD_MGR != 0 #if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = get_linear_mem_size(); linear_mem_size = get_linear_mem_size();
#endif #endif
/* dst boundary check */
#ifndef OS_ENABLE_HW_BOUND_CHECK #ifndef OS_ENABLE_HW_BOUND_CHECK
CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
#else #else
if ((uint64)(uint32)src + len > linear_mem_size) if ((uint64)dst + len > linear_mem_size)
goto out_of_bounds; goto out_of_bounds;
msrc = memory->memory_data + (uint32)src; mdst = memory->memory_data + dst;
#endif
dlen = linear_mem_size - dst;
if ((uint64)(uint32)dst + len > linear_mem_size) #if WASM_ENABLE_MULTI_MEMORY != 0
/* src memidx */
read_leb_memidx(frame_ip, frame_ip_end, memidx);
#else
/* skip src memidx */
frame_ip += 1;
#endif
#if WASM_ENABLE_THREAD_MGR != 0
linear_mem_size = get_linear_mem_size();
#endif
/* src boundary check */
#ifndef OS_ENABLE_HW_BOUND_CHECK
CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
#else
if ((uint64)src + len > linear_mem_size)
goto out_of_bounds; goto out_of_bounds;
mdst = memory->memory_data + (uint32)dst; msrc = memory->memory_data + src;
#endif #endif
/* allowing the destination and source to overlap */
#if WASM_ENABLE_MEMORY64 == 0 #if WASM_ENABLE_MEMORY64 == 0
bh_memmove_s(mdst, (uint32)(linear_mem_size - dst), /* allowing the destination and source to overlap */
msrc, (uint32)len); bh_memmove_s(mdst, (uint32)dlen, msrc, (uint32)len);
#else #else
/* use memmove when memory64 is enabled since len /* use memmove when memory64 is enabled since len
may be larger than UINT32_MAX */ may be larger than UINT32_MAX */
@ -5698,7 +5746,13 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
mem_offset_t dst, len; mem_offset_t dst, len;
uint8 fill_val, *mdst; uint8 fill_val, *mdst;
#if WASM_ENABLE_MULTI_MEMORY != 0
read_leb_memidx(frame_ip, frame_ip_end, memidx);
#else
/* skip memory index */
frame_ip++; frame_ip++;
#endif
len = POP_MEM_OFFSET(); len = POP_MEM_OFFSET();
fill_val = POP_I32(); fill_val = POP_I32();

View File

@ -3837,6 +3837,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr_ret = GET_OFFSET(); addr_ret = GET_OFFSET();
delta = (uint32)frame_lp[addr1]; delta = (uint32)frame_lp[addr1];
/* TODO: multi-memory wasm_enlarge_memory_with_idx() */
if (!wasm_enlarge_memory(module, delta)) { if (!wasm_enlarge_memory(module, delta)) {
/* failed to memory.grow, return -1 */ /* failed to memory.grow, return -1 */
frame_lp[addr_ret] = -1; frame_lp[addr_ret] = -1;

View File

@ -127,6 +127,17 @@ check_buf1(const uint8 *buf, const uint8 *buf_end, uint32 length,
#define skip_leb_uint32(p, p_end) skip_leb(p) #define skip_leb_uint32(p, p_end) skip_leb(p)
#define skip_leb_int32(p, p_end) skip_leb(p) #define skip_leb_int32(p, p_end) skip_leb(p)
#define skip_leb_mem_offset(p, p_end) skip_leb(p) #define skip_leb_mem_offset(p, p_end) skip_leb(p)
#define skip_leb_memidx(p, p_end) skip_leb(p)
#if WASM_ENABLE_MULTI_MEMORY == 0
#define skip_leb_align(p, p_end) skip_leb(p)
#else
/* Skip the following memidx if applicable */
#define skip_leb_align(p, p_end) \
do { \
if (*p++ & OPT_MEMIDX_FLAG) \
skip_leb_uint32(p, p_end); \
} while (0)
#endif
#define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p) #define read_uint8(p) TEMPLATE_READ_VALUE(uint8, p)
#define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p) #define read_uint32(p) TEMPLATE_READ_VALUE(uint32, p)
@ -173,6 +184,40 @@ check_buf1(const uint8 *buf, const uint8 *buf_end, uint32 length,
res = (int32)res64; \ res = (int32)res64; \
} while (0) } while (0)
#define read_leb_memidx(p, p_end, res) read_leb_uint32(p, p_end, res)
#if WASM_ENABLE_MULTI_MEMORY != 0
#define check_memidx(module, memidx) \
do { \
if (memidx >= module->import_memory_count + module->memory_count) { \
set_error_buf_v(error_buf, error_buf_size, "unknown memory %d", \
memidx); \
goto fail; \
} \
} while (0)
/* Bit 6(0x40) indicating the optional memidx, and reset bit 6 for
* alignment check */
#define read_leb_memarg(p, p_end, res) \
do { \
read_leb_uint32(p, p_end, res); \
if (res & OPT_MEMIDX_FLAG) { \
res &= ~OPT_MEMIDX_FLAG; \
read_leb_uint32(p, p_end, memidx); /* memidx */ \
check_memidx(module, memidx); \
} \
} while (0)
#else
/* reserved byte 0x00 */
#define check_memidx(module, memidx) \
do { \
(void)module; \
if (memidx != 0) { \
set_error_buf(error_buf, error_buf_size, "zero byte expected"); \
goto fail; \
} \
} while (0)
#define read_leb_memarg(p, p_end, res) read_leb_uint32(p, p_end, res)
#endif
static char * static char *
type2str(uint8 type) type2str(uint8 type)
{ {
@ -3288,11 +3333,13 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (flags & 1) if (flags & 1)
read_leb_uint32(p, p_end, u32); read_leb_uint32(p, p_end, u32);
module->import_memory_count++; module->import_memory_count++;
#if WASM_ENABLE_MULTI_MEMORY == 0
if (module->import_memory_count > 1) { if (module->import_memory_count > 1) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"multiple memories"); "multiple memories");
return false; return false;
} }
#endif
break; break;
#if WASM_ENABLE_TAGS != 0 #if WASM_ENABLE_TAGS != 0
@ -3903,11 +3950,14 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
WASMMemory *memory; WASMMemory *memory;
read_leb_uint32(p, p_end, memory_count); read_leb_uint32(p, p_end, memory_count);
#if WASM_ENABLE_MULTI_MEMORY == 0
/* a total of one memory is allowed */ /* a total of one memory is allowed */
if (module->import_memory_count + memory_count > 1) { if (module->import_memory_count + memory_count > 1) {
set_error_buf(error_buf, error_buf_size, "multiple memories"); set_error_buf(error_buf, error_buf_size, "multiple memories");
return false; return false;
} }
#endif
if (memory_count) { if (memory_count) {
module->memory_count = memory_count; module->memory_count = memory_count;
@ -7258,13 +7308,13 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
case WASM_OP_I64_STORE8: case WASM_OP_I64_STORE8:
case WASM_OP_I64_STORE16: case WASM_OP_I64_STORE16:
case WASM_OP_I64_STORE32: case WASM_OP_I64_STORE32:
skip_leb_uint32(p, p_end); /* align */ skip_leb_align(p, p_end); /* align */
skip_leb_mem_offset(p, p_end); /* offset */ skip_leb_mem_offset(p, p_end); /* offset */
break; break;
case WASM_OP_MEMORY_SIZE: case WASM_OP_MEMORY_SIZE:
case WASM_OP_MEMORY_GROW: case WASM_OP_MEMORY_GROW:
skip_leb_uint32(p, p_end); /* 0x00 */ skip_leb_memidx(p, p_end); /* memidx */
break; break;
case WASM_OP_I32_CONST: case WASM_OP_I32_CONST:
@ -7562,19 +7612,17 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
case WASM_OP_MEMORY_INIT: case WASM_OP_MEMORY_INIT:
skip_leb_uint32(p, p_end); skip_leb_uint32(p, p_end);
/* skip memory idx */ skip_leb_memidx(p, p_end);
p++;
break; break;
case WASM_OP_DATA_DROP: case WASM_OP_DATA_DROP:
skip_leb_uint32(p, p_end); skip_leb_uint32(p, p_end);
break; break;
case WASM_OP_MEMORY_COPY: case WASM_OP_MEMORY_COPY:
/* skip two memory idx */ skip_leb_memidx(p, p_end);
p += 2; skip_leb_memidx(p, p_end);
break; break;
case WASM_OP_MEMORY_FILL: case WASM_OP_MEMORY_FILL:
/* skip memory idx */ skip_leb_memidx(p, p_end);
p++;
break; break;
#endif /* WASM_ENABLE_BULK_MEMORY */ #endif /* WASM_ENABLE_BULK_MEMORY */
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -7701,7 +7749,6 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
case WASM_OP_ATOMIC_PREFIX: case WASM_OP_ATOMIC_PREFIX:
{ {
/* TODO: memory64 offset type changes */
uint32 opcode1; uint32 opcode1;
/* atomic_op (u32_leb) + memarg (2 u32_leb) */ /* atomic_op (u32_leb) + memarg (2 u32_leb) */
@ -10876,6 +10923,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
#else #else
mem_offset_type = VALUE_TYPE_I32; mem_offset_type = VALUE_TYPE_I32;
#endif #endif
uint32 memidx;
global_count = module->import_global_count + module->global_count; global_count = module->import_global_count + module->global_count;
@ -13155,7 +13203,7 @@ re_scan:
} }
#endif #endif
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_memarg(p, p_end, align); /* align */
read_leb_mem_offset(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
if (!check_memory_access_align(opcode, align, error_buf, if (!check_memory_access_align(opcode, align, error_buf,
error_buf_size)) { error_buf_size)) {
@ -13221,12 +13269,8 @@ re_scan:
case WASM_OP_MEMORY_SIZE: case WASM_OP_MEMORY_SIZE:
CHECK_MEMORY(); CHECK_MEMORY();
/* reserved byte 0x00 */ read_leb_uint32(p, p_end, memidx);
if (*p++ != 0x00) { check_memidx(module, memidx);
set_error_buf(error_buf, error_buf_size,
"zero byte expected");
goto fail;
}
PUSH_PAGE_COUNT(); PUSH_PAGE_COUNT();
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -13237,12 +13281,8 @@ re_scan:
case WASM_OP_MEMORY_GROW: case WASM_OP_MEMORY_GROW:
CHECK_MEMORY(); CHECK_MEMORY();
/* reserved byte 0x00 */ read_leb_uint32(p, p_end, memidx);
if (*p++ != 0x00) { check_memidx(module, memidx);
set_error_buf(error_buf, error_buf_size,
"zero byte expected");
goto fail;
}
POP_AND_PUSH(mem_offset_type, mem_offset_type); POP_AND_PUSH(mem_offset_type, mem_offset_type);
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -14594,8 +14634,8 @@ re_scan:
&& module->memory_count == 0) && module->memory_count == 0)
goto fail_unknown_memory; goto fail_unknown_memory;
if (*p++ != 0x00) read_leb_uint32(p, p_end, memidx);
goto fail_zero_byte_expected; check_memidx(module, memidx);
if (data_seg_idx >= module->data_seg_count) { if (data_seg_idx >= module->data_seg_count) {
set_error_buf_v(error_buf, error_buf_size, set_error_buf_v(error_buf, error_buf_size,
@ -14644,10 +14684,11 @@ re_scan:
case WASM_OP_MEMORY_COPY: case WASM_OP_MEMORY_COPY:
{ {
CHECK_BUF(p, p_end, sizeof(int16)); CHECK_BUF(p, p_end, sizeof(int16));
/* both src and dst memory index should be 0 */ /* check both src and dst memory index */
if (*(int16 *)p != 0x0000) read_leb_uint32(p, p_end, memidx);
goto fail_zero_byte_expected; check_memidx(module, memidx);
p += 2; read_leb_uint32(p, p_end, memidx);
check_memidx(module, memidx);
if (module->import_memory_count == 0 if (module->import_memory_count == 0
&& module->memory_count == 0) && module->memory_count == 0)
@ -14666,9 +14707,8 @@ re_scan:
} }
case WASM_OP_MEMORY_FILL: case WASM_OP_MEMORY_FILL:
{ {
if (*p++ != 0x00) { read_leb_uint32(p, p_end, memidx);
goto fail_zero_byte_expected; check_memidx(module, memidx);
}
if (module->import_memory_count == 0 if (module->import_memory_count == 0
&& module->memory_count == 0) { && module->memory_count == 0) {
goto fail_unknown_memory; goto fail_unknown_memory;
@ -14684,10 +14724,6 @@ re_scan:
#endif #endif
break; break;
} }
fail_zero_byte_expected:
set_error_buf(error_buf, error_buf_size,
"zero byte expected");
goto fail;
fail_unknown_memory: fail_unknown_memory:
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
@ -14921,7 +14957,6 @@ re_scan:
#if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0) #if (WASM_ENABLE_WAMR_COMPILER != 0) || (WASM_ENABLE_JIT != 0)
case WASM_OP_SIMD_PREFIX: case WASM_OP_SIMD_PREFIX:
{ {
/* TODO: memory64 offset type changes */
uint32 opcode1; uint32 opcode1;
#if WASM_ENABLE_WAMR_COMPILER != 0 #if WASM_ENABLE_WAMR_COMPILER != 0

View File

@ -62,6 +62,17 @@ set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
#define skip_leb_uint32(p, p_end) skip_leb(p) #define skip_leb_uint32(p, p_end) skip_leb(p)
#define skip_leb_int32(p, p_end) skip_leb(p) #define skip_leb_int32(p, p_end) skip_leb(p)
#define skip_leb_mem_offset(p, p_end) skip_leb(p) #define skip_leb_mem_offset(p, p_end) skip_leb(p)
#define skip_leb_memidx(p, p_end) skip_leb(p)
#if WASM_ENABLE_MULTI_MEMORY == 0
#define skip_leb_align(p, p_end) skip_leb(p)
#else
/* Skip the following memidx if applicable */
#define skip_leb_align(p, p_end) \
do { \
if (*p++ & OPT_MEMIDX_FLAG) \
skip_leb_uint32(p, p_end); \
} while (0)
#endif
static bool static bool
is_32bit_type(uint8 type) is_32bit_type(uint8 type)
@ -132,6 +143,35 @@ is_byte_a_type(uint8 type)
#else #else
#define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res) #define read_leb_mem_offset(p, p_end, res) read_leb_uint32(p, p_end, res)
#endif #endif
#define read_leb_memidx(p, p_end, res) read_leb_uint32(p, p_end, res)
#if WASM_ENABLE_MULTI_MEMORY != 0
#define check_memidx(module, memidx) \
do { \
bh_assert(memidx \
< module->import_memory_count + module->memory_count); \
(void)memidx; \
} while (0)
/* Bit 6 indicating the optional memidx, and reset bit 6 for
* alignment check */
#define read_leb_memarg(p, p_end, res) \
do { \
read_leb_uint32(p, p_end, res); \
if (res & OPT_MEMIDX_FLAG) { \
res &= ~OPT_MEMIDX_FLAG; \
read_leb_uint32(p, p_end, memidx); /* memidx */ \
check_memidx(module, memidx); \
} \
} while (0)
#else
/* reserved byte 0x00 */
#define check_memidx(module, memidx) \
do { \
(void)module; \
bh_assert(memidx == 0); \
(void)memidx; \
} while (0)
#define read_leb_memarg(p, p_end, res) read_leb_uint32(p, p_end, res)
#endif
static void * static void *
loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size) loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
@ -882,7 +922,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
if (flags & 1) if (flags & 1)
read_leb_uint32(p, p_end, u32); read_leb_uint32(p, p_end, u32);
module->import_memory_count++; module->import_memory_count++;
#if WASM_ENABLE_MULTI_MEMORY != 0
bh_assert(module->import_memory_count <= 1); bh_assert(module->import_memory_count <= 1);
#endif
break; break;
case IMPORT_KIND_GLOBAL: /* import global */ case IMPORT_KIND_GLOBAL: /* import global */
@ -1223,7 +1265,9 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
WASMMemory *memory; WASMMemory *memory;
read_leb_uint32(p, p_end, memory_count); read_leb_uint32(p, p_end, memory_count);
#if WASM_ENABLE_MULTI_MEMORY != 0
bh_assert(module->import_memory_count + memory_count <= 1); bh_assert(module->import_memory_count + memory_count <= 1);
#endif
if (memory_count) { if (memory_count) {
module->memory_count = memory_count; module->memory_count = memory_count;
@ -3585,13 +3629,13 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
case WASM_OP_I64_STORE8: case WASM_OP_I64_STORE8:
case WASM_OP_I64_STORE16: case WASM_OP_I64_STORE16:
case WASM_OP_I64_STORE32: case WASM_OP_I64_STORE32:
skip_leb_uint32(p, p_end); /* align */ skip_leb_align(p, p_end); /* align */
skip_leb_mem_offset(p, p_end); /* offset */ skip_leb_mem_offset(p, p_end); /* offset */
break; break;
case WASM_OP_MEMORY_SIZE: case WASM_OP_MEMORY_SIZE:
case WASM_OP_MEMORY_GROW: case WASM_OP_MEMORY_GROW:
skip_leb_uint32(p, p_end); /* 0x00 */ skip_leb_memidx(p, p_end); /* memidx */
break; break;
case WASM_OP_I32_CONST: case WASM_OP_I32_CONST:
@ -3758,19 +3802,17 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
case WASM_OP_MEMORY_INIT: case WASM_OP_MEMORY_INIT:
skip_leb_uint32(p, p_end); skip_leb_uint32(p, p_end);
/* skip memory idx */ skip_leb_memidx(p, p_end);
p++;
break; break;
case WASM_OP_DATA_DROP: case WASM_OP_DATA_DROP:
skip_leb_uint32(p, p_end); skip_leb_uint32(p, p_end);
break; break;
case WASM_OP_MEMORY_COPY: case WASM_OP_MEMORY_COPY:
/* skip two memory idx */ skip_leb_memidx(p, p_end);
p += 2; skip_leb_memidx(p, p_end);
break; break;
case WASM_OP_MEMORY_FILL: case WASM_OP_MEMORY_FILL:
/* skip memory idx */ skip_leb_memidx(p, p_end);
p++;
break; break;
#endif #endif
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
@ -5905,7 +5947,7 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint8 *param_types, *local_types, local_type, global_type, mem_offset_type; uint8 *param_types, *local_types, local_type, global_type, mem_offset_type;
BlockType func_block_type; BlockType func_block_type;
uint16 *local_offsets, local_offset; uint16 *local_offsets, local_offset;
uint32 count, local_idx, global_idx, u32, align, i; uint32 count, local_idx, global_idx, u32, align, i, memidx;
mem_offset_t mem_offset; mem_offset_t mem_offset;
int32 i32, i32_const = 0; int32 i32, i32_const = 0;
int64 i64_const; int64 i64_const;
@ -7267,7 +7309,7 @@ re_scan:
} }
#endif #endif
CHECK_MEMORY(); CHECK_MEMORY();
read_leb_uint32(p, p_end, align); /* align */ read_leb_memarg(p, p_end, align); /* align */
read_leb_mem_offset(p, p_end, mem_offset); /* offset */ read_leb_mem_offset(p, p_end, mem_offset); /* offset */
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_uint32(loader_ctx, mem_offset); emit_uint32(loader_ctx, mem_offset);
@ -7329,9 +7371,8 @@ re_scan:
case WASM_OP_MEMORY_SIZE: case WASM_OP_MEMORY_SIZE:
CHECK_MEMORY(); CHECK_MEMORY();
/* reserved byte 0x00 */ read_leb_memidx(p, p_end, memidx);
bh_assert(*p == 0x00); check_memidx(module, memidx);
p++;
PUSH_PAGE_COUNT(); PUSH_PAGE_COUNT();
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -7342,9 +7383,8 @@ re_scan:
case WASM_OP_MEMORY_GROW: case WASM_OP_MEMORY_GROW:
CHECK_MEMORY(); CHECK_MEMORY();
/* reserved byte 0x00 */ read_leb_memidx(p, p_end, memidx);
bh_assert(*p == 0x00); check_memidx(module, memidx);
p++;
POP_AND_PUSH(mem_offset_type, mem_offset_type); POP_AND_PUSH(mem_offset_type, mem_offset_type);
module->possible_memory_grow = true; module->possible_memory_grow = true;
@ -7682,16 +7722,13 @@ re_scan:
#if WASM_ENABLE_BULK_MEMORY != 0 #if WASM_ENABLE_BULK_MEMORY != 0
case WASM_OP_MEMORY_INIT: case WASM_OP_MEMORY_INIT:
{ {
CHECK_MEMORY();
read_leb_uint32(p, p_end, segment_index); read_leb_uint32(p, p_end, segment_index);
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
emit_uint32(loader_ctx, segment_index); emit_uint32(loader_ctx, segment_index);
#endif #endif
bh_assert(module->import_memory_count read_leb_memidx(p, p_end, memidx);
+ module->memory_count check_memidx(module, memidx);
> 0);
bh_assert(*p == 0x00);
p++;
bh_assert(segment_index < module->data_seg_count); bh_assert(segment_index < module->data_seg_count);
bh_assert(module->data_seg_count1 > 0); bh_assert(module->data_seg_count1 > 0);
@ -7719,14 +7756,13 @@ re_scan:
} }
case WASM_OP_MEMORY_COPY: case WASM_OP_MEMORY_COPY:
{ {
CHECK_MEMORY();
CHECK_BUF(p, p_end, sizeof(int16)); CHECK_BUF(p, p_end, sizeof(int16));
/* both src and dst memory index should be 0 */ /* check both src and dst memory index */
bh_assert(*(int16 *)p == 0x0000); read_leb_memidx(p, p_end, memidx);
p += 2; check_memidx(module, memidx);
read_leb_memidx(p, p_end, memidx);
bh_assert(module->import_memory_count check_memidx(module, memidx);
+ module->memory_count
> 0);
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_MEM_OFFSET(); POP_MEM_OFFSET();
@ -7738,12 +7774,9 @@ re_scan:
} }
case WASM_OP_MEMORY_FILL: case WASM_OP_MEMORY_FILL:
{ {
bh_assert(*p == 0); CHECK_MEMORY();
p++; read_leb_memidx(p, p_end, memidx);
check_memidx(module, memidx);
bh_assert(module->import_memory_count
+ module->memory_count
> 0);
POP_MEM_OFFSET(); POP_MEM_OFFSET();
POP_I32(); POP_I32();

View File

@ -194,114 +194,119 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
default_max_page = default_max_page =
memory->is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES; memory->is_memory64 ? DEFAULT_MEM64_MAX_PAGES : DEFAULT_MAX_PAGES;
if (heap_size > 0 && module_inst->module->malloc_function != (uint32)-1 /* The app heap should be in the default memory */
&& module_inst->module->free_function != (uint32)-1) { if (memory_idx == 0) {
/* Disable app heap, use malloc/free function exported if (heap_size > 0 && module_inst->module->malloc_function != (uint32)-1
by wasm app to allocate/free memory instead */ && module_inst->module->free_function != (uint32)-1) {
heap_size = 0; /* Disable app heap, use malloc/free function exported
} by wasm app to allocate/free memory instead */
heap_size = 0;
}
/* If initial memory is the largest size allowed, disallowing insert host /* If initial memory is the largest size allowed, disallowing insert
* managed heap */ * host managed heap */
if (heap_size > 0 if (heap_size > 0
&& heap_offset == GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64)) { && heap_offset == GET_MAX_LINEAR_MEMORY_SIZE(memory->is_memory64)) {
set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, "
"try using `--heap-size=0` option");
return NULL;
}
if (init_page_count == max_page_count && init_page_count == 1) {
/* If only one page and at most one page, we just append
the app heap to the end of linear memory, enlarge the
num_bytes_per_page, and don't change the page count */
heap_offset = num_bytes_per_page;
num_bytes_per_page += heap_size;
if (num_bytes_per_page < heap_size) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, " "failed to insert app heap into linear memory, "
"try using `--heap-size=0` option"); "try using `--heap-size=0` option");
return NULL; return NULL;
} }
}
else if (heap_size > 0) {
if (init_page_count == max_page_count && init_page_count == 0) {
/* If the memory data size is always 0, we resize it to
one page for app heap */
num_bytes_per_page = heap_size;
heap_offset = 0;
inc_page_count = 1;
}
else if (module->aux_heap_base_global_index != (uint32)-1
&& module->aux_heap_base
< (uint64)num_bytes_per_page * init_page_count) {
/* Insert app heap before __heap_base */
aux_heap_base = module->aux_heap_base;
bytes_of_last_page = aux_heap_base % num_bytes_per_page;
if (bytes_of_last_page == 0)
bytes_of_last_page = num_bytes_per_page;
bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
inc_page_count =
(heap_size - bytes_to_page_end + num_bytes_per_page - 1)
/ num_bytes_per_page;
heap_offset = aux_heap_base;
aux_heap_base += heap_size;
bytes_of_last_page = aux_heap_base % num_bytes_per_page; if (init_page_count == max_page_count && init_page_count == 1) {
if (bytes_of_last_page == 0) /* If only one page and at most one page, we just append
bytes_of_last_page = num_bytes_per_page; the app heap to the end of linear memory, enlarge the
bytes_to_page_end = num_bytes_per_page - bytes_of_last_page; num_bytes_per_page, and don't change the page count */
if (bytes_to_page_end < 1 * BH_KB) { heap_offset = num_bytes_per_page;
aux_heap_base += 1 * BH_KB; num_bytes_per_page += heap_size;
inc_page_count++; if (num_bytes_per_page < heap_size) {
set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, "
"try using `--heap-size=0` option");
return NULL;
} }
}
else if (heap_size > 0) {
if (init_page_count == max_page_count && init_page_count == 0) {
/* If the memory data size is always 0, we resize it to
one page for app heap */
num_bytes_per_page = heap_size;
heap_offset = 0;
inc_page_count = 1;
}
else if (module->aux_heap_base_global_index != (uint32)-1
&& module->aux_heap_base
< (uint64)num_bytes_per_page * init_page_count) {
/* Insert app heap before __heap_base */
aux_heap_base = module->aux_heap_base;
bytes_of_last_page = aux_heap_base % num_bytes_per_page;
if (bytes_of_last_page == 0)
bytes_of_last_page = num_bytes_per_page;
bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
inc_page_count =
(heap_size - bytes_to_page_end + num_bytes_per_page - 1)
/ num_bytes_per_page;
heap_offset = aux_heap_base;
aux_heap_base += heap_size;
/* Adjust __heap_base global value */ bytes_of_last_page = aux_heap_base % num_bytes_per_page;
global_idx = module->aux_heap_base_global_index; if (bytes_of_last_page == 0)
bh_assert(module_inst->e->globals bytes_of_last_page = num_bytes_per_page;
&& global_idx < module_inst->e->global_count); bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
global_addr = module_inst->global_data if (bytes_to_page_end < 1 * BH_KB) {
+ module_inst->e->globals[global_idx].data_offset; aux_heap_base += 1 * BH_KB;
inc_page_count++;
}
/* Adjust __heap_base global value */
global_idx = module->aux_heap_base_global_index;
bh_assert(module_inst->e->globals
&& global_idx < module_inst->e->global_count);
global_addr = module_inst->global_data
+ module_inst->e->globals[global_idx].data_offset;
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
if (memory->is_memory64) { if (memory->is_memory64) {
/* For memory64, the global value should be i64 */ /* For memory64, the global value should be i64 */
*(uint64 *)global_addr = aux_heap_base; *(uint64 *)global_addr = aux_heap_base;
} }
else else
#endif #endif
{ {
/* For memory32, the global value should be i32 */ /* For memory32, the global value should be i32 */
*(uint32 *)global_addr = (uint32)aux_heap_base; *(uint32 *)global_addr = (uint32)aux_heap_base;
}
LOG_VERBOSE("Reset __heap_base global to %" PRIu64,
aux_heap_base);
}
else {
/* Insert app heap before new page */
inc_page_count =
(heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
heap_offset = (uint64)num_bytes_per_page * init_page_count;
heap_size = (uint64)num_bytes_per_page * inc_page_count;
if (heap_size > 0)
heap_size -= 1 * BH_KB;
}
init_page_count += inc_page_count;
max_page_count += inc_page_count;
if (init_page_count > default_max_page) {
set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, "
"try using `--heap-size=0` option");
return NULL;
} }
LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
}
else {
/* Insert app heap before new page */
inc_page_count =
(heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
heap_offset = (uint64)num_bytes_per_page * init_page_count;
heap_size = (uint64)num_bytes_per_page * inc_page_count;
if (heap_size > 0)
heap_size -= 1 * BH_KB;
}
init_page_count += inc_page_count;
max_page_count += inc_page_count;
if (init_page_count > default_max_page) {
set_error_buf(error_buf, error_buf_size,
"failed to insert app heap into linear memory, "
"try using `--heap-size=0` option");
return NULL;
}
if (max_page_count > default_max_page) if (max_page_count > default_max_page)
max_page_count = default_max_page; max_page_count = default_max_page;
}
} }
LOG_VERBOSE("Memory instantiate:"); LOG_VERBOSE("Memory instantiate:");
LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u", LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
num_bytes_per_page, init_page_count, max_page_count); num_bytes_per_page, init_page_count, max_page_count);
LOG_VERBOSE(" heap offset: %" PRIu64 ", heap size: %u\n", heap_offset, if (memory_idx == 0)
heap_size); LOG_VERBOSE(" heap offset: %" PRIu64 ", heap size: %u\n", heap_offset,
heap_size);
max_memory_data_size = (uint64)num_bytes_per_page * max_page_count; max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
bh_assert(max_memory_data_size bh_assert(max_memory_data_size
@ -326,12 +331,14 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
memory->max_page_count = max_page_count; memory->max_page_count = max_page_count;
memory->memory_data_size = memory_data_size; memory->memory_data_size = memory_data_size;
memory->heap_data = memory->memory_data + heap_offset; if (memory_idx == 0) {
memory->heap_data_end = memory->heap_data + heap_size; memory->heap_data = memory->memory_data + heap_offset;
memory->memory_data_end = memory->memory_data + memory_data_size; memory->heap_data_end = memory->heap_data + heap_size;
memory->memory_data_end = memory->memory_data + memory_data_size;
}
/* Initialize heap */ /* Initialize heap */
if (heap_size > 0) { if (memory_idx == 0 && heap_size > 0) {
uint32 heap_struct_size = mem_allocator_get_heap_struct_size(); uint32 heap_struct_size = mem_allocator_get_heap_struct_size();
if (!(memory->heap_handle = runtime_malloc( if (!(memory->heap_handle = runtime_malloc(
@ -361,7 +368,7 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
return memory; return memory;
fail2: fail2:
if (heap_size > 0) if (memory_idx == 0 && heap_size > 0)
wasm_runtime_free(memory->heap_handle); wasm_runtime_free(memory->heap_handle);
fail1: fail1:
if (memory->memory_data) if (memory->memory_data)
@ -1351,7 +1358,45 @@ export_globals_instantiate(const WASMModule *module,
bh_assert((uint32)(export_global - export_globals) == export_glob_count); bh_assert((uint32)(export_global - export_globals) == export_glob_count);
return export_globals; return export_globals;
} }
#endif
#if WASM_ENABLE_MULTI_MEMORY != 0
static void
export_memories_deinstantiate(WASMExportMemInstance *memories)
{
if (memories)
wasm_runtime_free(memories);
}
static WASMExportMemInstance *
export_memories_instantiate(const WASMModule *module,
WASMModuleInstance *module_inst,
uint32 export_mem_count, char *error_buf,
uint32 error_buf_size)
{
WASMExportMemInstance *export_memories, *export_memory;
WASMExport *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 */
#endif /* end of if WASM_ENABLE_MULTI_MODULE != 0 */
static WASMFunctionInstance * static WASMFunctionInstance *
lookup_post_instantiate_func(WASMModuleInstance *module_inst, lookup_post_instantiate_func(WASMModuleInstance *module_inst,
@ -2387,6 +2432,12 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
module, module_inst, module_inst->export_global_count, module, module_inst, module_inst->export_global_count,
error_buf, error_buf_size))) error_buf, error_buf_size)))
#endif #endif
#if WASM_ENABLE_MULTI_MODULE != 0 && 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,
error_buf, error_buf_size)))
#endif
#if WASM_ENABLE_JIT != 0 #if WASM_ENABLE_JIT != 0
|| (module_inst->e->function_count > 0 || (module_inst->e->function_count > 0
&& !init_func_ptrs(module_inst, module, error_buf, error_buf_size)) && !init_func_ptrs(module_inst, module, error_buf, error_buf_size))
@ -3189,6 +3240,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
export_globals_deinstantiate(module_inst->export_globals); export_globals_deinstantiate(module_inst->export_globals);
#endif #endif
#if WASM_ENABLE_MULTI_MODULE != 0 && WASM_ENABLE_MULTI_MEMORY != 0
export_memories_deinstantiate(module_inst->export_memories);
#endif
#if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
wasm_externref_cleanup((WASMModuleInstanceCommon *)module_inst); wasm_externref_cleanup((WASMModuleInstanceCommon *)module_inst);
#endif #endif
@ -3251,12 +3306,16 @@ wasm_lookup_global(const WASMModuleInstance *module_inst, const char *name)
WASMMemoryInstance * WASMMemoryInstance *
wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name) wasm_lookup_memory(const WASMModuleInstance *module_inst, const char *name)
{ {
/** #if WASM_ENABLE_MULTI_MEMORY != 0
* using a strong assumption that one module instance only has uint32 i;
* one memory instance 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; (void)module_inst->export_memories;
return module_inst->memories[0]; return module_inst->memories[0];
#endif
} }
WASMTableInstance * WASMTableInstance *

View File

@ -620,9 +620,16 @@ wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
WASMMemoryInstance * WASMMemoryInstance *
wasm_get_default_memory(WASMModuleInstance *module_inst); wasm_get_default_memory(WASMModuleInstance *module_inst);
WASMMemoryInstance *
wasm_get_memory_with_idx(WASMModuleInstance *module_inst, uint32 index);
bool bool
wasm_enlarge_memory(WASMModuleInstance *module_inst, uint32 inc_page_count); wasm_enlarge_memory(WASMModuleInstance *module_inst, uint32 inc_page_count);
bool
wasm_enlarge_memory_with_idx(WASMModuleInstance *module_inst,
uint32 inc_page_count, uint32 memidx);
bool bool
wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx, wasm_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
uint32 argc, uint32 argv[]); uint32 argc, uint32 argv[]);

View File

@ -14,7 +14,7 @@ import time
""" """
The script itself has to be put under the same directory with the "spec". The script itself has to be put under the same directory with the "spec".
To run a single non-GC and non-memory64 case with interpreter mode: To run a single non-GC case with interpreter mode:
cd workspace cd workspace
python3 runtest.py --wast2wasm wabt/bin/wat2wasm --interpreter iwasm \ python3 runtest.py --wast2wasm wabt/bin/wat2wasm --interpreter iwasm \
spec/test/core/xxx.wast spec/test/core/xxx.wast
@ -22,7 +22,7 @@ To run a single non-GC case with aot mode:
cd workspace cd workspace
python3 runtest.py --aot --wast2wasm wabt/bin/wat2wasm --interpreter iwasm \ python3 runtest.py --aot --wast2wasm wabt/bin/wat2wasm --interpreter iwasm \
--aot-compiler wamrc spec/test/core/xxx.wast --aot-compiler wamrc spec/test/core/xxx.wast
To run a single GC case or single memory64 case: To run a single GC case case:
cd workspace cd workspace
python3 runtest.py --wast2wasm spec/interpreter/wasm --interpreter iwasm \ python3 runtest.py --wast2wasm spec/interpreter/wasm --interpreter iwasm \
--aot-compiler wamrc --gc spec/test/core/xxx.wast --aot-compiler wamrc --gc spec/test/core/xxx.wast
@ -79,6 +79,7 @@ def ignore_the_case(
simd_flag=False, simd_flag=False,
gc_flag=False, gc_flag=False,
memory64_flag=False, memory64_flag=False,
multi_memory_flag=False,
xip_flag=False, xip_flag=False,
eh_flag=False, eh_flag=False,
qemu_flag=False, qemu_flag=False,
@ -165,6 +166,7 @@ def test_case(
verbose_flag=True, verbose_flag=True,
gc_flag=False, gc_flag=False,
memory64_flag=False, memory64_flag=False,
multi_memory_flag=False,
qemu_flag=False, qemu_flag=False,
qemu_firmware="", qemu_firmware="",
log="", log="",
@ -223,6 +225,9 @@ def test_case(
if memory64_flag: if memory64_flag:
CMD.append("--memory64") CMD.append("--memory64")
if multi_memory_flag:
CMD.append("--multi-memory")
if log != "": if log != "":
CMD.append("--log-dir") CMD.append("--log-dir")
CMD.append(log) CMD.append(log)
@ -291,6 +296,7 @@ def test_suite(
verbose_flag=True, verbose_flag=True,
gc_flag=False, gc_flag=False,
memory64_flag=False, memory64_flag=False,
multi_memory_flag=False,
parl_flag=False, parl_flag=False,
qemu_flag=False, qemu_flag=False,
qemu_firmware="", qemu_firmware="",
@ -316,6 +322,10 @@ def test_suite(
eh_case_list_include = [test for test in eh_case_list if test.stem in ["throw", "tag", "try_catch", "rethrow", "try_delegate"]] eh_case_list_include = [test for test in eh_case_list if test.stem in ["throw", "tag", "try_catch", "rethrow", "try_delegate"]]
case_list.extend(eh_case_list_include) case_list.extend(eh_case_list_include)
if multi_memory_flag:
multi_memory_list = sorted(suite_path.glob("multi-memory/*.wast"))
case_list.extend(multi_memory_list)
# ignore based on command line options # ignore based on command line options
filtered_case_list = [] filtered_case_list = []
for case_path in case_list: for case_path in case_list:
@ -330,6 +340,7 @@ def test_suite(
simd_flag, simd_flag,
gc_flag, gc_flag,
memory64_flag, memory64_flag,
multi_memory_flag,
xip_flag, xip_flag,
eh_flag, eh_flag,
qemu_flag, qemu_flag,
@ -366,6 +377,7 @@ def test_suite(
verbose_flag, verbose_flag,
gc_flag, gc_flag,
memory64_flag, memory64_flag,
multi_memory_flag,
qemu_flag, qemu_flag,
qemu_firmware, qemu_firmware,
log, log,
@ -408,6 +420,7 @@ def test_suite(
verbose_flag, verbose_flag,
gc_flag, gc_flag,
memory64_flag, memory64_flag,
multi_memory_flag,
qemu_flag, qemu_flag,
qemu_firmware, qemu_firmware,
log, log,
@ -546,6 +559,13 @@ def main():
dest="memory64_flag", dest="memory64_flag",
help="Running with memory64 feature", help="Running with memory64 feature",
) )
parser.add_argument(
"--multi-memory",
action="store_true",
default=False,
dest="multi_memory_flag",
help="Running with multi-memory feature",
)
parser.add_argument( parser.add_argument(
"cases", "cases",
metavar="path_to__case", metavar="path_to__case",
@ -591,6 +611,7 @@ def main():
options.verbose_flag, options.verbose_flag,
options.gc_flag, options.gc_flag,
options.memory64_flag, options.memory64_flag,
options.multi_memory_flag,
options.parl_flag, options.parl_flag,
options.qemu_flag, options.qemu_flag,
options.qemu_firmware, options.qemu_firmware,
@ -619,6 +640,7 @@ def main():
options.verbose_flag, options.verbose_flag,
options.gc_flag, options.gc_flag,
options.memory64_flag, options.memory64_flag,
options.multi_memory_flag,
options.qemu_flag, options.qemu_flag,
options.qemu_firmware, options.qemu_firmware,
options.log, options.log,

File diff suppressed because it is too large Load Diff

View File

@ -327,6 +327,9 @@ parser.add_argument('--gc', default=False, action='store_true',
parser.add_argument('--memory64', default=False, action='store_true', parser.add_argument('--memory64', default=False, action='store_true',
help='Test with Memory64') help='Test with Memory64')
parser.add_argument('--multi-memory', default=False, action='store_true',
help='Test with multi-memory(with multi-module auto enabled)')
parser.add_argument('--qemu', default=False, action='store_true', parser.add_argument('--qemu', default=False, action='store_true',
help="Enable QEMU") help="Enable QEMU")
@ -1097,6 +1100,8 @@ def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts):
cmd = [opts.wast2wasm, "--enable-threads", "--no-check", "--enable-exceptions", "--enable-tail-call", wast_tempfile, "-o", wasm_tempfile ] cmd = [opts.wast2wasm, "--enable-threads", "--no-check", "--enable-exceptions", "--enable-tail-call", wast_tempfile, "-o", wasm_tempfile ]
elif opts.memory64: elif opts.memory64:
cmd = [opts.wast2wasm, "--enable-memory64", "--no-check", wast_tempfile, "-o", wasm_tempfile ] cmd = [opts.wast2wasm, "--enable-memory64", "--no-check", wast_tempfile, "-o", wasm_tempfile ]
elif opts.multi_memory:
cmd = [opts.wast2wasm, "--enable-multi-memory", "--no-check", wast_tempfile, "-o", wasm_tempfile ]
else: else:
cmd = [opts.wast2wasm, "--enable-threads", "--no-check", cmd = [opts.wast2wasm, "--enable-threads", "--no-check",
wast_tempfile, "-o", wasm_tempfile ] wast_tempfile, "-o", wasm_tempfile ]

View File

@ -25,6 +25,7 @@ function help()
echo "-S enable SIMD feature" echo "-S enable SIMD feature"
echo "-G enable GC feature" echo "-G enable GC feature"
echo "-W enable memory64 feature" echo "-W enable memory64 feature"
echo "-E enable multi memory feature"
echo "-X enable XIP feature" echo "-X enable XIP feature"
echo "-e enable exception handling" echo "-e enable exception handling"
echo "-x test SGX" echo "-x test SGX"
@ -59,6 +60,7 @@ COLLECT_CODE_COVERAGE=0
ENABLE_SIMD=0 ENABLE_SIMD=0
ENABLE_GC=0 ENABLE_GC=0
ENABLE_MEMORY64=0 ENABLE_MEMORY64=0
ENABLE_MULTI_MEMORY=0
ENABLE_XIP=0 ENABLE_XIP=0
ENABLE_EH=0 ENABLE_EH=0
ENABLE_DEBUG_VERSION=0 ENABLE_DEBUG_VERSION=0
@ -85,7 +87,7 @@ REQUIREMENT_NAME=""
# Initialize an empty array for subrequirement IDs # Initialize an empty array for subrequirement IDs
SUBREQUIREMENT_IDS=() SUBREQUIREMENT_IDS=()
while getopts ":s:cabgvt:m:MCpSXexwWPGQF:j:T:r:A:" opt while getopts ":s:cabgvt:m:MCpSXexwWEPGQF:j:T:r:A:" opt
do do
OPT_PARSED="TRUE" OPT_PARSED="TRUE"
case $opt in case $opt in
@ -148,6 +150,11 @@ do
echo "enable wasm64(memory64) feature" echo "enable wasm64(memory64) feature"
ENABLE_MEMORY64=1 ENABLE_MEMORY64=1
;; ;;
E)
echo "enable multi memory feature(auto enable multi module)"
ENABLE_MULTI_MEMORY=1
ENABLE_MULTI_MODULE=1
;;
C) C)
echo "enable code coverage" echo "enable code coverage"
COLLECT_CODE_COVERAGE=1 COLLECT_CODE_COVERAGE=1
@ -496,6 +503,20 @@ function spec_test()
git reset --hard 48e69f394869c55b7bbe14ac963c09f4605490b6 git reset --hard 48e69f394869c55b7bbe14ac963c09f4605490b6
git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast test/core/data.wast git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast test/core/data.wast
git apply ../../spec-test-script/memory64_ignore_cases.patch || exit 1 git apply ../../spec-test-script/memory64_ignore_cases.patch || exit 1
elif [[ ${ENABLE_MULTI_MEMORY} == 1 ]]; then
echo "checkout spec for multi memory proposal"
# check spec test cases for multi memory
git clone -b main --single-branch https://github.com/WebAssembly/multi-memory.git spec
pushd spec
# Reset to commit: "Merge pull request #48 from backes/specify-memcpy-immediate-order"
git reset --hard 48e69f394869c55b7bbe14ac963c09f4605490b6
git checkout 044d0d2e77bdcbe891f7e0b9dd2ac01d56435f0b -- test/core/elem.wast
git apply ../../spec-test-script/multi_memory_ignore_cases.patch || exit 1
if [[ ${RUNNING_MODE} == "aot" ]]; then
git apply ../../spec-test-script/multi_module_aot_ignore_cases.patch || exit 1
fi
else else
echo "checkout spec for default proposal" echo "checkout spec for default proposal"
@ -572,6 +593,13 @@ function spec_test()
ARGS_FOR_SPEC_TEST+="--memory64 " ARGS_FOR_SPEC_TEST+="--memory64 "
fi fi
# multi memory is only enabled in interp and aot mode
if [[ 1 == ${ENABLE_MULTI_MEMORY} ]]; then
if [[ $1 == 'classic-interp' || $1 == 'aot' ]]; then
ARGS_FOR_SPEC_TEST+="--multi-memory "
fi
fi
if [[ ${ENABLE_QEMU} == 1 ]]; then if [[ ${ENABLE_QEMU} == 1 ]]; then
ARGS_FOR_SPEC_TEST+="--qemu " ARGS_FOR_SPEC_TEST+="--qemu "
ARGS_FOR_SPEC_TEST+="--qemu-firmware ${QEMU_FIRMWARE} " ARGS_FOR_SPEC_TEST+="--qemu-firmware ${QEMU_FIRMWARE} "
@ -852,6 +880,14 @@ function do_execute_in_running_mode()
{ {
local RUNNING_MODE="$1" local RUNNING_MODE="$1"
if [[ ${ENABLE_MULTI_MEMORY} -eq 1 ]]; then
if [[ "${RUNNING_MODE}" != "classic-interp" \
&& "${RUNNING_MODE}" != "aot" ]]; then
echo "support multi-memory in classic-interp mode and aot mode"
return 0
fi
fi
if [[ ${ENABLE_MEMORY64} -eq 1 ]]; then if [[ ${ENABLE_MEMORY64} -eq 1 ]]; then
if [[ "${RUNNING_MODE}" != "classic-interp" \ if [[ "${RUNNING_MODE}" != "classic-interp" \
&& "${RUNNING_MODE}" != "aot" ]]; then && "${RUNNING_MODE}" != "aot" ]]; then
@ -941,6 +977,12 @@ function trigger()
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_MEMORY64=0" EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_MEMORY64=0"
fi fi
if [[ ${ENABLE_MULTI_MEMORY} == 1 ]];then
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_MULTI_MEMORY=1"
else
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_MULTI_MEMORY=0"
fi
if [[ ${ENABLE_MULTI_THREAD} == 1 ]];then if [[ ${ENABLE_MULTI_THREAD} == 1 ]];then
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_LIB_PTHREAD=1" EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_LIB_PTHREAD=1"
fi fi