This code is C code written as unsafe Rust:
let mut ptr = buf.as_ptr();
let end_ptr = buf.as_ptr().offset(buf.len() as isize & !0x1F) as usize;
while end_ptr > ptr as usize {
a = a ^ read_u64(ptr);
ptr = ptr.offset(8);
b = b ^ read_u64(ptr);
ptr = ptr.offset(8);
c = c ^ read_u64(ptr);
ptr = ptr.offset(8);
d = d ^ read_u64(ptr);
ptr = ptr.offset(8);
....
match excessive {
0 => {},
1...7 => {
a = a ^ read_int(slice::from_raw_parts(ptr as *const u8, excessive));
a = diffuse(a);
},
8 => {
a = a ^ read_u64(ptr);
a = diffuse(a);
},
9...15 => {
a = a ^ read_u64(ptr);
ptr = ptr.offset(8);
excessive = excessive - 8;
....
This bothers me about Rust. There's too much "unsafe" code in libraries. The language is unable to express some essential concepts. Known areas of trouble include partial initialization of an array, needed to implement growable collections, and single ownership doubly linked lists. Neither of those is expressible within Rust, which leads to unsafe code to implement them. Here, though, it's purely a performance issue. That's disturbing. If you can't do fast big-banging in safe Rust, there's a problem somewhere.
If Rust let you access a slice of bytes as an slice of ints, alignment and length permitting, the code above could be much more straightforward. That's what I mean about expressive power. The hack to do that used here:
let end_ptr = buf.as_ptr().offset(buf.len() as isize & !0x1F) as usize;
is iffy. Why is there an "isize" (a signed quantity) in there? They want to align with a 32-bit cache line, yes, but why the signed quantity? The documentation for Rust's "std::ops::BitAnd" doesn't say what the semantics are for signed numbers. What would happen on a 32-bit machine if someone allocated a buffer bigger than 2GB? Exploitable?