}
}
- fn write_vuint<W: Write>(w: &mut W, n: usize) -> EncodeResult {
+ pub fn write_vuint<W: Write>(w: &mut W, n: usize) -> EncodeResult {
if n < 0x7f { return write_sized_vuint(w, n, 1); }
if n < 0x4000 { return write_sized_vuint(w, n, 2); }
if n < 0x200000 { return write_sized_vuint(w, n, 3); }
}
// Get the encoded string for a type
-pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
+pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Vec<u8> {
let mut wr = Cursor::new(Vec::new());
tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
diag: tcx.sess.diagnostic(),
tcx: tcx,
abbrevs: &RefCell::new(FnvHashMap())
}, t);
- String::from_utf8(wr.into_inner()).unwrap()
+ wr.into_inner()
}
return &self.data[start_pos..end_pos];
}
+ fn parse_vuint(&mut self) -> usize {
+ let res = rbml::reader::vuint_at(self.data, self.pos).unwrap();
+ self.pos = res.next;
+ res.val
+ }
+
fn parse_name(&mut self, last: char) -> ast::Name {
fn is_last(b: char, c: char) -> bool { return c == b; }
let bytes = self.scan(|a| is_last(last, a));
// we return it (modulo closure types, see below). But if not, then we
// jump to offset 123 and read the type from there.
- let pos = self.parse_hex();
- assert_eq!(self.next(), ':');
- let len = self.parse_hex();
- assert_eq!(self.next(), '#');
- let key = ty::CReaderCacheKey {cnum: self.krate, pos: pos, len: len };
+ let pos = self.parse_vuint();
+ let key = ty::CReaderCacheKey { cnum: self.krate, pos: pos };
match tcx.rcache.borrow().get(&key).cloned() {
Some(tt) => {
// If there is a closure buried in the type some where, then we
subst::ParamSpace::from_uint(self.parse_uint())
}
- fn parse_hex(&mut self) -> usize {
- let mut n = 0;
- loop {
- let cur = self.peek();
- if (cur < '0' || cur > '9') && (cur < 'a' || cur > 'f') { return n; }
- self.pos = self.pos + 1;
- n *= 16;
- if '0' <= cur && cur <= '9' {
- n += (cur as usize) - ('0' as usize);
- } else { n += 10 + (cur as usize) - ('a' as usize); }
- };
- }
-
fn parse_abi_set(&mut self) -> abi::Abi {
assert_eq!(self.next(), '[');
let bytes = self.scan(|c| c == ']');
#![allow(non_camel_case_types)]
use std::cell::RefCell;
-use std::str;
+use std::io::Cursor;
use std::io::prelude::*;
use middle::def_id::DefId;
use syntax::ast;
use syntax::diagnostic::SpanHandler;
-use rbml::writer::Encoder;
+use rbml::writer::{self, Encoder};
macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
// Extra parameters are for converting to/from def_ids in the string rep.
// Whatever format you choose should not contain pipe characters.
pub struct ty_abbrev {
- s: String
+ s: Vec<u8>
}
pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
match cx.abbrevs.borrow_mut().get(&t) {
- Some(a) => { w.writer.write_all(a.s.as_bytes()); return; }
+ Some(a) => { w.writer.write_all(&a.s); return; }
None => {}
}
let end = w.mark_stable_position();
let len = end - pos;
- fn estimate_sz(u: u64) -> u64 {
- let mut n = u;
- let mut len = 0;
- while n != 0 { len += 1; n = n >> 4; }
- return len;
- }
- let abbrev_len = 3 + estimate_sz(pos) + estimate_sz(len);
+
+ let buf: &mut [u8] = &mut [0; 16]; // vuint < 15 bytes
+ let mut abbrev = Cursor::new(buf);
+ abbrev.write_all(b"#");
+ writer::write_vuint(&mut abbrev, pos as usize);
+
cx.abbrevs.borrow_mut().insert(t, ty_abbrev {
- s: if abbrev_len < len {
- format!("#{:x}:{:x}#", pos, len)
+ s: if abbrev.position() < len {
+ abbrev.get_ref()[..abbrev.position() as usize].to_owned()
} else {
// if the abbreviation is longer than the real type,
// don't use #-notation. However, insert it here so
// other won't have to `mark_stable_position`
- str::from_utf8(
- &w.writer.get_ref()[pos as usize..end as usize]
- ).unwrap().to_owned()
+ w.writer.get_ref()[pos as usize..end as usize].to_owned()
}
});
}
pub struct CReaderCacheKey {
pub cnum: CrateNum,
pub pos: usize,
- pub len: usize
}
/// A restriction that certain types must be the same size. The use of
symbol_hasher.input_str(&meta[..]);
}
symbol_hasher.input_str("-");
- symbol_hasher.input_str(&encoder::encoded_ty(tcx, t));
+ symbol_hasher.input(&encoder::encoded_ty(tcx, t));
// Prefix with 'h' so that it never blends into adjacent digits
let mut hash = String::from("h");
hash.push_str(&truncated_hash_result(symbol_hasher));