diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-10-15 00:37:32 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-10-15 16:23:28 -0400 |
| commit | e1a26ad2713994ccba65d62ca64a2eb5db4eaf81 (patch) | |
| tree | f7727d6f22617258d6a5e05917defc459418af0c /src/libstd | |
| parent | aa93381e1459c5e739fab400ce8f5f83c9466804 (diff) | |
| download | rust-e1a26ad2713994ccba65d62ca64a2eb5db4eaf81.tar.gz rust-e1a26ad2713994ccba65d62ca64a2eb5db4eaf81.zip | |
use element count in slices, not size in bytes
This allows the indexing bounds check or other comparisons against an element length to avoid a multiplication by the size.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rand/mod.rs | 14 | ||||
| -rw-r--r-- | src/libstd/repr.rs | 35 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 81 |
3 files changed, 109 insertions, 21 deletions
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index b800c7b03af..1e76effd0d2 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -52,6 +52,8 @@ fn main () { ``` */ +use sys::size_of; +use unstable::raw::Slice; use cast; use container::Container; use iter::{Iterator, range}; @@ -133,10 +135,10 @@ pub trait Rng { /// println!("{:?}", v); /// } /// ``` - fn fill_bytes(&mut self, mut dest: &mut [u8]) { - // this relies on the lengths being transferred correctly when - // transmuting between vectors like this. - let as_u64: &mut &mut [u64] = unsafe { cast::transmute(&mut dest) }; + fn fill_bytes(&mut self, dest: &mut [u8]) { + let mut slice: Slice<u64> = unsafe { cast::transmute_copy(&dest) }; + slice.len /= size_of::<u64>(); + let as_u64: &mut [u64] = unsafe { cast::transmute(slice) }; for dest in as_u64.mut_iter() { *dest = self.next_u64(); } @@ -147,7 +149,9 @@ pub trait Rng { // space for a u32 if remaining >= 4 { - let as_u32: &mut &mut [u32] = unsafe { cast::transmute(&mut dest) }; + let mut slice: Slice<u32> = unsafe { cast::transmute_copy(&dest) }; + slice.len /= size_of::<u32>(); + let as_u32: &mut [u32] = unsafe { cast::transmute(slice) }; as_u32[as_u32.len() - 1] = self.next_u32(); remaining -= 4; } diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index ff2663fb1f7..49d5bb3918b 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -186,12 +186,7 @@ impl<'self> ReprVisitor<'self> { } } - pub fn write_vec_range(&mut self, - _mtbl: uint, - ptr: *(), - len: uint, - inner: *TyDesc) - -> bool { + pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool { let mut p = ptr as *u8; let (sz, al) = unsafe { ((*inner).size, (*inner).align) }; self.writer.write(['[' as u8]); @@ -213,13 +208,8 @@ impl<'self> ReprVisitor<'self> { true } - pub fn write_unboxed_vec_repr(&mut self, - mtbl: uint, - v: &raw::Vec<()>, - inner: *TyDesc) - -> bool { - self.write_vec_range(mtbl, ptr::to_unsafe_ptr(&v.data), - v.fill, inner) + pub fn write_unboxed_vec_repr(&mut self, _: uint, v: &raw::Vec<()>, inner: *TyDesc) -> bool { + self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner) } fn write_escaped_char(&mut self, ch: char, is_str: bool) { @@ -377,19 +367,32 @@ impl<'self> TyVisitor for ReprVisitor<'self> { } } + #[cfg(stage0)] fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool { do self.get::<raw::Slice<()>> |this, s| { this.writer.write(['&' as u8]); this.write_mut_qualifier(mtbl); - this.write_vec_range(mtbl, s.data, s.len, inner); + this.write_vec_range(s.data, s.len, inner); + } + } + + #[cfg(not(stage0))] + fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool { + do self.get::<raw::Slice<()>> |this, s| { + this.writer.write(['&' as u8]); + this.write_mut_qualifier(mtbl); + let size = unsafe { + if (*inner).size == 0 { 1 } else { (*inner).size } + }; + this.write_vec_range(s.data, s.len * size, inner); } } fn visit_evec_fixed(&mut self, n: uint, sz: uint, _align: uint, - mtbl: uint, inner: *TyDesc) -> bool { + _: uint, inner: *TyDesc) -> bool { let assumed_size = if sz == 0 { n } else { sz }; do self.get::<()> |this, b| { - this.write_vec_range(mtbl, ptr::to_unsafe_ptr(b), assumed_size, inner); + this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner); } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 77e38b48067..93374d97db5 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -974,6 +974,7 @@ pub trait ImmutableVector<'self, T> { impl<'self,T> ImmutableVector<'self, T> for &'self [T] { #[inline] + #[cfg(stage0)] fn slice(&self, start: uint, end: uint) -> &'self [T] { assert!(start <= end); assert!(end <= self.len()); @@ -986,10 +987,27 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } } } + + #[inline] + #[cfg(not(stage0))] + fn slice(&self, start: uint, end: uint) -> &'self [T] { + assert!(start <= end); + assert!(end <= self.len()); + do self.as_imm_buf |p, _len| { + unsafe { + cast::transmute(Slice { + data: ptr::offset(p, start as int), + len: (end - start) + }) + } + } + } + #[inline] fn slice_from(&self, start: uint) -> &'self [T] { self.slice(start, self.len()) } + #[inline] fn slice_to(&self, end: uint) -> &'self [T] { self.slice(0, end) @@ -1130,10 +1148,18 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] { } #[inline] + #[cfg(stage0)] fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U { let s = self.repr(); f(s.data, s.len / sys::nonzero_size_of::<T>()) } + + #[inline] + #[cfg(not(stage0))] + fn as_imm_buf<U>(&self, f: &fn(*T, uint) -> U) -> U { + let s = self.repr(); + f(s.data, s.len) + } } /// Extension methods for vectors contain `Eq` elements. @@ -1899,6 +1925,7 @@ pub trait MutableVector<'self, T> { impl<'self,T> MutableVector<'self, T> for &'self mut [T] { #[inline] + #[cfg(stage0)] fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { assert!(start <= end); assert!(end <= self.len()); @@ -1913,6 +1940,21 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } #[inline] + #[cfg(not(stage0))] + fn mut_slice(self, start: uint, end: uint) -> &'self mut [T] { + assert!(start <= end); + assert!(end <= self.len()); + do self.as_mut_buf |p, _len| { + unsafe { + cast::transmute(Slice { + data: ptr::mut_offset(p, start as int) as *T, + len: (end - start) + }) + } + } + } + + #[inline] fn mut_slice_from(self, start: uint) -> &'self mut [T] { let len = self.len(); self.mut_slice(start, len) @@ -1991,11 +2033,18 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] { } #[inline] + #[cfg(stage0)] fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U { let Slice{ data, len } = self.repr(); f(data as *mut T, len / sys::nonzero_size_of::<T>()) } + #[inline] + #[cfg(not(stage0))] + fn as_mut_buf<U>(self, f: &fn(*mut T, uint) -> U) -> U { + let Slice{ data, len } = self.repr(); + f(data as *mut T, len) + } } /// Trait for &[T] where T is Cloneable @@ -2083,6 +2132,7 @@ pub mod raw { * not bytes). */ #[inline] + #[cfg(stage0)] pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: &fn(v: &[T]) -> U) -> U { @@ -2097,6 +2147,22 @@ pub mod raw { * not bytes). */ #[inline] + #[cfg(not(stage0))] + pub unsafe fn buf_as_slice<T,U>(p: *T, + len: uint, + f: &fn(v: &[T]) -> U) -> U { + f(cast::transmute(Slice { + data: p, + len: len + })) + } + + /** + * Form a slice from a pointer and length (as a number of units, + * not bytes). + */ + #[inline] + #[cfg(stage0)] pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T, len: uint, f: &fn(v: &mut [T]) -> U) -> U { @@ -2107,6 +2173,21 @@ pub mod raw { } /** + * Form a slice from a pointer and length (as a number of units, + * not bytes). + */ + #[inline] + #[cfg(not(stage0))] + pub unsafe fn mut_buf_as_slice<T,U>(p: *mut T, + len: uint, + f: &fn(v: &mut [T]) -> U) -> U { + f(cast::transmute(Slice { + data: p as *T, + len: len + })) + } + + /** * Unchecked vector indexing. */ #[inline] |
