Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcore: Reexport a couple of widely-used low-level intrinsics to reduce #15569

Merged
merged 1 commit into from
Jul 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 63 additions & 9 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,73 @@ extern "rust-intrinsic" {
/// integer, since the conversion would throw away aliasing information.
pub fn offset<T>(dst: *const T, offset: int) -> *const T;

/// 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>()`
/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may *not* overlap.
///
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
///
/// # Example
///
/// A safe swap function:
///
/// ```
/// use std::mem;
/// use std::ptr;
///
/// fn swap<T>(x: &mut T, y: &mut T) {
/// unsafe {
/// // Give ourselves some scratch space to work with
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
/// ptr::copy_nonoverlapping_memory(y, &t, 1);
///
/// // y and t now point to the same thing, but we need to completely forget `tmp`
/// // because it's no longer relevant.
/// mem::forget(t);
/// }
/// }
/// ```
///
/// # Safety Note
///
/// If the source and destination overlap then the behavior of this
/// function is undefined.
#[unstable]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);

/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
/// a size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may overlap.
///
/// `copy_memory` is semantically equivalent to C's `memmove`.
///
/// # Example
///
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
/// use std::ptr;
///
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
/// dst
/// }
/// ```
///
#[unstable]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);

/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
/// size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[experimental = "uncertain about naming and semantics"]
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);

/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
Expand Down
84 changes: 4 additions & 80 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ use option::{Some, None, Option};

use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};

pub use intrinsics::copy_memory;
pub use intrinsics::copy_nonoverlapping_memory;
pub use intrinsics::set_memory;

/// Create a null pointer.
///
/// # Example
Expand Down Expand Up @@ -123,86 +127,6 @@ pub fn null<T>() -> *const T { 0 as *const T }
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }

/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may overlap.
///
/// `copy_memory` is semantically equivalent to C's `memmove`.
///
/// # Example
///
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
/// use std::ptr;
///
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
/// dst
/// }
/// ```
///
#[inline]
#[unstable]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
intrinsics::copy_memory(dst, src, count)
}

/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may *not* overlap.
///
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
///
/// # Example
///
/// A safe swap function:
///
/// ```
/// use std::mem;
/// use std::ptr;
///
/// fn swap<T>(x: &mut T, y: &mut T) {
/// unsafe {
/// // Give ourselves some scratch space to work with
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
/// ptr::copy_nonoverlapping_memory(y, &t, 1);
///
/// // y and t now point to the same thing, but we need to completely forget `tmp`
/// // because it's no longer relevant.
/// mem::forget(t);
/// }
/// }
/// ```
///
/// # Safety Note
///
/// If the source and destination overlap then the behavior of this
/// function is undefined.
#[inline]
#[unstable]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *const T,
count: uint) {
intrinsics::copy_nonoverlapping_memory(dst, src, count)
}

/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[inline]
#[experimental = "uncertain about naming and semantics"]
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
intrinsics::set_memory(dst, c, count)
}

/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
Expand Down