summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 44ce9a2d1..c96157f1a 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -954,7 +954,10 @@ void WasmBinaryWriter::visitStore(Store *curr) {
void WasmBinaryWriter::visitAtomicRMW(AtomicRMW *curr) {
if (debug) std::cerr << "zz node: AtomicRMW" << std::endl;
recurse(curr->ptr);
+ // stop if the rest isn't reachable anyhow
+ if (curr->ptr->type == unreachable) return;
recurse(curr->value);
+ if (curr->value->type == unreachable) return;
if (curr->type == unreachable) {
// don't even emit it; we don't know the right type
@@ -1005,8 +1008,12 @@ void WasmBinaryWriter::visitAtomicRMW(AtomicRMW *curr) {
void WasmBinaryWriter::visitAtomicCmpxchg(AtomicCmpxchg *curr) {
if (debug) std::cerr << "zz node: AtomicCmpxchg" << std::endl;
recurse(curr->ptr);
+ // stop if the rest isn't reachable anyhow
+ if (curr->ptr->type == unreachable) return;
recurse(curr->expected);
+ if (curr->expected->type == unreachable) return;
recurse(curr->replacement);
+ if (curr->replacement->type == unreachable) return;
if (curr->type == unreachable) {
// don't even emit it; we don't know the right type
@@ -1041,13 +1048,25 @@ void WasmBinaryWriter::visitAtomicCmpxchg(AtomicCmpxchg *curr) {
void WasmBinaryWriter::visitAtomicWait(AtomicWait *curr) {
if (debug) std::cerr << "zz node: AtomicWait" << std::endl;
recurse(curr->ptr);
+ // stop if the rest isn't reachable anyhow
+ if (curr->ptr->type == unreachable) return;
recurse(curr->expected);
+ if (curr->expected->type == unreachable) return;
recurse(curr->timeout);
+ if (curr->timeout->type == unreachable) return;
o << int8_t(BinaryConsts::AtomicPrefix);
switch (curr->expectedType) {
- case i32: o << int8_t(BinaryConsts::I32AtomicWait); break;
- case i64: o << int8_t(BinaryConsts::I64AtomicWait); break;
+ case i32: {
+ o << int8_t(BinaryConsts::I32AtomicWait);
+ emitMemoryAccess(4, 4, 0);
+ break;
+ }
+ case i64: {
+ o << int8_t(BinaryConsts::I64AtomicWait);
+ emitMemoryAccess(8, 8, 0);
+ break;
+ }
default: WASM_UNREACHABLE();
}
}
@@ -1055,9 +1074,13 @@ void WasmBinaryWriter::visitAtomicWait(AtomicWait *curr) {
void WasmBinaryWriter::visitAtomicWake(AtomicWake *curr) {
if (debug) std::cerr << "zz node: AtomicWake" << std::endl;
recurse(curr->ptr);
+ // stop if the rest isn't reachable anyhow
+ if (curr->ptr->type == unreachable) return;
recurse(curr->wakeCount);
+ if (curr->wakeCount->type == unreachable) return;
o << int8_t(BinaryConsts::AtomicPrefix) << int8_t(BinaryConsts::AtomicWake);
+ emitMemoryAccess(4, 4, 0);
}
void WasmBinaryWriter::visitConst(Const *curr) {
@@ -2555,7 +2578,7 @@ void WasmBinaryBuilder::visitSetGlobal(SetGlobal *curr) {
curr->finalize();
}
-void WasmBinaryBuilder::readMemoryAccess(Address& alignment, size_t bytes, Address& offset) {
+void WasmBinaryBuilder::readMemoryAccess(Address& alignment, Address& offset) {
auto rawAlignment = getU32LEB();
if (rawAlignment > 4) throw ParseException("Alignment must be of a reasonable size");
alignment = Pow2(rawAlignment);
@@ -2599,7 +2622,7 @@ bool WasmBinaryBuilder::maybeVisitLoad(Expression*& out, uint8_t code, bool isAt
}
curr->isAtomic = isAtomic;
- readMemoryAccess(curr->align, curr->bytes, curr->offset);
+ readMemoryAccess(curr->align, curr->offset);
curr->ptr = popNonVoidExpression();
curr->finalize();
out = curr;
@@ -2636,7 +2659,7 @@ bool WasmBinaryBuilder::maybeVisitStore(Expression*& out, uint8_t code, bool isA
curr->isAtomic = isAtomic;
if (debug) std::cerr << "zz node: Store" << std::endl;
- readMemoryAccess(curr->align, curr->bytes, curr->offset);
+ readMemoryAccess(curr->align, curr->offset);
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
curr->finalize();
@@ -2679,7 +2702,7 @@ bool WasmBinaryBuilder::maybeVisitAtomicRMW(Expression*& out, uint8_t code) {
if (debug) std::cerr << "zz node: AtomicRMW" << std::endl;
Address readAlign;
- readMemoryAccess(readAlign, curr->bytes, curr->offset);
+ readMemoryAccess(readAlign, curr->offset);
if (readAlign != curr->bytes) throw ParseException("Align of AtomicRMW must match size");
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
@@ -2710,7 +2733,7 @@ bool WasmBinaryBuilder::maybeVisitAtomicCmpxchg(Expression*& out, uint8_t code)
if (debug) std::cerr << "zz node: AtomicCmpxchg" << std::endl;
Address readAlign;
- readMemoryAccess(readAlign, curr->bytes, curr->offset);
+ readMemoryAccess(readAlign, curr->offset);
if (readAlign != curr->bytes) throw ParseException("Align of AtomicCpxchg must match size");
curr->replacement = popNonVoidExpression();
curr->expected = popNonVoidExpression();
@@ -2734,6 +2757,9 @@ bool WasmBinaryBuilder::maybeVisitAtomicWait(Expression*& out, uint8_t code) {
curr->timeout = popNonVoidExpression();
curr->expected = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
+ Address readAlign;
+ readMemoryAccess(readAlign, curr->offset);
+ if (readAlign != getWasmTypeSize(curr->expectedType)) throw ParseException("Align of AtomicWait must match size");
curr->finalize();
out = curr;
return true;
@@ -2747,6 +2773,9 @@ bool WasmBinaryBuilder::maybeVisitAtomicWake(Expression*& out, uint8_t code) {
curr->type = i32;
curr->wakeCount = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
+ Address readAlign;
+ readMemoryAccess(readAlign, curr->offset);
+ if (readAlign != getWasmTypeSize(curr->type)) throw ParseException("Align of AtomicWake must match size");
curr->finalize();
out = curr;
return true;