feat(wasm): support bulk memory operations proposal (interpreter mode)#415
feat(wasm): support bulk memory operations proposal (interpreter mode)#415ys8888john wants to merge 1 commit into
Conversation
32a3bcb to
eab5dfa
Compare
⚡ Performance Regression Check Results✅ Performance Check Passed (interpreter)Performance Benchmark Results (threshold: 25%)
Summary: 194 benchmarks, 0 regressions ✅ Performance Check Passed (multipass)Performance Benchmark Results (threshold: 25%)
Summary: 194 benchmarks, 0 regressions |
eab5dfa to
95f78a0
Compare
There was a problem hiding this comment.
Pull request overview
Adds WebAssembly Bulk Memory Operations proposal support for the interpreter execution mode, with corresponding spec/proposal tests and validation/runtime plumbing.
Changes:
- Implement interpreter execution for
memory.init,data.drop,memory.copy,memory.fill,table.init,elem.drop, andtable.copy(0xFC-prefixed opcodes). - Extend module loading/instantiation to track element/data segment modes and “dropped” state.
- Update spec/proposals test inputs and CI test generation to include bulk-memory instructions; skip these proposal tests in JIT modes.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/wast/spec.patch | Adjusts upstream spec test patch content to align with updated wast expectations. |
| tests/wast/proposals/table_init.wast | Adds proposal test coverage for table.init + elem.drop. |
| tests/wast/proposals/table_copy.wast | Adds proposal test coverage for table.copy. |
| tests/wast/proposals/memory_init.wast | Adds proposal test coverage for memory.init. |
| tests/wast/proposals/memory_fill.wast | Adds proposal test coverage for memory.fill. |
| tests/wast/proposals/memory_copy.wast | Adds proposal test coverage for memory.copy. |
| tests/wast/proposals/elem_drop.wast | Adds proposal test coverage for elem.drop. |
| tests/wast/proposals/data_drop.wast | Adds proposal test coverage for data.drop. |
| tests/bulk_memory/run_tests.sh | Adds a standalone bulk-memory test runner script (manual). |
| src/utils/wasm.cpp | Updates bytecode skipping logic to understand 0xFC-prefixed instructions. |
| src/tests/spec_unit_tests.cpp | Skips bulk-memory proposal tests in non-interpreter modes. |
| src/tests/CMakeLists.txt | Enables wast2json bulk-memory support during spec JSON generation. |
| src/runtime/module.h | Adds element/data segment mode fields and segment validation/helpers. |
| src/runtime/instance.h | Adds dropped segment tracking API/state on instances. |
| src/runtime/instance.cpp | Frees dropped segment tracking arrays in the instance destructor. |
| src/common/wasm_defs/opcode.def | Adds bulk-memory opcode names (currently as single-byte entries). |
| src/common/errors.def | Adds errors for unknown segments + out-of-bounds table access. |
| src/common/enums.h | Defines 0xFC prefix constant and sub-opcode constants. |
| src/action/module_loader.cpp | Parses new element/data segment encodings with flags and mode tracking. |
| src/action/interpreter.cpp | Implements runtime semantics for bulk-memory ops in interpreter mode. |
| src/action/instantiator.cpp | Skips non-active segments during instantiation; initializes dropped tracking arrays. |
| src/action/function_loader.cpp | Validates bulk-memory ops during function validation. |
| src/action/bytecode_visitor.h | Makes JIT paths reject bulk-memory ops with a clear UnsupportedOpcode error. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if echo "$result" | grep -q "error\|trap\|failed"; then | ||
| FAIL=$((FAIL + 1)) | ||
| echo -e "${RED}FAIL${NC}: $desc (expected success, got '$result')" | ||
| else | ||
| PASS=$((PASS + 1)) | ||
| echo -e "${GREEN}PASS${NC}: $desc (success)" | ||
| fi | ||
| fi | ||
| } | ||
|
|
| # ---- memory.fill tests ---- | ||
| echo "--- memory.fill ---" | ||
| assert_return "basic fill" "0xff:i32" \ | ||
| $DTVM -m interpreter "$SCRIPT_DIR/memory_fill.wasm" -f test_basic_fill | ||
|
|
||
| assert_return "fill value truncation (0xABCD -> 0xCD)" "0xcd:i32" \ | ||
| $DTVM -m interpreter "$SCRIPT_DIR/memory_fill.wasm" -f test_fill_value_truncation | ||
|
|
| ;; The data segment is active (format 0 with no explicit offset means passive | ||
| ;; in this case since there's no offset expression). Actually this is passive | ||
| ;; because there's no (i32.const X) offset. |
| ZEN_ASSERT_TODO(); | ||
| } | ||
| } else { | ||
| ZEN_LOG_ERROR("munimplemented opcode: 0x%x", Opcode); |
| Entry->TableIdx = 0; | ||
| Entry->InitExprKind = 0; | ||
| Entry->InitExprVal = {}; | ||
| Entry->Mode = 1; // passive |
| // Bulk Memory Operations (encoded as 0xFC prefix + sub-opcode in wasm binary) | ||
| DEFINE_WASM_OPCODE(MEMORY_INIT, 0xc7, "memory.init") | ||
| DEFINE_WASM_OPCODE(DATA_DROP, 0xc8, "data.drop") | ||
| DEFINE_WASM_OPCODE(MEMORY_COPY, 0xc9, "memory.copy") | ||
| DEFINE_WASM_OPCODE(MEMORY_FILL, 0xca, "memory.fill") | ||
| DEFINE_WASM_OPCODE(TABLE_INIT, 0xcb, "table.init") | ||
| DEFINE_WASM_OPCODE(ELEM_DROP, 0xcc, "elem.drop") | ||
| DEFINE_WASM_OPCODE(TABLE_COPY, 0xcd, "table.copy") | ||
|
|
| handleIntExtend<WASMType::I64, WASMType::I32, true>(); | ||
| break; | ||
|
|
||
| case common::WASM_PREFIX_FC: { // Bulk memory operations prefix |
There was a problem hiding this comment.
The entire opcode handler block needs to be wrapped in a macro, otherwise the original WASM_PREFIX_FC opcode will cause an error: getErrorWithExtraMessage(ErrorCode::UnsupportedOpcode, std::to_string(Opcode)). Now it will throw an error: getErrorWithExtraMessage(ErrorCode::UnsupportedOpcode, "bulk memory operations not supported in JIT mode")
| case I64_EXTEND32_S: | ||
| popAndPushValueType(1, WASMType::I64, WASMType::I64); | ||
| break; | ||
| case WASM_PREFIX_FC: { |
There was a problem hiding this comment.
The entire opcode handler block needs to be wrapped in a macro, otherwise the original WASM_PREFIX_FC opcode will cause an error: getErrorWithExtraMessage(ErrorCode::UnsupportedOpcode, std::to_string(Opcode)). Now it will throw an error: getErrorWithExtraMessage(ErrorCode::UnsupportedOpcode, "bulk memory operations not supported in JIT mode")
| case I64_EXTEND16_S: | ||
| case I64_EXTEND32_S: | ||
| break; | ||
| case WASM_PREFIX_FC: { // Bulk memory operations prefix |
|
Refactored url : #432 |
1. Does this PR affect any open issues?(Y/N) and add issue references (e.g. "fix #123", "re #123".):
2. What is the scope of this PR (e.g. component or file name):
3. Provide a description of the PR(e.g. more details, effects, motivations or doc link):
4. Are there any breaking changes?(Y/N) and describe the breaking changes(e.g. more details, motivations or doc link):
5. Are there test cases for these changes?(Y/N) select and add more details, references or doc links:
6. Release note