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.
This commit is contained in:
Kang Seonghoon 2015-03-02 14:34:16 +09:00
parent de00b858d1
commit 84e9a61e9c
4 changed files with 138 additions and 102 deletions

View file

@ -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<uint>,
relax_limit: u64, // do not move encoded bytes before this position
}
fn write_tag<W: Writer>(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<F>(&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<F>(&mut self, f: F) -> EncodeResult where
F: FnOnce(&mut Encoder<W>) -> 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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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<F>(&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));

View file

@ -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<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
@ -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<entry<i64>>) {
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<T, F>(rbml_w: &mut Encoder, index: Vec<entry<T>>, 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<u8> {
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,

View file

@ -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<FnvHashMap<Ty<'tcx>, 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<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
F: FnOnce(&mut SeekableMemWriter, T),
fn enc_opt<T, F>(w: &mut Encoder, t: Option<T>, enc_f: F) where
F: FnOnce(&mut Encoder, T),
{
match t {
None => mywrite!(w, "n"),
@ -196,11 +198,11 @@ fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, 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<T>,
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, &param_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<ty::ObjectLifetimeDefault>)
{
@ -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);

View file

@ -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<P<ast::Item>>) {
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);