about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-05-03 11:30:30 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-05-08 17:03:58 -0700
commit4dc1c2976d03b6e0fc114019341be51593ef49b2 (patch)
treea29c2a8b4b5d89a4f10f30febfdf61cb169541a3
parent2961997f169a526ccf5a3bafd95db3e12f7e0283 (diff)
downloadrust-4dc1c2976d03b6e0fc114019341be51593ef49b2.tar.gz
rust-4dc1c2976d03b6e0fc114019341be51593ef49b2.zip
libcore: Remove mutable fields from hash
-rw-r--r--src/libcore/hash.rs208
-rw-r--r--src/librustc/back/link.rs48
-rw-r--r--src/librustc/middle/trans/base.rs5
-rw-r--r--src/librustc/middle/trans/common.rs2
-rw-r--r--src/librustdoc/markdown_writer.rs1
-rw-r--r--src/librustpkg/util.rs7
6 files changed, 160 insertions, 111 deletions
diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs
index ba1f8cebdb0..486f0e096e8 100644
--- a/src/libcore/hash.rs
+++ b/src/libcore/hash.rs
@@ -19,12 +19,16 @@
  * CPRNG like rand::rng.
  */
 
-use io;
-use io::Writer;
+#[cfg(stage0)]
+use cast;
+use rt::io::Writer;
 use to_bytes::IterBytes;
 use uint;
 use vec;
 
