summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apply-names.cc12
-rw-r--r--src/binary-reader-ir.cc48
-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-objdump.cc16
-rw-r--r--src/binary-reader-opcnt.cc5
-rw-r--r--src/binary-reader-opcnt.h1
-rw-r--r--src/binary-reader.cc223
-rw-r--r--src/binary-reader.h12
-rw-r--r--src/binary-writer.cc29
-rw-r--r--src/interp/binary-reader-interp.cc63
-rw-r--r--src/ir.h25
-rw-r--r--src/resolve-names.cc12
-rw-r--r--src/shared-validator.cc32
-rw-r--r--src/shared-validator.h18
-rw-r--r--src/validator.cc23
-rw-r--r--src/wast-parser.cc42
-rw-r--r--src/wast-parser.h4
-rw-r--r--src/wat-writer.cc2
20 files changed, 362 insertions, 256 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc
index 9f5b2002..d0958b7d 100644
--- a/src/apply-names.cc
+++ b/src/apply-names.cc
@@ -77,6 +77,8 @@ class NameApplier : public ExprVisitor::DelegateNop {
Result OnDelegateExpr(TryExpr*) override;
Result OnThrowExpr(ThrowExpr*) override;
Result OnRethrowExpr(RethrowExpr*) override;
+ Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) override;
+ Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) override;
private:
void PushLabel(const std::string& label);
@@ -463,6 +465,16 @@ Result NameApplier::OnLocalTeeExpr(LocalTeeExpr* expr) {
return Result::Ok;
}
+Result NameApplier::OnSimdLoadLaneExpr(SimdLoadLaneExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnSimdStoreLaneExpr(SimdStoreLaneExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
Result NameApplier::VisitFunc(Index func_index, Func* func) {
current_func_ = func;
if (func->decl.has_func_type) {
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc
index 44e93782..49feb255 100644
--- a/src/binary-reader-ir.cc
+++ b/src/binary-reader-ir.cc
@@ -164,22 +164,28 @@ class BinaryReaderIR : public BinaryReaderNop {
Result OnOpcode(Opcode opcode) override;
Result OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicFenceExpr(uint32_t consistency_model) override;
Result OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnBinaryExpr(Opcode opcode) override;
@@ -262,9 +268,11 @@ class BinaryReaderIR : public BinaryReaderNop {
uint64_t value) override;
Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override;
Result OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
@@ -737,38 +745,43 @@ Result BinaryReaderIR::OnOpcode(Opcode opcode) {
}
Result BinaryReaderIR::OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicLoadExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicLoadExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicStoreExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicStoreExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicRmwExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicRmwExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicRmwCmpxchgExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicRmwCmpxchgExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicWaitExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicWaitExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) {
@@ -776,10 +789,11 @@ Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) {
}
Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<AtomicNotifyExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<AtomicNotifyExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnBinaryExpr(Opcode opcode) {
@@ -1193,17 +1207,19 @@ Result BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode, v128 value) {
}
Result BinaryReaderIR::OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<LoadSplatExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<LoadSplatExpr>(
+ opcode, Var(memidx, GetLocation()), 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) {
- return AppendExpr(
- MakeUnique<LoadZeroExpr>(opcode, 1 << alignment_log2, offset));
+ return AppendExpr(MakeUnique<LoadZeroExpr>(opcode, Var(memidx, GetLocation()),
+ 1 << alignment_log2, offset));
}
Result BinaryReaderIR::OnElemSegmentCount(Index count) {
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
index 13c68852..0f885e45 100644
--- a/src/binary-reader-logging.cc
+++ b/src/binary-reader-logging.cc
@@ -715,16 +715,7 @@ Result BinaryReaderLogging::OnCodeMetadata(Offset code_offset,
return reader_->name(opcode); \
}
-#define DEFINE_LOAD_STORE_OPCODE(name) \
- Result BinaryReaderLogging::name(Opcode opcode, Address alignment_log2, \
- Address offset) { \
- LOGF(#name "(opcode: \"%s\" (%u), align log2: %" PRIaddress \
- ", offset: %" PRIaddress ")\n", \
- opcode.GetName(), opcode.GetCode(), alignment_log2, offset); \
- return reader_->name(opcode, alignment_log2, offset); \
- }
-
-#define DEFINE_MEMORY_LOAD_STORE_OPCODE(name) \
+#define DEFINE_LOAD_STORE_OPCODE(name) \
Result BinaryReaderLogging::name(Opcode opcode, Index memidx, \
Address alignment_log2, Address offset) { \
LOGF(#name "(opcode: \"%s\" (%u), memidx: %" PRIindex \
@@ -816,7 +807,7 @@ DEFINE0(OnElseExpr)
DEFINE0(OnEndExpr)
DEFINE_INDEX_DESC(OnGlobalGetExpr, "index")
DEFINE_INDEX_DESC(OnGlobalSetExpr, "index")
-DEFINE_MEMORY_LOAD_STORE_OPCODE(OnLoadExpr);
+DEFINE_LOAD_STORE_OPCODE(OnLoadExpr);
DEFINE_INDEX_DESC(OnLocalGetExpr, "index")
DEFINE_INDEX_DESC(OnLocalSetExpr, "index")
DEFINE_INDEX_DESC(OnLocalTeeExpr, "index")
@@ -845,7 +836,7 @@ DEFINE_INDEX_INDEX(OnReturnCallIndirectExpr, "sig_index", "table_index")
DEFINE0(OnReturnExpr)
DEFINE_LOAD_STORE_OPCODE(OnLoadSplatExpr);
DEFINE_LOAD_STORE_OPCODE(OnLoadZeroExpr);
-DEFINE_MEMORY_LOAD_STORE_OPCODE(OnStoreExpr);
+DEFINE_LOAD_STORE_OPCODE(OnStoreExpr);
DEFINE_INDEX_DESC(OnThrowExpr, "tag_index")
DEFINE0(OnUnreachableExpr)
DEFINE_OPCODE(OnUnaryExpr)
@@ -945,6 +936,14 @@ Result BinaryReaderLogging::OnOpcodeUint32Uint32Uint32(uint32_t value,
return reader_->OnOpcodeUint32Uint32Uint32(value, value2, value3);
}
+Result BinaryReaderLogging::OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) {
+ return reader_->OnOpcodeUint32Uint32Uint32Uint32(value, value2, value3,
+ value4);
+}
+
Result BinaryReaderLogging::OnOpcodeUint64(uint64_t value) {
return reader_->OnOpcodeUint64(value);
}
diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h
index 51cd5985..c5176bdf 100644
--- a/src/binary-reader-logging.h
+++ b/src/binary-reader-logging.h
@@ -140,6 +140,10 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnOpcodeUint32Uint32Uint32(uint32_t value,
uint32_t value2,
uint32_t value3) override;
+ Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) override;
Result OnOpcodeUint64(uint64_t value) override;
Result OnOpcodeF32(uint32_t value) override;
Result OnOpcodeF64(uint64_t value) override;
@@ -147,15 +151,19 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnOpcodeBlockSig(Type sig_type) override;
Result OnOpcodeType(Type type) override;
Result OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnBinaryExpr(Opcode opcode) override;
@@ -225,10 +233,12 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
Result OnTernaryExpr(Opcode opcode) override;
Result OnUnreachableExpr() override;
Result OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicFenceExpr(uint32_t consistency_model) override;
Result OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result EndFunctionBody(Index index) override;
@@ -246,9 +256,11 @@ class BinaryReaderLogging : public BinaryReaderDelegate {
uint64_t value) override;
Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override;
Result OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h
index ff78aa7f..c8ee065f 100644
--- a/src/binary-reader-nop.h
+++ b/src/binary-reader-nop.h
@@ -190,6 +190,12 @@ class BinaryReaderNop : public BinaryReaderDelegate {
uint32_t value3) override {
return Result::Ok;
}
+ Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) override {
+ return Result::Ok;
+ }
Result OnOpcodeUint64(uint64_t value) override { return Result::Ok; }
Result OnOpcodeF32(uint32_t value) override { return Result::Ok; }
Result OnOpcodeF64(uint64_t value) override { return Result::Ok; }
@@ -197,30 +203,34 @@ class BinaryReaderNop : public BinaryReaderDelegate {
Result OnOpcodeBlockSig(Type sig_type) override { return Result::Ok; }
Result OnOpcodeType(Type type) override { return Result::Ok; }
Result OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
}
Result OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
}
Result OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
}
Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
}
- Result OnAtomicWaitExpr(Opcode, Address, Address) override {
+ Result OnAtomicWaitExpr(Opcode, Index, Address, Address) override {
return Result::Ok;
}
Result OnAtomicFenceExpr(uint32_t) override { return Result::Ok; }
- Result OnAtomicNotifyExpr(Opcode, Address, Address) override {
+ Result OnAtomicNotifyExpr(Opcode, Index, Address, Address) override {
return Result::Ok;
}
Result OnBinaryExpr(Opcode opcode) override { return Result::Ok; }
@@ -332,11 +342,13 @@ class BinaryReaderNop : public BinaryReaderDelegate {
return Result::Ok;
}
Result OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
}
Result OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override {
return Result::Ok;
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc
index dec861d7..b6ff58a6 100644
--- a/src/binary-reader-objdump.cc
+++ b/src/binary-reader-objdump.cc
@@ -535,6 +535,10 @@ class BinaryReaderObjdumpDisassemble : public BinaryReaderObjdumpBase {
Result OnOpcodeUint32Uint32Uint32(uint32_t value,
uint32_t value2,
uint32_t value3) override;
+ Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) override;
Result OnOpcodeUint64(uint64_t value) override;
Result OnOpcodeF32(uint32_t value) override;
Result OnOpcodeF64(uint64_t value) override;
@@ -829,6 +833,18 @@ Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32Uint32(
return Result::Ok;
}
+Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32Uint32Uint32(
+ uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) {
+ if (!in_function_body) {
+ return Result::Ok;
+ }
+ LogOpcode("%u %u %u %u", value, value2, value3, value4);
+ return Result::Ok;
+}
+
Result BinaryReaderObjdumpDisassemble::OnOpcodeUint64(uint64_t value) {
if (!in_function_body) {
return Result::Ok;
diff --git a/src/binary-reader-opcnt.cc b/src/binary-reader-opcnt.cc
index 94ba1b08..96e3ef23 100644
--- a/src/binary-reader-opcnt.cc
+++ b/src/binary-reader-opcnt.cc
@@ -125,11 +125,8 @@ void OpcodeInfo::Write(Stream& stream) {
}
case Kind::Uint32Uint32:
- WriteArray<uint32_t>(
- stream, [&stream](uint32_t value) { stream.Writef("%u", value); });
- break;
-
case Kind::Uint32Uint32Uint32:
+ case Kind::Uint32Uint32Uint32Uint32:
WriteArray<uint32_t>(
stream, [&stream](uint32_t value) { stream.Writef("%u", value); });
break;
diff --git a/src/binary-reader-opcnt.h b/src/binary-reader-opcnt.h
index d7a947b0..e499c75d 100644
--- a/src/binary-reader-opcnt.h
+++ b/src/binary-reader-opcnt.h
@@ -40,6 +40,7 @@ class OpcodeInfo {
Float64,
Uint32Uint32,
Uint32Uint32Uint32,
+ Uint32Uint32Uint32Uint32,
BlockSig,
BrTable,
V128,
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index 77651025..3408b9da 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -119,6 +119,18 @@ class BinaryReader {
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 ReadMemLocation(Address* alignment_log2,
+ Index* memidx,
+ Address* offset,
+ const char* desc_align,
+ const char* desc_memidx,
+ const char* desc_offset,
+ uint8_t* lane_val = nullptr) WABT_WARN_UNUSED;
+ Result CallbackMemLocation(const Address* alignment_log2,
+ const Index* memidx,
+ const Address* offset,
+ const uint8_t* lane_val = nullptr)
+ WABT_WARN_UNUSED;
Result ReadCount(Index* index, const char* desc) WABT_WARN_UNUSED;
Result ReadField(TypeMut* out_value) WABT_WARN_UNUSED;
@@ -430,6 +442,52 @@ Result BinaryReader::ReadMemidx(Index* memidx, const char* desc) {
return Result::Ok;
}
+Result BinaryReader::ReadMemLocation(Address* alignment_log2,
+ Index* memidx,
+ Address* offset,
+ const char* desc_align,
+ const char* desc_memidx,
+ const char* desc_offset,
+ uint8_t* lane_val) {
+ CHECK_RESULT(ReadAlignment(alignment_log2, desc_align));
+ *memidx = 0;
+ if (*alignment_log2 >> 6) {
+ ERROR_IF(!options_.features.multi_memory_enabled(),
+ "multi_memory not allowed");
+ *alignment_log2 = *alignment_log2 & ((1 << 6) - 1);
+ CHECK_RESULT(ReadMemidx(memidx, desc_memidx));
+ }
+ CHECK_RESULT(ReadAddress(offset, 0, desc_offset));
+
+ if (lane_val) {
+ CHECK_RESULT(ReadU8(lane_val, "Lane idx"));
+ }
+
+ return Result::Ok;
+}
+
+Result BinaryReader::CallbackMemLocation(const Address* alignment_log2,
+ const Index* memidx,
+ const Address* offset,
+ const uint8_t* lane_val) {
+ if (lane_val) {
+ if (*memidx) {
+ CALLBACK(OnOpcodeUint32Uint32Uint32Uint32, *alignment_log2, *memidx,
+ *offset, *lane_val);
+ } else {
+ CALLBACK(OnOpcodeUint32Uint32Uint32, *alignment_log2, *offset, *lane_val);
+ }
+ } else {
+ if (*memidx) {
+ CALLBACK(OnOpcodeUint32Uint32Uint32, *alignment_log2, *memidx, *offset);
+ } else {
+ CALLBACK(OnOpcodeUint32Uint32, *alignment_log2, *offset);
+ }
+ }
+
+ return Result::Ok;
+}
+
Result BinaryReader::ReadCount(Index* count, const char* desc) {
CHECK_RESULT(ReadIndex(count, desc));
@@ -911,23 +969,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::V128Load32X2S:
case Opcode::V128Load32X2U: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load 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);
- }
-
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "load alignment", "load memidx",
+ "load offset"));
CALLBACK(OnLoadExpr, opcode, memidx, alignment_log2, offset);
- if (memidx) {
- CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, memidx);
- } else {
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
- }
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -942,23 +990,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::F64Store:
case Opcode::V128Store: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "store alignment"));
+ Index memidx;
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);
- }
-
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "store alignment", "store memidx",
+ "store offset"));
CALLBACK(OnStoreExpr, opcode, memidx, alignment_log2, offset);
- if (memidx) {
- CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, memidx);
- } else {
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
- }
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -1324,12 +1362,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::V128Load32Splat:
case Opcode::V128Load64Splat: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
-
- CALLBACK(OnLoadSplatExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "load alignment", "load memidx",
+ "load offset"));
+ CALLBACK(OnLoadSplatExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
case Opcode::V128Load8Lane:
@@ -1337,22 +1376,16 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::V128Load32Lane:
case Opcode::V128Load64Lane: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
- 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);
- }
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
uint8_t lane_val;
- CHECK_RESULT(ReadU8(&lane_val, "Lane idx"));
-
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "load alignment", "load memidx",
+ "load offset", &lane_val));
CALLBACK(OnSimdLoadLaneExpr, opcode, memidx, alignment_log2, offset,
lane_val);
- CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, lane_val);
+ CHECK_RESULT(
+ CallbackMemLocation(&alignment_log2, &memidx, &offset, &lane_val));
break;
}
case Opcode::V128Store8Lane:
@@ -1360,33 +1393,28 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::V128Store32Lane:
case Opcode::V128Store64Lane: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
- 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);
- }
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
uint8_t lane_val;
- CHECK_RESULT(ReadU8(&lane_val, "Lane idx"));
-
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "store alignment", "store memidx",
+ "store offset", &lane_val));
CALLBACK(OnSimdStoreLaneExpr, opcode, memidx, alignment_log2, offset,
lane_val);
- CALLBACK(OnOpcodeUint32Uint32Uint32, alignment_log2, offset, lane_val);
+ CHECK_RESULT(
+ CallbackMemLocation(&alignment_log2, &memidx, &offset, &lane_val));
break;
}
case Opcode::V128Load32Zero:
case Opcode::V128Load64Zero: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
-
- CALLBACK(OnLoadZeroExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "load alignment", "load memidx",
+ "load offset"));
+ CALLBACK(OnLoadZeroExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
case Opcode::I32TruncF32S:
@@ -1501,24 +1529,26 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::MemoryAtomicNotify: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
-
- CALLBACK(OnAtomicNotifyExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "notify alignment", "notify memidx",
+ "notify offset"));
+ CALLBACK(OnAtomicNotifyExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
case Opcode::MemoryAtomicWait32:
case Opcode::MemoryAtomicWait64: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
-
- CALLBACK(OnAtomicWaitExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "wait alignment", "wait memidx",
+ "wait offset"));
+ CALLBACK(OnAtomicWaitExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -1540,12 +1570,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::I32AtomicLoad:
case Opcode::I64AtomicLoad: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "load alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "load offset"));
-
- CALLBACK(OnAtomicLoadExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "load alignment", "load memidx",
+ "load offset"));
+ CALLBACK(OnAtomicLoadExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -1557,12 +1588,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::I32AtomicStore:
case Opcode::I64AtomicStore: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "store alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "store offset"));
-
- CALLBACK(OnAtomicStoreExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "store alignment", "store memidx",
+ "store offset"));
+ CALLBACK(OnAtomicStoreExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -1609,12 +1641,13 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::I64AtomicRmw16XchgU:
case Opcode::I64AtomicRmw32XchgU: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "memory alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "memory offset"));
-
- CALLBACK(OnAtomicRmwExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "memory alignment", "memory memidx",
+ "memory offset"));
+ CALLBACK(OnAtomicRmwExpr, opcode, memidx, alignment_log2, offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
@@ -1626,12 +1659,14 @@ Result BinaryReader::ReadInstructions(bool stop_on_end,
case Opcode::I64AtomicRmw16CmpxchgU:
case Opcode::I64AtomicRmw32CmpxchgU: {
Address alignment_log2;
- CHECK_RESULT(ReadAlignment(&alignment_log2, "memory alignment"));
+ Index memidx;
Address offset;
- CHECK_RESULT(ReadAddress(&offset, 0, "memory offset"));
-
- CALLBACK(OnAtomicRmwCmpxchgExpr, opcode, alignment_log2, offset);
- CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
+ CHECK_RESULT(ReadMemLocation(&alignment_log2, &memidx, &offset,
+ "memory alignment", "memory memidx",
+ "memory offset"));
+ CALLBACK(OnAtomicRmwCmpxchgExpr, opcode, memidx, alignment_log2,
+ offset);
+ CHECK_RESULT(CallbackMemLocation(&alignment_log2, &memidx, &offset));
break;
}
diff --git a/src/binary-reader.h b/src/binary-reader.h
index 521fe906..9ab067fe 100644
--- a/src/binary-reader.h
+++ b/src/binary-reader.h
@@ -200,6 +200,10 @@ class BinaryReaderDelegate {
virtual Result OnOpcodeUint32Uint32Uint32(uint32_t value,
uint32_t value2,
uint32_t value3) = 0;
+ virtual Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
+ uint32_t value2,
+ uint32_t value3,
+ uint32_t value4) = 0;
virtual Result OnOpcodeUint64(uint64_t value) = 0;
virtual Result OnOpcodeF32(uint32_t value) = 0;
virtual Result OnOpcodeF64(uint64_t value) = 0;
@@ -207,22 +211,28 @@ class BinaryReaderDelegate {
virtual Result OnOpcodeBlockSig(Type sig_type) = 0;
virtual Result OnOpcodeType(Type type) = 0;
virtual Result OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnAtomicFenceExpr(uint32_t consistency_model) = 0;
virtual Result OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnBinaryExpr(Opcode opcode) = 0;
@@ -311,9 +321,11 @@ class BinaryReaderDelegate {
uint64_t value) = 0;
virtual Result OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
virtual Result OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) = 0;
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index 00beede6..423eed3e 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -411,10 +411,6 @@ class BinaryWriter {
template <typename T>
void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc);
template <typename T>
- 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);
@@ -691,37 +687,22 @@ void BinaryWriter::WriteLoadStoreExpr(const Func* func,
auto* typed_expr = cast<T>(expr);
WriteOpcode(stream_, typed_expr->opcode);
Address align = typed_expr->opcode.GetAlignment(typed_expr->align);
- stream_->WriteU8(log2_u32(align), "alignment");
- WriteU32Leb128(stream_, typed_expr->offset, desc);
-}
-
-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);
}
-};
+ WriteU32Leb128(stream_, typed_expr->offset, desc);
+}
template <typename T>
void BinaryWriter::WriteSimdLoadStoreLaneExpr(const Func* func,
const Expr* expr,
const char* desc) {
+ WriteLoadStoreExpr<T>(func, expr, desc);
auto* typed_expr = cast<T>(expr);
- WriteOpcode(stream_, typed_expr->opcode);
- Address align = typed_expr->opcode.GetAlignment(typed_expr->align);
- stream_->WriteU8(log2_u32(align), "alignment");
- WriteU32Leb128(stream_, typed_expr->offset, desc);
stream_->WriteU8(static_cast<uint8_t>(typed_expr->val), "Simd Lane literal");
}
@@ -885,7 +866,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
break;
}
case ExprType::Load:
- WriteMemoryLoadStoreExpr<LoadExpr>(func, expr, "load offset");
+ WriteLoadStoreExpr<LoadExpr>(func, expr, "load offset");
break;
case ExprType::LocalGet: {
Index index = GetLocalIndex(func, cast<LocalGetExpr>(expr)->var);
@@ -1055,7 +1036,7 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) {
break;
}
case ExprType::Store:
- WriteMemoryLoadStoreExpr<StoreExpr>(func, expr, "store offset");
+ WriteLoadStoreExpr<StoreExpr>(func, expr, "store offset");
break;
case ExprType::Throw:
WriteOpcode(stream_, Opcode::Throw);
diff --git a/src/interp/binary-reader-interp.cc b/src/interp/binary-reader-interp.cc
index 5429a88a..e1696ce2 100644
--- a/src/interp/binary-reader-interp.cc
+++ b/src/interp/binary-reader-interp.cc
@@ -150,22 +150,28 @@ class BinaryReaderInterp : public BinaryReaderNop {
Result OnOpcode(Opcode Opcode) override;
Result OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnAtomicFenceExpr(uint32_t consistency_model) override;
Result OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnBinaryExpr(Opcode opcode) override;
@@ -247,9 +253,11 @@ class BinaryReaderInterp : public BinaryReaderNop {
uint64_t value) override;
Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override;
Result OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
Result OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address alignment_log2,
Address offset) override;
@@ -333,7 +341,6 @@ class BinaryReaderInterp : public BinaryReaderNop {
std::vector<GlobalType> global_types_; // Includes imported and defined.
std::vector<TagType> tag_types_; // Includes imported and defined.
- static const Index kMemoryIndex0 = 0;
std::string_view filename_;
};
@@ -902,6 +909,7 @@ Result BinaryReaderInterp::OnSimdLoadLaneExpr(Opcode opcode,
Address offset,
uint64_t value) {
CHECK_RESULT(validator_.OnSimdLoadLane(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
GetAlignment(alignment_log2), value));
istream_.Emit(opcode, memidx, offset, static_cast<u8>(value));
return Result::Ok;
@@ -913,6 +921,7 @@ Result BinaryReaderInterp::OnSimdStoreLaneExpr(Opcode opcode,
Address offset,
uint64_t value) {
CHECK_RESULT(validator_.OnSimdStoreLane(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
GetAlignment(alignment_log2), value));
istream_.Emit(opcode, memidx, offset, static_cast<u8>(value));
return Result::Ok;
@@ -925,56 +934,68 @@ Result BinaryReaderInterp::OnSimdShuffleOpExpr(Opcode opcode, v128 value) {
}
Result BinaryReaderInterp::OnLoadSplatExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(
- validator_.OnLoadSplat(GetLocation(), opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(validator_.OnLoadSplat(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
+ GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnLoadZeroExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(
- validator_.OnLoadZero(GetLocation(), opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(validator_.OnLoadZero(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
+ GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnAtomicLoadExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(
- validator_.OnAtomicLoad(GetLocation(), opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(validator_.OnAtomicLoad(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
+ GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnAtomicStoreExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
CHECK_RESULT(validator_.OnAtomicStore(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnAtomicRmwExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(
- validator_.OnAtomicRmw(GetLocation(), opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(validator_.OnAtomicRmw(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
+ GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
Result BinaryReaderInterp::OnAtomicRmwCmpxchgExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
CHECK_RESULT(validator_.OnAtomicRmwCmpxchg(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
@@ -1368,11 +1389,13 @@ Result BinaryReaderInterp::OnUnreachableExpr() {
}
Result BinaryReaderInterp::OnAtomicWaitExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
- CHECK_RESULT(
- validator_.OnAtomicWait(GetLocation(), opcode, GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ CHECK_RESULT(validator_.OnAtomicWait(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
+ GetAlignment(align_log2)));
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
@@ -1383,11 +1406,13 @@ Result BinaryReaderInterp::OnAtomicFenceExpr(uint32_t consistency_model) {
}
Result BinaryReaderInterp::OnAtomicNotifyExpr(Opcode opcode,
+ Index memidx,
Address align_log2,
Address offset) {
CHECK_RESULT(validator_.OnAtomicNotify(GetLocation(), opcode,
+ Var(memidx, GetLocation()),
GetAlignment(align_log2)));
- istream_.Emit(opcode, kMemoryIndex0, offset);
+ istream_.Emit(opcode, memidx, offset);
return Result::Ok;
}
diff --git a/src/ir.h b/src/ir.h
index fbc48c7c..09c57a7f 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -717,30 +717,13 @@ class ConstExpr : public ExprMixin<ExprType::Const> {
// TODO(binji): Rename this, it is used for more than loads/stores now.
template <ExprType TypeEnum>
-class LoadStoreExpr : public ExprMixin<TypeEnum> {
+class LoadStoreExpr : public MemoryExpr<TypeEnum> {
public:
LoadStoreExpr(Opcode opcode,
+ Var memidx,
Address align,
Address offset,
const Location& loc = Location())
- : ExprMixin<TypeEnum>(loc),
- opcode(opcode),
- align(align),
- offset(offset) {}
-
- Opcode opcode;
- Address align;
- Address offset;
-};
-
-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),
@@ -751,8 +734,8 @@ class MemoryLoadStoreExpr : public MemoryExpr<TypeEnum> {
Address offset;
};
-typedef MemoryLoadStoreExpr<ExprType::Load> LoadExpr;
-typedef MemoryLoadStoreExpr<ExprType::Store> StoreExpr;
+typedef LoadStoreExpr<ExprType::Load> LoadExpr;
+typedef LoadStoreExpr<ExprType::Store> StoreExpr;
typedef LoadStoreExpr<ExprType::AtomicLoad> AtomicLoadExpr;
typedef LoadStoreExpr<ExprType::AtomicStore> AtomicStoreExpr;
diff --git a/src/resolve-names.cc b/src/resolve-names.cc
index b721d078..fcd274c9 100644
--- a/src/resolve-names.cc
+++ b/src/resolve-names.cc
@@ -77,6 +77,8 @@ class NameResolver : public ExprVisitor::DelegateNop {
Result EndTryExpr(TryExpr*) override;
Result OnThrowExpr(ThrowExpr*) override;
Result OnRethrowExpr(RethrowExpr*) override;
+ Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) override;
+ Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) override;
private:
void PrintError(const Location* loc, const char* fmt, ...);
@@ -470,6 +472,16 @@ Result NameResolver::OnRethrowExpr(RethrowExpr* expr) {
return Result::Ok;
}
+Result NameResolver::OnSimdLoadLaneExpr(SimdLoadLaneExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
+Result NameResolver::OnSimdStoreLaneExpr(SimdStoreLaneExpr* expr) {
+ ResolveMemoryVar(&expr->memidx);
+ return Result::Ok;
+}
+
void NameResolver::VisitFunc(Func* func) {
current_func_ = func;
if (func->decl.has_func_type) {
diff --git a/src/shared-validator.cc b/src/shared-validator.cc
index 086ca68e..6513f2d7 100644
--- a/src/shared-validator.cc
+++ b/src/shared-validator.cc
@@ -564,10 +564,11 @@ Result SharedValidator::OnAtomicFence(const Location& loc,
Result SharedValidator::OnAtomicLoad(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicLoad(opcode, mt.limits);
return result;
@@ -575,10 +576,11 @@ Result SharedValidator::OnAtomicLoad(const Location& loc,
Result SharedValidator::OnAtomicNotify(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicNotify(opcode, mt.limits);
return result;
@@ -586,10 +588,11 @@ Result SharedValidator::OnAtomicNotify(const Location& loc,
Result SharedValidator::OnAtomicRmwCmpxchg(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicRmwCmpxchg(opcode, mt.limits);
return result;
@@ -597,10 +600,11 @@ Result SharedValidator::OnAtomicRmwCmpxchg(const Location& loc,
Result SharedValidator::OnAtomicRmw(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicRmw(opcode, mt.limits);
return result;
@@ -608,10 +612,11 @@ Result SharedValidator::OnAtomicRmw(const Location& loc,
Result SharedValidator::OnAtomicStore(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicStore(opcode, mt.limits);
return result;
@@ -619,10 +624,11 @@ Result SharedValidator::OnAtomicStore(const Location& loc,
Result SharedValidator::OnAtomicWait(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAtomicAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnAtomicWait(opcode, mt.limits);
return result;
@@ -841,10 +847,11 @@ Result SharedValidator::OnLoad(const Location& loc,
Result SharedValidator::OnLoadSplat(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnLoad(opcode, mt.limits);
return result;
@@ -852,10 +859,11 @@ Result SharedValidator::OnLoadSplat(const Location& loc,
Result SharedValidator::OnLoadZero(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnLoad(opcode, mt.limits);
return result;
@@ -911,7 +919,7 @@ Result SharedValidator::OnMemoryCopy(const Location& loc,
Result SharedValidator::OnMemoryFill(const Location& loc, Var memidx) {
Result result = CheckInstr(Opcode::MemoryFill, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= typechecker_.OnMemoryFill(mt.limits);
return result;
}
@@ -1033,11 +1041,12 @@ Result SharedValidator::OnSimdLaneOp(const Location& loc,
Result SharedValidator::OnSimdLoadLane(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment,
uint64_t value) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnSimdLoadLane(opcode, mt.limits, value);
return result;
@@ -1045,11 +1054,12 @@ Result SharedValidator::OnSimdLoadLane(const Location& loc,
Result SharedValidator::OnSimdStoreLane(const Location& loc,
Opcode opcode,
+ Var memidx,
Address alignment,
uint64_t value) {
Result result = CheckInstr(opcode, loc);
MemoryType mt;
- result |= CheckMemoryIndex(Var(0, loc), &mt);
+ result |= CheckMemoryIndex(memidx, &mt);
result |= CheckAlign(loc, alignment, opcode.GetMemorySize());
result |= typechecker_.OnSimdStoreLane(opcode, mt.limits, value);
return result;
diff --git a/src/shared-validator.h b/src/shared-validator.h
index 33fe09ba..76d1b6b2 100644
--- a/src/shared-validator.h
+++ b/src/shared-validator.h
@@ -104,12 +104,12 @@ class SharedValidator {
Result OnLocalDecl(const Location&, Index count, Type type);
Result OnAtomicFence(const Location&, uint32_t consistency_model);
- Result OnAtomicLoad(const Location&, Opcode, Address align);
- Result OnAtomicNotify(const Location&, Opcode, Address align);
- Result OnAtomicRmwCmpxchg(const Location&, Opcode, Address align);
- Result OnAtomicRmw(const Location&, Opcode, Address align);
- Result OnAtomicStore(const Location&, Opcode, Address align);
- Result OnAtomicWait(const Location&, Opcode, Address align);
+ Result OnAtomicLoad(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicNotify(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicRmwCmpxchg(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicRmw(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicStore(const Location&, Opcode, Var memidx, Address align);
+ Result OnAtomicWait(const Location&, Opcode, Var memidx, Address align);
Result OnBinary(const Location&, Opcode);
Result OnBlock(const Location&, Type sig_type);
Result OnBr(const Location&, Var depth);
@@ -134,8 +134,8 @@ class SharedValidator {
Result OnGlobalSet(const Location&, Var);
Result OnIf(const Location&, Type sig_type);
Result OnLoad(const Location&, Opcode, Var memidx, Address align);
- Result OnLoadSplat(const Location&, Opcode, Address align);
- Result OnLoadZero(const Location&, Opcode, Address align);
+ Result OnLoadSplat(const Location&, Opcode, Var memidx, Address align);
+ Result OnLoadZero(const Location&, Opcode, Var memidx, Address align);
Result OnLocalGet(const Location&, Var);
Result OnLocalSet(const Location&, Var);
Result OnLocalTee(const Location&, Var);
@@ -157,10 +157,12 @@ class SharedValidator {
Result OnSimdLaneOp(const Location&, Opcode, uint64_t lane_idx);
Result OnSimdLoadLane(const Location&,
Opcode,
+ Var memidx,
Address align,
uint64_t lane_idx);
Result OnSimdStoreLane(const Location&,
Opcode,
+ Var memidx,
Address align,
uint64_t lane_idx);
Result OnSimdShuffleOp(const Location&, Opcode, v128 lane_idx);
diff --git a/src/validator.cc b/src/validator.cc
index 06831a8d..d44764cb 100644
--- a/src/validator.cc
+++ b/src/validator.cc
@@ -537,7 +537,7 @@ Result Validator::OnRethrowExpr(RethrowExpr* expr) {
}
Result Validator::OnAtomicWaitExpr(AtomicWaitExpr* expr) {
- result_ |= validator_.OnAtomicWait(expr->loc, expr->opcode,
+ result_ |= validator_.OnAtomicWait(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
@@ -548,32 +548,33 @@ Result Validator::OnAtomicFenceExpr(AtomicFenceExpr* expr) {
}
Result Validator::OnAtomicNotifyExpr(AtomicNotifyExpr* expr) {
- result_ |= validator_.OnAtomicNotify(expr->loc, expr->opcode,
+ result_ |= validator_.OnAtomicNotify(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
Result Validator::OnAtomicLoadExpr(AtomicLoadExpr* expr) {
- result_ |= validator_.OnAtomicLoad(expr->loc, expr->opcode,
+ result_ |= validator_.OnAtomicLoad(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
Result Validator::OnAtomicStoreExpr(AtomicStoreExpr* expr) {
- result_ |= validator_.OnAtomicStore(expr->loc, expr->opcode,
+ result_ |= validator_.OnAtomicStore(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
Result Validator::OnAtomicRmwExpr(AtomicRmwExpr* expr) {
- result_ |= validator_.OnAtomicRmw(expr->loc, expr->opcode,
+ result_ |= validator_.OnAtomicRmw(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
Result Validator::OnAtomicRmwCmpxchgExpr(AtomicRmwCmpxchgExpr* expr) {
- result_ |= validator_.OnAtomicRmwCmpxchg(
- expr->loc, expr->opcode, expr->opcode.GetAlignment(expr->align));
+ result_ |=
+ validator_.OnAtomicRmwCmpxchg(expr->loc, expr->opcode, expr->memidx,
+ expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
@@ -588,14 +589,14 @@ Result Validator::OnSimdLaneOpExpr(SimdLaneOpExpr* expr) {
}
Result Validator::OnSimdLoadLaneExpr(SimdLoadLaneExpr* expr) {
- result_ |= validator_.OnSimdLoadLane(expr->loc, expr->opcode,
+ result_ |= validator_.OnSimdLoadLane(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align),
expr->val);
return Result::Ok;
}
Result Validator::OnSimdStoreLaneExpr(SimdStoreLaneExpr* expr) {
- result_ |= validator_.OnSimdStoreLane(expr->loc, expr->opcode,
+ result_ |= validator_.OnSimdStoreLane(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align),
expr->val);
return Result::Ok;
@@ -607,13 +608,13 @@ Result Validator::OnSimdShuffleOpExpr(SimdShuffleOpExpr* expr) {
}
Result Validator::OnLoadSplatExpr(LoadSplatExpr* expr) {
- result_ |= validator_.OnLoadSplat(expr->loc, expr->opcode,
+ result_ |= validator_.OnLoadSplat(expr->loc, expr->opcode, expr->memidx,
expr->opcode.GetAlignment(expr->align));
return Result::Ok;
}
Result Validator::OnLoadZeroExpr(LoadZeroExpr* expr) {
- result_ |= validator_.OnLoadZero(expr->loc, expr->opcode,
+ result_ |= validator_.OnLoadZero(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 d1564439..3f276658 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -1993,22 +1993,9 @@ Result WastParser::ParseMemoryInstrVar(Location loc,
}
template <typename T>
-Result WastParser::ParsePlainLoadStoreInstr(Location loc,
- Token token,
- std::unique_ptr<Expr>* out_expr) {
- Opcode opcode = token.opcode();
- Address offset;
- Address align;
- ParseOffsetOpt(&offset);
- ParseAlignOpt(&align);
- out_expr->reset(new T(opcode, align, offset, loc));
- return Result::Ok;
-}
-
-template <typename T>
-Result WastParser::ParseMemoryLoadStoreInstr(Location loc,
- Token token,
- std::unique_ptr<Expr>* out_expr) {
+Result WastParser::ParseLoadStoreInstr(Location loc,
+ Token token,
+ std::unique_ptr<Expr>* out_expr) {
Opcode opcode = token.opcode();
Var memidx;
Address offset;
@@ -2227,13 +2214,11 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
break;
case TokenType::Load:
- CHECK_RESULT(
- ParseMemoryLoadStoreInstr<LoadExpr>(loc, Consume(), out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<LoadExpr>(loc, Consume(), out_expr));
break;
case TokenType::Store:
- CHECK_RESULT(
- ParseMemoryLoadStoreInstr<StoreExpr>(loc, Consume(), out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<StoreExpr>(loc, Consume(), out_expr));
break;
case TokenType::Const: {
@@ -2393,8 +2378,7 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::AtomicNotify: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicNotifyExpr>(loc, token, out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<AtomicNotifyExpr>(loc, token, out_expr));
break;
}
@@ -2409,32 +2393,28 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
case TokenType::AtomicWait: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicWaitExpr>(loc, token, out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<AtomicWaitExpr>(loc, token, out_expr));
break;
}
case TokenType::AtomicLoad: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicLoadExpr>(loc, token, out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<AtomicLoadExpr>(loc, token, out_expr));
break;
}
case TokenType::AtomicStore: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicStoreExpr>(loc, token, out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<AtomicStoreExpr>(loc, token, out_expr));
break;
}
case TokenType::AtomicRmw: {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
- CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicRmwExpr>(loc, token, out_expr));
+ CHECK_RESULT(ParseLoadStoreInstr<AtomicRmwExpr>(loc, token, out_expr));
break;
}
@@ -2442,7 +2422,7 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) {
Token token = Consume();
ErrorUnlessOpcodeEnabled(token);
CHECK_RESULT(
- ParsePlainLoadStoreInstr<AtomicRmwCmpxchgExpr>(loc, token, out_expr));
+ ParseLoadStoreInstr<AtomicRmwCmpxchgExpr>(loc, token, out_expr));
break;
}
diff --git a/src/wast-parser.h b/src/wast-parser.h
index b3ac652f..53aa4321 100644
--- a/src/wast-parser.h
+++ b/src/wast-parser.h
@@ -207,9 +207,7 @@ class WastParser {
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>*);
+ Result ParseLoadStoreInstr(Location, Token, std::unique_ptr<Expr>*);
template <typename T>
Result ParseSIMDLoadStoreInstr(Location loc,
Token token,
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index b6f19652..265f4285 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -1041,6 +1041,7 @@ Result WatWriter::ExprVisitorDelegate::OnSimdLaneOpExpr(SimdLaneOpExpr* expr) {
Result WatWriter::ExprVisitorDelegate::OnSimdLoadLaneExpr(
SimdLoadLaneExpr* expr) {
writer_->WritePutsSpace(expr->opcode.GetName());
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
if (expr->offset) {
writer_->Writef("offset=%" PRIaddress, expr->offset);
}
@@ -1055,6 +1056,7 @@ Result WatWriter::ExprVisitorDelegate::OnSimdLoadLaneExpr(
Result WatWriter::ExprVisitorDelegate::OnSimdStoreLaneExpr(
SimdStoreLaneExpr* expr) {
writer_->WritePutsSpace(expr->opcode.GetName());
+ writer_->WriteMemoryVarUnlessZero(expr->memidx, NextChar::Space);
if (expr->offset) {
writer_->Writef("offset=%" PRIaddress, expr->offset);
}