diff options
author | Ashley Nelson <nashley@google.com> | 2022-12-12 15:33:45 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-12 15:33:45 -0800 |
commit | 6c0d8f7bb674da1cf22499873f6fe87e45f3be64 (patch) | |
tree | 5787b22097c08fa94ab02cc8cd906f24a8877d47 /src | |
parent | 05dda84ea6d175237a92d3c2aae94cde0e6a6abb (diff) | |
download | binaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.tar.gz binaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.tar.bz2 binaryen-6c0d8f7bb674da1cf22499873f6fe87e45f3be64.zip |
Add Atomics support to Multi-Memory Lowering Pass (#5339)
This PR adds support for Atomic instructions in the multi-memory lowering pass. Also includes optional bounds checks per the wasm spec guidelines, (visitAtomicRMW, visitAtomicCmpxchg, visitAtomicWait, visitAtomicNotify).
Note: The latter two instructions, memory.atomic.wait and memory.atomic.notify, have browser engine implementations that predate the still-in-progress threads spec. And whether or not atomic.notify should trap for out-of-bounds addresses remains an open issue. For now, this PR is using the same semantics as v8, which is to bounds check all Atomic instructions the same way and trap for out-of-bounds.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/MultiMemoryLowering.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/passes/MultiMemoryLowering.cpp b/src/passes/MultiMemoryLowering.cpp index 452aa21af..0b066c39b 100644 --- a/src/passes/MultiMemoryLowering.cpp +++ b/src/passes/MultiMemoryLowering.cpp @@ -31,6 +31,14 @@ // would not trap. In theory we could compute like the spec, by expanding the // i32s to i64s and adding there (where we won't overflow), but we don't have // i128s to handle i64 overflow. +// +// The Atomic instructions memory.atomic.wait and memory.atomic.notify, have +// browser engine implementations that predate the still-in-progress threads +// spec (https://github.com/WebAssembly/threads). And whether or not +// atomic.notify should trap for out-of-bounds addresses remains an open issue +// (https://github.com/WebAssembly/threads/issues/105). For now, we are using +// the same semantics as v8, which is to bounds check all Atomic instructions +// the same way and trap for out-of-bounds. #include "ir/module-utils.h" #include "ir/names.h" @@ -193,6 +201,39 @@ struct MultiMemoryLowering : public Pass { curr->ptr = getPtr(curr, getFunction(), curr->getMemBytes()); setMemory(curr); } + + void visitAtomicRMW(AtomicRMW* curr) { + curr->ptr = getPtr(curr, getFunction(), curr->bytes); + setMemory(curr); + } + + void visitAtomicCmpxchg(AtomicCmpxchg* curr) { + curr->ptr = getPtr(curr, getFunction(), curr->bytes); + setMemory(curr); + } + + void visitAtomicWait(AtomicWait* curr) { + Index bytes; + switch (curr->expectedType.getBasic()) { + case Type::i32: { + bytes = 4; + break; + } + case Type::i64: { + bytes = 8; + break; + } + default: + WASM_UNREACHABLE("unexpected type"); + } + curr->ptr = getPtr(curr, getFunction(), bytes); + setMemory(curr); + } + + void visitAtomicNotify(AtomicNotify* curr) { + curr->ptr = getPtr(curr, getFunction(), Index(4)); + setMemory(curr); + } }; void run(Module* module) override { |