+// Alias `SipState` to `State`.
+pub use State = hash::SipState;
+
 /**
  * Types that can meaningfully be hashed should implement this.
  *
@@ -65,20 +69,32 @@ impl<A:Hash> HashUtil for A {
 
 /// Streaming hash-functions should implement this.
 pub trait Streaming {
-    fn input(&self, (&const [u8]));
+    fn input(&mut self, &[u8]);
     // These can be refactored some when we have default methods.
-    fn result_bytes(&self) -> ~[u8];
-    fn result_str(&self) -> ~str;
-    fn result_u64(&self) -> u64;
-    fn reset(&self);
+    fn result_bytes(&mut self) -> ~[u8];
+    fn result_str(&mut self) -> ~str;
+    fn result_u64(&mut self) -> u64;
+    fn reset(&mut self);
+}
+
+// XXX: Ugly workaround for bootstrapping.
+#[cfg(stage0)]
+fn transmute_for_stage0<'a>(bytes: &'a [const u8]) -> &'a [u8] {
+    unsafe {
+        cast::transmute(bytes)
+    }
+}
+#[cfg(not(stage0))]
+fn transmute_for_stage0<'a>(bytes: &'a [u8]) -> &'a [u8] {
+    bytes
 }
 
 impl<A:IterBytes> Hash for A {
     #[inline(always)]
     fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
-        let s = &State(k0, k1);
+        let mut s = State::new(k0, k1);
         for self.iter_bytes(true) |bytes| {
-            s.input(bytes);
+            s.input(transmute_for_stage0(bytes));
         }
         s.result_u64()
     }
@@ -86,32 +102,56 @@ impl<A:IterBytes> Hash for A {
 
 fn hash_keyed_2<A: IterBytes,
                 B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
 fn hash_keyed_3<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
 fn hash_keyed_4<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
-                D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64)
-                           -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
-    for d.iter_bytes(true) |bytes| { s.input(bytes); }
+                D: IterBytes>(
+                a: &A,
+                b: &B,
+                c: &C,
+                d: &D,
+                k0: u64,
+                k1: u64)
+                -> u64 {
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for d.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
@@ -119,58 +159,68 @@ fn hash_keyed_5<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes,
-                E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E,
-                              k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
-    for d.iter_bytes(true) |bytes| { s.input(bytes); }
-    for e.iter_bytes(true) |bytes| { s.input(bytes); }
+                E: IterBytes>(
+                a: &A,
+                b: &B,
+                c: &C,
+                d: &D,
+                e: &E,
+                k0: u64,
+                k1: u64)
+                -> u64 {
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for d.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for e.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
-// Implement State as SipState
-
-pub type State = SipState;
-
-#[inline(always)]
-pub fn State(k0: u64, k1: u64) -> State {
-    SipState(k0, k1)
-}
-
 #[inline(always)]
 pub fn default_state() -> State {
-    State(0,0)
+    State::new(0, 0)
 }
 
 struct SipState {
     k0: u64,
     k1: u64,
-    mut length: uint, // how many bytes we've processed
-    mut v0: u64,      // hash state
-    mut v1: u64,
-    mut v2: u64,
-    mut v3: u64,
-    mut tail: [u8, ..8], // unprocessed bytes
-    mut ntail: uint,  // how many bytes in tail are valid
+    length: uint, // how many bytes we've processed
+    v0: u64,      // hash state
+    v1: u64,
+    v2: u64,
+    v3: u64,
+    tail: [u8, ..8], // unprocessed bytes
+    ntail: uint,  // how many bytes in tail are valid
 }
 
-#[inline(always)]
-fn SipState(key0: u64, key1: u64) -> SipState {
-    let state = SipState {
-        k0 : key0,
-        k1 : key1,
-        mut length : 0u,
-        mut v0 : 0u64,
-        mut v1 : 0u64,
-        mut v2 : 0u64,
-        mut v3 : 0u64,
-        mut tail : [0u8,0,0,0,0,0,0,0],
-        mut ntail : 0u,
-    };
-    (&state).reset();
-    state
+impl SipState {
+    #[inline(always)]
+    fn new(key0: u64, key1: u64) -> SipState {
+        let mut state = SipState {
+            k0: key0,
+            k1: key1,
+            length: 0,
+            v0: 0,
+            v1: 0,
+            v2: 0,
+            v3: 0,
+            tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
+            ntail: 0,
+        };
+        state.reset();
+        state
+    }
 }
 
 // sadly, these macro definitions can't appear later,
@@ -207,12 +257,10 @@ macro_rules! compress (
 )
 
 
-impl io::Writer for SipState {
-
+impl Writer for SipState {
     // Methods for io::writer
     #[inline(always)]
-    fn write(&self, msg: &const [u8]) {
-
+    fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
 
@@ -272,29 +320,19 @@ impl io::Writer for SipState {
         self.ntail = left;
     }
 
-    fn seek(&self, _x: int, _s: io::SeekStyle) {
-        fail!();
-    }
-    fn tell(&self) -> uint {
-        self.length
-    }
-    fn flush(&self) -> int {
-        0
-    }
-    fn get_type(&self) -> io::WriterType {
-        io::File
+    fn flush(&mut self) {
+        // No-op
     }
 }
 
 impl Streaming for SipState {
-
     #[inline(always)]
-    fn input(&self, buf: &const [u8]) {
+    fn input(&mut self, buf: &[u8]) {
         self.write(buf);
     }
 
     #[inline(always)]
-    fn result_u64(&self) -> u64 {
+    fn result_u64(&mut self) -> u64 {
         let mut v0 = self.v0;
         let mut v1 = self.v1;
         let mut v2 = self.v2;
@@ -324,7 +362,7 @@ impl Streaming for SipState {
         return (v0 ^ v1 ^ v2 ^ v3);
     }
 
-    fn result_bytes(&self) -> ~[u8] {
+    fn result_bytes(&mut self) -> ~[u8] {
         let h = self.result_u64();
         ~[(h >> 0) as u8,
           (h >> 8) as u8,
@@ -337,7 +375,7 @@ impl Streaming for SipState {
         ]
     }
 
-    fn result_str(&self) -> ~str {
+    fn result_str(&mut self) -> ~str {
         let r = self.result_bytes();
         let mut s = ~"";
         for vec::each(r) |b| {
@@ -347,7 +385,7 @@ impl Streaming for SipState {
     }
 
     #[inline(always)]
-    fn reset(&self) {
+    fn reset(&mut self) {
         self.length = 0;
         self.v0 = self.k0 ^ 0x736f6d6570736575;
         self.v1 = self.k1 ^ 0x646f72616e646f6d;
@@ -529,4 +567,4 @@ mod tests {
             val & !(0xff << (byte * 8))
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index c34c7fe303e..3b5c90ec1f9 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -22,9 +22,9 @@ use util::ppaux;
 
 use core::hash::Streaming;
 use core::hash;
-use core::io::WriterUtil;
 use core::libc::{c_int, c_uint};
 use core::os::consts::{macos, freebsd, linux, android, win32};
+use core::rt::io::Writer;
 use core::run;
 use syntax::ast;
 use syntax::ast_map::{path, path_mod, path_name};
@@ -41,6 +41,11 @@ pub enum output_type {
     output_type_exe,
 }
 
+fn write_string<W:Writer>(writer: &mut W, string: &str) {
+    let buffer = str::as_bytes_slice(string);
+    writer.write(buffer);
+}
+
 pub fn llvm_err(sess: Session, msg: ~str) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
@@ -458,9 +463,11 @@ pub mod write {
  *
  */
 
-pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
-                   symbol_hasher: &hash::State) -> LinkMeta {
-
+pub fn build_link_meta(sess: Session,
+                       c: &ast::crate,
+                       output: &Path,
+                       symbol_hasher: &mut hash::State)
+                       -> LinkMeta {
     struct ProvidedMetas {
         name: Option<@str>,
         vers: Option<@str>,
@@ -498,7 +505,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
     }
 
     // This calculates CMH as defined above
-    fn crate_meta_extras_hash(symbol_hasher: &hash::State,
+    fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
                               cmh_items: ~[@ast::meta_item],
                               dep_hashes: ~[~str]) -> @str {
         fn len_and_str(s: &str) -> ~str {
@@ -511,17 +518,17 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
 
         let cmh_items = attr::sort_meta_items(cmh_items);
 
-        fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) {
+        fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) {
             match m.node {
               ast::meta_name_value(key, value) => {
-                symbol_hasher.write_str(len_and_str(*key));
-                symbol_hasher.write_str(len_and_str_lit(value));
+                write_string(symbol_hasher, len_and_str(*key));
+                write_string(symbol_hasher, len_and_str_lit(value));
               }
               ast::meta_word(name) => {
-                symbol_hasher.write_str(len_and_str(*name));
+                write_string(symbol_hasher, len_and_str(*name));
               }
               ast::meta_list(name, ref mis) => {
-                symbol_hasher.write_str(len_and_str(*name));
+                write_string(symbol_hasher, len_and_str(*name));
                 for mis.each |m_| {
                     hash(symbol_hasher, m_);
                 }
@@ -535,7 +542,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
         }
 
         for dep_hashes.each |dh| {
-            symbol_hasher.write_str(len_and_str(*dh));
+            write_string(symbol_hasher, len_and_str(*dh));
         }
 
     // tjc: allocation is unfortunate; need to change core::hash
@@ -596,23 +603,26 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
     }
 }
 
-pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str {
+pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str {
     symbol_hasher.result_str()
 }
 
 
 // This calculates STH for a symbol, as defined above
-pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
-               link_meta: LinkMeta) -> @str {
+pub fn symbol_hash(tcx: ty::ctxt,
+                   symbol_hasher: &mut hash::State,
+                   t: ty::t,
+                   link_meta: LinkMeta)
+                   -> @str {
     // NB: do *not* use abbrevs here as we want the symbol names
     // to be independent of one another in the crate.
 
     symbol_hasher.reset();
-    symbol_hasher.write_str(link_meta.name);
-    symbol_hasher.write_str(~"-");
-    symbol_hasher.write_str(link_meta.extras_hash);
-    symbol_hasher.write_str(~"-");
-    symbol_hasher.write_str(encoder::encoded_ty(tcx, t));
+    write_string(symbol_hasher, link_meta.name);
+    write_string(symbol_hasher, ~"-");
+    write_string(symbol_hasher, link_meta.extras_hash);
+    write_string(symbol_hasher, ~"-");
+    write_string(symbol_hasher, encoder::encoded_ty(tcx, t));
     let mut hash = truncated_hash_result(symbol_hasher);
     // Prefix with _ so that it never blends into adjacent digits
     str::unshift_char(&mut hash, '_');
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 34f798ec7a6..76ad7d74053 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2987,9 +2987,8 @@ pub fn trans_crate(sess: session::Session,
                    emap2: resolve::ExportMap2,
                    maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
 
-    let symbol_hasher = @hash::default_state();
-    let link_meta =
-        link::build_link_meta(sess, crate, output, symbol_hasher);
+    let symbol_hasher = @mut hash::default_state();
+    let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher);
     let reachable = reachable::find_reachable(
         &crate.node.module,
         emap2,
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index b004ba9d41f..c1309b42288 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -207,7 +207,7 @@ pub struct CrateContext {
      adt_reprs: @mut HashMap<ty::t, @adt::Repr>,
      names: namegen,
      next_addrspace: addrspace_gen,
-     symbol_hasher: @hash::State,
+     symbol_hasher: @mut hash::State,
      type_hashcodes: @mut HashMap<ty::t, @str>,
      type_short_names: @mut HashMap<ty::t, ~str>,
      all_llvm_symbols: @mut HashSet<@~str>,
diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs
index b9a2ee7ccb7..fc5a9a60df2 100644
--- a/src/librustdoc/markdown_writer.rs
+++ b/src/librustdoc/markdown_writer.rs
@@ -230,6 +230,7 @@ pub fn future_writer_factory(
         let markdown_ch = markdown_ch.clone();
         do task::spawn || {
             let (writer, future) = future_writer();
+            let mut future = future;
             writer_ch.send(writer);
             let s = future.get();
             markdown_ch.send((copy page, s));
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 0762fa4ad7f..5e43cb43960 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -11,6 +11,7 @@
 use core::*;
 use core::cmp::Ord;
 use core::hash::Streaming;
+use core::rt::io::Writer;
 use rustc::driver::{driver, session};
 use rustc::driver::session::{lib_crate, unknown_crate};
 use rustc::metadata::filesearch;
@@ -367,9 +368,9 @@ pub fn error(msg: ~str) {
 }
 
 pub fn hash(data: ~str) -> ~str {
-    let hasher = &hash::default_state();
-
-    hasher.write_str(data);
+    let mut hasher = hash::default_state();
+    let buffer = str::as_bytes_slice(data);
+    hasher.write(buffer);
     hasher.result_str()
 }