Skip to content

Commit 1d2d902

Browse files
committed
feat: RacyMemory::from_raw_parts
1 parent 85a1859 commit 1d2d902

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

ecmascript_atomics/src/lib.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,9 @@ impl<T: Sealed> RacyMemory<T> {
211211
options(nostack, preserves_flags)
212212
)
213213
}
214-
RacyMemory {
215-
// SAFETY: Magic spell always returns non-null pointers.
216-
ptr: RacyPtr::from_ptr(unsafe { NonNull::new_unchecked(ptr.cast()) }),
217-
len,
218-
}
214+
// SAFETY: Magic spell always returns non-null pointers.
215+
let ptr = RacyPtr::from_ptr(unsafe { NonNull::new_unchecked(ptr.cast()) });
216+
RacyMemory::from_raw_parts(ptr, len)
219217
}
220218

221219
/// Move a typed memory allocation into the ECMAScript memory model.
@@ -231,10 +229,7 @@ impl<T: Sealed> RacyMemory<T> {
231229
/// [`enter`]: crate::RacyMemory::enter
232230
pub unsafe fn enter_ptr(ptr: NonNull<T>) -> Self {
233231
let RacyMemory { ptr, .. } = unsafe { Self::enter(ptr.cast(), size_of::<T>()) };
234-
Self {
235-
ptr: ptr.cast(),
236-
len: 1,
237-
}
232+
Self::from_raw_parts(ptr.cast(), 1)
238233
}
239234

240235
/// Move a typed memory allocation slice into the ECMAScript memory model.
@@ -251,10 +246,7 @@ impl<T: Sealed> RacyMemory<T> {
251246
pub unsafe fn enter_slice(ptr: NonNull<[T]>) -> Self {
252247
let len = ptr.len();
253248
let RacyMemory { ptr, .. } = unsafe { Self::enter(ptr.cast(), size_of::<T>() * len) };
254-
Self {
255-
ptr: ptr.cast(),
256-
len,
257-
}
249+
Self::from_raw_parts(ptr.cast(), len)
258250
}
259251

260252
/// Move an ECMAScript memory model into the void and return a new Rust
@@ -302,6 +294,17 @@ impl<T: Sealed> RacyMemory<T> {
302294
pub const fn into_raw_parts(self) -> (RacyPtr<T>, usize) {
303295
(self.ptr, self.len)
304296
}
297+
298+
/// Recrate a racy atomic memory slice from raw parts.
299+
///
300+
/// # Safety
301+
///
302+
/// `ptr` must point to a racy atomic memory with a length of exactly `len`
303+
/// elements and be properly aligned. Note that this function does
304+
/// not "reallocate" the pointed-to memory.
305+
pub const fn from_raw_parts(ptr: RacyPtr<T>, len: usize) -> Self {
306+
Self { ptr, len }
307+
}
305308
}
306309

307310
mod private {
@@ -351,7 +354,7 @@ impl<'a, T: Sealed> RacySlice<'a, T> {
351354
#[inline(always)]
352355
pub const unsafe fn from_raw_parts(ptr: RacyPtr<T>, len: usize) -> Self {
353356
Self {
354-
ptr: ptr,
357+
ptr,
355358
len,
356359
__marker: PhantomData,
357360
}
@@ -633,7 +636,10 @@ impl<'a, T: Sealed> RacySlice<'a, T> {
633636
}
634637
if const { align_of::<T>() >= align_of::<u16>() } || UNALIGNED_ACCESS_IS_OK {
635638
// Always properly aligned.
636-
return Some(atomic_store_16_unsynchronized(self.ptr.as_ptr(), val));
639+
return {
640+
atomic_store_16_unsynchronized(self.ptr.as_ptr(), val);
641+
Some(())
642+
};
637643
}
638644
// SAFETY: checked self length, dst is proper length.
639645
let src = unsafe { NonNull::new_unchecked(&val as *const _ as *mut ()) };
@@ -658,7 +664,10 @@ impl<'a, T: Sealed> RacySlice<'a, T> {
658664
}
659665
if const { align_of::<T>() >= align_of::<u32>() } || UNALIGNED_ACCESS_IS_OK {
660666
// Always properly aligned.
661-
return Some(atomic_store_32_unsynchronized(self.ptr.as_ptr(), val));
667+
return {
668+
atomic_store_32_unsynchronized(self.ptr.as_ptr(), val);
669+
Some(())
670+
};
662671
}
663672
// SAFETY: checked self length, dst is proper length.
664673
let src = unsafe { NonNull::new_unchecked(&val as *const _ as *mut ()) };
@@ -684,7 +693,10 @@ impl<'a, T: Sealed> RacySlice<'a, T> {
684693
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64",))]
685694
if const { align_of::<T>() >= align_of::<u64>() } || UNALIGNED_ACCESS_IS_OK {
686695
// Always properly aligned.
687-
return Some(atomic_store_64_unsynchronized(self.ptr.as_ptr(), val));
696+
return {
697+
atomic_store_64_unsynchronized(self.ptr.as_ptr(), val);
698+
Some(())
699+
};
688700
}
689701
// SAFETY: checked self length, dst is proper length.
690702
let src = unsafe { NonNull::new_unchecked(&val as *const _ as *mut ()) };
@@ -1944,7 +1956,7 @@ unsafe fn unordered_copy_nonoverlapping<T: Sealed>(src: NonNull<T>, dst: NonNull
19441956
/// Behavior is undefined if any of the following conditions are violated:
19451957
///
19461958
/// * `src` must be [valid] for reads of `count` elements, OR it must be an
1947-
/// opaque racy handle into a racy slice of `count` elements.
1959+
/// opaque racy handle into a racy slice of `count` elements.
19481960
///
19491961
/// * `dst` must be [valid] for writes of `count` elements, and must remain
19501962
/// valid even when `src` is read for `count` elements (this means if the

0 commit comments

Comments
 (0)