summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/binary-reader-ir.cc41
-rw-r--r--src/binary-reader-logging.cc23
-rw-r--r--src/binary-reader-logging.h12
-rw-r--r--src/binary-reader-nop.h16
-rw-r--r--src/binary-reader.cc124
-rw-r--r--src/binary-reader.h12
-rw-r--r--src/binary-writer.cc74
-rw-r--r--src/c-writer.cc29
-rw-r--r--src/feature.def1
-rw-r--r--src/interp/binary-reader-interp.cc56
-rw-r--r--src/ir.h68
-rw-r--r--src/resolve-names.cc38
-rw-r--r--src/shared-validator.cc31
-rw-r--r--src/shared-validator.h14
-rw-r--r--src/validator.cc15
-rw-r--r--src/wast-parser.cc98
-rw-r--r--src/wast-parser.h9
-rw-r--r--src/wat-writer.cc67
-rw-r--r--test/dump/current-memory.txt2
-rw-r--r--test/dump/grow-memory.txt2
-rw-r--r--test/help/spectest-interp.txt1
-rw-r--r--test/help/wasm-interp.txt1
-rw-r--r--test/help/wasm-opcodecnt.txt1
-rw-r--r--test/help/wasm-validate.txt1
-rw-r--r--test/help/wasm2wat.txt1
-rw-r--r--test/help/wast2json.txt1
-rw-r--r--test/help/wat-desugar.txt1
-rw-r--r--test/help/wat2wasm.txt1
-rw-r--r--test/spec/memory.txt4
-rw-r--r--test/spec/memory64/memory.txt4
-rw-r--r--test/spec/memory64/memory64.txt4
-rw-r--r--test/spec/memory_copy.txt3
-rw-r--r--test/spec/multi-memory/binary.txt260
-rw-r--r--test/spec/multi-memory/data.txt56
-rw-r--r--test/spec/multi-memory/imports.txt234
-rw-r--r--test/spec/multi-memory/load.txt196
-rw-r--r--test/spec/multi-memory/memory-multi.txt6
-rw-r--r--test/spec/multi-memory/memory.txt75
-rw-r--r--test/spec/multi-memory/memory_grow.txt40
-rw-r--r--test/spec/multi-memory/memory_size.txt12
-rw-r--r--test/spec/multi-memory/store.txt195
-rw-r--r--test/typecheck/bad-bulk-memory-no-memory.txt3
-rwxr-xr-xtest/update-spec-tests.py4
44 files changed, 1656 insertions, 182 deletions
diff --git a/README.md b/README.md
index 41f3ead7..154d0b81 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i
| [reference types][] | `--disable-reference-types` | ✓ | ✓ | ✓ | ✓ | ✓ |
| [annotations][] | `--enable-annotations` | | | ✓ | | |
| [memory64][] | `--enable-memory64` | | | | | |
+| [multi-memory][] | `--enable-multi-memory` | | ✓ | ✓ | ✓ | ✓ |
[exception handling]: https://github.com/WebAssembly/exception-handling
[mutable globals]: https://github.com/WebAssembly/mutable-global
@@ -71,6 +72,7 @@ Wabt has been compiled to JavaScript via emscripten. Some of the functionality i
[reference types]: https://github.com/WebAssembly/reference-types
[annotations]: https://github.com/WebAssembly/annotations
[memory64]: https://github.com/WebAssembly/memory64
+[multi-memory]: https://github.com/WebAssembly/multi-memory
## Cloning
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc
index f454174b..27e97c85 100644
--- a/src/binary-reader-ir.cc
+++ b/src/binary-reader-ir.cc
@@ -165,18 +165,19 @@ class BinaryReaderIR : public BinaryReaderNop {
Result OnI64ConstExpr(uint64_t value) override;
Result OnIfExpr(Type sig_type) override;
Result OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLocalGetExpr(Index local_index) override;
Result OnLocalSetExpr(Index local_index) override;
Result OnLocalTeeExpr(Index local_index) override;
Result OnLoopExpr(Type sig_type) override;
- Result OnMemoryCopyExpr() override;
+ Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override;
Result OnDataDropExpr(Index segment_index) override;
- Result OnMemoryFillExpr() override;
- Result OnMemoryGrowExpr() override;
- Result OnMemoryInitExpr(Index segment_index) override;
- Result OnMemorySizeExpr() override;
+ Result OnMemoryFillExpr(Index memidx) override;
+ Result OnMemoryGrowExpr(Index memidx) override;
+ Result OnMemoryInitExpr(Index segment_index, Index memidx) override;
+ Result OnMemorySizeExpr(Index memidx) override;
Result OnTableCopyExpr(Index dst_index, Index src_index) override;
Result OnElemDropExpr(Index segment_index) override;
Result OnTableInitExpr(Index segment_index, Index table_index) override;
@@ -193,6 +194,7 @@ class BinaryReaderIR : public BinaryReaderNop {
Result OnReturnExpr() override;
Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnThrowExpr(Index tag_index) override;
@@ -873,9 +875,11 @@ Result BinaryReaderIR::OnIfExpr(Type sig_type) {
}
Result BinaryReaderIR::OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(MakeUnique<LoadExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(
+ MakeUnique<LoadExpr>(opcode, Var(memidx), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnLoopExpr(Type sig_type) {
@@ -887,28 +891,29 @@ Result BinaryReaderIR::OnLoopExpr(Type sig_type) {
return Result::Ok;
}
-Result BinaryReaderIR::OnMemoryCopyExpr() {
- return AppendExpr(MakeUnique<MemoryCopyExpr>());
+Result BinaryReaderIR::OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) {
+ return AppendExpr(
+ MakeUnique<MemoryCopyExpr>(Var(srcmemidx), Var(destmemidx)));
}
Result BinaryReaderIR::OnDataDropExpr(Index segment) {
return AppendExpr(MakeUnique<DataDropExpr>(Var(segment)));
}
-Result BinaryReaderIR::OnMemoryFillExpr() {
- return AppendExpr(MakeUnique<MemoryFillExpr>());
+Result BinaryReaderIR::OnMemoryFillExpr(Index memidx) {
+ return AppendExpr(MakeUnique<MemoryFillExpr>(Var(memidx)));
}
-Result BinaryReaderIR::OnMemoryGrowExpr() {
- return AppendExpr(MakeUnique<MemoryGrowExpr>());
+Result BinaryReaderIR::OnMemoryGrowExpr(Index memidx) {
+ return AppendExpr(MakeUnique<MemoryGrowExpr>(Var(memidx)));
}
-Result BinaryReaderIR::OnMemoryInitExpr(Index segment) {
- return AppendExpr(MakeUnique<MemoryInitExpr>(Var(segment)));
+Result BinaryReaderIR::OnMemoryInitExpr(Index segment, Index memidx) {
+ return AppendExpr(MakeUnique<MemoryInitExpr>(Var(segment), Var(memidx)));
}
-Result BinaryReaderIR::OnMemorySizeExpr() {
- return AppendExpr(MakeUnique<MemorySizeExpr>());
+Result BinaryReaderIR::OnMemorySizeExpr(Index memidx) {
+ return AppendExpr(MakeUnique<MemorySizeExpr>(Var(memidx)));
}
Result BinaryReaderIR::OnTableCopyExpr(Index dst_index, Index src_index) {
@@ -983,9 +988,11 @@ Result BinaryReaderIR::OnLocalSetExpr(Index local_index) {
}
Result BinaryReaderIR::OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(MakeUnique<StoreExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(
+ MakeUnique<StoreExpr>(opcode, Var(memidx), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnThrowExpr(Index tag_index) {
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
index 9fa906ba..6e0779a5 100644
--- a/src/binary-reader-logging.cc
+++ b/src/binary-reader-logging.cc
@@ -748,6 +748,15 @@ Result BinaryReaderLogging::OnComdatEntry(ComdatType kind, Index index) {
return reader_->name(opcode, alignment_log2, offset); \
}
+#define DEFINE_MEMORY_LOAD_STORE_OPCODE(name) \
+ Result BinaryReaderLogging::name(Opcode opcode, Index memidx, \
+ Address alignment_log2, Address offset) { \
+ LOGF(#name "(opcode: \"%s\" (%u), memidx: %" PRIindex \
+ ", align log2: %" PRIaddress ", offset: %" PRIaddress ")\n", \
+ opcode.GetName(), opcode.GetCode(), memidx, alignment_log2, offset); \
+ return reader_->name(opcode, memidx, alignment_log2, offset); \
+ }
+
#define DEFINE_SIMD_LOAD_STORE_LANE_OPCODE(name) \
Result BinaryReaderLogging::name(Opcode opcode, Address alignment_log2, \
Address offset, uint64_t value) { \
@@ -828,16 +837,16 @@ DEFINE0(OnElseExpr)
DEFINE0(OnEndExpr)
DEFINE_INDEX_DESC(OnGlobalGetExpr, "index")
DEFINE_INDEX_DESC(OnGlobalSetExpr, "index")
-DEFINE_LOAD_STORE_OPCODE(OnLoadExpr);
+DEFINE_MEMORY_LOAD_STORE_OPCODE(OnLoadExpr);
DEFINE_INDEX_DESC(OnLocalGetExpr, "index")
DEFINE_INDEX_DESC(OnLocalSetExpr, "index")
DEFINE_INDEX_DESC(OnLocalTeeExpr, "index")
-DEFINE0(OnMemoryCopyExpr)
+DEFINE_INDEX_INDEX(OnMemoryCopyExpr, "src_memory_index", "dest_memory_index")
DEFINE_INDEX(OnDataDropExpr)
-DEFINE0(OnMemoryFillExpr)
-DEFINE0(OnMemoryGrowExpr)
-DEFINE_INDEX(OnMemoryInitExpr)
-DEFINE0(OnMemorySizeExpr)
+DEFINE_INDEX(OnMemoryFillExpr)
+DEFINE_INDEX(OnMemoryGrowExpr)
+DEFINE_INDEX_INDEX(OnMemoryInitExpr, "segment_index", "memory_index")
+DEFINE_INDEX(OnMemorySizeExpr)
DEFINE_INDEX_INDEX(OnTableCopyExpr, "dst_index", "src_index")
DEFINE_INDEX(OnElemDropExpr)
DEFINE_INDEX_INDEX(OnTableInitExpr, "segment_index", "table_index")
@@ -857,7 +866,7 @@ DEFINE_INDEX_INDEX(OnReturnCallIndirectExpr, "sig_index", "table_index")
DEFINE0(OnReturnExpr)
DEFINE_LOAD_STORE_OPCODE(OnLoadSplatExpr);
DEFINE_LOAD_STORE_OPCODE(OnLoadZeroExpr);
-DEFINE_LOAD_STORE_OPCODE(OnStoreExpr);
+DEFINE_MEMORY_LOAD_STORE_OPCODE(OnStoreExpr);
DEFINE_INDEX_DESC(OnThrowExpr, "tag_index")
DEFINE0(OnUnreachableExpr)
DEFINE_OPCODE(OnUnaryExpr)
diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h
index 41ecf07d..d1531b35 100644
--- a/src/binary-reader-logging.h
+++ b/src/binary-reader-logging.h
@@ -185,18 +185,19 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnI64ConstExpr(uint64_t value) override;
Result OnIfExpr(Type sig_type) override;
Result OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLocalGetExpr(Index local_index) override;
Result OnLocalSetExpr(Index local_index) override;
Result OnLocalTeeExpr(Index local_index) override;
Result OnLoopExpr(Type sig_type) override;
- Result OnMemoryCopyExpr() override;
+ Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override;
Result OnDataDropExpr(Index segment_index) override;
- Result OnMemoryFillExpr() override;
- Result OnMemoryGrowExpr() override;
- Result OnMemoryInitExpr(Index segment_index) override;
- Result OnMemorySizeExpr() override;
+ Result OnMemoryFillExpr(Index memidx) override;
+ Result OnMemoryGrowExpr(Index memidx) override;
+ Result OnMemoryInitExpr(Index segment_index, Index memidx) override;
+ Result OnMemorySizeExpr(Index memidx) override;
Result OnTableCopyExpr(Index dst_index, Index src_index) override;
Result OnElemDropExpr(Index segment_index) override;
Result OnTableInitExpr(Index segment_index, Index table_index) override;
@@ -215,6 +216,7 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnReturnExpr() override;
Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnThrowExpr(Index tag_index) override;
diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h
index 167ea8c7..256ac920 100644
--- a/src/binary-reader-nop.h
+++ b/src/binary-reader-nop.h
@@ -256,6 +256,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnI64ConstExpr(uint64_t value) override { return Result::Ok; }
Result OnIfExpr(Type sig_type) override { return Result::Ok; }
Result OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
@@ -264,12 +265,16 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnLocalSetExpr(Index local_index) override { return Result::Ok; }
Result OnLocalTeeExpr(Index local_index) override { return Result::Ok; }
Result OnLoopExpr(Type sig_type) override { return Result::Ok; }
- Result OnMemoryCopyExpr() override { return Result::Ok; }
+ Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override {
+ return Result::Ok;
+ }
Result OnDataDropExpr(Index segment_index) override { return Result::Ok; }
- Result OnMemoryFillExpr() override { return Result::Ok; }
- Result OnMemoryGrowExpr() override { return Result::Ok; }
- Result OnMemoryInitExpr(Index segment_index) override { return Result::Ok; }
- Result OnMemorySizeExpr() override { return Result::Ok; }
+ Result OnMemoryFillExpr(Index memidx) override { return Result::Ok; }
+ Result OnMemoryGrowExpr(Index memidx) override { return Result::Ok; }
+ Result OnMemoryInitExpr(Index segment_index, Index memidx) override {
+ return Result::Ok;
+ }
+ Result OnMemorySizeExpr(Index memidx) override { return Result::Ok; }
Result OnTableCopyExpr(Index dst_index, Index src_index) override {
return Result::Ok;
}
@@ -294,6 +299,7 @@ class BinaryReaderNop : public BinaryReaderDelegate {
return Result::Ok;
}
Result OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index 9c6aeffb..c146c7ec 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -110,6 +110,7 @@ class BinaryReader {
Result ReadIndex(Index* index, const char* desc) WABT_WARN_UNUSED;
Result ReadOffset(Offset* offset, const char* desc) WABT_WARN_UNUSED;
Result ReadAlignment(Address* align_log2, const char* desc) WABT_WARN_UNUSED;
+ Result ReadMemidx(Index* memidx, const char* desc) WABT_WARN_UNUSED;
Result ReadCount(Index* index, const char* desc) WABT_WARN_UNUSED;
Result ReadField(TypeMut* out_value) WABT_WARN_UNUSED;
@@ -398,7 +399,8 @@ Result BinaryReader::ReadOffset(Offset* offset, const char* desc) {
Result BinaryReader::ReadAlignment(Address* alignment_log2, const char* desc) {
uint32_t value;
CHECK_RESULT(ReadU32Leb128(&value, desc));
- if (value >= 32) {
+ if (value >= 128 ||
+ (value >= 32 && !options_.features.multi_memory_enabled())) {
PrintError("invalid %s: %u", desc, value);
return Result::Error;
}
@@ -406,6 +408,13 @@ Result BinaryReader::ReadAlignment(Address* alignment_log2, const char* desc) {
return Result::Ok;
}
+Result BinaryReader::ReadMemidx(Index* memidx, const char* desc) {
+ CHECK_RESULT(ReadIndex(memidx, desc));
+ ERROR_UNLESS(*memidx < memories.size(), "memory index %u out of range",
+ *memidx);
+ return Result::Ok;
+}
+
Result BinaryReader::ReadCount(Index* count, const char* desc) {
CHECK_RESULT(ReadIndex(count, desc));
@@ -953,8 +962,20 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
Address offset;
CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
- CALLBACK(OnLoadExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ Index memidx = 0;
+ if (alignment_log2 >> 6) {
+ ERROR_IF(!options_.features.multi_memory_enabled(),
+ "multi_memory not allowed");
+ CHECK_RESULT(ReadMemidx(&memidx, "store memidx"));
+ alignment_log2 = alignment_log2 & ((1 << 6) - 1);
+ }
+
+ CALLBACK(OnLoadExpr, opcode, memidx, alignment_log2, offset);
+ if (memidx) {
+ CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, memidx);
+ } else {
+ CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ }
break;
}
@@ -972,27 +993,48 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
CHECK_RESULT(ReadAlignment(&alignment_log2, "store alignment"));
Address offset;
CHECK_RESULT(ReadAddress(&offset, 0, "store offset"));
+ Index memidx = 0;
+ if (alignment_log2 >> 6) {
+ ERROR_IF(!options_.features.multi_memory_enabled(),
+ "multi_memory not allowed");
+ CHECK_RESULT(ReadMemidx(&memidx, "store memidx"));
+ alignment_log2 = alignment_log2 & ((1 << 6) - 1);
+ }
- CALLBACK(OnStoreExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CALLBACK(OnStoreExpr, opcode, memidx, alignment_log2, offset);
+ if (memidx) {
+ CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, memidx);
+ } else {
+ CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ }
break;
}
case Opcode::MemorySize: {
- uint8_t reserved;
- CHECK_RESULT(ReadU8(&reserved, "memory.size reserved"));
- ERROR_UNLESS(reserved == 0, "memory.size reserved value must be 0");
- CALLBACK0(OnMemorySizeExpr);
- CALLBACK(OnOpcodeUint32, reserved);
+ Index memidx = 0;
+ if (!options_.features.multi_memory_enabled()) {
+ uint8_t reserved;
+ CHECK_RESULT(ReadU8(&reserved, "memory.size reserved"));
+ ERROR_UNLESS(reserved == 0, "memory.size reserved value must be 0");
+ } else {
+ CHECK_RESULT(ReadMemidx(&memidx, "memory.size memidx"));
+ }
+ CALLBACK(OnMemorySizeExpr, memidx);
+ CALLBACK(OnOpcodeUint32, memidx);
break;
}
case Opcode::MemoryGrow: {
- uint8_t reserved;
- CHECK_RESULT(ReadU8(&reserved, "memory.grow reserved"));
- ERROR_UNLESS(reserved == 0, "memory.grow reserved value must be 0");
- CALLBACK0(OnMemoryGrowExpr);
- CALLBACK(OnOpcodeUint32, reserved);
+ Index memidx = 0;
+ if (!options_.features.multi_memory_enabled()) {
+ uint8_t reserved;
+ CHECK_RESULT(ReadU8(&reserved, "memory.grow reserved"));
+ ERROR_UNLESS(reserved == 0, "memory.grow reserved value must be 0");
+ } else {
+ CHECK_RESULT(ReadMemidx(&memidx, "memory.grow memidx"));
+ }
+ CALLBACK(OnMemoryGrowExpr, memidx);
+ CALLBACK(OnOpcodeUint32, memidx);
break;
}
@@ -1640,11 +1682,16 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
ERROR_IF(data_count_ == kInvalidIndex,
"memory.init requires data count section");
CHECK_RESULT(ReadIndex(&segment, "elem segment index"));
- uint8_t reserved;
- CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
- ERROR_UNLESS(reserved == 0, "reserved value must be 0");
- CALLBACK(OnMemoryInitExpr, segment);
- CALLBACK(OnOpcodeUint32Uint32, segment, reserved);
+ Index memidx = 0;
+ if (!options_.features.multi_memory_enabled()) {
+ uint8_t reserved;
+ CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
+ ERROR_UNLESS(reserved == 0, "reserved value must be 0");
+ } else {
+ CHECK_RESULT(ReadMemidx(&memidx, "memory.init memidx"));
+ }
+ CALLBACK(OnMemoryInitExpr, segment, memidx);
+ CALLBACK(OnOpcodeUint32Uint32, segment, memidx);
break;
}
@@ -1665,21 +1712,34 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) {
}
case Opcode::MemoryFill: {
- uint8_t reserved;
- CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
- ERROR_UNLESS(reserved == 0, "reserved value must be 0");
- CALLBACK(OnMemoryFillExpr);
- CALLBACK(OnOpcodeUint32, reserved);
+ Index memidx = 0;
+ if (!options_.features.multi_memory_enabled()) {
+ uint8_t reserved;
+ CHECK_RESULT(ReadU8(&reserved, "memory.fill reserved"));
+ ERROR_UNLESS(reserved == 0, "memory.fill reserved value must be 0");
+ } else {
+ CHECK_RESULT(ReadMemidx(&memidx, "memory.fill memidx"));
+ }
+ CALLBACK(OnMemoryFillExpr, memidx);
+ CALLBACK(OnOpcodeUint32, memidx);
break;
}
+
case Opcode::MemoryCopy: {
- uint8_t reserved;
- CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
- ERROR_UNLESS(reserved == 0, "reserved value must be 0");
- CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
- ERROR_UNLESS(reserved == 0, "reserved value must be 0");
- CALLBACK(OnMemoryCopyExpr);
- CALLBACK(OnOpcodeUint32Uint32, reserved, reserved);
+ Index srcmemidx = 0;
+ Index destmemidx = 0;
+ if (!options_.features.multi_memory_enabled()) {
+ uint8_t reserved;
+ CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
+ ERROR_UNLESS(reserved == 0, "reserved value must be 0");
+ CHECK_RESULT(ReadU8(&reserved, "reserved memory index"));
+ ERROR_UNLESS(reserved == 0, "reserved value must be 0");
+ } else {
+ CHECK_RESULT(ReadMemidx(&srcmemidx, "memory.copy srcmemidx"));
+ CHECK_RESULT(ReadMemidx(&destmemidx, "memory.copy destmemindex"));
+ }
+ CALLBACK(OnMemoryCopyExpr, srcmemidx, destmemidx);
+ CALLBACK(OnOpcodeUint32Uint32, srcmemidx, destmemidx);
break;
}
diff --git a/src/binary-reader.h b/src/binary-reader.h
index ff954d9d..a10fa395 100644
--- a/src/binary-reader.h
+++ b/src/binary-reader.h
@@ -251,18 +251,19 @@ class BinaryReaderDelegate {
virtual Result OnI64ConstExpr(uint64_t value) = 0;
virtual Result OnIfExpr(Type sig_type) = 0;
virtual Result OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnLocalGetExpr(Index local_index) = 0;
virtual Result OnLocalSetExpr(Index local_index) = 0;
virtual Result OnLocalTeeExpr(Index local_index) = 0;
virtual Result OnLoopExpr(Type sig_type) = 0;
- virtual Result OnMemoryCopyExpr() = 0;
+ virtual Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) = 0;
virtual Result OnDataDropExpr(Index segment_index) = 0;
- virtual Result OnMemoryFillExpr() = 0;
- virtual Result OnMemoryGrowExpr() = 0;
- virtual Result OnMemoryInitExpr(Index segment_index) = 0;
- virtual Result OnMemorySizeExpr() = 0;
+ virtual Result OnMemoryFillExpr(Index memidx) = 0;
+ virtual Result OnMemoryGrowExpr(Index memidx) = 0;
+ virtual Result OnMemoryInitExpr(Index segment_index, Index memidx) = 0;
+ virtual Result OnMemorySizeExpr(Index memidx) = 0;
virtual Result OnTableCopyExpr(Index dst_index, Index src_index) = 0;
virtual Result OnElemDropExpr(Index segment_index) = 0;
virtual Result OnTableInitExpr(Index segment_index, Index table_index) = 0;
@@ -282,6 +283,7 @@ class BinaryReaderDelegate {
Index table_index) = 0;
virtual Result OnSelectExpr(Index result_count, Type* result_types) = 0;
virtual Result OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnThrowExpr(Index tag_index) = 0;
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index d78d98df..c3adfbf6 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -386,7 +386,13 @@ class BinaryWriter {
template <typename T>
void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc);
template <typename T>
- void WriteSimdLoadStoreLaneExpr(const Func* func, const Expr* expr, const char* desc);
+ void WriteMemoryLoadStoreExpr(const Func* func,
+ const Expr* expr,
+ const char* desc);
+ template <typename T>
+ void WriteSimdLoadStoreLaneExpr(const Func* func,
+ const Expr* expr,
+ const char* desc);
void WriteExpr(const Func* func, const Expr* expr);
void WriteExprList(const Func* func, const ExprList& exprs);
void WriteInitExpr(const ExprList& expr);
@@ -659,6 +665,24 @@ void BinaryWriter::WriteLoadStoreExpr(const Func* func,
}
template <typename T>
+void BinaryWriter::WriteMemoryLoadStoreExpr(const Func* func,
+ const Expr* expr,
+ const char* desc) {
+ auto* typed_expr = cast<T>(expr);
+ WriteOpcode(stream_, typed_expr->opcode);
+ Address align = typed_expr->opcode.GetAlignment(typed_expr->align);
+ Index memidx = module_->GetMemoryIndex(typed_expr->memidx);
+ if (memidx != 0) {
+ stream_->WriteU8(log2_u32(align) | (1 << 6), "alignment");
+ WriteU32Leb128(stream_, typed_expr->offset, desc);
+ WriteU32Leb128(stream_, memidx, "memidx");
+ } else {
+ stream_->WriteU8(log2_u32(align), "alignment");
+ WriteU32Leb128(stream_, typed_expr->offset, desc);
+ }
+};
+
+template <typename T>
void BinaryWriter::WriteSimdLoadStoreLaneExpr(const Func* func,
const Expr* expr,
const char* desc) {
@@ -828,7 +852,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
break;
}
case ExprType::Load:
- WriteLoadStoreExpr<LoadExpr>(func, expr, "load offset");
+ WriteMemoryLoadStoreExpr<LoadExpr>(func, expr, "load offset");
break;
case ExprType::LocalGet: {
Index index = GetLocalIndex(func, cast<LocalGetExpr>(expr)->var);
@@ -854,11 +878,16 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
WriteExprList(func, cast<LoopExpr>(expr)->block.exprs);
WriteOpcode(stream_, Opcode::End);
break;
- case ExprType::MemoryCopy:
+ case ExprType::MemoryCopy: {
+ Index srcmemidx =
+ module_->GetMemoryIndex(cast<MemoryCopyExpr>(expr)->srcmemidx);
+ Index destmemidx =
+ module_->GetMemoryIndex(cast<MemoryCopyExpr>(expr)->destmemidx);
WriteOpcode(stream_, Opcode::MemoryCopy);
- WriteU32Leb128(stream_, 0, "memory.copy reserved");
- WriteU32Leb128(stream_, 0, "memory.copy reserved");
+ WriteU32Leb128(stream_, srcmemidx, "memory.copy srcmemidx");
+ WriteU32Leb128(stream_, destmemidx, "memory.copy destmemidx");
break;
+ }
case ExprType::DataDrop: {
Index index =
module_->GetDataSegmentIndex(cast<DataDropExpr>(expr)->var);
@@ -867,27 +896,38 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
has_data_segment_instruction_ = true;
break;
}
- case ExprType::MemoryFill:
+ case ExprType::MemoryFill: {
+ Index memidx =
+ module_->GetMemoryIndex(cast<MemoryFillExpr>(expr)->memidx);
WriteOpcode(stream_, Opcode::MemoryFill);
- WriteU32Leb128(stream_, 0, "memory.fill reserved");
+ WriteU32Leb128(stream_, memidx, "memory.fill memidx");
break;
- case ExprType::MemoryGrow:
+ }
+ case ExprType::MemoryGrow: {
+ Index memidx =
+ module_->GetMemoryIndex(cast<MemoryGrowExpr>(expr)->memidx);
WriteOpcode(stream_, Opcode::MemoryGrow);
- WriteU32Leb128(stream_, 0, "memory.grow reserved");
+ WriteU32Leb128(stream_, memidx, "memory.grow memidx");
break;
+ }
case ExprType::MemoryInit: {
Index index =
module_->GetDataSegmentIndex(cast<MemoryInitExpr>(expr)->var);
+ Index memidx =
+ module_->GetMemoryIndex(cast<MemoryInitExpr>(expr)->memidx);
WriteOpcode(stream_, Opcode::MemoryInit);
WriteU32Leb128(stream_, index, "memory.init segment");
- WriteU32Leb128(stream_, 0, "memory.init reserved");
+ WriteU32Leb128(stream_, memidx, "memory.init memidx");
has_data_segment_instruction_ = true;
break;
}
- case ExprType::MemorySize:
+ case ExprType::MemorySize: {
+ Index memidx =
+ module_->GetMemoryIndex(cast<MemorySizeExpr>(expr)->memidx);
WriteOpcode(stream_, Opcode::MemorySize);
- WriteU32Leb128(stream_, 0, "memory.size reserved");
+ WriteU32Leb128(stream_, memidx, "memory.size memidx");
break;
+ }
case ExprType::TableCopy: {
auto* copy_expr = cast<TableCopyExpr>(expr);
Index dst = module_->GetTableIndex(copy_expr->dst_table);
@@ -989,7 +1029,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
break;
}
case ExprType::Store:
- WriteLoadStoreExpr<StoreExpr>(func, expr, "store offset");
+ WriteMemoryLoadStoreExpr<StoreExpr>(func, expr, "store offset");
break;
case ExprType::Throw:
WriteOpcode(stream_, Opcode::Throw);
@@ -1591,7 +1631,13 @@ Result BinaryWriter::WriteModule() {
uint8_t flags = segment->GetFlags(module_);
stream_->WriteU8(flags, "segment flags");
if (!(flags & SegPassive)) {
- assert(module_->GetMemoryIndex(segment->memory_var) == 0);
+ if (options_.features.multi_memory_enabled() &&
+ (flags & SegExplicitIndex)) {
+ WriteU32Leb128(stream_, module_->GetMemoryIndex(segment->memory_var),
+ "memidx");
+ } else {
+ assert(module_->GetMemoryIndex(segment->memory_var) == 0);
+ }
WriteInitExpr(segment->offset);
}
WriteU32Leb128(stream_, segment->data.size(), "data segment size");
diff --git a/src/c-writer.cc b/src/c-writer.cc
index df8c037b..d4381a6e 100644
--- a/src/c-writer.cc
+++ b/src/c-writer.cc
@@ -1001,7 +1001,6 @@ void CWriter::WriteMemories() {
Write(Newline());
- assert(module_->memories.size() <= 1);
Index memory_index = 0;
for (const Memory* memory : module_->memories) {
bool is_import = memory_index < module_->num_memory_imports;
@@ -1069,11 +1068,15 @@ void CWriter::WriteDataInitializers() {
}
Write(Newline(), "static void init_memory(void) ", OpenBrace());
- if (memory && module_->num_memory_imports == 0) {
- uint32_t max =
- memory->page_limits.has_max ? memory->page_limits.max : 65536;
- Write("wasm_rt_allocate_memory(", ExternalPtr(memory->name), ", ",
- memory->page_limits.initial, ", ", max, ");", Newline());
+ if (module_->memories.size() > module_->num_memory_imports) {
+ Index memory_idx = module_->num_memory_imports;
+ for (Index i = memory_idx; i < module_->memories.size(); i++) {
+ memory = module_->memories[i];
+ uint32_t max =
+ memory->page_limits.has_max ? memory->page_limits.max : 65536;
+ Write("wasm_rt_allocate_memory(", ExternalPtr(memory->name), ", ",
+ memory->page_limits.initial, ", ", max, ");", Newline());
+ }
}
data_segment_index = 0;
for (const DataSegment* data_segment : module_->data_segments) {
@@ -1613,8 +1616,8 @@ void CWriter::Write(const ExprList& exprs) {
break;
case ExprType::MemoryGrow: {
- assert(module_->memories.size() == 1);
- Memory* memory = module_->memories[0];
+ Memory* memory = module_->memories[module_->GetMemoryIndex(
+ cast<MemoryGrowExpr>(&expr)->memidx)];
Write(StackVar(0), " = wasm_rt_grow_memory(", ExternalPtr(memory->name),
", ", StackVar(0), ");", Newline());
@@ -1622,8 +1625,8 @@ void CWriter::Write(const ExprList& exprs) {
}
case ExprType::MemorySize: {
- assert(module_->memories.size() == 1);
- Memory* memory = module_->memories[0];
+ Memory* memory = module_->memories[module_->GetMemoryIndex(
+ cast<MemorySizeExpr>(&expr)->memidx)];
PushType(Type::I32);
Write(StackVar(0), " = ", ExternalRef(memory->name), ".pages;",
@@ -2119,8 +2122,7 @@ void CWriter::Write(const LoadExpr& expr) {
WABT_UNREACHABLE;
}
- assert(module_->memories.size() == 1);
- Memory* memory = module_->memories[0];
+ Memory* memory = module_->memories[module_->GetMemoryIndex(expr.memidx)];
Type result_type = expr.opcode.GetResultType();
Write(StackVar(0, result_type), " = ", func, "(", ExternalPtr(memory->name),
@@ -2149,8 +2151,7 @@ void CWriter::Write(const StoreExpr& expr) {
WABT_UNREACHABLE;
}
- assert(module_->memories.size() == 1);
- Memory* memory = module_->memories[0];
+ Memory* memory = module_->memories[module_->GetMemoryIndex(expr.memidx)];
Write(func, "(", ExternalPtr(memory->name), ", (u64)(", StackVar(1), ")");
if (expr.offset != 0)
diff --git a/src/feature.def b/src/feature.def
index 238e8518..cecab3e6 100644
--- a/src/feature.def
+++ b/src/feature.def
@@ -36,3 +36,4 @@ WABT_FEATURE(reference_types, "reference-types", true, "Reference
WABT_FEATURE(annotations, "annotations", false, "Custom annotation syntax")
WABT_FEATURE(gc, "gc", false, "Garbage collection")
WABT_FEATURE(memory64, "memory64", false, "64-bit memory")
+WABT_FEATURE(multi_memory, "multi-memory", false, "Multi-memory")
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc
index eaae9f1b..0cec0c21 100644
--- a/src/interp/binary-reader-interp.cc
+++ b/src/interp/binary-reader-interp.cc
@@ -196,19 +196,20 @@ class BinaryReaderInterp : public BinaryReaderNop {
Result OnI64ConstExpr(uint64_t value) override;
Result OnIfExpr(Type sig_type) override;
Result OnLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLocalGetExpr(Index local_index) override;
Result OnLocalSetExpr(Index local_index) override;
Result OnLocalTeeExpr(Index local_index) override;
Result OnLoopExpr(Type sig_type) override;
- Result OnMemoryCopyExpr() override;
+ Result OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) override;
Result OnDataDropExpr(Index segment_index) override;
- Result OnMemoryGrowExpr() override;
- Result OnMemoryFillExpr() override;
- Result OnMemoryInitExpr(Index segment_index) override;
- Result OnMemorySizeExpr() override;
- Result OnRefFuncExpr(Index type_index) override;
+ Result OnMemoryGrowExpr(Index memidx) override;
+ Result OnMemoryFillExpr(Index memidx) override;
+ Result OnMemoryInitExpr(Index segment_index, Index memidx) override;
+ Result OnMemorySizeExpr(Index memidx) override;
+ Result OnRefFuncExpr(Index func_index) override;
Result OnRefNullExpr(Type type) override;
Result OnRefIsNullExpr() override;
Result OnNopExpr() override;
@@ -216,6 +217,7 @@ class BinaryReaderInterp : public BinaryReaderNop {
Result OnReturnExpr() override;
Result OnSelectExpr(Index result_count, Type* result_types) override;
Result OnStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnUnaryExpr(Opcode opcode) override;
@@ -1331,30 +1333,34 @@ Result BinaryReaderInterp::OnLocalTeeExpr(Index local_index) {
}
Result BinaryReaderInterp::OnLoadExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(validator_.OnLoad(loc, opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(
+ validator_.OnLoad(loc, opcode, Var(memidx), GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnStoreExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(validator_.OnStore(loc, opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(
+ validator_.OnStore(loc, opcode, Var(memidx), GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
-Result BinaryReaderInterp::OnMemoryGrowExpr() {
- CHECK_RESULT(validator_.OnMemoryGrow(loc));
- istream_.Emit(Opcode::MemoryGrow, kMemoryIndex0);
+Result BinaryReaderInterp::OnMemoryGrowExpr(Index memidx) {
+ CHECK_RESULT(validator_.OnMemoryGrow(loc, Var(memidx)));
+ istream_.Emit(Opcode::MemoryGrow, memidx);
return Result::Ok;
}
-Result BinaryReaderInterp::OnMemorySizeExpr() {
- CHECK_RESULT(validator_.OnMemorySize(loc));
- istream_.Emit(Opcode::MemorySize, kMemoryIndex0);
+Result BinaryReaderInterp::OnMemorySizeExpr(Index memidx) {
+ CHECK_RESULT(validator_.OnMemorySize(loc, Var(memidx)));
+ istream_.Emit(Opcode::MemorySize, memidx);
return Result::Ok;
}
@@ -1447,9 +1453,9 @@ Result BinaryReaderInterp::OnAtomicNotifyExpr(Opcode opcode,
return Result::Ok;
}
-Result BinaryReaderInterp::OnMemoryCopyExpr() {
- CHECK_RESULT(validator_.OnMemoryCopy(loc));
- istream_.Emit(Opcode::MemoryCopy, kMemoryIndex0, kMemoryIndex0);
+Result BinaryReaderInterp::OnMemoryCopyExpr(Index srcmemidx, Index destmemidx) {
+ CHECK_RESULT(validator_.OnMemoryCopy(loc, Var(srcmemidx), Var(destmemidx)));
+ istream_.Emit(Opcode::MemoryCopy, srcmemidx, destmemidx);
return Result::Ok;
}
@@ -1459,15 +1465,15 @@ Result BinaryReaderInterp::OnDataDropExpr(Index segment_index) {
return Result::Ok;
}
-Result BinaryReaderInterp::OnMemoryFillExpr() {
- CHECK_RESULT(validator_.OnMemoryFill(loc));
- istream_.Emit(Opcode::MemoryFill, kMemoryIndex0);
+Result BinaryReaderInterp::OnMemoryFillExpr(Index memidx) {
+ CHECK_RESULT(validator_.OnMemoryFill(loc, Var(memidx)));
+ istream_.Emit(Opcode::MemoryFill, memidx);
return Result::Ok;
}
-Result BinaryReaderInterp::OnMemoryInitExpr(Index segment_index) {
- CHECK_RESULT(validator_.OnMemoryInit(loc, Var(segment_index)));
- istream_.Emit(Opcode::MemoryInit, kMemoryIndex0, segment_index);
+Result BinaryReaderInterp::OnMemoryInitExpr(Index segment_index, Index memidx) {
+ CHECK_RESULT(validator_.OnMemoryInit(loc, Var(segment_index), Var(memidx)));
+ istream_.Emit(Opcode::MemoryInit, memidx, segment_index);
return Result::Ok;
}
diff --git a/src/ir.h b/src/ir.h
index 286a4420..31597d40 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -418,15 +418,40 @@ class ExprMixin : public Expr {
explicit ExprMixin(const Location& loc = Location()) : Expr(TypeEnum, loc) {}
};
+template <ExprType TypeEnum>
+class MemoryExpr : public ExprMixin<TypeEnum> {
+ public:
+ MemoryExpr(Var memidx, const Location& loc = Location())
+ : ExprMixin<TypeEnum>(loc), memidx(memidx) {}
+
+ Var memidx;
+};
+
+template <ExprType TypeEnum>
+class MemoryBinaryExpr : public ExprMixin<TypeEnum> {
+ public:
+ MemoryBinaryExpr(Var srcmemidx,
+ Var destmemidx,
+ const Location& loc = Location())
+ : ExprMixin<TypeEnum>(loc),
+ srcmemidx(srcmemidx),
+ destmemidx(destmemidx) {}
+
+ Var srcmemidx;
+ Var destmemidx;
+};
+
typedef ExprMixin<ExprType::Drop> DropExpr;
-typedef ExprMixin<ExprType::MemoryGrow> MemoryGrowExpr;
-typedef ExprMixin<ExprType::MemorySize> MemorySizeExpr;
-typedef ExprMixin<ExprType::MemoryCopy> MemoryCopyExpr;
-typedef ExprMixin<ExprType::MemoryFill> MemoryFillExpr;
typedef ExprMixin<ExprType::Nop> NopExpr;
typedef ExprMixin<ExprType::Return> ReturnExpr;
typedef ExprMixin<ExprType::Unreachable> UnreachableExpr;
+typedef MemoryExpr<ExprType::MemoryGrow> MemoryGrowExpr;
+typedef MemoryExpr<ExprType::MemorySize> MemorySizeExpr;
+typedef MemoryExpr<ExprType::MemoryFill> MemoryFillExpr;
+
+typedef MemoryBinaryExpr<ExprType::MemoryCopy> MemoryCopyExpr;
+
template <ExprType TypeEnum>
class RefTypeExpr : public ExprMixin<TypeEnum> {
public:
@@ -515,6 +540,15 @@ class VarExpr : public ExprMixin<TypeEnum> {
Var var;
};
+template <ExprType TypeEnum>
+class MemoryVarExpr : public MemoryExpr<TypeEnum> {
+ public:
+ MemoryVarExpr(const Var& var, Var memidx, const Location& loc = Location())
+ : MemoryExpr<TypeEnum>(memidx, loc), var(var) {}
+
+ Var var;
+};
+
typedef VarExpr<ExprType::Br> BrExpr;
typedef VarExpr<ExprType::BrIf> BrIfExpr;
typedef VarExpr<ExprType::Call> CallExpr;
@@ -528,7 +562,6 @@ typedef VarExpr<ExprType::ReturnCall> ReturnCallExpr;
typedef VarExpr<ExprType::Throw> ThrowExpr;
typedef VarExpr<ExprType::Rethrow> RethrowExpr;
-typedef VarExpr<ExprType::MemoryInit> MemoryInitExpr;
typedef VarExpr<ExprType::DataDrop> DataDropExpr;
typedef VarExpr<ExprType::ElemDrop> ElemDropExpr;
typedef VarExpr<ExprType::TableGet> TableGetExpr;
@@ -537,6 +570,8 @@ typedef VarExpr<ExprType::TableGrow> TableGrowExpr;
typedef VarExpr<ExprType::TableSize> TableSizeExpr;
typedef VarExpr<ExprType::TableFill> TableFillExpr;
+typedef MemoryVarExpr<ExprType::MemoryInit> MemoryInitExpr;
+
class SelectExpr : public ExprMixin<ExprType::Select> {
public:
SelectExpr(TypeVector type, const Location& loc = Location())
@@ -664,8 +699,27 @@ class LoadStoreExpr : public ExprMixin<TypeEnum> {
Address offset;
};
-typedef LoadStoreExpr<ExprType::Load> LoadExpr;
-typedef LoadStoreExpr<ExprType::Store> StoreExpr;
+template <ExprType TypeEnum>
+class MemoryLoadStoreExpr : public MemoryExpr<TypeEnum> {
+ public:
+ MemoryLoadStoreExpr(Opcode opcode,
+ Var memidx,
+ Address align,
+ Address offset,
+ const Location& loc = Location())
+ : MemoryExpr<TypeEnum>(memidx, loc),
+ opcode(opcode),
+ align(align),
+ offset(offset) {}
+
+ Opcode opcode;
+ Address align;
+ Address offset;
+};
+
+typedef MemoryLoadStoreExpr<ExprType::Load> LoadExpr;
+typedef MemoryLoadStoreExpr<ExprType::Store> StoreExpr;
+
typedef LoadStoreExpr<ExprType::AtomicLoad> AtomicLoadExpr;
typedef LoadStoreExpr<ExprType::AtomicStore> AtomicStoreExpr;
typedef LoadStoreExpr<ExprType::AtomicRmw> AtomicRmwExpr;
diff --git a/src/resolve-names.cc b/src/resolve-names.cc
index abd554ff..4c4c1495 100644
--- a/src/resolve-names.cc
+++ b/src/resolve-names.cc
@@ -51,13 +51,18 @@ class NameResolver : public ExprVisitor::DelegateNop {
Result OnGlobalSetExpr(GlobalSetExpr*) override;
Result BeginIfExpr(IfExpr*) override;
Result EndIfExpr(IfExpr*) override;
+ Result OnLoadExpr(LoadExpr*) override;
Result OnLocalGetExpr(LocalGetExpr*) override;
Result OnLocalSetExpr(LocalSetExpr*) override;
Result OnLocalTeeExpr(LocalTeeExpr*) override;
Result BeginLoopExpr(LoopExpr*) override;
Result EndLoopExpr(LoopExpr*) override;
+ Result OnMemoryCopyExpr(MemoryCopyExpr*) override;
Result OnDataDropExpr(DataDropExpr*) override;
+ Result OnMemoryFillExpr(MemoryFillExpr*) override;
+ Result OnMemoryGrowExpr(MemoryGrowExpr*) override;
Result OnMemoryInitExpr(MemoryInitExpr*) override;
+ Result OnMemorySizeExpr(MemorySizeExpr*) override;
Result OnElemDropExpr(ElemDropExpr*) override;
Result OnTableCopyExpr(TableCopyExpr*) override;
Result OnTableInitExpr(TableInitExpr*) override;
@@ -67,6 +72,7 @@ class NameResolver : public ExprVisitor::DelegateNop {
Result OnTableSizeExpr(TableSizeExpr*) override;
Result OnTableFillExpr(TableFillExpr*) override;
Result OnRefFuncExpr(RefFuncExpr*) override;
+ Result OnStoreExpr(StoreExpr*) override;
Result BeginTryExpr(TryExpr*) override;
Result EndTryExpr(TryExpr*) override;
Result OnThrowExpr(ThrowExpr*) override;
@@ -321,6 +327,11 @@ Result NameResolver::EndIfExpr(IfExpr* expr) {
return Result::Ok;
}
+Result NameResolver::OnLoadExpr(LoadExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
Result NameResolver::OnLocalGetExpr(LocalGetExpr* expr) {
ResolveLocalVar(&expr->var);
return Result::Ok;
@@ -336,13 +347,35 @@ Result NameResolver::OnLocalTeeExpr(LocalTeeExpr* expr) {
return Result::Ok;
}
+Result NameResolver::OnMemoryCopyExpr(MemoryCopyExpr* expr) {
+ ResolveMemoryVar(&expr->srcmemidx);
+ ResolveMemoryVar(&expr->destmemidx);
+ return Result::Ok;
+}
+
Result NameResolver::OnDataDropExpr(DataDropExpr* expr) {
ResolveDataSegmentVar(&expr->var);
return Result::Ok;
}
+Result NameResolver::OnMemoryFillExpr(MemoryFillExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
+Result NameResolver::OnMemoryGrowExpr(MemoryGrowExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
Result NameResolver::OnMemoryInitExpr(MemoryInitExpr* expr) {
ResolveDataSegmentVar(&expr->var);
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
+Result NameResolver::OnMemorySizeExpr(MemorySizeExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
return Result::Ok;
}
@@ -393,6 +426,11 @@ Result NameResolver::OnRefFuncExpr(RefFuncExpr* expr) {
return Result::Ok;
}
+Result NameResolver::OnStoreExpr(StoreExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
Result NameResolver::BeginTryExpr(TryExpr* expr) {
PushLabel(expr->block.label);
ResolveBlockDeclarationVar(&expr->block.decl);
diff --git a/src/shared-validator.cc b/src/shared-validator.cc
index 071a1c0f..2a5a4a8e 100644
--- a/src/shared-validator.cc
+++ b/src/shared-validator.cc
@@ -135,7 +135,7 @@ Result SharedValidator::OnTable(const Location& loc,
Result SharedValidator::OnMemory(const Location& loc, const Limits& limits) {
Result result = Result::Ok;
- if (memories_.size() > 0) {
+ if (memories_.size() > 0 && !options_.features.multi_memory_enabled()) {
result |= PrintError(loc, "only one memory block allowed");
}
result |= CheckLimits(
@@ -903,11 +903,12 @@ Result SharedValidator::OnIf(const Location& loc, Type sig_type) {
Result SharedValidator::OnLoad(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnLoad(opcode, mt.limits);
return result;
@@ -974,16 +975,19 @@ Result SharedValidator::OnLoop(const Location& loc, Type sig_type) {
return result;
}
-Result SharedValidator::OnMemoryCopy(const Location& loc) {
+Result SharedValidator::OnMemoryCopy(const Location& loc,
+ Var srcmemidx,
+ Var destmemidx) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(srcmemidx, &mt);
+ result |= CheckMemoryIndex(destmemidx, &mt);
result |= typechecker_.OnMemoryCopy(mt.limits);
return result;
}
-Result SharedValidator::OnMemoryFill(const Location& loc) {
+Result SharedValidator::OnMemoryFill(const Location& loc, Var memidx) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
@@ -992,30 +996,32 @@ Result SharedValidator::OnMemoryFill(const Location& loc) {
return result;
}
-Result SharedValidator::OnMemoryGrow(const Location& loc) {
+Result SharedValidator::OnMemoryGrow(const Location& loc, Var memidx) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= typechecker_.OnMemoryGrow(mt.limits);
return result;
}
-Result SharedValidator::OnMemoryInit(const Location& loc, Var segment_var) {
+Result SharedValidator::OnMemoryInit(const Location& loc,
+ Var segment_var,
+ Var memidx) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckDataSegmentIndex(segment_var);
result |= typechecker_.OnMemoryInit(segment_var.index(), mt.limits);
return result;
}
-Result SharedValidator::OnMemorySize(const Location& loc) {
+Result SharedValidator::OnMemorySize(const Location& loc, Var memidx) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= typechecker_.OnMemorySize(mt.limits);
return result;
}
@@ -1144,11 +1150,12 @@ Result SharedValidator::OnSimdShuffleOp(const Location& loc,
Result SharedValidator::OnStore(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = Result::Ok;
MemoryType mt;
expr_loc_ = &loc;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnStore(opcode, mt.limits);
return result;
diff --git a/src/shared-validator.h b/src/shared-validator.h
index 3bc02ff3..9c28af74 100644
--- a/src/shared-validator.h
+++ b/src/shared-validator.h
@@ -142,18 +142,18 @@ class SharedValidator {
Result OnGlobalGet(const Location&, Var);
Result OnGlobalSet(const Location&, Var);
Result OnIf(const Location&, Type sig_type);
- Result OnLoad(const Location&, Opcode, Address align);
+ Result OnLoad(const Location&, Opcode, Var memidx, Address align);
Result OnLoadSplat(const Location&, Opcode, Address align);
Result OnLoadZero(const Location&, Opcode, Address align);
Result OnLocalGet(const Location&, Var);
Result OnLocalSet(const Location&, Var);
Result OnLocalTee(const Location&, Var);
Result OnLoop(const Location&, Type sig_type);
- Result OnMemoryCopy(const Location&);
- Result OnMemoryFill(const Location&);
- Result OnMemoryGrow(const Location&);
- Result OnMemoryInit(const Location&, Var segment_var);
- Result OnMemorySize(const Location&);
+ Result OnMemoryCopy(const Location&, Var srcmemidx, Var destmemidx);
+ Result OnMemoryFill(const Location&, Var memidx);
+ Result OnMemoryGrow(const Location&, Var memidx);
+ Result OnMemoryInit(const Location&, Var segment_var, Var memidx);
+ Result OnMemorySize(const Location&, Var memidx);
Result OnNop(const Location&);
Result OnRefFunc(const Location&, Var func_var);
Result OnRefIsNull(const Location&);
@@ -167,7 +167,7 @@ class SharedValidator {
Result OnSimdLoadLane(const Location&, Opcode, Address align, uint64_t lane_idx);
Result OnSimdStoreLane(const Location&, Opcode, Address align, uint64_t lane_idx);
Result OnSimdShuffleOp(const Location&, Opcode, v128 lane_idx);
- Result OnStore(const Location&, Opcode, Address align);
+ Result OnStore(const Location&, Opcode, Var memidx, Address align);
Result OnTableCopy(const Location&, Var dst_var, Var src_var);
Result OnTableFill(const Location&, Var table_var);
Result OnTableGet(const Location&, Var table_var);
diff --git a/src/validator.cc b/src/validator.cc
index 672f698b..75c06211 100644
--- a/src/validator.cc
+++ b/src/validator.cc
@@ -334,7 +334,7 @@ Result Validator::EndIfExpr(IfExpr* expr) {
}
Result Validator::OnLoadExpr(LoadExpr* expr) {
- result_ |= validator_.OnLoad(expr->loc, expr->opcode,
+ result_ |= validator_.OnLoad(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
@@ -365,7 +365,8 @@ Result Validator::EndLoopExpr(LoopExpr* expr) {
}
Result Validator::OnMemoryCopyExpr(MemoryCopyExpr* expr) {
- result_ |= validator_.OnMemoryCopy(expr->loc);
+ result_ |=
+ validator_.OnMemoryCopy(expr->loc, expr->srcmemidx, expr->destmemidx);
return Result::Ok;
}
@@ -375,22 +376,22 @@ Result Validator::OnDataDropExpr(DataDropExpr* expr) {
}
Result Validator::OnMemoryFillExpr(MemoryFillExpr* expr) {
- result_ |= validator_.OnMemoryFill(expr->loc);
+ result_ |= validator_.OnMemoryFill(expr->loc, expr->memidx);
return Result::Ok;
}
Result Validator::OnMemoryGrowExpr(MemoryGrowExpr* expr) {
- result_ |= validator_.OnMemoryGrow(expr->loc);
+ result_ |= validator_.OnMemoryGrow(expr->loc, expr->memidx);
return Result::Ok;
}
Result Validator::OnMemoryInitExpr(MemoryInitExpr* expr) {
- result_ |= validator_.OnMemoryInit(expr->loc, expr->var);
+ result_ |= validator_.OnMemoryInit(expr->loc, expr->var, expr->memidx);
return Result::Ok;
}
Result Validator::OnMemorySizeExpr(MemorySizeExpr* expr) {
- result_ |= validator_.OnMemorySize(expr->loc);
+ result_ |= validator_.OnMemorySize(expr->loc, expr->memidx);
return Result::Ok;
}
@@ -484,7 +485,7 @@ Result Validator::OnSelectExpr(SelectExpr* expr) {
}
Result Validator::OnStoreExpr(StoreExpr* expr) {
- result_ |= validator_.OnStore(expr->loc, expr->opcode,
+ result_ |= validator_.OnStore(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index d12cbc44..79436fc1 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -1024,6 +1024,27 @@ bool WastParser::ParseAlignOpt(Address* out_align) {
}
}
+Result WastParser::ParseMemidx(Location loc, Var* out_memidx) {
+ WABT_TRACE(ParseMemidx);
+ if (PeekMatchLpar(TokenType::Memory)) {
+ if (!options_->features.multi_memory_enabled()) {
+ Error(loc, "Specifying memory variable is not allowed");
+ return Result::Error;
+ }
+ EXPECT(Lpar);
+ EXPECT(Memory);
+ CHECK_RESULT(ParseVar(out_memidx));
+ EXPECT(Rpar);
+ } else {
+ if (ParseVarOpt(out_memidx, Var(0, loc)) &&
+ !options_->features.multi_memory_enabled()) {
+ Error(loc, "Specifying memory variable is not allowed");
+ return Result::Error;
+ }
+ }
+ return Result::Ok;
+}
+
Result WastParser::ParseLimitsIndex(Limits* out_limits) {
WABT_TRACE(ParseLimitsIndex);
@@ -1861,6 +1882,34 @@ Result WastParser::ParsePlainInstrVar(Location loc,
}
template <typename T>
+Result WastParser::ParseMemoryInstrVar(Location loc,
+ std::unique_ptr<Expr>* out_expr) {
+ Var memidx;
+ Var var;
+ if (PeekMatchLpar(TokenType::Memory)) {
+ if (!options_->features.multi_memory_enabled()) {
+ Error(loc, "Specifying memory variable is not allowed");
+ return Result::Error;
+ }
+ CHECK_RESULT(ParseMemidx(loc, &memidx));
+ CHECK_RESULT(ParseVar(&var));
+ out_expr->reset(new T(var, memidx, loc));
+ } else {
+ CHECK_RESULT(ParseVar(&memidx));
+ if (ParseVarOpt(&var, Var(0, loc))) {
+ if (!options_->features.multi_memory_enabled()) {
+ Error(loc, "Specifiying memory variable is not allowed");
+ return Result::Error;
+ }
+ out_expr->reset(new T(var, memidx, loc));
+ } else {
+ out_expr->reset(new T(memidx, var, loc));
+ }
+ }
+ return Result::Ok;
+}
+
+template <typename T>
Result WastParser::ParsePlainLoadStoreInstr(Location loc,
Token token,
std::unique_ptr<Expr>* out_expr) {
@@ -1873,6 +1922,41 @@ Result WastParser::ParsePlainLoadStoreInstr(Location loc,
return Result::Ok;
}
+template <typename T>
+Result WastParser::ParseMemoryLoadStoreInstr(Location loc,
+ Token token,
+ std::unique_ptr<Expr>* out_expr) {
+ Opcode opcode = token.opcode();
+ Var memidx;
+ Address offset;
+ Address align;
+ CHECK_RESULT(ParseMemidx(loc, &memidx));
+ ParseOffsetOpt(&offset);
+ ParseAlignOpt(&align);
+ out_expr->reset(new T(opcode, memidx, align, offset, loc));
+ return Result::Ok;
+}
+
+template <typename T>
+Result WastParser::ParseMemoryExpr(Location loc,
+ std::unique_ptr<Expr>* out_expr) {
+ Var memidx;
+ CHECK_RESULT(ParseMemidx(loc, &memidx));
+ out_expr->reset(new T(memidx, loc));
+ return Result::Ok;
+}
+
+template <typename T>
+Result WastParser::ParseMemoryBinaryExpr(Location loc,
+ std::unique_ptr<Expr>* out_expr) {
+ Var srcmemidx;
+ Var destmemidx;
+ CHECK_RESULT(ParseMemidx(loc, &srcmemidx));
+ CHECK_RESULT(ParseMemidx(loc, &destmemidx));
+ out_expr->reset(new T(srcmemidx, destmemidx, loc));
+ return Result::Ok;
+}
+
Result WastParser::ParseSimdLane(Location loc, uint64_t* lane_idx) {
if (!PeekMatch(TokenType::Nat) && !PeekMatch(TokenType::Int)) {
return ErrorExpected({"a natural number in range [0, 32)"});
@@ -2019,12 +2103,12 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::Load:
CHECK_RESULT(
- ParsePlainLoadStoreInstr<LoadExpr>(loc, Consume(), out_expr));
+ ParseMemoryLoadStoreInstr<LoadExpr>(loc, Consume(), out_expr));
break;
case TokenType::Store:
CHECK_RESULT(
- ParsePlainLoadStoreInstr<StoreExpr>(loc, Consume(), out_expr));
+ ParseMemoryLoadStoreInstr<StoreExpr>(loc, Consume(), out_expr));
break;
case TokenType::Const: {
@@ -2061,12 +2145,12 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::MemoryCopy:
ErrorUnlessOpcodeEnabled(Consume());
- out_expr->reset(new MemoryCopyExpr(loc));
+ CHECK_RESULT(ParseMemoryBinaryExpr<MemoryCopyExpr>(loc, out_expr));
break;
case TokenType::MemoryFill:
ErrorUnlessOpcodeEnabled(Consume());
- out_expr->reset(new MemoryFillExpr(loc));
+ CHECK_RESULT(ParseMemoryExpr<MemoryFillExpr>(loc, out_expr));
break;
case TokenType::DataDrop:
@@ -2076,17 +2160,17 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::MemoryInit:
ErrorUnlessOpcodeEnabled(Consume());
- CHECK_RESULT(ParsePlainInstrVar<MemoryInitExpr>(loc, out_expr));
+ CHECK_RESULT(ParseMemoryInstrVar<MemoryInitExpr>(loc, out_expr));
break;
case TokenType::MemorySize:
Consume();
- out_expr->reset(new MemorySizeExpr(loc));
+ CHECK_RESULT(ParseMemoryExpr<MemorySizeExpr>(loc, out_expr));
break;
case TokenType::MemoryGrow:
Consume();
- out_expr->reset(new MemoryGrowExpr(loc));
+ CHECK_RESULT(ParseMemoryExpr<MemoryGrowExpr>(loc, out_expr));
break;
case TokenType::TableCopy: {
diff --git a/src/wast-parser.h b/src/wast-parser.h
index 1d304484..00285d31 100644
--- a/src/wast-parser.h
+++ b/src/wast-parser.h
@@ -143,6 +143,7 @@ class WastParser {
Result ParseQuotedText(std::string* text);
bool ParseOffsetOpt(Address* offset);
bool ParseAlignOpt(Address* align);
+ Result ParseMemidx(Location loc, Var* memidx);
Result ParseLimitsIndex(Limits*);
Result ParseLimits(Limits*);
Result ParseNat(uint64_t*, bool is_64);
@@ -203,7 +204,15 @@ class WastParser {
template <typename T>
Result ParsePlainInstrVar(Location, std::unique_ptr<Expr>*);
template <typename T>
+ Result ParseMemoryInstrVar(Location, std::unique_ptr<Expr>*);
+ template <typename T>
Result ParsePlainLoadStoreInstr(Location, Token, std::unique_ptr<Expr>*);
+ template <typename T>
+ Result ParseMemoryLoadStoreInstr(Location, Token, std::unique_ptr<Expr>*);
+ template <typename T>
+ Result ParseMemoryExpr(Location, std::unique_ptr<Expr>*);
+ template <typename T>
+ Result ParseMemoryBinaryExpr(Location, std::unique_ptr<Expr>*);
Result ParseSimdLane(Location, uint64_t*);
Result ParseCommandList(Script*, CommandPtrVector*);
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index 4f40fd2a..531cb5b9 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -122,6 +122,10 @@ class WatWriter : ModuleContext {
void WriteQuotedString(string_view str, NextChar next_char);
void WriteVar(const Var& var, NextChar next_char);
void WriteVarUnlessZero(const Var& var, NextChar next_char);
+ void WriteMemoryVarUnlessZero(const Var& memidx, NextChar next_char);
+ void WriteTwoMemoryVarsUnlessBothZero(const Var& srcmemidx,
+ const Var& destmemidx,
+ NextChar next_char);
void WriteBrVar(const Var& var, NextChar next_char);
void WriteRefKind(Type type, NextChar next_char);
void WriteType(Type type, NextChar next_char);
@@ -135,6 +139,8 @@ class WatWriter : ModuleContext {
void WriteExpr(const Expr* expr);
template <typename T>
void WriteLoadStoreExpr(const Expr* expr);
+ template <typename T>
+ void WriteMemoryLoadStoreExpr(const Expr* expr);
void WriteExprList(const ExprList& exprs);
void WriteInitExpr(const ExprList& expr);
template <typename T>
@@ -375,6 +381,27 @@ void WatWriter::WriteVarUnlessZero(const Var& var, NextChar next_char) {
}
}
+void WatWriter::WriteMemoryVarUnlessZero(const Var& memidx,
+ NextChar next_char) {
+ if (module.GetMemoryIndex(memidx) != 0) {
+ WriteVar(memidx, next_char);
+ } else {
+ next_char_ = next_char;
+ }
+}
+
+void WatWriter::WriteTwoMemoryVarsUnlessBothZero(const Var& srcmemidx,
+ const Var& destmemidx,
+ NextChar next_char) {
+ if (module.GetMemoryIndex(srcmemidx) != 0 ||
+ module.GetMemoryIndex(destmemidx) != 0) {
+ WriteVar(srcmemidx, NextChar::Space);
+ WriteVar(destmemidx, next_char);
+ } else {
+ next_char_ = next_char;
+ }
+}
+
void WatWriter::WriteBrVar(const Var& var, NextChar next_char) {
if (var.is_index()) {
if (var.index() < GetLabelStackSize()) {
@@ -504,6 +531,20 @@ void WatWriter::WriteLoadStoreExpr(const Expr* expr) {
WriteNewline(NO_FORCE_NEWLINE);
}
+template <typename T>
+void WatWriter::WriteMemoryLoadStoreExpr(const Expr* expr) {
+ auto typed_expr = cast<T>(expr);
+ WritePutsSpace(typed_expr->opcode.GetName());
+ WriteMemoryVarUnlessZero(typed_expr->memidx, NextChar::Space);
+ if (typed_expr->offset) {
+ Writef("offset=%" PRIaddress, typed_expr->offset);
+ }
+ if (!typed_expr->opcode.IsNaturallyAligned(typed_expr->align)) {
+ Writef("align=%" PRIaddress, typed_expr->align);
+ }
+ WriteNewline(NO_FORCE_NEWLINE);
+}
+
class WatWriter::ExprVisitorDelegate : public ExprVisitor::Delegate {
public:
explicit ExprVisitorDelegate(WatWriter* writer) : writer_(writer) {}
@@ -695,7 +736,7 @@ Result WatWriter::ExprVisitorDelegate::EndIfExpr(IfExpr* expr) {
}
Result WatWriter::ExprVisitorDelegate::OnLoadExpr(LoadExpr* expr) {
- writer_->WriteLoadStoreExpr<LoadExpr>(expr);
+ writer_->WriteMemoryLoadStoreExpr<LoadExpr>(expr);
return Result::Ok;
}
@@ -729,7 +770,10 @@ Result WatWriter::ExprVisitorDelegate::EndLoopExpr(LoopExpr* expr) {
}
Result WatWriter::ExprVisitorDelegate::OnMemoryCopyExpr(MemoryCopyExpr* expr) {
- writer_->WritePutsNewline(Opcode::MemoryCopy_Opcode.GetName());
+ writer_->WritePutsSpace(Opcode::MemoryCopy_Opcode.GetName());
+ writer_->WriteTwoMemoryVarsUnlessBothZero(expr->srcmemidx, expr->destmemidx,
+ NextChar::Space);
+ writer_->WriteNewline(NO_FORCE_NEWLINE);
return Result::Ok;
}
@@ -740,23 +784,31 @@ Result WatWriter::ExprVisitorDelegate::OnDataDropExpr(DataDropExpr* expr) {
}
Result WatWriter::ExprVisitorDelegate::OnMemoryFillExpr(MemoryFillExpr* expr) {
- writer_->WritePutsNewline(Opcode::MemoryFill_Opcode.GetName());
+ writer_->WritePutsSpace(Opcode::MemoryFill_Opcode.GetName());
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
+ writer_->WriteNewline(NO_FORCE_NEWLINE);
return Result::Ok;
}
Result WatWriter::ExprVisitorDelegate::OnMemoryGrowExpr(MemoryGrowExpr* expr) {
- writer_->WritePutsNewline(Opcode::MemoryGrow_Opcode.GetName());
+ writer_->WritePutsSpace(Opcode::MemoryGrow_Opcode.GetName());
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
+ writer_->WriteNewline(NO_FORCE_NEWLINE);
return Result::Ok;
}
Result WatWriter::ExprVisitorDelegate::OnMemorySizeExpr(MemorySizeExpr* expr) {
- writer_->WritePutsNewline(Opcode::MemorySize_Opcode.GetName());
+ writer_->WritePutsSpace(Opcode::MemorySize_Opcode.GetName());
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
+ writer_->WriteNewline(NO_FORCE_NEWLINE);
return Result::Ok;
}
Result WatWriter::ExprVisitorDelegate::OnMemoryInitExpr(MemoryInitExpr* expr) {
writer_->WritePutsSpace(Opcode::MemoryInit_Opcode.GetName());
- writer_->WriteVar(expr->var, NextChar::Newline);
+ writer_->WriteVar(expr->var, NextChar::Space);
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
+ writer_->WriteNewline(NO_FORCE_NEWLINE);
return Result::Ok;
}
@@ -865,7 +917,7 @@ Result WatWriter::ExprVisitorDelegate::OnSelectExpr(SelectExpr* expr) {
}
Result WatWriter::ExprVisitorDelegate::OnStoreExpr(StoreExpr* expr) {
- writer_->WriteLoadStoreExpr<StoreExpr>(expr);
+ writer_->WriteMemoryLoadStoreExpr<StoreExpr>(expr);
return Result::Ok;
}
@@ -1423,6 +1475,7 @@ void WatWriter::WriteDataSegment(const DataSegment& segment) {
WriteOpenSpace("data");
WriteNameOrIndex(segment.name, data_segment_index_, NextChar::Space);
if (segment.kind != SegmentKind::Passive) {
+ WriteMemoryVarUnlessZero(segment.memory_var, NextChar::Space);
WriteInitExpr(segment.offset);
}
WriteQuotedData(segment.data.data(), segment.data.size());
diff --git a/test/dump/current-memory.txt b/test/dump/current-memory.txt
index 3e44fcd0..28059287 100644
--- a/test/dump/current-memory.txt
+++ b/test/dump/current-memory.txt
@@ -39,7 +39,7 @@
000001b: 00 ; func body size (guess)
000001c: 00 ; local decl count
000001d: 3f ; memory.size
-000001e: 00 ; memory.size reserved
+000001e: 00 ; memory.size memidx
000001f: 0b ; end
000001b: 04 ; FIXUP func body size
0000019: 06 ; FIXUP section size
diff --git a/test/dump/grow-memory.txt b/test/dump/grow-memory.txt
index 59f7735a..80de8a01 100644
--- a/test/dump/grow-memory.txt
+++ b/test/dump/grow-memory.txt
@@ -44,7 +44,7 @@
000001e: 20 ; local.get
000001f: 00 ; local index
0000020: 40 ; memory.grow
-0000021: 00 ; memory.grow reserved
+0000021: 00 ; memory.grow memidx
0000022: 1a ; drop
0000023: 0b ; end
000001c: 07 ; FIXUP func body size
diff --git a/test/help/spectest-interp.txt b/test/help/spectest-interp.txt
index db37eec6..c9e13728 100644
--- a/test/help/spectest-interp.txt
+++ b/test/help/spectest-interp.txt
@@ -27,6 +27,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
-V, --value-stack-size=SIZE Size in elements of the value stack
-C, --call-stack-size=SIZE Size in elements of the call stack
diff --git a/test/help/wasm-interp.txt b/test/help/wasm-interp.txt
index 762a0113..26c401e9 100644
--- a/test/help/wasm-interp.txt
+++ b/test/help/wasm-interp.txt
@@ -38,6 +38,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
-V, --value-stack-size=SIZE Size in elements of the value stack
-C, --call-stack-size=SIZE Size in elements of the call stack
diff --git a/test/help/wasm-opcodecnt.txt b/test/help/wasm-opcodecnt.txt
index 6274d83d..43096ecb 100644
--- a/test/help/wasm-opcodecnt.txt
+++ b/test/help/wasm-opcodecnt.txt
@@ -28,6 +28,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
-o, --output=FILENAME Output file for the opcode counts, by default use stdout
-c, --cutoff=N Cutoff for reporting counts less than N
diff --git a/test/help/wasm-validate.txt b/test/help/wasm-validate.txt
index 35e3f0ef..bc124d85 100644
--- a/test/help/wasm-validate.txt
+++ b/test/help/wasm-validate.txt
@@ -27,6 +27,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
--no-debug-names Ignore debug names in the binary file
--ignore-custom-section-errors Ignore errors in custom sections
diff --git a/test/help/wasm2wat.txt b/test/help/wasm2wat.txt
index f60fc3a3..f0788fdf 100644
--- a/test/help/wasm2wat.txt
+++ b/test/help/wasm2wat.txt
@@ -33,6 +33,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
--inline-exports Write all exports inline
--inline-imports Write all imports inline
diff --git a/test/help/wast2json.txt b/test/help/wast2json.txt
index 07b2df59..2482279f 100644
--- a/test/help/wast2json.txt
+++ b/test/help/wast2json.txt
@@ -30,6 +30,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
-o, --output=FILE output JSON file
-r, --relocatable Create a relocatable wasm binary (suitable for linking with e.g. lld)
diff --git a/test/help/wat-desugar.txt b/test/help/wat-desugar.txt
index 3d427f39..e3ecbd26 100644
--- a/test/help/wat-desugar.txt
+++ b/test/help/wat-desugar.txt
@@ -37,6 +37,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
--generate-names Give auto-generated names to non-named functions, types, etc.
;;; STDOUT ;;)
diff --git a/test/help/wat2wasm.txt b/test/help/wat2wasm.txt
index d8aa797c..0f018a0c 100644
--- a/test/help/wat2wasm.txt
+++ b/test/help/wat2wasm.txt
@@ -37,6 +37,7 @@ options:
--enable-annotations Enable Custom annotation syntax
--enable-gc Enable Garbage collection
--enable-memory64 Enable 64-bit memory
+ --enable-multi-memory Enable Multi-memory
--enable-all Enable all features
-o, --output=FILE output wasm binary file
-r, --relocatable Create a relocatable wasm binary (suitable for linking with e.g. lld)
diff --git a/test/spec/memory.txt b/test/spec/memory.txt
index 5fdf5eed..332a1211 100644
--- a/test/spec/memory.txt
+++ b/test/spec/memory.txt
@@ -25,10 +25,10 @@ out/test/spec/memory.wast:33: assert_invalid passed:
out/test/spec/memory.wast:37: assert_invalid passed:
000001d: error: load/store memory 0 out of range 0
out/test/spec/memory.wast:41: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
0000019: error: OnMemorySizeExpr callback failed
out/test/spec/memory.wast:45: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
000001b: error: OnMemoryGrowExpr callback failed
out/test/spec/memory.wast:51: assert_invalid passed:
error: max pages (0) must be >= initial pages (1)
diff --git a/test/spec/memory64/memory.txt b/test/spec/memory64/memory.txt
index 515ee069..4138b908 100644
--- a/test/spec/memory64/memory.txt
+++ b/test/spec/memory64/memory.txt
@@ -26,10 +26,10 @@ out/test/spec/memory64/memory.wast:33: assert_invalid passed:
out/test/spec/memory64/memory.wast:37: assert_invalid passed:
000001d: error: load/store memory 0 out of range 0
out/test/spec/memory64/memory.wast:41: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
0000019: error: OnMemorySizeExpr callback failed
out/test/spec/memory64/memory.wast:45: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
000001b: error: OnMemoryGrowExpr callback failed
out/test/spec/memory64/memory.wast:51: assert_invalid passed:
error: max pages (0) must be >= initial pages (1)
diff --git a/test/spec/memory64/memory64.txt b/test/spec/memory64/memory64.txt
index 305b267c..8e6a7d6a 100644
--- a/test/spec/memory64/memory64.txt
+++ b/test/spec/memory64/memory64.txt
@@ -26,10 +26,10 @@ out/test/spec/memory64/memory64.wast:31: assert_invalid passed:
out/test/spec/memory64/memory64.wast:35: assert_invalid passed:
000001d: error: load/store memory 0 out of range 0
out/test/spec/memory64/memory64.wast:39: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
0000019: error: OnMemorySizeExpr callback failed
out/test/spec/memory64/memory64.wast:43: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
error: type mismatch in memory.grow, expected [i32] but got [i64]
000001b: error: OnMemoryGrowExpr callback failed
out/test/spec/memory64/memory64.wast:49: assert_invalid passed:
diff --git a/test/spec/memory_copy.txt b/test/spec/memory_copy.txt
index e37ca6e5..52819ef3 100644
--- a/test/spec/memory_copy.txt
+++ b/test/spec/memory_copy.txt
@@ -21,7 +21,8 @@ out/test/spec/memory_copy.wast:3240: assert_trap passed: out of bounds memory ac
out/test/spec/memory_copy.wast:3601: assert_trap passed: out of bounds memory access: memory.copy out of bound
out/test/spec/memory_copy.wast:3962: assert_trap passed: out of bounds memory access: memory.copy out of bound
out/test/spec/memory_copy.wast:4316: assert_invalid passed:
- error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 0000000: error: memory variable out of range: 0 (max 0)
000002d: error: OnMemoryCopyExpr callback failed
out/test/spec/memory_copy.wast:4322: assert_invalid passed:
error: type mismatch in memory.copy, expected [i32, i32, i32] but got [i32, i32, f32]
diff --git a/test/spec/multi-memory/binary.txt b/test/spec/multi-memory/binary.txt
new file mode 100644
index 00000000..4ab0a28e
--- /dev/null
+++ b/test/spec/multi-memory/binary.txt
@@ -0,0 +1,260 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/binary.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/binary.wast:6: assert_malformed passed:
+ 0000000: error: unable to read uint32_t: magic
+out/test/spec/multi-memory/binary.wast:7: assert_malformed passed:
+ 0000000: error: unable to read uint32_t: magic
+out/test/spec/multi-memory/binary.wast:8: assert_malformed passed:
+ 0000000: error: unable to read uint32_t: magic
+out/test/spec/multi-memory/binary.wast:9: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:10: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:11: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:12: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:13: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:14: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:15: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:16: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:17: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:18: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:21: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:24: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:25: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:28: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:31: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:34: assert_malformed passed:
+ 0000004: error: bad magic value
+out/test/spec/multi-memory/binary.wast:37: assert_malformed passed:
+ 0000004: error: unable to read uint32_t: version
+out/test/spec/multi-memory/binary.wast:38: assert_malformed passed:
+ 0000004: error: unable to read uint32_t: version
+out/test/spec/multi-memory/binary.wast:39: assert_malformed passed:
+ 0000004: error: unable to read uint32_t: version
+out/test/spec/multi-memory/binary.wast:40: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0 (expected 0x1)
+out/test/spec/multi-memory/binary.wast:41: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0xd (expected 0x1)
+out/test/spec/multi-memory/binary.wast:42: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0xe (expected 0x1)
+out/test/spec/multi-memory/binary.wast:43: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0x100 (expected 0x1)
+out/test/spec/multi-memory/binary.wast:44: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0x10000 (expected 0x1)
+out/test/spec/multi-memory/binary.wast:45: assert_malformed passed:
+ 0000008: error: bad wasm file version: 0x1000000 (expected 0x1)
+out/test/spec/multi-memory/binary.wast:48: assert_malformed passed:
+ 000000a: error: invalid section code: 13
+out/test/spec/multi-memory/binary.wast:49: assert_malformed passed:
+ 000000a: error: invalid section code: 127
+out/test/spec/multi-memory/binary.wast:50: assert_malformed passed:
+ 000000a: error: invalid section code: 128
+out/test/spec/multi-memory/binary.wast:51: assert_malformed passed:
+ 000000a: error: invalid section code: 129
+out/test/spec/multi-memory/binary.wast:52: assert_malformed passed:
+ 000000a: error: invalid section code: 255
+out/test/spec/multi-memory/binary.wast:165: assert_malformed passed:
+ 000000c: error: unexpected type form (got 0xe0)
+out/test/spec/multi-memory/binary.wast:178: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:188: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:198: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:209: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:219: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:231: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:239: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:249: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:259: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:269: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:279: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:290: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:300: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:310: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:320: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:331: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:341: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:351: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:361: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:374: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:382: assert_malformed passed:
+ 0000022: error: unable to read u32 leb128: load offset
+out/test/spec/multi-memory/binary.wast:401: assert_malformed passed:
+ 0000021: error: unable to read u32 leb128: load alignment
+out/test/spec/multi-memory/binary.wast:420: assert_malformed passed:
+ 0000023: error: unable to read u32 leb128: store alignment
+out/test/spec/multi-memory/binary.wast:439: assert_malformed passed:
+ 0000024: error: unable to read u32 leb128: store offset
+out/test/spec/multi-memory/binary.wast:460: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:470: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:481: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:491: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:503: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:511: assert_malformed passed:
+ 000000c: error: unable to read u32 leb128: memory initial page count
+out/test/spec/multi-memory/binary.wast:519: assert_malformed passed:
+ 0000022: error: unable to read u32 leb128: load offset
+out/test/spec/multi-memory/binary.wast:538: assert_malformed passed:
+ 0000022: error: unable to read u32 leb128: load offset
+out/test/spec/multi-memory/binary.wast:557: assert_malformed passed:
+ 0000021: error: unable to read u32 leb128: load alignment
+out/test/spec/multi-memory/binary.wast:575: assert_malformed passed:
+ 0000021: error: unable to read u32 leb128: load alignment
+out/test/spec/multi-memory/binary.wast:594: assert_malformed passed:
+ 0000023: error: unable to read u32 leb128: store alignment
+out/test/spec/multi-memory/binary.wast:613: assert_malformed passed:
+ 0000023: error: unable to read u32 leb128: store alignment
+out/test/spec/multi-memory/binary.wast:632: assert_malformed passed:
+ 0000024: error: unable to read u32 leb128: store offset
+out/test/spec/multi-memory/binary.wast:651: assert_malformed passed:
+ 0000024: error: unable to read u32 leb128: store offset
+out/test/spec/multi-memory/binary.wast:673: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:683: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:693: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:703: assert_malformed passed:
+ 000000e: error: unable to read i32 leb128: init_expr i32.const value
+out/test/spec/multi-memory/binary.wast:714: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:724: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:734: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:744: assert_malformed passed:
+ 000000e: error: unable to read i64 leb128: init_expr i64.const value
+out/test/spec/multi-memory/binary.wast:756: assert_malformed passed:
+ 0000017: error: unable to read u32 leb128: local type count
+out/test/spec/multi-memory/binary.wast:773: assert_malformed passed:
+ 0000017: error: unable to read u32 leb128: local type count
+out/test/spec/multi-memory/binary.wast:790: assert_malformed passed:
+ 000001c: error: local count must be < 0x10000000
+out/test/spec/multi-memory/binary.wast:806: assert_malformed passed:
+ 0000030: error: local count must be < 0x10000000
+out/test/spec/multi-memory/binary.wast:840: assert_malformed passed:
+ 0000013: error: function signature count != function body count
+out/test/spec/multi-memory/binary.wast:850: assert_malformed passed:
+ 000000b: error: function signature count != function body count
+out/test/spec/multi-memory/binary.wast:859: assert_malformed passed:
+ 0000016: error: function signature count != function body count
+out/test/spec/multi-memory/binary.wast:870: assert_malformed passed:
+ 0000015: error: function signature count != function body count
+out/test/spec/multi-memory/binary.wast:893: assert_malformed passed:
+ 000000e: error: data segment count does not equal count in DataCount section
+out/test/spec/multi-memory/binary.wast:903: assert_malformed passed:
+ 000000e: error: data segment count does not equal count in DataCount section
+out/test/spec/multi-memory/binary.wast:913: assert_malformed passed:
+ 0000024: error: memory.init requires data count section
+out/test/spec/multi-memory/binary.wast:935: assert_malformed passed:
+ 000001e: error: data.drop requires data count section
+out/test/spec/multi-memory/binary.wast:954: assert_malformed passed:
+ 0000024: error: expected ref.null or ref.func in passive element segment
+ 0000025: error: expected END opcode after element expression
+out/test/spec/multi-memory/binary.wast:980: assert_malformed passed:
+ 0000022: error: table elem type must be a reference type
+out/test/spec/multi-memory/binary.wast:1061: assert_malformed passed:
+ 000000a: error: invalid section size: extends past end
+out/test/spec/multi-memory/binary.wast:1072: assert_malformed passed:
+ 000000e: error: unfinished section (expected end: 0x11)
+out/test/spec/multi-memory/binary.wast:1091: assert_malformed passed:
+ 000000e: error: invalid import tag kind: exceptions not allowed
+out/test/spec/multi-memory/binary.wast:1101: assert_malformed passed:
+ 000000e: error: invalid import tag kind: exceptions not allowed
+out/test/spec/multi-memory/binary.wast:1112: assert_malformed passed:
+ 000000e: error: malformed import kind: 5
+out/test/spec/multi-memory/binary.wast:1122: assert_malformed passed:
+ 000000e: error: malformed import kind: 5
+out/test/spec/multi-memory/binary.wast:1133: assert_malformed passed:
+ 000000e: error: malformed import kind: 128
+out/test/spec/multi-memory/binary.wast:1143: assert_malformed passed:
+ 000000e: error: malformed import kind: 128
+out/test/spec/multi-memory/binary.wast:1156: assert_malformed passed:
+ 0000027: error: unable to read u32 leb128: string length
+out/test/spec/multi-memory/binary.wast:1175: assert_malformed passed:
+ 000002b: error: unfinished section (expected end: 0x40)
+out/test/spec/multi-memory/binary.wast:1206: assert_malformed passed:
+ 000000b: error: invalid table count 1, only 0 bytes left in section
+out/test/spec/multi-memory/binary.wast:1216: assert_malformed passed:
+ 000000d: error: tables may not be shared
+out/test/spec/multi-memory/binary.wast:1225: assert_malformed passed:
+ 000000d: error: tables may not be shared
+out/test/spec/multi-memory/binary.wast:1235: assert_malformed passed:
+ 000000d: error: malformed table limits flag: 129
+out/test/spec/multi-memory/binary.wast:1253: assert_malformed passed:
+ 000000b: error: invalid memory count 1, only 0 bytes left in section
+out/test/spec/multi-memory/binary.wast:1263: assert_malformed passed:
+ 000000c: error: memory may not be shared: threads not allowed
+out/test/spec/multi-memory/binary.wast:1271: assert_malformed passed:
+ 000000c: error: memory may not be shared: threads not allowed
+out/test/spec/multi-memory/binary.wast:1280: assert_malformed passed:
+ 000000c: error: malformed memory limits flag: 129
+out/test/spec/multi-memory/binary.wast:1289: assert_malformed passed:
+ 000000c: error: malformed memory limits flag: 129
+out/test/spec/multi-memory/binary.wast:1306: assert_malformed passed:
+ 0000010: error: unable to read i32 leb128: global type
+out/test/spec/multi-memory/binary.wast:1317: assert_malformed passed:
+ 0000010: error: unfinished section (expected end: 0x15)
+out/test/spec/multi-memory/binary.wast:1340: assert_malformed passed:
+ 000001b: error: unable to read u32 leb128: string length
+out/test/spec/multi-memory/binary.wast:1361: assert_malformed passed:
+ 000001b: error: unfinished section (expected end: 0x20)
+out/test/spec/multi-memory/binary.wast:1395: assert_malformed passed:
+ 0000021: error: unable to read u32 leb128: elem segment flags
+out/test/spec/multi-memory/binary.wast:1411: assert_malformed passed:
+ 0000021: error: unable to read u32 leb128: elem segment flags
+out/test/spec/multi-memory/binary.wast:1428: assert_malformed passed:
+ 0000021: error: unfinished section (expected end: 0x27)
+out/test/spec/multi-memory/binary.wast:1454: assert_malformed passed:
+ 0000016: error: unable to read u32 leb128: data segment flags
+out/test/spec/multi-memory/binary.wast:1467: assert_malformed passed:
+ 0000016: error: unfinished section (expected end: 0x1c)
+out/test/spec/multi-memory/binary.wast:1480: assert_malformed passed:
+ 0000015: error: unable to read data: data segment data
+out/test/spec/multi-memory/binary.wast:1494: assert_malformed passed:
+ 000001a: error: unfinished section (expected end: 0x1b)
+out/test/spec/multi-memory/binary.wast:1525: assert_malformed passed:
+ error: function type variable out of range: 11 (max 1)
+ 0000025: error: OnBlockExpr callback failed
+out/test/spec/multi-memory/binary.wast:1560: assert_malformed passed:
+ 0000017: error: multiple Start sections
+126/126 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/data.txt b/test/spec/multi-memory/data.txt
new file mode 100644
index 00000000..8e3973aa
--- /dev/null
+++ b/test/spec/multi-memory/data.txt
@@ -0,0 +1,56 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/data.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/data.wast:294: assert_invalid passed:
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 000000c: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:302: assert_invalid passed:
+ 0000000: error: memory variable out of range: 1 (max 1)
+ 0000012: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:315: assert_invalid passed:
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 000000c: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:326: assert_invalid passed:
+ 0000000: error: memory variable out of range: 1 (max 0)
+ 000000d: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:338: assert_invalid passed:
+ 0000000: error: memory variable out of range: 1 (max 1)
+ 0000012: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:360: assert_invalid passed:
+ 0000000: error: memory variable out of range: 1 (max 0)
+ 000000d: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/data.wast:379: assert_invalid passed:
+ 0000013: error: expected i32 init_expr
+out/test/spec/multi-memory/data.wast:387: assert_invalid passed:
+ 0000013: error: expected i32 init_expr
+out/test/spec/multi-memory/data.wast:395: assert_invalid passed:
+ error: invalid data segment offset, must be a constant expression; either iXX.const or global.get.
+ 0000012: error: EndDataSegmentInitExpr callback failed
+out/test/spec/multi-memory/data.wast:403: assert_invalid passed:
+ 0000014: error: expected END opcode after initializer expression
+out/test/spec/multi-memory/data.wast:411: assert_invalid passed:
+ 000002a: error: expected END opcode after initializer expression
+out/test/spec/multi-memory/data.wast:420: assert_invalid passed:
+ 000002a: error: expected END opcode after initializer expression
+out/test/spec/multi-memory/data.wast:429: assert_invalid passed:
+ 0000014: error: expected END opcode after initializer expression
+out/test/spec/multi-memory/data.wast:437: assert_invalid passed:
+ 0000012: error: unexpected opcode in initializer expression: 0x1
+out/test/spec/multi-memory/data.wast:445: assert_invalid passed:
+ 0000012: error: unexpected opcode in initializer expression: 0x1
+out/test/spec/multi-memory/data.wast:453: assert_invalid passed:
+ 0000014: error: expected END opcode after initializer expression
+out/test/spec/multi-memory/data.wast:467: assert_invalid passed:
+ 0000000: error: global variable out of range: 0 (max 0)
+ error: initializer expression cannot reference a mutable global
+ 0000014: error: EndDataSegmentInitExpr callback failed
+out/test/spec/multi-memory/data.wast:475: assert_invalid passed:
+ 0000000: error: global variable out of range: 1 (max 1)
+ error: initializer expression cannot reference a mutable global
+ 000002a: error: EndDataSegmentInitExpr callback failed
+out/test/spec/multi-memory/data.wast:484: assert_invalid passed:
+ error: initializer expression cannot reference a mutable global
+ 000002e: error: EndDataSegmentInitExpr callback failed
+33/33 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/imports.txt b/test/spec/multi-memory/imports.txt
new file mode 100644
index 00000000..d6738043
--- /dev/null
+++ b/test/spec/multi-memory/imports.txt
@@ -0,0 +1,234 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/imports.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+called host spectest.print_i32(i32:13) =>
+called host spectest.print_i32_f32(i32:14, f32:42.000000) =>
+called host spectest.print_i32(i32:13) =>
+called host spectest.print_i32(i32:13) =>
+called host spectest.print_f32(f32:13.000000) =>
+called host spectest.print_i32(i32:13) =>
+called host spectest.print_f64_f64(f64:25.000000, f64:53.000000) =>
+called host spectest.print_f64(f64:24.000000) =>
+called host spectest.print_f64(f64:24.000000) =>
+called host spectest.print_f64(f64:24.000000) =>
+out/test/spec/multi-memory/imports.wast:93: assert_invalid passed:
+ 0000000: error: function type variable out of range: 1 (max 1)
+ 000001e: error: OnImportFunc callback failed
+called host spectest.print_i32(i32:13) =>
+out/test/spec/multi-memory/imports.wast:129: assert_unlinkable passed:
+ error: invalid import "test.unknown"
+out/test/spec/multi-memory/imports.wast:133: assert_unlinkable passed:
+ error: invalid import "spectest.unknown"
+out/test/spec/multi-memory/imports.wast:138: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:142: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:146: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:150: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:154: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:158: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:162: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:166: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:170: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:174: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:178: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:182: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:186: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:190: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:194: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:198: assert_unlinkable passed:
+ error: import signature mismatch
+out/test/spec/multi-memory/imports.wast:203: assert_unlinkable passed:
+ error: expected import "test.global-i32" to have kind func, not global
+out/test/spec/multi-memory/imports.wast:207: assert_unlinkable passed:
+ error: expected import "test.table-10-inf" to have kind func, not table
+out/test/spec/multi-memory/imports.wast:211: assert_unlinkable passed:
+ error: expected import "test.memory-2-inf" to have kind func, not memory
+out/test/spec/multi-memory/imports.wast:215: assert_unlinkable passed:
+ error: expected import "spectest.global_i32" to have kind func, not global
+out/test/spec/multi-memory/imports.wast:219: assert_unlinkable passed:
+ error: expected import "spectest.table" to have kind func, not table
+out/test/spec/multi-memory/imports.wast:223: assert_unlinkable passed:
+ error: expected import "spectest.memory" to have kind func, not memory
+out/test/spec/multi-memory/imports.wast:258: assert_unlinkable passed:
+ error: invalid import "test.unknown"
+out/test/spec/multi-memory/imports.wast:262: assert_unlinkable passed:
+ error: invalid import "spectest.unknown"
+out/test/spec/multi-memory/imports.wast:267: assert_unlinkable passed:
+ error: type mismatch in imported global, expected i64 but got i32.
+out/test/spec/multi-memory/imports.wast:271: assert_unlinkable passed:
+ error: type mismatch in imported global, expected f32 but got i32.
+out/test/spec/multi-memory/imports.wast:275: assert_unlinkable passed:
+ error: type mismatch in imported global, expected f64 but got i32.
+out/test/spec/multi-memory/imports.wast:279: assert_unlinkable passed:
+ error: mutability mismatch in imported global, expected immutable but got mutable.
+out/test/spec/multi-memory/imports.wast:283: assert_unlinkable passed:
+ error: type mismatch in imported global, expected i32 but got f32.
+out/test/spec/multi-memory/imports.wast:287: assert_unlinkable passed:
+ error: type mismatch in imported global, expected i64 but got f32.
+out/test/spec/multi-memory/imports.wast:291: assert_unlinkable passed:
+ error: type mismatch in imported global, expected f64 but got f32.
+out/test/spec/multi-memory/imports.wast:295: assert_unlinkable passed:
+ error: mutability mismatch in imported global, expected immutable but got mutable.
+out/test/spec/multi-memory/imports.wast:299: assert_unlinkable passed:
+ error: type mismatch in imported global, expected i32 but got i64.
+out/test/spec/multi-memory/imports.wast:303: assert_unlinkable passed:
+ error: type mismatch in imported global, expected f32 but got i64.
+out/test/spec/multi-memory/imports.wast:307: assert_unlinkable passed:
+ error: type mismatch in imported global, expected f64 but got i64.
+out/test/spec/multi-memory/imports.wast:311: assert_unlinkable passed:
+ error: mutability mismatch in imported global, expected mutable but got immutable.
+out/test/spec/multi-memory/imports.wast:316: assert_unlinkable passed:
+ error: expected import "test.func" to have kind global, not func
+out/test/spec/multi-memory/imports.wast:320: assert_unlinkable passed:
+ error: expected import "test.table-10-inf" to have kind global, not table
+out/test/spec/multi-memory/imports.wast:324: assert_unlinkable passed:
+ error: expected import "test.memory-2-inf" to have kind global, not memory
+out/test/spec/multi-memory/imports.wast:328: assert_unlinkable passed:
+ error: expected import "spectest.print_i32" to have kind global, not func
+out/test/spec/multi-memory/imports.wast:332: assert_unlinkable passed:
+ error: expected import "spectest.table" to have kind global, not table
+out/test/spec/multi-memory/imports.wast:336: assert_unlinkable passed:
+ error: expected import "spectest.memory" to have kind global, not memory
+out/test/spec/multi-memory/imports.wast:355: assert_trap passed: uninitialized table element
+out/test/spec/multi-memory/imports.wast:358: assert_trap passed: uninitialized table element
+out/test/spec/multi-memory/imports.wast:359: assert_trap passed: undefined table index
+out/test/spec/multi-memory/imports.wast:374: assert_trap passed: uninitialized table element
+out/test/spec/multi-memory/imports.wast:377: assert_trap passed: uninitialized table element
+out/test/spec/multi-memory/imports.wast:378: assert_trap passed: undefined table index
+out/test/spec/multi-memory/imports.wast:410: assert_unlinkable passed:
+ error: invalid import "test.unknown"
+out/test/spec/multi-memory/imports.wast:414: assert_unlinkable passed:
+ error: invalid import "spectest.unknown"
+out/test/spec/multi-memory/imports.wast:419: assert_unlinkable passed:
+ error: actual size (10) smaller than declared (12)
+out/test/spec/multi-memory/imports.wast:423: assert_unlinkable passed:
+ error: max size (unspecified) larger than declared (20)
+out/test/spec/multi-memory/imports.wast:427: assert_unlinkable passed:
+ error: actual size (10) smaller than declared (12)
+out/test/spec/multi-memory/imports.wast:431: assert_unlinkable passed:
+ error: max size (20) larger than declared (18)
+out/test/spec/multi-memory/imports.wast:435: assert_unlinkable passed:
+ error: actual size (10) smaller than declared (12)
+out/test/spec/multi-memory/imports.wast:439: assert_unlinkable passed:
+ error: max size (20) larger than declared (15)
+out/test/spec/multi-memory/imports.wast:444: assert_unlinkable passed:
+ error: expected import "test.func" to have kind table, not func
+out/test/spec/multi-memory/imports.wast:448: assert_unlinkable passed:
+ error: expected import "test.global-i32" to have kind table, not global
+out/test/spec/multi-memory/imports.wast:452: assert_unlinkable passed:
+ error: expected import "test.memory-2-inf" to have kind table, not memory
+out/test/spec/multi-memory/imports.wast:456: assert_unlinkable passed:
+ error: expected import "spectest.print_i32" to have kind table, not func
+out/test/spec/multi-memory/imports.wast:474: assert_trap passed: out of bounds memory access: access at 1000000+4 >= max value 65536
+out/test/spec/multi-memory/imports.wast:485: assert_trap passed: out of bounds memory access: access at 1000000+4 >= max value 65536
+out/test/spec/multi-memory/imports.wast:498: assert_unlinkable passed:
+ error: invalid import "test.unknown"
+out/test/spec/multi-memory/imports.wast:502: assert_unlinkable passed:
+ error: invalid import "spectest.unknown"
+out/test/spec/multi-memory/imports.wast:507: assert_unlinkable passed:
+ error: actual size (2) smaller than declared (3)
+out/test/spec/multi-memory/imports.wast:511: assert_unlinkable passed:
+ error: max size (unspecified) larger than declared (3)
+out/test/spec/multi-memory/imports.wast:515: assert_unlinkable passed:
+ error: actual size (1) smaller than declared (2)
+out/test/spec/multi-memory/imports.wast:519: assert_unlinkable passed:
+ error: max size (2) larger than declared (1)
+out/test/spec/multi-memory/imports.wast:524: assert_unlinkable passed:
+ error: expected import "test.func-i32" to have kind memory, not func
+out/test/spec/multi-memory/imports.wast:528: assert_unlinkable passed:
+ error: expected import "test.global-i32" to have kind memory, not global
+out/test/spec/multi-memory/imports.wast:532: assert_unlinkable passed:
+ error: expected import "test.table-10-inf" to have kind memory, not table
+out/test/spec/multi-memory/imports.wast:536: assert_unlinkable passed:
+ error: expected import "spectest.print_i32" to have kind memory, not func
+out/test/spec/multi-memory/imports.wast:540: assert_unlinkable passed:
+ error: expected import "spectest.global_i32" to have kind memory, not global
+out/test/spec/multi-memory/imports.wast:544: assert_unlinkable passed:
+ error: expected import "spectest.table" to have kind memory, not table
+out/test/spec/multi-memory/imports.wast:549: assert_unlinkable passed:
+ error: actual size (1) smaller than declared (2)
+out/test/spec/multi-memory/imports.wast:553: assert_unlinkable passed:
+ error: max size (2) larger than declared (1)
+out/test/spec/multi-memory/imports.wast:591: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.124.wat:1:9: error: imports must occur before all non-import definitions
+ (func) (import "" "" (func))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:595: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.125.wat:1:9: error: imports must occur before all non-import definitions
+ (func) (import "" "" (global i64))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:599: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.126.wat:1:9: error: imports must occur before all non-import definitions
+ (func) (import "" "" (table 0 funcref))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:603: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.127.wat:1:9: error: imports must occur before all non-import definitions
+ (func) (import "" "" (memory 0))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:608: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.128.wat:1:29: error: imports must occur before all non-import definitions
+ (global i64 (i64.const 0)) (import "" "" (func))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:612: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.129.wat:1:29: error: imports must occur before all non-import definitions
+ (global i64 (i64.const 0)) (import "" "" (global f32))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:616: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.130.wat:1:29: error: imports must occur before all non-import definitions
+ (global i64 (i64.const 0)) (import "" "" (table 0 funcref))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:620: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.131.wat:1:29: error: imports must occur before all non-import definitions
+ (global i64 (i64.const 0)) (import "" "" (memory 0))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:625: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.132.wat:1:20: error: imports must occur before all non-import definitions
+ (table 0 funcref) (import "" "" (func))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:629: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.133.wat:1:20: error: imports must occur before all non-import definitions
+ (table 0 funcref) (import "" "" (global i32))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:633: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.134.wat:1:20: error: imports must occur before all non-import definitions
+ (table 0 funcref) (import "" "" (table 0 funcref))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:637: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.135.wat:1:20: error: imports must occur before all non-import definitions
+ (table 0 funcref) (import "" "" (memory 0))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:642: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.136.wat:1:13: error: imports must occur before all non-import definitions
+ (memory 0) (import "" "" (func))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:646: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.137.wat:1:13: error: imports must occur before all non-import definitions
+ (memory 0) (import "" "" (global i32))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:650: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.138.wat:1:13: error: imports must occur before all non-import definitions
+ (memory 0) (import "" "" (table 1 3 funcref))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:654: assert_malformed passed:
+ out/test/spec/multi-memory/imports/imports.139.wat:1:13: error: imports must occur before all non-import definitions
+ (memory 0) (import "" "" (memory 1 2))
+ ^^^^^^
+out/test/spec/multi-memory/imports.wast:664: assert_unlinkable passed:
+ error: invalid import "not wasm.overloaded"
+122/122 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/load.txt b/test/spec/multi-memory/load.txt
new file mode 100644
index 00000000..976a755c
--- /dev/null
+++ b/test/spec/multi-memory/load.txt
@@ -0,0 +1,196 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/load.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/load.wast:278: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.4.wat:1:43: error: unexpected token "i32.load32", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load32 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:285: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.5.wat:1:43: error: unexpected token "i32.load32_u", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load32_u (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:292: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.6.wat:1:43: error: unexpected token "i32.load32_s", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load32_s (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:299: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.7.wat:1:43: error: unexpected token "i32.load64", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load64 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:306: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.8.wat:1:43: error: unexpected token "i32.load64_u", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load64_u (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:313: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.9.wat:1:43: error: unexpected token "i32.load64_s", expected an instr.
+ (memory 1)(func (param i32) (result i32) (i32.load64_s (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:321: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.10.wat:1:43: error: unexpected token "i64.load64", expected an instr.
+ (memory 1)(func (param i32) (result i64) (i64.load64 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:328: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.11.wat:1:43: error: unexpected token "i64.load64_u", expected an instr.
+ (memory 1)(func (param i32) (result i64) (i64.load64_u (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:335: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.12.wat:1:43: error: unexpected token "i64.load64_s", expected an instr.
+ (memory 1)(func (param i32) (result i64) (i64.load64_s (local.get 0)))
+ ^^^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:343: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.13.wat:1:43: error: unexpected token "f32.load32", expected an instr.
+ (memory 1)(func (param i32) (result f32) (f32.load32 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:350: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.14.wat:1:43: error: unexpected token "f32.load64", expected an instr.
+ (memory 1)(func (param i32) (result f32) (f32.load64 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:358: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.15.wat:1:43: error: unexpected token "f64.load32", expected an instr.
+ (memory 1)(func (param i32) (result f64) (f64.load32 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:365: assert_malformed passed:
+ out/test/spec/multi-memory/load/load.16.wat:1:43: error: unexpected token "f64.load64", expected an instr.
+ (memory 1)(func (param i32) (result f64) (f64.load64 (local.get 0)))
+ ^^^^^^^^^^
+out/test/spec/multi-memory/load.wast:376: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:380: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:384: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:388: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:392: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:396: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:400: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:404: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:408: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:412: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:416: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:420: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:424: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [f32]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:428: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [f64]
+ 0000022: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/load.wast:435: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:436: assert_invalid passed:
+ error: type mismatch in i32.load8_s, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:437: assert_invalid passed:
+ error: type mismatch in i32.load8_u, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:438: assert_invalid passed:
+ error: type mismatch in i32.load16_s, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:439: assert_invalid passed:
+ error: type mismatch in i32.load16_u, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:440: assert_invalid passed:
+ error: type mismatch in i64.load, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:441: assert_invalid passed:
+ error: type mismatch in i64.load8_s, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:442: assert_invalid passed:
+ error: type mismatch in i64.load8_u, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:443: assert_invalid passed:
+ error: type mismatch in i64.load16_s, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:444: assert_invalid passed:
+ error: type mismatch in i64.load16_u, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:445: assert_invalid passed:
+ error: type mismatch in i64.load32_s, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:446: assert_invalid passed:
+ error: type mismatch in i64.load32_u, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:447: assert_invalid passed:
+ error: type mismatch in f32.load, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:448: assert_invalid passed:
+ error: type mismatch in f64.load, expected [i32] but got [f32]
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:452: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:461: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000023: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:471: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000023: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:481: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:491: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000028: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:501: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000023: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:511: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000023: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:521: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000023: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:531: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:540: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:549: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000025: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:559: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000003c: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:576: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000021: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:586: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000021: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:596: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 0000027: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:606: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:615: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+out/test/spec/multi-memory/load.wast:624: assert_invalid passed:
+ error: type mismatch in i32.load, expected [i32] but got []
+ 000001f: error: OnLoadExpr callback failed
+113/113 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/memory-multi.txt b/test/spec/multi-memory/memory-multi.txt
new file mode 100644
index 00000000..f66109d9
--- /dev/null
+++ b/test/spec/multi-memory/memory-multi.txt
@@ -0,0 +1,6 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/memory-multi.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+4/4 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/memory.txt b/test/spec/multi-memory/memory.txt
new file mode 100644
index 00000000..bb0b346d
--- /dev/null
+++ b/test/spec/multi-memory/memory.txt
@@ -0,0 +1,75 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/memory.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/memory.wast:17: assert_invalid passed:
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 000000c: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/memory.wast:18: assert_invalid passed:
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 000000c: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/memory.wast:19: assert_invalid passed:
+ 0000000: error: memory variable out of range: 0 (max 0)
+ 000000c: error: BeginDataSegment callback failed
+out/test/spec/multi-memory/memory.wast:22: assert_invalid passed:
+ 000001b: error: load/store memory 0 out of range 0
+out/test/spec/multi-memory/memory.wast:26: assert_invalid passed:
+ 0000020: error: load/store memory 0 out of range 0
+out/test/spec/multi-memory/memory.wast:30: assert_invalid passed:
+ 000001b: error: load/store memory 0 out of range 0
+out/test/spec/multi-memory/memory.wast:34: assert_invalid passed:
+ 000001d: error: load/store memory 0 out of range 0
+out/test/spec/multi-memory/memory.wast:38: assert_invalid passed:
+ 0000019: error: memory index 0 out of range
+out/test/spec/multi-memory/memory.wast:42: assert_invalid passed:
+ 000001b: error: memory index 0 out of range
+out/test/spec/multi-memory/memory.wast:48: assert_invalid passed:
+ error: max pages (0) must be >= initial pages (1)
+ 000000e: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:52: assert_invalid passed:
+ error: initial pages (65537) must be <= (65536)
+ 000000f: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:56: assert_invalid passed:
+ error: initial pages (2147483648) must be <= (65536)
+ 0000011: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:60: assert_invalid passed:
+ error: initial pages (4294967295) must be <= (65536)
+ 0000011: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:64: assert_invalid passed:
+ error: max pages (65537) must be <= (65536)
+ 0000010: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:68: assert_invalid passed:
+ error: max pages (2147483648) must be <= (65536)
+ 0000012: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:72: assert_invalid passed:
+ error: max pages (4294967295) must be <= (65536)
+ 0000012: error: OnMemory callback failed
+out/test/spec/multi-memory/memory.wast:77: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.25.wat:1:9: error: invalid int "0x1_0000_0000"
+ (memory 0x1_0000_0000)
+ ^^^^^^^^^^^^^
+out/test/spec/multi-memory/memory.wast:81: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.26.wat:1:9: error: invalid int "0x1_0000_0000"
+ (memory 0x1_0000_0000 0x1_0000_0000)
+ ^^^^^^^^^^^^^
+ out/test/spec/multi-memory/memory/memory.26.wat:1:23: error: invalid int "0x1_0000_0000"
+ (memory 0x1_0000_0000 0x1_0000_0000)
+ ^^^^^^^^^^^^^
+out/test/spec/multi-memory/memory.wast:85: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.27.wat:1:11: error: invalid int "0x1_0000_0000"
+ (memory 0 0x1_0000_0000)
+ ^^^^^^^^^^^^^
+out/test/spec/multi-memory/memory.wast:228: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.29.wat:1:17: error: redefinition of memory "$foo"
+ (memory $foo 1)(memory $foo 1)
+ ^^^^^^
+out/test/spec/multi-memory/memory.wast:232: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.30.wat:1:32: error: redefinition of memory "$foo"
+ (import "" "" (memory $foo 1))(memory $foo 1)
+ ^^^^^^
+out/test/spec/multi-memory/memory.wast:236: assert_malformed passed:
+ out/test/spec/multi-memory/memory/memory.31.wat:1:32: error: redefinition of memory "$foo"
+ (import "" "" (memory $foo 1))(import "" "" (memory $foo 1))
+ ^^^^^^
+67/67 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/memory_grow.txt b/test/spec/multi-memory/memory_grow.txt
new file mode 100644
index 00000000..585eedd0
--- /dev/null
+++ b/test/spec/multi-memory/memory_grow.txt
@@ -0,0 +1,40 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/memory_grow.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/memory_grow.wast:86: assert_trap passed: out of bounds memory access: access at 0+4 >= max value 0
+out/test/spec/multi-memory/memory_grow.wast:87: assert_trap passed: out of bounds memory access: access at 0+4 >= max value 0
+out/test/spec/multi-memory/memory_grow.wast:88: assert_trap passed: out of bounds memory access: access at 65536+4 >= max value 0
+out/test/spec/multi-memory/memory_grow.wast:89: assert_trap passed: out of bounds memory access: access at 65536+4 >= max value 0
+out/test/spec/multi-memory/memory_grow.wast:95: assert_trap passed: out of bounds memory access: access at 65536+4 >= max value 65536
+out/test/spec/multi-memory/memory_grow.wast:96: assert_trap passed: out of bounds memory access: access at 65536+4 >= max value 65536
+out/test/spec/multi-memory/memory_grow.wast:376: assert_trap passed: undefined table index
+out/test/spec/multi-memory/memory_grow.wast:431: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got [f32]
+ 0000024: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:440: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got []
+ 000001f: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:449: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got []
+ 0000023: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:459: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got []
+ 0000023: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:469: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got []
+ 0000025: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:480: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000021: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/memory_grow.wast:489: assert_invalid passed:
+ error: type mismatch in memory.grow, expected [i32] but got [f32]
+ 0000024: error: OnMemoryGrowExpr callback failed
+out/test/spec/multi-memory/memory_grow.wast:499: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 0000021: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/memory_grow.wast:508: assert_invalid passed:
+ error: type mismatch in implicit return, expected [f32] but got [i32]
+ 0000022: error: EndFunctionBody callback failed
+140/140 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/memory_size.txt b/test/spec/multi-memory/memory_size.txt
new file mode 100644
index 00000000..79e546b2
--- /dev/null
+++ b/test/spec/multi-memory/memory_size.txt
@@ -0,0 +1,12 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/memory_size.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+out/test/spec/multi-memory/memory_size.wast:95: assert_invalid passed:
+ error: type mismatch in function, expected [] but got [i32]
+ 000001f: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/memory_size.wast:104: assert_invalid passed:
+ error: type mismatch in implicit return, expected [f32] but got [i32]
+ 0000020: error: EndFunctionBody callback failed
+42/42 tests passed.
+;;; STDOUT ;;)
diff --git a/test/spec/multi-memory/store.txt b/test/spec/multi-memory/store.txt
new file mode 100644
index 00000000..3b71accf
--- /dev/null
+++ b/test/spec/multi-memory/store.txt
@@ -0,0 +1,195 @@
+;;; TOOL: run-interp-spec
+;;; STDIN_FILE: third_party/testsuite/proposals/multi-memory/store.wast
+;;; ARGS*: --enable-multi-memory
+(;; STDOUT ;;;
+store1(i32:0, i64:1) =>
+store2(i32:0, i64:2) =>
+store(i32:0, i64:1) =>
+store(i32:0, i64:2) =>
+store1(i32:0, i64:1) =>
+store2(i32:0, i64:2) =>
+copy-1-to-2() =>
+copy-2-to-1() =>
+out/test/spec/multi-memory/store.wast:206: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.7.wat:1:30: error: unexpected token "i32.store32", expected an instr.
+ (memory 1)(func (param i32) (i32.store32 (local.get 0) (i32.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:213: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.8.wat:1:30: error: unexpected token "i32.store64", expected an instr.
+ (memory 1)(func (param i32) (i32.store64 (local.get 0) (i64.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:221: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.9.wat:1:30: error: unexpected token "i64.store64", expected an instr.
+ (memory 1)(func (param i32) (i64.store64 (local.get 0) (i64.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:229: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.10.wat:1:30: error: unexpected token "f32.store32", expected an instr.
+ (memory 1)(func (param i32) (f32.store32 (local.get 0) (f32.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:236: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.11.wat:1:30: error: unexpected token "f32.store64", expected an instr.
+ (memory 1)(func (param i32) (f32.store64 (local.get 0) (f64.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:244: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.12.wat:1:30: error: unexpected token "f64.store32", expected an instr.
+ (memory 1)(func (param i32) (f64.store32 (local.get 0) (f32.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:251: assert_malformed passed:
+ out/test/spec/multi-memory/store/store.13.wat:1:30: error: unexpected token "f64.store64", expected an instr.
+ (memory 1)(func (param i32) (f64.store64 (local.get 0) (f64.const 0)))
+ ^^^^^^^^^^^
+out/test/spec/multi-memory/store.wast:260: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i32] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:264: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i64] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:268: assert_invalid passed:
+ error: type mismatch in implicit return, expected [f32] but got []
+ 0000029: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:272: assert_invalid passed:
+ error: type mismatch in implicit return, expected [f64] but got []
+ 000002d: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:276: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i32] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:280: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i32] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:284: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i64] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:288: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i64] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:292: assert_invalid passed:
+ error: type mismatch in implicit return, expected [i64] but got []
+ 0000026: error: EndFunctionBody callback failed
+out/test/spec/multi-memory/store.wast:298: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 000001f: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:307: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000021: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:316: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:326: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:336: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:346: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:356: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:366: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:376: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000028: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:386: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000028: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:396: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:406: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:416: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:426: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:436: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:446: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:456: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 000001f: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:465: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000021: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:474: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 000001f: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:483: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000021: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:492: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 0000025: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:502: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 0000027: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:512: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got []
+ 000003c: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:528: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32]
+ 000003e: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:547: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [f32, i32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:548: assert_invalid passed:
+ error: type mismatch in i32.store8, expected [i32, i32] but got [f32, i32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:549: assert_invalid passed:
+ error: type mismatch in i32.store16, expected [i32, i32] but got [f32, i32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:550: assert_invalid passed:
+ error: type mismatch in i64.store, expected [i32, i64] but got [f32, i32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:551: assert_invalid passed:
+ error: type mismatch in i64.store8, expected [i32, i64] but got [f32, i64]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:552: assert_invalid passed:
+ error: type mismatch in i64.store16, expected [i32, i64] but got [f32, i64]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:553: assert_invalid passed:
+ error: type mismatch in i64.store32, expected [i32, i64] but got [f32, i64]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:554: assert_invalid passed:
+ error: type mismatch in f32.store, expected [i32, f32] but got [f32, f32]
+ 0000029: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:555: assert_invalid passed:
+ error: type mismatch in f64.store, expected [i32, f64] but got [f32, f64]
+ 000002d: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:557: assert_invalid passed:
+ error: type mismatch in i32.store, expected [i32, i32] but got [i32, f32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:558: assert_invalid passed:
+ error: type mismatch in i32.store8, expected [i32, i32] but got [i32, f32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:559: assert_invalid passed:
+ error: type mismatch in i32.store16, expected [i32, i32] but got [i32, f32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:560: assert_invalid passed:
+ error: type mismatch in i64.store, expected [i32, i64] but got [i32, f32]
+ 0000026: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:561: assert_invalid passed:
+ error: type mismatch in i64.store8, expected [i32, i64] but got [i32, f64]
+ 000002a: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:562: assert_invalid passed:
+ error: type mismatch in i64.store16, expected [i32, i64] but got [i32, f64]
+ 000002a: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:563: assert_invalid passed:
+ error: type mismatch in i64.store32, expected [i32, i64] but got [i32, f64]
+ 000002a: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:564: assert_invalid passed:
+ error: type mismatch in f32.store, expected [i32, f32] but got [i32, i32]
+ 0000023: error: OnStoreExpr callback failed
+out/test/spec/multi-memory/store.wast:565: assert_invalid passed:
+ error: type mismatch in f64.store, expected [i32, f64] but got [i32, i64]
+ 0000023: error: OnStoreExpr callback failed
+101/101 tests passed.
+;;; STDOUT ;;)
diff --git a/test/typecheck/bad-bulk-memory-no-memory.txt b/test/typecheck/bad-bulk-memory-no-memory.txt
index ae45fd34..fc949ce6 100644
--- a/test/typecheck/bad-bulk-memory-no-memory.txt
+++ b/test/typecheck/bad-bulk-memory-no-memory.txt
@@ -18,6 +18,9 @@ out/test/typecheck/bad-bulk-memory-no-memory.txt:6:53: error: data_segment varia
out/test/typecheck/bad-bulk-memory-no-memory.txt:7:41: error: memory variable out of range: 0 (max 0)
i32.const 0 i32.const 0 i32.const 0 memory.copy
^^^^^^^^^^^
+out/test/typecheck/bad-bulk-memory-no-memory.txt:7:41: error: memory variable out of range: 0 (max 0)
+ i32.const 0 i32.const 0 i32.const 0 memory.copy
+ ^^^^^^^^^^^
out/test/typecheck/bad-bulk-memory-no-memory.txt:8:41: error: memory variable out of range: 0 (max 0)
i32.const 0 i32.const 0 i32.const 0 memory.fill
^^^^^^^^^^^
diff --git a/test/update-spec-tests.py b/test/update-spec-tests.py
index e40ae114..44eecc06 100755
--- a/test/update-spec-tests.py
+++ b/test/update-spec-tests.py
@@ -89,14 +89,14 @@ def main(args):
all_proposals = [e.name for e in os.scandir(PROPOSALS_DIR) if e.is_dir()]
flags = {
- 'memory64': '--enable-memory64'
+ 'memory64': '--enable-memory64',
+ 'multi-memory': '--enable-multi-memory'
}
unimplemented = set([
'gc',
'tail-call',
'function-references',
- 'multi-memory',
'threads',
'annotations',
'exception-handling',