From 84e9a61e9c697ffb6f6f783e9190d5a93dfdc10a Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Mon, 2 Mar 2015 14:34:16 +0900 Subject: [PATCH] metadata: Implement relaxation of short RBML lengths. We try to move the data when the length can be encoded in the much smaller number of bytes. This interferes with indices and type abbreviations however, so this commit introduces a public interface to get and mark a "stable" (i.e. not affected by relaxation) position of the current pointer. The relaxation logic only moves a small data, currently at most 256 bytes, as moving the data can be costly. There might be further opportunities to allow more relaxation by moving fields around, which I didn't seriously try. --- src/librbml/lib.rs | 94 ++++++++++++++++++++----------- src/librustc/metadata/encoder.rs | 57 ++++++++++--------- src/librustc/metadata/tyencode.rs | 68 +++++++++++----------- src/librustc/middle/astencode.rs | 21 ++++--- 4 files changed, 138 insertions(+), 102 deletions(-) diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index fc4fbb36707e..d74d9ae81251 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -729,11 +729,13 @@ pub mod writer { use std::num::Int; use std::old_io::{Writer, Seek}; use std::old_io; + use std::slice::bytes; use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsUint, EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS }; + use super::io::SeekableMemWriter; use serialize; @@ -741,9 +743,10 @@ pub mod writer { pub type EncodeResult = old_io::IoResult<()>; // rbml writing - pub struct Encoder<'a, W:'a> { - pub writer: &'a mut W, + pub struct Encoder<'a> { + pub writer: &'a mut SeekableMemWriter, size_positions: Vec, + relax_limit: u64, // do not move encoded bytes before this position } fn write_tag(w: &mut W, n: uint) -> EncodeResult { @@ -788,19 +791,21 @@ pub mod writer { }) } - impl<'a, W: Writer + Seek> Encoder<'a, W> { - pub fn new(w: &'a mut W) -> Encoder<'a, W> { + impl<'a> Encoder<'a> { + pub fn new(w: &'a mut SeekableMemWriter) -> Encoder<'a> { Encoder { writer: w, size_positions: vec!(), + relax_limit: 0, } } /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME. - pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> { + pub unsafe fn unsafe_clone(&self) -> Encoder<'a> { Encoder { writer: mem::transmute_copy(&self.writer), size_positions: self.size_positions.clone(), + relax_limit: self.relax_limit, } } @@ -822,11 +827,29 @@ pub mod writer { let cur_pos = try!(self.writer.tell()); try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet)); let size = cur_pos as uint - last_size_pos - 4; - try!(write_sized_vuint(self.writer, size, 4)); - let r = try!(self.writer.seek(cur_pos as i64, old_io::SeekSet)); + + // relax the size encoding for small tags (bigger tags are costly to move). + // we should never try to move the stable positions, however. + const RELAX_MAX_SIZE: uint = 0x100; + if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit as uint { + // we can't alter the buffer in place, so have a temporary buffer + let mut buf = [0u8; RELAX_MAX_SIZE]; + { + let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as uint]; + bytes::copy_memory(&mut buf, data); + } + + // overwrite the size and data and continue + try!(write_vuint(self.writer, size)); + try!(self.writer.write_all(&buf[..size])); + } else { + // overwrite the size with an overlong encoding and skip past the data + try!(write_sized_vuint(self.writer, size, 4)); + try!(self.writer.seek(cur_pos as i64, old_io::SeekSet)); + } debug!("End tag (size = {:?})", size); - Ok(r) + Ok(()) } pub fn wr_tag(&mut self, tag_id: uint, blk: F) -> EncodeResult where @@ -933,12 +956,19 @@ pub mod writer { debug!("Write str: {:?}", s); self.writer.write_all(s.as_bytes()) } + + /// Returns the current position while marking it stable, i.e. + /// generated bytes so far woundn't be affected by relaxation. + pub fn mark_stable_position(&mut self) -> u64 { + let pos = self.writer.tell().unwrap(); + if self.relax_limit < pos { + self.relax_limit = pos; + } + pos + } } - // FIXME (#2743): optionally perform "relaxations" on end_tag to more - // efficiently encode sizes; this is a fixed point iteration - - impl<'a, W: Writer + Seek> Encoder<'a, W> { + impl<'a> Encoder<'a> { // used internally to emit things like the vector length and so on fn _emit_tagged_sub(&mut self, v: uint) -> EncodeResult { if let Some(v) = v.to_u8() { @@ -955,7 +985,7 @@ pub mod writer { } pub fn emit_opaque(&mut self, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder) -> EncodeResult, + F: FnOnce(&mut Encoder) -> EncodeResult, { try!(self.start_tag(EsOpaque as uint)); try!(f(self)); @@ -963,7 +993,7 @@ pub mod writer { } } - impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> { + impl<'a> serialize::Encoder for Encoder<'a> { type Error = old_io::IoError; fn emit_nil(&mut self) -> EncodeResult { @@ -1023,7 +1053,7 @@ pub mod writer { } fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsEnum as uint)); try!(f(self)); @@ -1035,14 +1065,14 @@ pub mod writer { v_id: uint, _: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self._emit_tagged_sub(v_id)); f(self) } fn emit_enum_variant_arg(&mut self, _: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { f(self) } @@ -1052,7 +1082,7 @@ pub mod writer { v_id: uint, cnt: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_enum_variant(v_name, v_id, cnt, f) } @@ -1061,47 +1091,47 @@ pub mod writer { _: &str, idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_enum_variant_arg(idx, f) } fn emit_struct(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { f(self) } fn emit_struct_field(&mut self, _name: &str, _: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { f(self) } fn emit_tuple(&mut self, len: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_seq(len, f) } fn emit_tuple_arg(&mut self, idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_seq_elt(idx, f) } fn emit_tuple_struct(&mut self, _: &str, len: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_seq(len, f) } fn emit_tuple_struct_arg(&mut self, idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_seq_elt(idx, f) } fn emit_option(&mut self, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_enum("Option", f) } @@ -1109,14 +1139,14 @@ pub mod writer { self.emit_enum_variant("None", 0, 0, |_| Ok(())) } fn emit_option_some(&mut self, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { self.emit_enum_variant("Some", 1, 1, f) } fn emit_seq(&mut self, len: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsVec as uint)); @@ -1126,7 +1156,7 @@ pub mod writer { } fn emit_seq_elt(&mut self, _idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsVecElt as uint)); @@ -1135,7 +1165,7 @@ pub mod writer { } fn emit_map(&mut self, len: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsMap as uint)); @@ -1145,7 +1175,7 @@ pub mod writer { } fn emit_map_elt_key(&mut self, _idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsMapKey as uint)); @@ -1154,7 +1184,7 @@ pub mod writer { } fn emit_map_elt_val(&mut self, _idx: uint, f: F) -> EncodeResult where - F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, { try!(self.start_tag(EsMapVal as uint)); try!(f(self)); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 7c28f0e17b5e..fa9e28bf56d2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -46,7 +46,7 @@ use syntax::ptr::P; use syntax::visit::Visitor; use syntax::visit; use syntax; -use rbml::writer; +use rbml::writer::Encoder; use rbml::io::SeekableMemWriter; /// A borrowed version of `ast::InlinedItem`. @@ -57,8 +57,6 @@ pub enum InlinedItemRef<'a> { IIForeignRef(&'a ast::ForeignItem) } -pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>; - pub type EncodeInlinedItem<'a> = Box; @@ -115,7 +113,7 @@ fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder, }; rbml_w.start_tag(tag); - tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref); + tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref); rbml_w.end_tag(); } @@ -169,7 +167,7 @@ pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_closure_ty(rbml_w.writer, ty_str_ctxt, closure_type); + tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type); } pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, @@ -181,7 +179,7 @@ pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_ty(rbml_w.writer, ty_str_ctxt, typ); + tyencode::enc_ty(rbml_w, ty_str_ctxt, typ); } pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, @@ -193,7 +191,7 @@ pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref); + tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref); } pub fn write_region(ecx: &EncodeContext, @@ -205,7 +203,7 @@ pub fn write_region(ecx: &EncodeContext, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_region(rbml_w.writer, ty_str_ctxt, r); + tyencode::enc_region(rbml_w, ty_str_ctxt, r); } fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder, @@ -218,7 +216,7 @@ fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder, ds: def_to_string, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_bounds(rbml_w.writer, ty_str_ctxt, bounds); + tyencode::enc_bounds(rbml_w, ty_str_ctxt, bounds); rbml_w.end_tag(); } @@ -250,7 +248,7 @@ fn encode_method_fty<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, tcx: ecx.tcx, abbrevs: &ecx.type_abbrevs }; - tyencode::enc_bare_fn_ty(rbml_w.writer, ty_str_ctxt, typ); + tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ); rbml_w.end_tag(); } @@ -312,7 +310,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let def_id = local_def(variant.node.id); index.push(entry { val: variant.node.id as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); rbml_w.start_tag(tag_items_data_item); encode_def_id(rbml_w, def_id); @@ -659,10 +657,11 @@ fn encode_info_for_struct(ecx: &EncodeContext, let nm = field.name; let id = field.id.node; - index.push(entry {val: id as i64, pos: rbml_w.writer.tell().unwrap()}); + let pos = rbml_w.mark_stable_position(); + index.push(entry {val: id as i64, pos: pos}); global_index.push(entry { val: id as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: pos, }); rbml_w.start_tag(tag_items_data_item); debug!("encode_info_for_struct: doing {} {}", @@ -688,7 +687,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, struct_id: NodeId) { index.push(entry { val: ctor_id as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); rbml_w.start_tag(tag_items_data_item); @@ -731,7 +730,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, }; for param in generics.types.iter() { rbml_w.start_tag(tag_type_param_def); - tyencode::enc_type_param_def(rbml_w.writer, ty_str_ctxt, param); + tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param); rbml_w.end_tag(); } @@ -765,7 +764,7 @@ fn encode_generics<'a, 'tcx>(rbml_w: &mut Encoder, rbml_w.wr_tagged_u8(tag_predicate_space, space as u8); rbml_w.start_tag(tag_predicate_data); - tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate); + tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate); rbml_w.end_tag(); rbml_w.end_tag(); @@ -964,11 +963,11 @@ fn encode_info_for_item(ecx: &EncodeContext, vis: ast::Visibility) { let tcx = ecx.tcx; - fn add_to_index(item: &ast::Item, rbml_w: &Encoder, + fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder, index: &mut Vec>) { index.push(entry { val: item.id as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); } @@ -1224,7 +1223,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index.push(entry { val: trait_item_def_id.def_id().node as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); let trait_item_type = @@ -1322,7 +1321,7 @@ fn encode_info_for_item(ecx: &EncodeContext, index.push(entry { val: item_def_id.def_id().node as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); rbml_w.start_tag(tag_items_data_item); @@ -1427,7 +1426,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, abi: abi::Abi) { index.push(entry { val: nitem.id as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); rbml_w.start_tag(tag_items_data_item); @@ -1527,7 +1526,7 @@ fn encode_info_for_items(ecx: &EncodeContext, rbml_w.start_tag(tag_items_data); index.push(entry { val: ast::CRATE_NODE_ID as i64, - pos: rbml_w.writer.tell().unwrap(), + pos: rbml_w.mark_stable_position(), }); encode_info_for_mod(ecx, rbml_w, @@ -1567,7 +1566,7 @@ fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: let mut bucket_locs = Vec::new(); rbml_w.start_tag(tag_index_buckets); for bucket in &buckets { - bucket_locs.push(rbml_w.writer.tell().unwrap()); + bucket_locs.push(rbml_w.mark_stable_position()); rbml_w.start_tag(tag_index_buckets_bucket); for elt in bucket { rbml_w.start_tag(tag_index_buckets_bucket_elt); @@ -1926,7 +1925,13 @@ pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec { let mut wr = SeekableMemWriter::new(); encode_metadata_inner(&mut wr, parms, krate); + + // RBML compacts the encoded bytes whenever appropriate, + // so there are some garbages left after the end of the data. + let metalen = wr.tell().unwrap() as uint; let mut v = wr.unwrap(); + v.truncate(metalen); + assert_eq!(v.len(), metalen); // And here we run into yet another obscure archive bug: in which metadata // loaded from archives may have trailing garbage bytes. Awhile back one of @@ -2008,7 +2013,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, reachable: reachable, }; - let mut rbml_w = writer::Encoder::new(wr); + let mut rbml_w = Encoder::new(wr); encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name); encode_crate_triple(&mut rbml_w, @@ -2099,7 +2104,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, // Get the encoded string for a type pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String { let mut wr = SeekableMemWriter::new(); - tyencode::enc_ty(&mut wr, &tyencode::ctxt { + tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt { diag: tcx.sess.diagnostic(), ds: def_to_string, tcx: tcx, diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index ebb4153e32bc..86f1605b8bfa 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -27,9 +27,9 @@ use syntax::ast; use syntax::diagnostic::SpanHandler; use syntax::parse::token; -use rbml::io::SeekableMemWriter; +use rbml::writer::Encoder; -macro_rules! mywrite { ($($arg:tt)*) => ({ write!($($arg)*); }) } +macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) } pub struct ctxt<'a, 'tcx: 'a> { pub diag: &'a SpanHandler, @@ -49,12 +49,14 @@ pub struct ty_abbrev { pub type abbrev_map<'tcx> = RefCell, ty_abbrev>>; -pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) { +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.write_all(a.s.as_bytes()); return; } + Some(a) => { w.writer.write_all(a.s.as_bytes()); return; } None => {} } - let pos = w.tell().unwrap(); + + // type abbreviations needs a stable position + let pos = w.mark_stable_position(); match t.sty { ty::ty_bool => mywrite!(w, "b"), @@ -154,7 +156,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t } } - let end = w.tell().unwrap(); + let end = w.mark_stable_position(); let len = end - pos; fn estimate_sz(u: u64) -> u64 { let mut n = u; @@ -171,21 +173,21 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t } } -fn enc_mutability(w: &mut SeekableMemWriter, mt: ast::Mutability) { +fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) { match mt { ast::MutImmutable => (), ast::MutMutable => mywrite!(w, "m"), } } -fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, mt: ty::mt<'tcx>) { enc_mutability(w, mt.mutbl); enc_ty(w, cx, mt.ty); } -fn enc_opt(w: &mut SeekableMemWriter, t: Option, enc_f: F) where - F: FnOnce(&mut SeekableMemWriter, T), +fn enc_opt(w: &mut Encoder, t: Option, enc_f: F) where + F: FnOnce(&mut Encoder, T), { match t { None => mywrite!(w, "n"), @@ -196,11 +198,11 @@ fn enc_opt(w: &mut SeekableMemWriter, t: Option, enc_f: F) where } } -fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter, +fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, v: &VecPerParamSpace, mut op: F) where - F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T), + F: FnMut(&mut Encoder, &ctxt<'a, 'tcx>, &T), { for &space in &subst::ParamSpace::all() { mywrite!(w, "["); @@ -211,14 +213,14 @@ fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter, } } -pub fn enc_substs<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_substs<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, substs: &subst::Substs<'tcx>) { enc_region_substs(w, cx, &substs.regions); enc_vec_per_param_space(w, cx, &substs.types, |w, cx, &ty| enc_ty(w, cx, ty)); } -fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::RegionSubsts) { +fn enc_region_substs(w: &mut Encoder, cx: &ctxt, substs: &subst::RegionSubsts) { match *substs { subst::ErasedRegions => { mywrite!(w, "e"); @@ -231,7 +233,7 @@ fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::Regio } } -pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) { +pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) { match r { ty::ReLateBound(id, br) => { mywrite!(w, "b[{}|", id.depth); @@ -270,7 +272,7 @@ pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) { } } -fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) { +fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) { match scope { region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id), region::CodeExtent::Remainder(region::BlockRemainder { @@ -279,12 +281,12 @@ fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) { } } -fn enc_destruction_scope_data(w: &mut SeekableMemWriter, +fn enc_destruction_scope_data(w: &mut Encoder, d: region::DestructionScopeData) { mywrite!(w, "{}", d.node_id); } -fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) { +fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) { match br { ty::BrAnon(idx) => { mywrite!(w, "a{}|", idx); @@ -303,40 +305,40 @@ fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) { } } -pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, s: &ty::TraitRef<'tcx>) { mywrite!(w, "{}|", (cx.ds)(s.def_id)); enc_substs(w, cx, s.substs); } -fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) { +fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) { match p { ast::Unsafety::Normal => mywrite!(w, "n"), ast::Unsafety::Unsafe => mywrite!(w, "u"), } } -fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) { +fn enc_abi(w: &mut Encoder, abi: Abi) { mywrite!(w, "["); mywrite!(w, "{}", abi.name()); mywrite!(w, "]") } -pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, ft: &ty::BareFnTy<'tcx>) { enc_unsafety(w, ft.unsafety); enc_abi(w, ft.abi); enc_fn_sig(w, cx, &ft.sig); } -pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_closure_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, ft: &ty::ClosureTy<'tcx>) { enc_unsafety(w, ft.unsafety); enc_fn_sig(w, cx, &ft.sig); enc_abi(w, ft.abi); } -fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +fn enc_fn_sig<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, fsig: &ty::PolyFnSig<'tcx>) { mywrite!(w, "["); for ty in &fsig.0.inputs { @@ -358,7 +360,7 @@ fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, } } -pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::BuiltinBounds) { +pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) { for bound in bs { match bound { ty::BoundSend => mywrite!(w, "S"), @@ -371,7 +373,7 @@ pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::Builti mywrite!(w, "."); } -pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter, +pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder, cx: &ctxt<'a,'tcx>, bs: &ty::ExistentialBounds<'tcx>) { let param_bounds = ty::ParamBounds { trait_bounds: vec!(), @@ -381,7 +383,7 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter, enc_bounds(w, cx, ¶m_bounds); } -pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, bs: &ty::ParamBounds<'tcx>) { enc_builtin_bounds(w, cx, &bs.builtin_bounds); @@ -400,7 +402,7 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, mywrite!(w, "."); } -pub fn enc_region_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, +pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, rs: &[ty::Region]) { for &r in rs { @@ -411,7 +413,7 @@ pub fn enc_region_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, mywrite!(w, "."); } -pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, +pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, v: &ty::TypeParameterDef<'tcx>) { mywrite!(w, "{}:{}|{}|{}|", token::get_name(v.name), (cx.ds)(v.def_id), @@ -420,7 +422,7 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tc enc_object_lifetime_default(w, cx, v.object_lifetime_default); } -fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter, +fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, default: Option) { @@ -434,7 +436,7 @@ fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter, } } -pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter, +pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, p: &ty::Predicate<'tcx>) { @@ -465,7 +467,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter, } } -fn enc_projection_predicate<'a, 'tcx>(w: &mut SeekableMemWriter, +fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, data: &ty::ProjectionPredicate<'tcx>) { enc_trait_ref(w, cx, &*data.projection_ty.trait_ref); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 5983829ed8fb..da3e6b4765b9 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1,4 +1,4 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -43,13 +43,14 @@ use std::old_io::Seek; use std::num::FromPrimitive; use std::rc::Rc; -use rbml::io::SeekableMemWriter; -use rbml::{reader, writer}; +use rbml::reader; +use rbml::writer::Encoder; use rbml; use serialize; use serialize::{Decodable, Decoder, DecoderHelpers, Encodable}; use serialize::{EncoderHelpers}; +#[cfg(test)] use rbml::io::SeekableMemWriter; #[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::print::pprust; @@ -68,8 +69,6 @@ trait tr_intern { fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId; } -pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>; - // ______________________________________________________________________ // Top-level methods. @@ -911,7 +910,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, type_param_def: &ty::TypeParameterDef<'tcx>) { self.emit_opaque(|this| { - Ok(tyencode::enc_type_param_def(this.writer, + Ok(tyencode::enc_type_param_def(this, &ecx.ty_str_ctxt(), type_param_def)) }); @@ -920,7 +919,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, predicate: &ty::Predicate<'tcx>) { self.emit_opaque(|this| { - Ok(tyencode::enc_predicate(this.writer, + Ok(tyencode::enc_predicate(this, &ecx.ty_str_ctxt(), predicate)) }); @@ -954,20 +953,20 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>, bounds: &ty::ExistentialBounds<'tcx>) { - self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this.writer, + self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this, &ecx.ty_str_ctxt(), bounds))); } fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) { - self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this.writer, + self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this, &ecx.ty_str_ctxt(), bounds))); } fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, substs: &subst::Substs<'tcx>) { - self.emit_opaque(|this| Ok(tyencode::enc_substs(this.writer, + self.emit_opaque(|this| Ok(tyencode::enc_substs(this, &ecx.ty_str_ctxt(), substs))); } @@ -1995,7 +1994,7 @@ fn mk_ctxt() -> parse::ParseSess { fn roundtrip(in_item: Option>) { let in_item = in_item.unwrap(); let mut wr = SeekableMemWriter::new(); - encode_item_ast(&mut writer::Encoder::new(&mut wr), &*in_item); + encode_item_ast(&mut Encoder::new(&mut wr), &*in_item); let rbml_doc = rbml::Doc::new(wr.get_ref()); let out_item = decode_item_ast(rbml_doc);