diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-08-06 17:44:40 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-08-06 23:41:20 -0400 |
| commit | 7d115c94205dd4b937d29c77d1704aa3f801869e (patch) | |
| tree | 442ecaf695dbb0689805656b178a1c3046468f3b /src/libstd | |
| parent | f23fb19ee508515912e136c948a0242cc88a2d4e (diff) | |
| download | rust-7d115c94205dd4b937d29c77d1704aa3f801869e.tar.gz rust-7d115c94205dd4b937d29c77d1704aa3f801869e.zip | |
add an intrinsic for inbounds GEP
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ptr.rs | 22 | ||||
| -rw-r--r-- | src/libstd/unstable/intrinsics.rs | 11 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index dfd11f9227d..98fb132672c 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -272,6 +272,8 @@ pub trait RawPtr<T> { fn is_not_null(&self) -> bool; unsafe fn to_option(&self) -> Option<&T>; fn offset(&self, count: int) -> Self; + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> Self; } /// Extension methods for immutable pointers @@ -304,6 +306,14 @@ impl<T> RawPtr<T> for *T { /// Calculates the offset from a pointer. #[inline] fn offset(&self, count: int) -> *T { offset(*self, count) } + + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. + #[inline] + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> *T { + intrinsics::offset_inbounds(self, count) + } } /// Extension methods for mutable pointers @@ -336,6 +346,18 @@ impl<T> RawPtr<T> for *mut T { /// Calculates the offset from a mutable pointer. #[inline] fn offset(&self, count: int) -> *mut T { mut_offset(*self, count) } + + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. An arithmetic overflow is also + /// undefined behaviour. + /// + /// This method should be preferred over `offset` when the guarantee can be + /// satisfied, to enable better optimization. + #[inline] + #[cfg(not(stage0))] + unsafe fn offset_inbounds(self, count: int) -> *mut T { + intrinsics::offset_inbounds(self as *T, count) as *mut T + } } // Equality for pointers diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 1270a80c354..c60edad3dbd 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -317,12 +317,21 @@ extern "rust-intrinsic" { /// Get the address of the `__morestack` stack growth function. pub fn morestack_addr() -> *(); - /// Adjust a pointer by an offset. + /// Calculates the offset from a pointer. /// /// This is implemented as an intrinsic to avoid converting to and from an /// integer, since the conversion would throw away aliasing information. pub fn offset<T>(dst: *T, offset: int) -> *T; + /// Calculates the offset from a pointer. The offset *must* be in-bounds of + /// the object, or one-byte-past-the-end. An arithmetic overflow is also + /// undefined behaviour. + /// + /// This intrinsic should be preferred over `offset` when the guarantee can + /// be satisfied, to enable better optimization. + #[cfg(not(stage0))] + pub fn offset_inbounds<T>(dst: *T, offset: int) -> *T; + /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32); |
