Skip to content

Commit 4dc1c29

Browse files
committed
libcore: Remove mutable fields from hash
1 parent 2961997 commit 4dc1c29

File tree

6 files changed

+160
-111
lines changed

6 files changed

+160
-111
lines changed

src/libcore/hash.rs

Lines changed: 123 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919
* CPRNG like rand::rng.
2020
*/
2121

22-
use io;
23-
use io::Writer;
22+
#[cfg(stage0)]
23+
use cast;
24+
use rt::io::Writer;
2425
use to_bytes::IterBytes;
2526
use uint;
2627
use vec;
2728

29+
// Alias `SipState` to `State`.
30+
pub use State = hash::SipState;
31+
2832
/**
2933
* Types that can meaningfully be hashed should implement this.
3034
*
@@ -65,112 +69,158 @@ impl<A:Hash> HashUtil for A {
6569

6670
/// Streaming hash-functions should implement this.
6771
pub trait Streaming {
68-
fn input(&self, (&const [u8]));
72+
fn input(&mut self, &[u8]);
6973
// These can be refactored some when we have default methods.
70-
fn result_bytes(&self) -> ~[u8];
71-
fn result_str(&self) -> ~str;
72-
fn result_u64(&self) -> u64;
73-
fn reset(&self);
74+
fn result_bytes(&mut self) -> ~[u8];
75+
fn result_str(&mut self) -> ~str;
76+
fn result_u64(&mut self) -> u64;
77+
fn reset(&mut self);
78+
}
79+
80+
// XXX: Ugly workaround for bootstrapping.
81+
#[cfg(stage0)]
82+
fn transmute_for_stage0<'a>(bytes: &'a [const u8]) -> &'a [u8] {
83+
unsafe {
84+
cast::transmute(bytes)
85+
}
86+
}
87+
#[cfg(not(stage0))]
88+
fn transmute_for_stage0<'a>(bytes: &'a [u8]) -> &'a [u8] {
89+
bytes
7490
}
7591

7692
impl<A:IterBytes> Hash for A {
7793
#[inline(always)]
7894
fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
79-
let s = &State(k0, k1);
95+
let mut s = State::new(k0, k1);
8096
for self.iter_bytes(true) |bytes| {
81-
s.input(bytes);
97+
s.input(transmute_for_stage0(bytes));
8298
}
8399
s.result_u64()
84100
}
85101
}
86102

87103
fn hash_keyed_2<A: IterBytes,
88104
B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
89-
let s = &State(k0, k1);
90-
for a.iter_bytes(true) |bytes| { s.input(bytes); }
91-
for b.iter_bytes(true) |bytes| { s.input(bytes); }
105+
let mut s = State::new(k0, k1);
106+
for a.iter_bytes(true) |bytes| {
107+
s.input(transmute_for_stage0(bytes));
108+
}
109+
for b.iter_bytes(true) |bytes| {
110+
s.input(transmute_for_stage0(bytes));
111+
}
92112
s.result_u64()
93113
}
94114

95115
fn hash_keyed_3<A: IterBytes,
96116
B: IterBytes,
97117
C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
98-
let s = &State(k0, k1);
99-
for a.iter_bytes(true) |bytes| { s.input(bytes); }
100-
for b.iter_bytes(true) |bytes| { s.input(bytes); }
101-
for c.iter_bytes(true) |bytes| { s.input(bytes); }
118+
let mut s = State::new(k0, k1);
119+
for a.iter_bytes(true) |bytes| {
120+
s.input(transmute_for_stage0(bytes));
121+
}
122+
for b.iter_bytes(true) |bytes| {
123+
s.input(transmute_for_stage0(bytes));
124+
}
125+
for c.iter_bytes(true) |bytes| {
126+
s.input(transmute_for_stage0(bytes));
127+
}
102128
s.result_u64()
103129
}
104130

105131
fn hash_keyed_4<A: IterBytes,
106132
B: IterBytes,
107133
C: IterBytes,
108-
D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64)
109-
-> u64 {
110-
let s = &State(k0, k1);
111-
for a.iter_bytes(true) |bytes| { s.input(bytes); }
112-
for b.iter_bytes(true) |bytes| { s.input(bytes); }
113-
for c.iter_bytes(true) |bytes| { s.input(bytes); }
114-
for d.iter_bytes(true) |bytes| { s.input(bytes); }
134+
D: IterBytes>(
135+
a: &A,
136+
b: &B,
137+
c: &C,
138+
d: &D,
139+
k0: u64,
140+
k1: u64)
141+
-> u64 {
142+
let mut s = State::new(k0, k1);
143+
for a.iter_bytes(true) |bytes| {
144+
s.input(transmute_for_stage0(bytes));
145+
}
146+
for b.iter_bytes(true) |bytes| {
147+
s.input(transmute_for_stage0(bytes));
148+
}
149+
for c.iter_bytes(true) |bytes| {
150+
s.input(transmute_for_stage0(bytes));
151+
}
152+
for d.iter_bytes(true) |bytes| {
153+
s.input(transmute_for_stage0(bytes));
154+
}
115155
s.result_u64()
116156
}
117157

118158
fn hash_keyed_5<A: IterBytes,
119159
B: IterBytes,
120160
C: IterBytes,
121161
D: IterBytes,
122-
E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E,
123-
k0: u64, k1: u64) -> u64 {
124-
let s = &State(k0, k1);
125-
for a.iter_bytes(true) |bytes| { s.input(bytes); }
126-
for b.iter_bytes(true) |bytes| { s.input(bytes); }
127-
for c.iter_bytes(true) |bytes| { s.input(bytes); }
128-
for d.iter_bytes(true) |bytes| { s.input(bytes); }
129-
for e.iter_bytes(true) |bytes| { s.input(bytes); }
162+
E: IterBytes>(
163+
a: &A,
164+
b: &B,
165+
c: &C,
166+
d: &D,
167+
e: &E,
168+
k0: u64,
169+
k1: u64)
170+
-> u64 {
171+
let mut s = State::new(k0, k1);
172+
for a.iter_bytes(true) |bytes| {
173+
s.input(transmute_for_stage0(bytes));
174+
}
175+
for b.iter_bytes(true) |bytes| {
176+
s.input(transmute_for_stage0(bytes));
177+
}
178+
for c.iter_bytes(true) |bytes| {
179+
s.input(transmute_for_stage0(bytes));
180+
}
181+
for d.iter_bytes(true) |bytes| {
182+
s.input(transmute_for_stage0(bytes));
183+
}
184+
for e.iter_bytes(true) |bytes| {
185+
s.input(transmute_for_stage0(bytes));
186+
}
130187
s.result_u64()
131188
}
132189

133-
// Implement State as SipState
134-
135-
pub type State = SipState;
136-
137-
#[inline(always)]
138-
pub fn State(k0: u64, k1: u64) -> State {
139-
SipState(k0, k1)
140-
}
141-
142190
#[inline(always)]
143191
pub fn default_state() -> State {
144-
State(0,0)
192+
State::new(0, 0)
145193
}
146194

147195
struct SipState {
148196
k0: u64,
149197
k1: u64,
150-
mut length: uint, // how many bytes we've processed
151-
mut v0: u64, // hash state
152-
mut v1: u64,
153-
mut v2: u64,
154-
mut v3: u64,
155-
mut tail: [u8, ..8], // unprocessed bytes
156-
mut ntail: uint, // how many bytes in tail are valid
198+
length: uint, // how many bytes we've processed
199+
v0: u64, // hash state
200+
v1: u64,
201+
v2: u64,
202+
v3: u64,
203+
tail: [u8, ..8], // unprocessed bytes
204+
ntail: uint, // how many bytes in tail are valid
157205
}
158206

159-
#[inline(always)]
160-
fn SipState(key0: u64, key1: u64) -> SipState {
161-
let state = SipState {
162-
k0 : key0,
163-
k1 : key1,
164-
mut length : 0u,
165-
mut v0 : 0u64,
166-
mut v1 : 0u64,
167-
mut v2 : 0u64,
168-
mut v3 : 0u64,
169-
mut tail : [0u8,0,0,0,0,0,0,0],
170-
mut ntail : 0u,
171-
};
172-
(&state).reset();
173-
state
207+
impl SipState {
208+
#[inline(always)]
209+
fn new(key0: u64, key1: u64) -> SipState {
210+
let mut state = SipState {
211+
k0: key0,
212+
k1: key1,
213+
length: 0,
214+
v0: 0,
215+
v1: 0,
216+
v2: 0,
217+
v3: 0,
218+
tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
219+
ntail: 0,
220+
};
221+
state.reset();
222+
state
223+
}
174224
}
175225

176226
// sadly, these macro definitions can't appear later,
@@ -207,12 +257,10 @@ macro_rules! compress (
207257
)
208258

209259

210-
impl io::Writer for SipState {
211-
260+
impl Writer for SipState {
212261
// Methods for io::writer
213262
#[inline(always)]
214-
fn write(&self, msg: &const [u8]) {
215-
263+
fn write(&mut self, msg: &[u8]) {
216264
let length = msg.len();
217265
self.length += length;
218266

@@ -272,29 +320,19 @@ impl io::Writer for SipState {
272320
self.ntail = left;
273321
}
274322

275-
fn seek(&self, _x: int, _s: io::SeekStyle) {
276-
fail!();
277-
}
278-
fn tell(&self) -> uint {
279-
self.length
280-
}
281-
fn flush(&self) -> int {
282-
0
283-
}
284-
fn get_type(&self) -> io::WriterType {
285-
io::File
323+
fn flush(&mut self) {
324+
// No-op
286325
}
287326
}
288327

289328
impl Streaming for SipState {
290-
291329
#[inline(always)]
292-
fn input(&self, buf: &const [u8]) {
330+
fn input(&mut self, buf: &[u8]) {
293331
self.write(buf);
294332
}
295333

296334
#[inline(always)]
297-
fn result_u64(&self) -> u64 {
335+
fn result_u64(&mut self) -> u64 {
298336
let mut v0 = self.v0;
299337
let mut v1 = self.v1;
300338
let mut v2 = self.v2;
@@ -324,7 +362,7 @@ impl Streaming for SipState {
324362
return (v0 ^ v1 ^ v2 ^ v3);
325363
}
326364

327-
fn result_bytes(&self) -> ~[u8] {
365+
fn result_bytes(&mut self) -> ~[u8] {
328366
let h = self.result_u64();
329367
~[(h >> 0) as u8,
330368
(h >> 8) as u8,
@@ -337,7 +375,7 @@ impl Streaming for SipState {
337375
]
338376
}
339377

340-
fn result_str(&self) -> ~str {
378+
fn result_str(&mut self) -> ~str {
341379
let r = self.result_bytes();
342380
let mut s = ~"";
343381
for vec::each(r) |b| {
@@ -347,7 +385,7 @@ impl Streaming for SipState {
347385
}
348386

349387
#[inline(always)]
350-
fn reset(&self) {
388+
fn reset(&mut self) {
351389
self.length = 0;
352390
self.v0 = self.k0 ^ 0x736f6d6570736575;
353391
self.v1 = self.k1 ^ 0x646f72616e646f6d;
@@ -529,4 +567,4 @@ mod tests {
529567
val & !(0xff << (byte * 8))
530568
}
531569
}
532-
}
570+
}

0 commit comments

Comments
 (0)