Skip to content

Commit

Permalink
fix memrchr in miri
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Jul 30, 2018
1 parent 7bbcd00 commit 6d5694a
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/libcore/slice/memchr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,30 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
// - the first remaining bytes, < 2 word size
let len = text.len();
let ptr = text.as_ptr();
let usize_bytes = mem::size_of::<usize>();
type Chunk = usize;

let mut offset = {
// We call this just to obtain the length of the suffix
let (_, _, suffix) = unsafe { text.align_to::<usize>() };
len - suffix.len()
let (min_aligned_offset, max_aligned_offset) = {
// We call this just to obtain the length of the prefix and suffix.
// In the middle we always process two chunks at once.
let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() };
(prefix.len(), len - suffix.len())
};

let mut offset = max_aligned_offset;
if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
return Some(offset + index);
}

// search the body of the text
// search the body of the text, make sure we don't cross min_aligned_offset.
// offset is always aligned, so just testing `>` is sufficient and avoids possible
// overflow.
let repeated_x = repeat_byte(x);
let chunk_bytes = mem::size_of::<Chunk>();

while offset >= 2 * usize_bytes {
while offset > min_aligned_offset {
unsafe {
let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);
let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk);
let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk);

// break if there is a matching byte
let zu = contains_zero_byte(u ^ repeated_x);
Expand All @@ -126,7 +132,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
break;
}
}
offset -= 2 * usize_bytes;
offset -= 2 * chunk_bytes;
}

// find the byte before the point the body loop stopped
Expand Down

0 comments on commit 6d5694a

Please sign in to comment.