feat: implement memory.atomic.notify,wait32,wait64 (#5255)
* feat: implement memory.atomic.notify,wait32,wait64 Added the parking_spot crate, which provides the needed registry for the operations. Signed-off-by: Harald Hoyer <harald@profian.com> * fix: change trap message for HeapMisaligned The threads spec test wants "unaligned atomic" instead of "misaligned memory access". Signed-off-by: Harald Hoyer <harald@profian.com> * tests: add test for atomic wait on non-shared memory Signed-off-by: Harald Hoyer <harald@profian.com> * tests: add tests/spec_testsuite/proposals/threads without pooling and reference types. Also "shared_memory" is added to the "spectest" interface. Signed-off-by: Harald Hoyer <harald@profian.com> * tests: add atomics_notify.wast checking that notify with 0 waiters returns 0 on shared and non-shared memory. Signed-off-by: Harald Hoyer <harald@profian.com> * tests: add tests for atomic wait on shared memory - return 2 - timeout for 0 - return 2 - timeout for 1000ns - return 1 - invalid value Signed-off-by: Harald Hoyer <harald@profian.com> * fixup! feat: implement memory.atomic.notify,wait32,wait64 Signed-off-by: Harald Hoyer <harald@profian.com> * fixup! feat: implement memory.atomic.notify,wait32,wait64 Signed-off-by: Harald Hoyer <harald@profian.com> Signed-off-by: Harald Hoyer <harald@profian.com>
This commit is contained in:
@@ -12,7 +12,7 @@ use std::ptr::NonNull;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::u32;
|
||||
pub use vm_host_func_context::VMHostFuncContext;
|
||||
use wasmtime_environ::DefinedMemoryIndex;
|
||||
use wasmtime_environ::{DefinedMemoryIndex, Trap};
|
||||
|
||||
pub const VMCONTEXT_MAGIC: u32 = u32::from_le_bytes(*b"core");
|
||||
|
||||
@@ -248,6 +248,30 @@ impl VMMemoryDefinition {
|
||||
current_length: other.current_length().into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// In the configurations where bounds checks were elided in JIT code (because
|
||||
/// we are using static memories with virtual memory guard pages) this manual
|
||||
/// check is here so we don't segfault from Rust. For other configurations,
|
||||
/// these checks are required anyways.
|
||||
pub fn validate_addr(
|
||||
&self,
|
||||
addr: u64,
|
||||
access_size: u64,
|
||||
access_alignment: u64,
|
||||
) -> Result<*const u8, Trap> {
|
||||
debug_assert!(access_alignment.is_power_of_two());
|
||||
if !(addr % access_alignment == 0) {
|
||||
return Err(Trap::HeapMisaligned);
|
||||
}
|
||||
|
||||
let length = u64::try_from(self.current_length()).unwrap();
|
||||
if !(addr.saturating_add(access_size) < length) {
|
||||
return Err(Trap::MemoryOutOfBounds);
|
||||
}
|
||||
|
||||
// SAFETY: checked above that the address is in bounds
|
||||
Ok(unsafe { self.base.add(addr as usize) })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user