diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 43 |
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; |