summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp17
-rw-r--r--src/wasm/wasm-s-parser.cpp4
-rw-r--r--src/wasm/wasm-stack.cpp5
-rw-r--r--src/wasm/wasm-validator.cpp16
-rw-r--r--src/wasm/wasm.cpp2
5 files changed, 44 insertions, 0 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index d75973ab0..b7daeda5a 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -2302,6 +2302,9 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) {
if (maybeVisitAtomicNotify(curr, code)) {
break;
}
+ if (maybeVisitAtomicFence(curr, code)) {
+ break;
+ }
throwError("invalid code after atomic prefix: " + std::to_string(code));
break;
}
@@ -3172,6 +3175,20 @@ bool WasmBinaryBuilder::maybeVisitAtomicNotify(Expression*& out, uint8_t code) {
return true;
}
+bool WasmBinaryBuilder::maybeVisitAtomicFence(Expression*& out, uint8_t code) {
+ if (code != BinaryConsts::AtomicFence) {
+ return false;
+ }
+ auto* curr = allocator.alloc<AtomicFence>();
+ if (debug) {
+ std::cerr << "zz node: AtomicFence" << std::endl;
+ }
+ curr->order = getU32LEB();
+ curr->finalize();
+ out = curr;
+ return true;
+}
+
bool WasmBinaryBuilder::maybeVisitConst(Expression*& out, uint8_t code) {
Const* curr;
if (debug) {
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 39f6b0a9f..3a1e0db09 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -1421,6 +1421,10 @@ Expression* SExpressionWasmBuilder::makeAtomicNotify(Element& s) {
return ret;
}
+Expression* SExpressionWasmBuilder::makeAtomicFence(Element& s) {
+ return allocator.alloc<AtomicFence>();
+}
+
static uint8_t parseLaneIndex(const Element* s, size_t lanes) {
const char* str = s->c_str();
char* end;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index cb60c50f9..faa06330b 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -422,6 +422,11 @@ void BinaryInstWriter::visitAtomicNotify(AtomicNotify* curr) {
emitMemoryAccess(4, 4, 0);
}
+void BinaryInstWriter::visitAtomicFence(AtomicFence* curr) {
+ o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicFence)
+ << int8_t(curr->order);
+}
+
void BinaryInstWriter::visitSIMDExtract(SIMDExtract* curr) {
o << int8_t(BinaryConsts::SIMDPrefix);
switch (curr->op) {
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 339ad6f68..9b1220371 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -270,6 +270,7 @@ public:
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicNotify(AtomicNotify* curr);
+ void visitAtomicFence(AtomicFence* curr);
void visitSIMDExtract(SIMDExtract* curr);
void visitSIMDReplace(SIMDReplace* curr);
void visitSIMDShuffle(SIMDShuffle* curr);
@@ -917,6 +918,21 @@ void FunctionValidator::visitAtomicNotify(AtomicNotify* curr) {
"AtomicNotify notifyCount type must be i32");
}
+void FunctionValidator::visitAtomicFence(AtomicFence* curr) {
+ shouldBeTrue(
+ getModule()->memory.exists, curr, "Memory operations require a memory");
+ shouldBeTrue(getModule()->features.hasAtomics(),
+ curr,
+ "Atomic operation (atomics are disabled)");
+ shouldBeFalse(!getModule()->memory.shared,
+ curr,
+ "Atomic operation with non-shared memory");
+ shouldBeTrue(curr->order == 0,
+ curr,
+ "Currently only sequentially consistent atomics are supported, "
+ "so AtomicFence's order should be 0");
+}
+
void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) {
shouldBeTrue(
getModule()->features.hasSIMD(), curr, "SIMD operation (SIMD is disabled)");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index f8791286c..b13797c89 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -147,6 +147,8 @@ const char* getExpressionName(Expression* curr) {
return "atomic_wait";
case Expression::Id::AtomicNotifyId:
return "atomic_notify";
+ case Expression::Id::AtomicFenceId:
+ return "atomic_fence";
case Expression::Id::SIMDExtractId:
return "simd_extract";
case Expression::Id::SIMDReplaceId: