summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp40
-rw-r--r--src/wasm/wasm-ir-builder.cpp13
-rw-r--r--src/wasm/wasm-stack.cpp21
-rw-r--r--src/wasm/wasm-validator.cpp10
4 files changed, 75 insertions, 9 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 791dc53d7..b0c5a54ac 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1737,6 +1737,20 @@ void WasmBinaryWriter::writeField(const Field& field) {
o << U32LEB(field.mutable_);
}
+void WasmBinaryWriter::writeMemoryOrder(MemoryOrder order) {
+ switch (order) {
+ case MemoryOrder::Unordered:
+ break;
+ case MemoryOrder::SeqCst:
+ o << uint8_t(BinaryConsts::OrderSeqCst);
+ return;
+ case MemoryOrder::AcqRel:
+ o << uint8_t(BinaryConsts::OrderAcqRel);
+ return;
+ }
+ WASM_UNREACHABLE("unexpected memory order");
+}
+
// reader
WasmBinaryReader::WasmBinaryReader(Module& wasm,
@@ -3406,6 +3420,21 @@ Result<> WasmBinaryReader::readInst() {
return Err{"expected 0x00 byte immediate on atomic.fence"};
}
return builder.makeAtomicFence();
+ case BinaryConsts::StructAtomicGet:
+ case BinaryConsts::StructAtomicGetS:
+ case BinaryConsts::StructAtomicGetU: {
+ auto order = getMemoryOrder();
+ auto type = getIndexedHeapType();
+ auto field = getU32LEB();
+ bool signed_ = op == BinaryConsts::StructAtomicGetS;
+ return builder.makeStructGet(type, field, signed_, order);
+ }
+ case BinaryConsts::StructAtomicSet: {
+ auto order = getMemoryOrder();
+ auto type = getIndexedHeapType();
+ auto field = getU32LEB();
+ return builder.makeStructSet(type, field, order);
+ }
}
return Err{"unknown atomic operation"};
}
@@ -4952,4 +4981,15 @@ std::tuple<Name, Address, Address> WasmBinaryReader::getMemarg() {
return {getMemoryName(memIdx), alignment, offset};
}
+MemoryOrder WasmBinaryReader::getMemoryOrder() {
+ auto code = getInt8();
+ switch (code) {
+ case BinaryConsts::OrderSeqCst:
+ return MemoryOrder::SeqCst;
+ case BinaryConsts::OrderAcqRel:
+ return MemoryOrder::AcqRel;
+ }
+ throwError("Unrecognized memory order code " + std::to_string(code));
+}
+
} // namespace wasm
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index 6cd62e439..4b0342410 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -1792,21 +1792,26 @@ Result<> IRBuilder::makeStructNewDefault(HeapType type) {
return Ok{};
}
-Result<> IRBuilder::makeStructGet(HeapType type, Index field, bool signed_) {
+Result<> IRBuilder::makeStructGet(HeapType type,
+ Index field,
+ bool signed_,
+ MemoryOrder order) {
const auto& fields = type.getStruct().fields;
StructGet curr;
CHECK_ERR(ChildPopper{*this}.visitStructGet(&curr, type));
CHECK_ERR(validateTypeAnnotation(type, curr.ref));
- push(builder.makeStructGet(field, curr.ref, fields[field].type, signed_));
+ push(
+ builder.makeStructGet(field, curr.ref, fields[field].type, signed_, order));
return Ok{};
}
-Result<> IRBuilder::makeStructSet(HeapType type, Index field) {
+Result<>
+IRBuilder::makeStructSet(HeapType type, Index field, MemoryOrder order) {
StructSet curr;
curr.index = field;
CHECK_ERR(ChildPopper{*this}.visitStructSet(&curr, type));
CHECK_ERR(validateTypeAnnotation(type, curr.ref));
- push(builder.makeStructSet(field, curr.ref, curr.value));
+ push(builder.makeStructSet(field, curr.ref, curr.value, order));
return Ok{};
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 61f59c76a..08043b27f 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2327,15 +2327,20 @@ void BinaryInstWriter::visitStructGet(StructGet* curr) {
}
const auto& heapType = curr->ref->type.getHeapType();
const auto& field = heapType.getStruct().fields[curr->index];
+ bool atomic = curr->order != MemoryOrder::Unordered;
int8_t op;
if (field.type != Type::i32 || field.packedType == Field::not_packed) {
- op = BinaryConsts::StructGet;
+ op = atomic ? BinaryConsts::StructAtomicGet : BinaryConsts::StructGet;
} else if (curr->signed_) {
- op = BinaryConsts::StructGetS;
+ op = atomic ? BinaryConsts::StructAtomicGetS : BinaryConsts::StructGetS;
} else {
- op = BinaryConsts::StructGetU;
+ op = atomic ? BinaryConsts::StructAtomicGetU : BinaryConsts::StructGetU;
+ }
+ auto prefix = atomic ? BinaryConsts::AtomicPrefix : BinaryConsts::GCPrefix;
+ o << int8_t(prefix) << U32LEB(op);
+ if (atomic) {
+ parent.writeMemoryOrder(curr->order);
}
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(op);
parent.writeIndexedHeapType(heapType);
o << U32LEB(curr->index);
}
@@ -2345,7 +2350,13 @@ void BinaryInstWriter::visitStructSet(StructSet* curr) {
emitUnreachable();
return;
}
- o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StructSet);
+ if (curr->order == MemoryOrder::Unordered) {
+ o << int8_t(BinaryConsts::GCPrefix) << U32LEB(BinaryConsts::StructSet);
+ } else {
+ o << int8_t(BinaryConsts::AtomicPrefix)
+ << U32LEB(BinaryConsts::StructAtomicSet);
+ parent.writeMemoryOrder(curr->order);
+ }
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
o << U32LEB(curr->index);
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 242e07c43..7de69a1ff 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -2989,6 +2989,11 @@ void FunctionValidator::visitStructGet(StructGet* curr) {
shouldBeTrue(getModule()->features.hasGC(),
curr,
"struct.get requires gc [--enable-gc]");
+ shouldBeTrue(curr->order == MemoryOrder::Unordered ||
+ getModule()->features.hasSharedEverything(),
+ curr,
+ "struct.atomic.get requires shared-everything "
+ "[--enable-shared-everything]");
if (curr->type == Type::unreachable || curr->ref->type.isNull()) {
return;
}
@@ -3016,6 +3021,11 @@ void FunctionValidator::visitStructSet(StructSet* curr) {
shouldBeTrue(getModule()->features.hasGC(),
curr,
"struct.set requires gc [--enable-gc]");
+ shouldBeTrue(curr->order == MemoryOrder::Unordered ||
+ getModule()->features.hasSharedEverything(),
+ curr,
+ "struct.atomic.set requires shared-everything "
+ "[--enable-shared-everything]");
if (curr->ref->type == Type::unreachable) {
return;
}