]> git.lizzy.rs Git - rust.git/commitdiff
Move the intrinsics into a submodule
authorValentin Tolmer <valentin.tolmer@gmail.com>
Fri, 8 Feb 2019 13:14:15 +0000 (14:14 +0100)
committerValentin Tolmer <valentin.tolmer@gmail.com>
Wed, 13 Feb 2019 12:31:11 +0000 (13:31 +0100)
src/libcore/intrinsics.rs

index f6de7566be914281686e5109f20760886c7abfd0..e6098b1b24cc0b9a3d6ce9b9fd3b13d4573b589c 100644 (file)
     /// value is not necessarily valid to be used to actually access memory.
     pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
 
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination must *not* overlap.
-    ///
-    /// For regions of memory which might overlap, use [`copy`] instead.
-    ///
-    /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
-    /// with the argument order swapped.
-    ///
-    /// [`copy`]: ./fn.copy.html
-    /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// * The region of memory beginning at `src` with a size of `count *
-    ///   size_of::<T>()` bytes must *not* overlap with the region of memory
-    ///   beginning at `dst` with the same size.
-    ///
-    /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-NULL and properly aligned.
-    ///
-    /// [`Copy`]: ../marker/trait.Copy.html
-    /// [`read`]: ../ptr/fn.read.html
-    /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
-    /// [valid]: ../ptr/index.html#safety
-    ///
-    /// # Examples
-    ///
-    /// Manually implement [`Vec::append`]:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
-    /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
-    ///     let src_len = src.len();
-    ///     let dst_len = dst.len();
-    ///
-    ///     // Ensure that `dst` has enough capacity to hold all of `src`.
-    ///     dst.reserve(src_len);
-    ///
-    ///     unsafe {
-    ///         // The call to offset is always safe because `Vec` will never
-    ///         // allocate more than `isize::MAX` bytes.
-    ///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
-    ///         let src_ptr = src.as_ptr();
-    ///
-    ///         // Truncate `src` without dropping its contents. We do this first,
-    ///         // to avoid problems in case something further down panics.
-    ///         src.set_len(0);
-    ///
-    ///         // The two regions cannot overlap because mutable references do
-    ///         // not alias, and two different vectors cannot own the same
-    ///         // memory.
-    ///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
-    ///
-    ///         // Notify `dst` that it now holds the contents of `src`.
-    ///         dst.set_len(dst_len + src_len);
-    ///     }
-    /// }
-    ///
-    /// let mut a = vec!['r'];
-    /// let mut b = vec!['u', 's', 't'];
-    ///
-    /// append(&mut a, &mut b);
-    ///
-    /// assert_eq!(a, &['r', 'u', 's', 't']);
-    /// assert!(b.is_empty());
-    /// ```
-    ///
-    /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
-
-    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
-    /// and destination may overlap.
-    ///
-    /// If the source and destination will *never* overlap,
-    /// [`copy_nonoverlapping`] can be used instead.
-    ///
-    /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
-    /// order swapped. Copying takes place as if the bytes were copied from `src`
-    /// to a temporary array and then copied from the array to `dst`.
-    ///
-    /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
-    /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * Both `src` and `dst` must be properly aligned.
-    ///
-    /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
-    /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
-    /// in the region beginning at `*src` and the region beginning at `*dst` can
-    /// [violate memory safety][read-ownership].
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointers must be non-NULL and properly aligned.
-    ///
-    /// [`Copy`]: ../marker/trait.Copy.html
-    /// [`read`]: ../ptr/fn.read.html
-    /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
-    /// [valid]: ../ptr/index.html#safety
-    ///
-    /// # Examples
-    ///
-    /// Efficiently create a Rust vector from an unsafe buffer:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// # #[allow(dead_code)]
-    /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
-    ///     let mut dst = Vec::with_capacity(elts);
-    ///     dst.set_len(elts);
-    ///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
-    ///     dst
-    /// }
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
-
-    /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
-    /// `val`.
-    ///
-    /// `write_bytes` is similar to C's [`memset`], but sets `count *
-    /// size_of::<T>()` bytes to `val`.
-    ///
-    /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
-    ///
-    /// # Safety
-    ///
-    /// Behavior is undefined if any of the following conditions are violated:
-    ///
-    /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
-    ///
-    /// * `dst` must be properly aligned.
-    ///
-    /// Additionally, the caller must ensure that writing `count *
-    /// size_of::<T>()` bytes to the given region of memory results in a valid
-    /// value of `T`. Using a region of memory typed as a `T` that contains an
-    /// invalid value of `T` is undefined behavior.
-    ///
-    /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
-    /// `0`, the pointer must be non-NULL and properly aligned.
-    ///
-    /// [valid]: ../ptr/index.html#safety
-    ///
-    /// # Examples
-    ///
-    /// Basic usage:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// let mut vec = vec![0u32; 4];
-    /// unsafe {
-    ///     let vec_ptr = vec.as_mut_ptr();
-    ///     ptr::write_bytes(vec_ptr, 0xfe, 2);
-    /// }
-    /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
-    /// ```
-    ///
-    /// Creating an invalid value:
-    ///
-    /// ```
-    /// use std::ptr;
-    ///
-    /// let mut v = Box::new(0i32);
-    ///
-    /// unsafe {
-    ///     // Leaks the previously held value by overwriting the `Box<T>` with
-    ///     // a null pointer.
-    ///     ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
-    /// }
-    ///
-    /// // At this point, using or dropping `v` results in undefined behavior.
-    /// // drop(v); // ERROR
-    ///
-    /// // Even leaking `v` "uses" it, and hence is undefined behavior.
-    /// // mem::forget(v); // ERROR
-    ///
-    /// // In fact, `v` is invalid according to basic type layout invariants, so *any*
-    /// // operation touching it is undefined behavior.
-    /// // let v2 = v; // ERROR
-    ///
-    /// unsafe {
-    ///     // Let us instead put in a valid value
-    ///     ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
-    /// }
-    ///
-    /// // Now the box is fine
-    /// assert_eq!(*v, 42);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
-
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`
@@ -1524,3 +1309,252 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// Probably will never become stable.
     pub fn nontemporal_store<T>(ptr: *mut T, val: T);
 }
+
+mod real_intrinsics {
+  extern "rust-intrinsic" {
+    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+    /// and destination must *not* overlap.
+    /// For the full docs, see the stabilized wrapper [`copy_nonoverlapping`].
+    ///
+    /// [`copy_nonoverlapping`]: ../../std/ptr/fn.copy_nonoverlapping.html
+    pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+    /// and destination may overlap.
+    /// For the full docs, see the stabilized wrapper [`copy`].
+    ///
+    /// [`copy`]: ../../std/ptr/fn.copy.html
+    pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
+
+    /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
+    /// `val`.
+    /// For the full docs, see the stabilized wrapper [`write_bytes`].
+    ///
+    /// [`write_bytes`]: ../../std/ptr/fn.write_bytes.html
+    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+  }
+}
+
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination must *not* overlap.
+///
+/// For regions of memory which might overlap, use [`copy`] instead.
+///
+/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
+/// with the argument order swapped.
+///
+/// [`copy`]: ./fn.copy.html
+/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// * The region of memory beginning at `src` with a size of `count *
+///   size_of::<T>()` bytes must *not* overlap with the region of memory
+///   beginning at `dst` with the same size.
+///
+/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-NULL and properly aligned.
+///
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`read`]: ../ptr/fn.read.html
+/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
+/// [valid]: ../ptr/index.html#safety
+///
+/// # Examples
+///
+/// Manually implement [`Vec::append`]:
+///
+/// ```
+/// use std::ptr;
+///
+/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
+/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
+///     let src_len = src.len();
+///     let dst_len = dst.len();
+///
+///     // Ensure that `dst` has enough capacity to hold all of `src`.
+///     dst.reserve(src_len);
+///
+///     unsafe {
+///         // The call to offset is always safe because `Vec` will never
+///         // allocate more than `isize::MAX` bytes.
+///         let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
+///         let src_ptr = src.as_ptr();
+///
+///         // Truncate `src` without dropping its contents. We do this first,
+///         // to avoid problems in case something further down panics.
+///         src.set_len(0);
+///
+///         // The two regions cannot overlap because mutable references do
+///         // not alias, and two different vectors cannot own the same
+///         // memory.
+///         ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
+///
+///         // Notify `dst` that it now holds the contents of `src`.
+///         dst.set_len(dst_len + src_len);
+///     }
+/// }
+///
+/// let mut a = vec!['r'];
+/// let mut b = vec!['u', 's', 't'];
+///
+/// append(&mut a, &mut b);
+///
+/// assert_eq!(a, &['r', 'u', 's', 't']);
+/// assert!(b.is_empty());
+/// ```
+///
+/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
+#[stable(feature = "rust1", since = "1.0.0")]
+#[inline]
+pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
+    real_intrinsics::copy_nonoverlapping(src, dst, count);
+}
+
+/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
+/// and destination may overlap.
+///
+/// If the source and destination will *never* overlap,
+/// [`copy_nonoverlapping`] can be used instead.
+///
+/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
+/// order swapped. Copying takes place as if the bytes were copied from `src`
+/// to a temporary array and then copied from the array to `dst`.
+///
+/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
+/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * Both `src` and `dst` must be properly aligned.
+///
+/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
+/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
+/// in the region beginning at `*src` and the region beginning at `*dst` can
+/// [violate memory safety][read-ownership].
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointers must be non-NULL and properly aligned.
+///
+/// [`Copy`]: ../marker/trait.Copy.html
+/// [`read`]: ../ptr/fn.read.html
+/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
+/// [valid]: ../ptr/index.html#safety
+///
+/// # Examples
+///
+/// Efficiently create a Rust vector from an unsafe buffer:
+///
+/// ```
+/// use std::ptr;
+///
+/// # #[allow(dead_code)]
+/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
+///     let mut dst = Vec::with_capacity(elts);
+///     dst.set_len(elts);
+///     ptr::copy(ptr, dst.as_mut_ptr(), elts);
+///     dst
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+#[inline]
+pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
+    real_intrinsics::copy(src, dst, count)
+}
+
+/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
+/// `val`.
+///
+/// `write_bytes` is similar to C's [`memset`], but sets `count *
+/// size_of::<T>()` bytes to `val`.
+///
+/// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
+///
+/// * `dst` must be properly aligned.
+///
+/// Additionally, the caller must ensure that writing `count *
+/// size_of::<T>()` bytes to the given region of memory results in a valid
+/// value of `T`. Using a region of memory typed as a `T` that contains an
+/// invalid value of `T` is undefined behavior.
+///
+/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
+/// `0`, the pointer must be non-NULL and properly aligned.
+///
+/// [valid]: ../ptr/index.html#safety
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut vec = vec![0u32; 4];
+/// unsafe {
+///     let vec_ptr = vec.as_mut_ptr();
+///     ptr::write_bytes(vec_ptr, 0xfe, 2);
+/// }
+/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
+/// ```
+///
+/// Creating an invalid value:
+///
+/// ```
+/// use std::ptr;
+///
+/// let mut v = Box::new(0i32);
+///
+/// unsafe {
+///     // Leaks the previously held value by overwriting the `Box<T>` with
+///     // a null pointer.
+///     ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
+/// }
+///
+/// // At this point, using or dropping `v` results in undefined behavior.
+/// // drop(v); // ERROR
+///
+/// // Even leaking `v` "uses" it, and hence is undefined behavior.
+/// // mem::forget(v); // ERROR
+///
+/// // In fact, `v` is invalid according to basic type layout invariants, so *any*
+/// // operation touching it is undefined behavior.
+/// // let v2 = v; // ERROR
+///
+/// unsafe {
+///     // Let us instead put in a valid value
+///     ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
+/// }
+///
+/// // Now the box is fine
+/// assert_eq!(*v, 42);
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+#[inline]
+pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
+    real_intrinsics::write_bytes(dst, val, count)
+}