libcore: Remove mutable fields from hash
This commit is contained in:
parent
2961997f16
commit
4dc1c2976d
6 changed files with 160 additions and 111 deletions
|
@ -19,12 +19,16 @@
|
||||||
* CPRNG like rand::rng.
|
* CPRNG like rand::rng.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use io;
|
#[cfg(stage0)]
|
||||||
use io::Writer;
|
use cast;
|
||||||
|
use rt::io::Writer;
|
||||||
use to_bytes::IterBytes;
|
use to_bytes::IterBytes;
|
||||||
use uint;
|
use uint;
|
||||||
use vec;
|
use vec;
|
||||||
|
|
||||||
|
// Alias `SipState` to `State`.
|
||||||
|
pub use State = hash::SipState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types that can meaningfully be hashed should implement this.
|
* 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.
|
/// Streaming hash-functions should implement this.
|
||||||
pub trait Streaming {
|
pub trait Streaming {
|
||||||
fn input(&self, (&const [u8]));
|
fn input(&mut self, &[u8]);
|
||||||
// These can be refactored some when we have default methods.
|
// These can be refactored some when we have default methods.
|
||||||
fn result_bytes(&self) -> ~[u8];
|
fn result_bytes(&mut self) -> ~[u8];
|
||||||
fn result_str(&self) -> ~str;
|
fn result_str(&mut self) -> ~str;
|
||||||
fn result_u64(&self) -> u64;
|
fn result_u64(&mut self) -> u64;
|
||||||
fn reset(&self);
|
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 {
|
impl<A:IterBytes> Hash for A {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
|
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| {
|
for self.iter_bytes(true) |bytes| {
|
||||||
s.input(bytes);
|
s.input(transmute_for_stage0(bytes));
|
||||||
}
|
}
|
||||||
s.result_u64()
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
@ -86,32 +102,56 @@ impl<A:IterBytes> Hash for A {
|
||||||
|
|
||||||
fn hash_keyed_2<A: IterBytes,
|
fn hash_keyed_2<A: IterBytes,
|
||||||
B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
|
B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
|
||||||
let s = &State(k0, k1);
|
let mut s = State::new(k0, k1);
|
||||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
for a.iter_bytes(true) |bytes| {
|
||||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
s.input(transmute_for_stage0(bytes));
|
||||||
|
}
|
||||||
|
for b.iter_bytes(true) |bytes| {
|
||||||
|
s.input(transmute_for_stage0(bytes));
|
||||||
|
}
|
||||||
s.result_u64()
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_keyed_3<A: IterBytes,
|
fn hash_keyed_3<A: IterBytes,
|
||||||
B: IterBytes,
|
B: IterBytes,
|
||||||
C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
|
C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
|
||||||
let s = &State(k0, k1);
|
let mut s = State::new(k0, k1);
|
||||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
for a.iter_bytes(true) |bytes| {
|
||||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
s.input(transmute_for_stage0(bytes));
|
||||||
for c.iter_bytes(true) |bytes| { s.input(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()
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_keyed_4<A: IterBytes,
|
fn hash_keyed_4<A: IterBytes,
|
||||||
B: IterBytes,
|
B: IterBytes,
|
||||||
C: IterBytes,
|
C: IterBytes,
|
||||||
D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64)
|
D: IterBytes>(
|
||||||
-> u64 {
|
a: &A,
|
||||||
let s = &State(k0, k1);
|
b: &B,
|
||||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
c: &C,
|
||||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
d: &D,
|
||||||
for c.iter_bytes(true) |bytes| { s.input(bytes); }
|
k0: u64,
|
||||||
for d.iter_bytes(true) |bytes| { s.input(bytes); }
|
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()
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,58 +159,68 @@ fn hash_keyed_5<A: IterBytes,
|
||||||
B: IterBytes,
|
B: IterBytes,
|
||||||
C: IterBytes,
|
C: IterBytes,
|
||||||
D: IterBytes,
|
D: IterBytes,
|
||||||
E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E,
|
E: IterBytes>(
|
||||||
k0: u64, k1: u64) -> u64 {
|
a: &A,
|
||||||
let s = &State(k0, k1);
|
b: &B,
|
||||||
for a.iter_bytes(true) |bytes| { s.input(bytes); }
|
c: &C,
|
||||||
for b.iter_bytes(true) |bytes| { s.input(bytes); }
|
d: &D,
|
||||||
for c.iter_bytes(true) |bytes| { s.input(bytes); }
|
e: &E,
|
||||||
for d.iter_bytes(true) |bytes| { s.input(bytes); }
|
k0: u64,
|
||||||
for e.iter_bytes(true) |bytes| { s.input(bytes); }
|
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()
|
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)]
|
#[inline(always)]
|
||||||
pub fn default_state() -> State {
|
pub fn default_state() -> State {
|
||||||
State(0,0)
|
State::new(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SipState {
|
struct SipState {
|
||||||
k0: u64,
|
k0: u64,
|
||||||
k1: u64,
|
k1: u64,
|
||||||
mut length: uint, // how many bytes we've processed
|
length: uint, // how many bytes we've processed
|
||||||
mut v0: u64, // hash state
|
v0: u64, // hash state
|
||||||
mut v1: u64,
|
v1: u64,
|
||||||
mut v2: u64,
|
v2: u64,
|
||||||
mut v3: u64,
|
v3: u64,
|
||||||
mut tail: [u8, ..8], // unprocessed bytes
|
tail: [u8, ..8], // unprocessed bytes
|
||||||
mut ntail: uint, // how many bytes in tail are valid
|
ntail: uint, // how many bytes in tail are valid
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
impl SipState {
|
||||||
fn SipState(key0: u64, key1: u64) -> SipState {
|
#[inline(always)]
|
||||||
let state = SipState {
|
fn new(key0: u64, key1: u64) -> SipState {
|
||||||
k0 : key0,
|
let mut state = SipState {
|
||||||
k1 : key1,
|
k0: key0,
|
||||||
mut length : 0u,
|
k1: key1,
|
||||||
mut v0 : 0u64,
|
length: 0,
|
||||||
mut v1 : 0u64,
|
v0: 0,
|
||||||
mut v2 : 0u64,
|
v1: 0,
|
||||||
mut v3 : 0u64,
|
v2: 0,
|
||||||
mut tail : [0u8,0,0,0,0,0,0,0],
|
v3: 0,
|
||||||
mut ntail : 0u,
|
tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
|
||||||
};
|
ntail: 0,
|
||||||
(&state).reset();
|
};
|
||||||
state
|
state.reset();
|
||||||
|
state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sadly, these macro definitions can't appear later,
|
// 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
|
// Methods for io::writer
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn write(&self, msg: &const [u8]) {
|
fn write(&mut self, msg: &[u8]) {
|
||||||
|
|
||||||
let length = msg.len();
|
let length = msg.len();
|
||||||
self.length += length;
|
self.length += length;
|
||||||
|
|
||||||
|
@ -272,29 +320,19 @@ impl io::Writer for SipState {
|
||||||
self.ntail = left;
|
self.ntail = left;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seek(&self, _x: int, _s: io::SeekStyle) {
|
fn flush(&mut self) {
|
||||||
fail!();
|
// No-op
|
||||||
}
|
|
||||||
fn tell(&self) -> uint {
|
|
||||||
self.length
|
|
||||||
}
|
|
||||||
fn flush(&self) -> int {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
fn get_type(&self) -> io::WriterType {
|
|
||||||
io::File
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Streaming for SipState {
|
impl Streaming for SipState {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn input(&self, buf: &const [u8]) {
|
fn input(&mut self, buf: &[u8]) {
|
||||||
self.write(buf);
|
self.write(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn result_u64(&self) -> u64 {
|
fn result_u64(&mut self) -> u64 {
|
||||||
let mut v0 = self.v0;
|
let mut v0 = self.v0;
|
||||||
let mut v1 = self.v1;
|
let mut v1 = self.v1;
|
||||||
let mut v2 = self.v2;
|
let mut v2 = self.v2;
|
||||||
|
@ -324,7 +362,7 @@ impl Streaming for SipState {
|
||||||
return (v0 ^ v1 ^ v2 ^ v3);
|
return (v0 ^ v1 ^ v2 ^ v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn result_bytes(&self) -> ~[u8] {
|
fn result_bytes(&mut self) -> ~[u8] {
|
||||||
let h = self.result_u64();
|
let h = self.result_u64();
|
||||||
~[(h >> 0) as u8,
|
~[(h >> 0) as u8,
|
||||||
(h >> 8) 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 r = self.result_bytes();
|
||||||
let mut s = ~"";
|
let mut s = ~"";
|
||||||
for vec::each(r) |b| {
|
for vec::each(r) |b| {
|
||||||
|
@ -347,7 +385,7 @@ impl Streaming for SipState {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn reset(&self) {
|
fn reset(&mut self) {
|
||||||
self.length = 0;
|
self.length = 0;
|
||||||
self.v0 = self.k0 ^ 0x736f6d6570736575;
|
self.v0 = self.k0 ^ 0x736f6d6570736575;
|
||||||
self.v1 = self.k1 ^ 0x646f72616e646f6d;
|
self.v1 = self.k1 ^ 0x646f72616e646f6d;
|
||||||
|
@ -529,4 +567,4 @@ mod tests {
|
||||||
val & !(0xff << (byte * 8))
|
val & !(0xff << (byte * 8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,9 @@ use util::ppaux;
|
||||||
|
|
||||||
use core::hash::Streaming;
|
use core::hash::Streaming;
|
||||||
use core::hash;
|
use core::hash;
|
||||||
use core::io::WriterUtil;
|
|
||||||
use core::libc::{c_int, c_uint};
|
use core::libc::{c_int, c_uint};
|
||||||
use core::os::consts::{macos, freebsd, linux, android, win32};
|
use core::os::consts::{macos, freebsd, linux, android, win32};
|
||||||
|
use core::rt::io::Writer;
|
||||||
use core::run;
|
use core::run;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_map::{path, path_mod, path_name};
|
use syntax::ast_map::{path, path_mod, path_name};
|
||||||
|
@ -41,6 +41,11 @@ pub enum output_type {
|
||||||
output_type_exe,
|
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) -> ! {
|
pub fn llvm_err(sess: Session, msg: ~str) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
let cstr = llvm::LLVMRustGetLastError();
|
let cstr = llvm::LLVMRustGetLastError();
|
||||||
|
@ -458,9 +463,11 @@ pub mod write {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
|
pub fn build_link_meta(sess: Session,
|
||||||
symbol_hasher: &hash::State) -> LinkMeta {
|
c: &ast::crate,
|
||||||
|
output: &Path,
|
||||||
|
symbol_hasher: &mut hash::State)
|
||||||
|
-> LinkMeta {
|
||||||
struct ProvidedMetas {
|
struct ProvidedMetas {
|
||||||
name: Option<@str>,
|
name: Option<@str>,
|
||||||
vers: 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
|
// 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],
|
cmh_items: ~[@ast::meta_item],
|
||||||
dep_hashes: ~[~str]) -> @str {
|
dep_hashes: ~[~str]) -> @str {
|
||||||
fn len_and_str(s: &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);
|
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 {
|
match m.node {
|
||||||
ast::meta_name_value(key, value) => {
|
ast::meta_name_value(key, value) => {
|
||||||
symbol_hasher.write_str(len_and_str(*key));
|
write_string(symbol_hasher, len_and_str(*key));
|
||||||
symbol_hasher.write_str(len_and_str_lit(value));
|
write_string(symbol_hasher, len_and_str_lit(value));
|
||||||
}
|
}
|
||||||
ast::meta_word(name) => {
|
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) => {
|
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_| {
|
for mis.each |m_| {
|
||||||
hash(symbol_hasher, 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| {
|
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
|
// 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()
|
symbol_hasher.result_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This calculates STH for a symbol, as defined above
|
// This calculates STH for a symbol, as defined above
|
||||||
pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
|
pub fn symbol_hash(tcx: ty::ctxt,
|
||||||
link_meta: LinkMeta) -> @str {
|
symbol_hasher: &mut hash::State,
|
||||||
|
t: ty::t,
|
||||||
|
link_meta: LinkMeta)
|
||||||
|
-> @str {
|
||||||
// NB: do *not* use abbrevs here as we want the symbol names
|
// NB: do *not* use abbrevs here as we want the symbol names
|
||||||
// to be independent of one another in the crate.
|
// to be independent of one another in the crate.
|
||||||
|
|
||||||
symbol_hasher.reset();
|
symbol_hasher.reset();
|
||||||
symbol_hasher.write_str(link_meta.name);
|
write_string(symbol_hasher, link_meta.name);
|
||||||
symbol_hasher.write_str(~"-");
|
write_string(symbol_hasher, ~"-");
|
||||||
symbol_hasher.write_str(link_meta.extras_hash);
|
write_string(symbol_hasher, link_meta.extras_hash);
|
||||||
symbol_hasher.write_str(~"-");
|
write_string(symbol_hasher, ~"-");
|
||||||
symbol_hasher.write_str(encoder::encoded_ty(tcx, t));
|
write_string(symbol_hasher, encoder::encoded_ty(tcx, t));
|
||||||
let mut hash = truncated_hash_result(symbol_hasher);
|
let mut hash = truncated_hash_result(symbol_hasher);
|
||||||
// Prefix with _ so that it never blends into adjacent digits
|
// Prefix with _ so that it never blends into adjacent digits
|
||||||
str::unshift_char(&mut hash, '_');
|
str::unshift_char(&mut hash, '_');
|
||||||
|
|
|
@ -2987,9 +2987,8 @@ pub fn trans_crate(sess: session::Session,
|
||||||
emap2: resolve::ExportMap2,
|
emap2: resolve::ExportMap2,
|
||||||
maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
|
maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
|
||||||
|
|
||||||
let symbol_hasher = @hash::default_state();
|
let symbol_hasher = @mut hash::default_state();
|
||||||
let link_meta =
|
let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher);
|
||||||
link::build_link_meta(sess, crate, output, symbol_hasher);
|
|
||||||
let reachable = reachable::find_reachable(
|
let reachable = reachable::find_reachable(
|
||||||
&crate.node.module,
|
&crate.node.module,
|
||||||
emap2,
|
emap2,
|
||||||
|
|
|
@ -207,7 +207,7 @@ pub struct CrateContext {
|
||||||
adt_reprs: @mut HashMap<ty::t, @adt::Repr>,
|
adt_reprs: @mut HashMap<ty::t, @adt::Repr>,
|
||||||
names: namegen,
|
names: namegen,
|
||||||
next_addrspace: addrspace_gen,
|
next_addrspace: addrspace_gen,
|
||||||
symbol_hasher: @hash::State,
|
symbol_hasher: @mut hash::State,
|
||||||
type_hashcodes: @mut HashMap<ty::t, @str>,
|
type_hashcodes: @mut HashMap<ty::t, @str>,
|
||||||
type_short_names: @mut HashMap<ty::t, ~str>,
|
type_short_names: @mut HashMap<ty::t, ~str>,
|
||||||
all_llvm_symbols: @mut HashSet<@~str>,
|
all_llvm_symbols: @mut HashSet<@~str>,
|
||||||
|
|
|
@ -230,6 +230,7 @@ pub fn future_writer_factory(
|
||||||
let markdown_ch = markdown_ch.clone();
|
let markdown_ch = markdown_ch.clone();
|
||||||
do task::spawn || {
|
do task::spawn || {
|
||||||
let (writer, future) = future_writer();
|
let (writer, future) = future_writer();
|
||||||
|
let mut future = future;
|
||||||
writer_ch.send(writer);
|
writer_ch.send(writer);
|
||||||
let s = future.get();
|
let s = future.get();
|
||||||
markdown_ch.send((copy page, s));
|
markdown_ch.send((copy page, s));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
use core::*;
|
use core::*;
|
||||||
use core::cmp::Ord;
|
use core::cmp::Ord;
|
||||||
use core::hash::Streaming;
|
use core::hash::Streaming;
|
||||||
|
use core::rt::io::Writer;
|
||||||
use rustc::driver::{driver, session};
|
use rustc::driver::{driver, session};
|
||||||
use rustc::driver::session::{lib_crate, unknown_crate};
|
use rustc::driver::session::{lib_crate, unknown_crate};
|
||||||
use rustc::metadata::filesearch;
|
use rustc::metadata::filesearch;
|
||||||
|
@ -367,9 +368,9 @@ pub fn error(msg: ~str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(data: ~str) -> ~str {
|
pub fn hash(data: ~str) -> ~str {
|
||||||
let hasher = &hash::default_state();
|
let mut hasher = hash::default_state();
|
||||||
|
let buffer = str::as_bytes_slice(data);
|
||||||
hasher.write_str(data);
|
hasher.write(buffer);
|
||||||
hasher.result_str()
|
hasher.result_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue