rustc_metadata: combine EncodeContext and rbml::writer::Encoder.
This commit is contained in:
parent
7b073343db
commit
82197287a2
7 changed files with 798 additions and 862 deletions
|
|
@ -46,7 +46,6 @@ use std::io::SeekFrom;
|
|||
use std::io::prelude::*;
|
||||
|
||||
use rbml::reader;
|
||||
use rbml::writer::Encoder;
|
||||
use rbml;
|
||||
use rustc_serialize::{Decodable, Decoder, DecoderHelpers};
|
||||
use rustc_serialize::{Encodable, EncoderHelpers};
|
||||
|
|
@ -67,9 +66,7 @@ trait tr {
|
|||
// ______________________________________________________________________
|
||||
// Top-level methods.
|
||||
|
||||
pub fn encode_inlined_item(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
ii: InlinedItemRef) {
|
||||
pub fn encode_inlined_item(ecx: &mut e::EncodeContext, ii: InlinedItemRef) {
|
||||
let id = match ii {
|
||||
InlinedItemRef::Item(_, i) => i.id,
|
||||
InlinedItemRef::TraitItem(_, ti) => ti.id,
|
||||
|
|
@ -77,22 +74,24 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
|
|||
};
|
||||
debug!("> Encoding inlined item: {} ({:?})",
|
||||
ecx.tcx.node_path_str(id),
|
||||
rbml_w.writer.seek(SeekFrom::Current(0)));
|
||||
ecx.writer.seek(SeekFrom::Current(0)));
|
||||
|
||||
// Folding could be avoided with a smarter encoder.
|
||||
let (ii, expected_id_range) = simplify_ast(ii);
|
||||
let id_range = inlined_item_id_range(&ii);
|
||||
assert_eq!(expected_id_range, id_range);
|
||||
|
||||
rbml_w.start_tag(c::tag_ast as usize);
|
||||
id_range.encode(rbml_w);
|
||||
encode_ast(rbml_w, &ii);
|
||||
encode_side_tables_for_ii(ecx, rbml_w, &ii);
|
||||
rbml_w.end_tag();
|
||||
ecx.start_tag(c::tag_ast as usize);
|
||||
id_range.encode(ecx);
|
||||
ecx.start_tag(c::tag_tree as usize);
|
||||
ecx.emit_opaque(|this| ii.encode(this));
|
||||
ecx.end_tag();
|
||||
encode_side_tables_for_ii(ecx, &ii);
|
||||
ecx.end_tag();
|
||||
|
||||
debug!("< Encoded inlined fn: {} ({:?})",
|
||||
ecx.tcx.node_path_str(id),
|
||||
rbml_w.writer.seek(SeekFrom::Current(0)));
|
||||
ecx.writer.seek(SeekFrom::Current(0)));
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'tcx> {
|
||||
|
|
@ -235,12 +234,6 @@ impl tr for syntax_pos::Span {
|
|||
// We also have to adjust the spans: for now we just insert a dummy span,
|
||||
// but eventually we should add entries to the local codemap as required.
|
||||
|
||||
fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) {
|
||||
rbml_w.start_tag(c::tag_tree as usize);
|
||||
rbml_w.emit_opaque(|this| item.encode(this));
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
|
||||
struct NestedItemsDropper {
|
||||
id_range: IdRange
|
||||
}
|
||||
|
|
@ -385,10 +378,6 @@ impl tr for Def {
|
|||
// ______________________________________________________________________
|
||||
// Encoding and decoding of freevar information
|
||||
|
||||
fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &hir::Freevar) {
|
||||
(*fv).encode(rbml_w).unwrap();
|
||||
}
|
||||
|
||||
impl<'a> reader::Decoder<'a> {
|
||||
fn read_freevar_entry(&mut self, dcx: &DecodeContext)
|
||||
-> hir::Freevar {
|
||||
|
|
@ -409,26 +398,27 @@ impl tr for hir::Freevar {
|
|||
// ______________________________________________________________________
|
||||
// Encoding and decoding of MethodCallee
|
||||
|
||||
fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
|
||||
rbml_w: &mut Encoder,
|
||||
autoderef: u32,
|
||||
method: &ty::MethodCallee<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
impl<'a, 'tcx> e::EncodeContext<'a, 'tcx> {
|
||||
fn encode_method_callee(&mut self,
|
||||
autoderef: u32,
|
||||
method: &ty::MethodCallee<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
|
||||
rbml_w.emit_struct("MethodCallee", 4, |rbml_w| {
|
||||
rbml_w.emit_struct_field("autoderef", 0, |rbml_w| {
|
||||
autoderef.encode(rbml_w)
|
||||
});
|
||||
rbml_w.emit_struct_field("def_id", 1, |rbml_w| {
|
||||
method.def_id.encode(rbml_w)
|
||||
});
|
||||
rbml_w.emit_struct_field("ty", 2, |rbml_w| {
|
||||
Ok(rbml_w.emit_ty(ecx, method.ty))
|
||||
});
|
||||
rbml_w.emit_struct_field("substs", 3, |rbml_w| {
|
||||
Ok(rbml_w.emit_substs(ecx, &method.substs))
|
||||
})
|
||||
}).unwrap();
|
||||
self.emit_struct("MethodCallee", 4, |this| {
|
||||
this.emit_struct_field("autoderef", 0, |this| {
|
||||
autoderef.encode(this)
|
||||
});
|
||||
this.emit_struct_field("def_id", 1, |this| {
|
||||
method.def_id.encode(this)
|
||||
});
|
||||
this.emit_struct_field("ty", 2, |this| {
|
||||
Ok(this.emit_ty(method.ty))
|
||||
});
|
||||
this.emit_struct_field("substs", 3, |this| {
|
||||
Ok(this.emit_substs(&method.substs))
|
||||
})
|
||||
}).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> reader::Decoder<'a> {
|
||||
|
|
@ -453,27 +443,25 @@ impl<'a, 'tcx> reader::Decoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
|
||||
kind.encode(ebml_w).unwrap();
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
// Encoding and decoding the side tables
|
||||
|
||||
impl<'a, 'tcx> Encoder<'a> {
|
||||
fn emit_region(&mut self, ecx: &e::EncodeContext, r: &'tcx ty::Region) {
|
||||
impl<'a, 'tcx> e::EncodeContext<'a, 'tcx> {
|
||||
fn emit_region(&mut self, r: &'tcx ty::Region) {
|
||||
let cx = self.ty_str_ctxt();
|
||||
self.emit_opaque(|this| Ok(tyencode::enc_region(&mut this.cursor,
|
||||
&ecx.ty_str_ctxt(),
|
||||
&cx,
|
||||
r)));
|
||||
}
|
||||
|
||||
fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
|
||||
fn emit_ty(&mut self, ty: Ty<'tcx>) {
|
||||
let cx = self.ty_str_ctxt();
|
||||
self.emit_opaque(|this| Ok(tyencode::enc_ty(&mut this.cursor,
|
||||
&ecx.ty_str_ctxt(),
|
||||
&cx,
|
||||
ty)));
|
||||
}
|
||||
|
||||
fn emit_upvar_capture(&mut self, ecx: &e::EncodeContext, capture: &ty::UpvarCapture) {
|
||||
fn emit_upvar_capture(&mut self, capture: &ty::UpvarCapture<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
|
||||
self.emit_enum("UpvarCapture", |this| {
|
||||
|
|
@ -486,22 +474,21 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
this.emit_enum_variant_arg(0,
|
||||
|this| kind.encode(this));
|
||||
this.emit_enum_variant_arg(1,
|
||||
|this| Ok(this.emit_region(ecx, region)))
|
||||
|this| Ok(this.emit_region(region)))
|
||||
})
|
||||
}
|
||||
}
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
|
||||
substs: &Substs<'tcx>) {
|
||||
fn emit_substs(&mut self, substs: &Substs<'tcx>) {
|
||||
let cx = self.ty_str_ctxt();
|
||||
self.emit_opaque(|this| Ok(tyencode::enc_substs(&mut this.cursor,
|
||||
&ecx.ty_str_ctxt(),
|
||||
&cx,
|
||||
substs)));
|
||||
}
|
||||
|
||||
fn emit_auto_adjustment<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
|
||||
adj: &adjustment::AutoAdjustment<'tcx>) {
|
||||
fn emit_auto_adjustment(&mut self, adj: &adjustment::AutoAdjustment<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
|
||||
self.emit_enum("AutoAdjustment", |this| {
|
||||
|
|
@ -525,21 +512,20 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
adjustment::AdjustDerefRef(ref auto_deref_ref) => {
|
||||
this.emit_enum_variant("AdjustDerefRef", 4, 2, |this| {
|
||||
this.emit_enum_variant_arg(0,
|
||||
|this| Ok(this.emit_auto_deref_ref(ecx, auto_deref_ref)))
|
||||
|this| Ok(this.emit_auto_deref_ref(auto_deref_ref)))
|
||||
})
|
||||
}
|
||||
|
||||
adjustment::AdjustNeverToAny(ref ty) => {
|
||||
this.emit_enum_variant("AdjustNeverToAny", 5, 1, |this| {
|
||||
this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ecx, ty)))
|
||||
this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ty)))
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn emit_autoref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
|
||||
autoref: &adjustment::AutoRef<'tcx>) {
|
||||
fn emit_autoref(&mut self, autoref: &adjustment::AutoRef<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
|
||||
self.emit_enum("AutoRef", |this| {
|
||||
|
|
@ -547,7 +533,7 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
&adjustment::AutoPtr(r, m) => {
|
||||
this.emit_enum_variant("AutoPtr", 0, 2, |this| {
|
||||
this.emit_enum_variant_arg(0,
|
||||
|this| Ok(this.emit_region(ecx, r)));
|
||||
|this| Ok(this.emit_region(r)));
|
||||
this.emit_enum_variant_arg(1, |this| m.encode(this))
|
||||
})
|
||||
}
|
||||
|
|
@ -560,8 +546,7 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
fn emit_auto_deref_ref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
|
||||
auto_deref_ref: &adjustment::AutoDerefRef<'tcx>) {
|
||||
fn emit_auto_deref_ref(&mut self, auto_deref_ref: &adjustment::AutoDerefRef<'tcx>) {
|
||||
use rustc_serialize::Encoder;
|
||||
|
||||
self.emit_struct("AutoDerefRef", 2, |this| {
|
||||
|
|
@ -571,7 +556,7 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
this.emit_option(|this| {
|
||||
match auto_deref_ref.autoref {
|
||||
None => this.emit_option_none(),
|
||||
Some(ref a) => this.emit_option_some(|this| Ok(this.emit_autoref(ecx, a))),
|
||||
Some(ref a) => this.emit_option_some(|this| Ok(this.emit_autoref(a))),
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
@ -581,20 +566,18 @@ impl<'a, 'tcx> Encoder<'a> {
|
|||
match auto_deref_ref.unsize {
|
||||
None => this.emit_option_none(),
|
||||
Some(target) => this.emit_option_some(|this| {
|
||||
Ok(this.emit_ty(ecx, target))
|
||||
Ok(this.emit_ty(target))
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
fn tag<F>(&mut self,
|
||||
tag_id: c::astencode_tag,
|
||||
f: F) where
|
||||
F: FnOnce(&mut Encoder<'a>),
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
self.start_tag(tag_id as usize);
|
||||
f(self);
|
||||
|
|
@ -606,68 +589,61 @@ impl<'a> Encoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
|
||||
ecx: &'a e::EncodeContext<'c, 'tcx>,
|
||||
rbml_w: &'a mut Encoder<'b>,
|
||||
struct SideTableEncodingIdVisitor<'a, 'b:'a, 'tcx:'b> {
|
||||
ecx: &'a mut e::EncodeContext<'b, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for
|
||||
SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> {
|
||||
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> {
|
||||
fn visit_id(&mut self, id: ast::NodeId) {
|
||||
encode_side_tables_for_id(self.ecx, self.rbml_w, id)
|
||||
encode_side_tables_for_id(self.ecx, id)
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_side_tables_for_ii(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
ii: &InlinedItem) {
|
||||
rbml_w.start_tag(c::tag_table as usize);
|
||||
fn encode_side_tables_for_ii(ecx: &mut e::EncodeContext, ii: &InlinedItem) {
|
||||
ecx.start_tag(c::tag_table as usize);
|
||||
ii.visit(&mut SideTableEncodingIdVisitor {
|
||||
ecx: ecx,
|
||||
rbml_w: rbml_w
|
||||
ecx: ecx
|
||||
});
|
||||
rbml_w.end_tag();
|
||||
ecx.end_tag();
|
||||
}
|
||||
|
||||
fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
id: ast::NodeId) {
|
||||
fn encode_side_tables_for_id(ecx: &mut e::EncodeContext, id: ast::NodeId) {
|
||||
let tcx = ecx.tcx;
|
||||
|
||||
debug!("Encoding side tables for id {}", id);
|
||||
|
||||
if let Some(def) = tcx.expect_def_or_none(id) {
|
||||
rbml_w.tag(c::tag_table_def, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
def.encode(rbml_w).unwrap();
|
||||
ecx.tag(c::tag_table_def, |ecx| {
|
||||
ecx.id(id);
|
||||
def.encode(ecx).unwrap();
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(ty) = tcx.node_types().get(&id) {
|
||||
rbml_w.tag(c::tag_table_node_type, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.emit_ty(ecx, *ty);
|
||||
ecx.tag(c::tag_table_node_type, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.emit_ty(*ty);
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) {
|
||||
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.emit_substs(ecx, &item_substs.substs);
|
||||
ecx.tag(c::tag_table_item_subst, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.emit_substs(&item_substs.substs);
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(fv) = tcx.freevars.borrow().get(&id) {
|
||||
rbml_w.tag(c::tag_table_freevars, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
|
||||
Ok(encode_freevar_entry(rbml_w, fv_entry))
|
||||
ecx.tag(c::tag_table_freevars, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.emit_from_vec(fv, |ecx, fv_entry| {
|
||||
fv_entry.encode(ecx)
|
||||
});
|
||||
});
|
||||
|
||||
for freevar in fv {
|
||||
rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
ecx.tag(c::tag_table_upvar_capture_map, |ecx| {
|
||||
ecx.id(id);
|
||||
|
||||
let var_id = freevar.def.var_id();
|
||||
let upvar_id = ty::UpvarId {
|
||||
|
|
@ -680,17 +656,17 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
|||
.get(&upvar_id)
|
||||
.unwrap()
|
||||
.clone();
|
||||
var_id.encode(rbml_w);
|
||||
rbml_w.emit_upvar_capture(ecx, &upvar_capture);
|
||||
var_id.encode(ecx);
|
||||
ecx.emit_upvar_capture(&upvar_capture);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let method_call = ty::MethodCall::expr(id);
|
||||
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
|
||||
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
|
||||
ecx.tag(c::tag_table_method_map, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.encode_method_callee(method_call.autoderef, method)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -700,10 +676,9 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
|||
for autoderef in 0..adj.autoderefs {
|
||||
let method_call = ty::MethodCall::autoderef(id, autoderef as u32);
|
||||
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
|
||||
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
encode_method_callee(ecx, rbml_w,
|
||||
method_call.autoderef, method)
|
||||
ecx.tag(c::tag_table_method_map, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.encode_method_callee(method_call.autoderef, method)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -711,23 +686,23 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
|||
_ => {}
|
||||
}
|
||||
|
||||
rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.emit_auto_adjustment(ecx, adjustment);
|
||||
ecx.tag(c::tag_table_adjustments, |ecx| {
|
||||
ecx.id(id);
|
||||
ecx.emit_auto_adjustment(adjustment);
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
|
||||
rbml_w.tag(c::tag_table_cast_kinds, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
encode_cast_kind(rbml_w, *cast_kind)
|
||||
ecx.tag(c::tag_table_cast_kinds, |ecx| {
|
||||
ecx.id(id);
|
||||
cast_kind.encode(ecx).unwrap()
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(qualif) = tcx.const_qualif_map.borrow().get(&id) {
|
||||
rbml_w.tag(c::tag_table_const_qualif, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
qualif.encode(rbml_w).unwrap()
|
||||
ecx.tag(c::tag_table_const_qualif, |ecx| {
|
||||
ecx.id(id);
|
||||
qualif.encode(ecx).unwrap()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use common;
|
|||
use decoder;
|
||||
use encoder;
|
||||
use loader;
|
||||
use rbml;
|
||||
|
||||
use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike};
|
||||
use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference};
|
||||
|
|
@ -707,15 +708,16 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
|
|||
mir_map: &MirMap<'tcx>,
|
||||
krate: &hir::Crate) -> Vec<u8>
|
||||
{
|
||||
let type_abbrevs = RefCell::new(FnvHashMap());
|
||||
let ecx = encoder::EncodeContext {
|
||||
diag: tcx.sess.diagnostic(),
|
||||
rbml_w: rbml::writer::Encoder::new(),
|
||||
tcx: tcx,
|
||||
reexports: reexports,
|
||||
link_meta: link_meta,
|
||||
cstore: self,
|
||||
reachable: reachable,
|
||||
mir_map: mir_map,
|
||||
type_abbrevs: RefCell::new(FnvHashMap()),
|
||||
type_abbrevs: &type_abbrevs,
|
||||
};
|
||||
encoder::encode_metadata(ecx, krate)
|
||||
|
||||
|
|
|
|||
|
|
@ -812,10 +812,8 @@ pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd,
|
|||
};
|
||||
let mut decoder = reader::Decoder::new(mir_doc);
|
||||
|
||||
let mut mir = decoder.read_opaque(|opaque_decoder, _| {
|
||||
tls::enter_decoding_context(&dcx, opaque_decoder, |_, opaque_decoder| {
|
||||
Decodable::decode(opaque_decoder)
|
||||
})
|
||||
let mut mir = tls::enter_decoding_context(&dcx, |_| {
|
||||
Decodable::decode(&mut decoder)
|
||||
}).unwrap();
|
||||
|
||||
assert!(decoder.position() == mir_doc.end);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -65,7 +65,6 @@
|
|||
use common::tag_items_data_item;
|
||||
use encoder::EncodeContext;
|
||||
use index::IndexData;
|
||||
use rbml::writer::Encoder;
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
|
@ -73,43 +72,63 @@ use rustc::ty::{self, TyCtxt};
|
|||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
use syntax::ast;
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
/// Builder that can encode new items, adding them into the index.
|
||||
/// Item encoding cannot be nested.
|
||||
pub struct IndexBuilder<'a, 'tcx: 'a, 'encoder: 'a> {
|
||||
pub struct IndexBuilder<'a, 'b: 'a, 'tcx: 'b> {
|
||||
items: IndexData,
|
||||
builder: ItemContentBuilder<'a, 'tcx, 'encoder>,
|
||||
builder: ItemContentBuilder<'a, 'b, 'tcx>,
|
||||
}
|
||||
|
||||
/// Builder that can encode the content of items, but can't start a
|
||||
/// new item itself. Most code is attached to here.
|
||||
pub struct ItemContentBuilder<'a, 'tcx: 'a, 'encoder: 'a> {
|
||||
pub struct ItemContentBuilder<'a, 'b: 'a, 'tcx: 'b> {
|
||||
xrefs: FnvHashMap<XRef<'tcx>, u32>, // sequentially-assigned
|
||||
pub ecx: &'a EncodeContext<'a, 'tcx>,
|
||||
pub rbml_w: &'a mut Encoder<'encoder>,
|
||||
pub ecx: &'a mut EncodeContext<'b, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> Deref for IndexBuilder<'a, 'b, 'tcx> {
|
||||
type Target = EncodeContext<'b, 'tcx>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.builder.ecx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.builder.ecx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> Deref for ItemContentBuilder<'a, 'b, 'tcx> {
|
||||
type Target = EncodeContext<'b, 'tcx>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.ecx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> DerefMut for ItemContentBuilder<'a, 'b, 'tcx> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.ecx
|
||||
}
|
||||
}
|
||||
|
||||
/// "interned" entries referenced by id
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) }
|
||||
|
||||
impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> {
|
||||
pub fn new(ecx: &'a EncodeContext<'a, 'tcx>,
|
||||
rbml_w: &'a mut Encoder<'encoder>)
|
||||
-> Self {
|
||||
impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
|
||||
pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self {
|
||||
IndexBuilder {
|
||||
items: IndexData::new(ecx.tcx.map.num_local_def_ids()),
|
||||
builder: ItemContentBuilder {
|
||||
ecx: ecx,
|
||||
xrefs: FnvHashMap(),
|
||||
rbml_w: rbml_w,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> {
|
||||
self.builder.ecx()
|
||||
}
|
||||
|
||||
/// Emit the data for a def-id to the metadata. The function to
|
||||
/// emit the data is `op`, and it will be given `data` as
|
||||
/// arguments. This `record` function will start/end an RBML tag
|
||||
|
|
@ -129,17 +148,17 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> {
|
|||
/// content system.
|
||||
pub fn record<DATA>(&mut self,
|
||||
id: DefId,
|
||||
op: fn(&mut ItemContentBuilder<'a, 'tcx, 'encoder>, DATA),
|
||||
op: fn(&mut ItemContentBuilder<'a, 'b, 'tcx>, DATA),
|
||||
data: DATA)
|
||||
where DATA: DepGraphRead
|
||||
{
|
||||
let position = self.builder.rbml_w.mark_stable_position();
|
||||
let position = self.builder.ecx.mark_stable_position();
|
||||
self.items.record(id, position);
|
||||
let _task = self.ecx().tcx.dep_graph.in_task(DepNode::MetaData(id));
|
||||
self.builder.rbml_w.start_tag(tag_items_data_item).unwrap();
|
||||
data.read(self.ecx().tcx);
|
||||
let _task = self.tcx.dep_graph.in_task(DepNode::MetaData(id));
|
||||
self.builder.ecx.start_tag(tag_items_data_item).unwrap();
|
||||
data.read(self.tcx);
|
||||
op(&mut self.builder, data);
|
||||
self.builder.rbml_w.end_tag().unwrap();
|
||||
self.builder.ecx.end_tag().unwrap();
|
||||
}
|
||||
|
||||
pub fn into_fields(self) -> (IndexData, FnvHashMap<XRef<'tcx>, u32>) {
|
||||
|
|
@ -147,11 +166,7 @@ impl<'a, 'tcx, 'encoder> IndexBuilder<'a, 'tcx, 'encoder> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
|
||||
pub fn ecx(&self) -> &'a EncodeContext<'a, 'tcx> {
|
||||
self.ecx
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> {
|
||||
pub fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 {
|
||||
let old_len = self.xrefs.len() as u32;
|
||||
*self.xrefs.entry(xref).or_insert(old_len)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ use rustc_serialize as serialize;
|
|||
pub type EncodeResult = io::Result<()>;
|
||||
|
||||
// rbml writing
|
||||
pub struct Encoder<'a> {
|
||||
pub writer: &'a mut Cursor<Vec<u8>>,
|
||||
pub struct Encoder {
|
||||
pub writer: Cursor<Vec<u8>>,
|
||||
size_positions: Vec<u64>,
|
||||
relax_limit: u64, // do not move encoded bytes before this position
|
||||
}
|
||||
|
|
@ -65,10 +65,10 @@ pub fn write_vuint<W: Write>(w: &mut W, n: usize) -> EncodeResult {
|
|||
Err(io::Error::new(io::ErrorKind::Other, &format!("isize too big: {}", n)[..]))
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
pub fn new(w: &'a mut Cursor<Vec<u8>>) -> Encoder<'a> {
|
||||
impl Encoder {
|
||||
pub fn new() -> Encoder {
|
||||
Encoder {
|
||||
writer: w,
|
||||
writer: Cursor::new(vec![]),
|
||||
size_positions: vec![],
|
||||
relax_limit: 0,
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ impl<'a> Encoder<'a> {
|
|||
assert!(tag_id >= NUM_IMPLICIT_TAGS);
|
||||
|
||||
// Write the enum ID:
|
||||
write_tag(self.writer, tag_id)?;
|
||||
write_tag(&mut self.writer, tag_id)?;
|
||||
|
||||
// Write a placeholder four-byte size.
|
||||
let cur_pos = self.writer.seek(SeekFrom::Current(0))?;
|
||||
|
|
@ -107,11 +107,11 @@ impl<'a> Encoder<'a> {
|
|||
}
|
||||
|
||||
// overwrite the size and data and continue
|
||||
write_vuint(self.writer, size)?;
|
||||
write_vuint(&mut self.writer, size)?;
|
||||
self.writer.write_all(&buf[..size])?;
|
||||
} else {
|
||||
// overwrite the size with an overlong encoding and skip past the data
|
||||
write_sized_vuint(self.writer, size, 4)?;
|
||||
write_sized_vuint(&mut self.writer, size, 4)?;
|
||||
self.writer.seek(SeekFrom::Start(cur_pos))?;
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +129,8 @@ impl<'a> Encoder<'a> {
|
|||
|
||||
pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
|
||||
assert!(tag_id >= NUM_IMPLICIT_TAGS);
|
||||
write_tag(self.writer, tag_id)?;
|
||||
write_vuint(self.writer, b.len())?;
|
||||
write_tag(&mut self.writer, tag_id)?;
|
||||
write_vuint(&mut self.writer, b.len())?;
|
||||
self.writer.write_all(b)
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ impl<'a> Encoder<'a> {
|
|||
|
||||
// for auto-serialization
|
||||
fn wr_tagged_raw_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult {
|
||||
write_tag(self.writer, tag_id)?;
|
||||
write_tag(&mut self.writer, tag_id)?;
|
||||
self.writer.write_all(b)
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +243,7 @@ impl<'a> Encoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Encoder<'a> {
|
||||
impl Encoder {
|
||||
// used internally to emit things like the vector length and so on
|
||||
fn _emit_tagged_sub(&mut self, v: usize) -> EncodeResult {
|
||||
if v as u8 as usize == v {
|
||||
|
|
@ -262,7 +262,7 @@ impl<'a> Encoder<'a> {
|
|||
self.start_tag(EsOpaque as usize)?;
|
||||
|
||||
{
|
||||
let mut opaque_encoder = opaque::Encoder::new(self.writer);
|
||||
let mut opaque_encoder = opaque::Encoder::new(&mut self.writer);
|
||||
f(&mut opaque_encoder)?;
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ impl<'a> Encoder<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> serialize::Encoder for Encoder<'a> {
|
||||
impl<'a, 'tcx> serialize::Encoder for ::encoder::EncodeContext<'a, 'tcx> {
|
||||
type Error = io::Error;
|
||||
|
||||
fn emit_nil(&mut self) -> EncodeResult {
|
||||
|
|
@ -355,7 +355,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.start_tag(EsEnum as usize)?;
|
||||
f(self)?;
|
||||
|
|
@ -363,14 +363,14 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_enum_variant<F>(&mut self, _: &str, v_id: usize, _: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self._emit_tagged_sub(v_id)?;
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_enum_variant_arg<F>(&mut self, _: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
|
@ -381,53 +381,53 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
cnt: usize,
|
||||
f: F)
|
||||
-> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_enum_variant(v_name, v_id, cnt, f)
|
||||
}
|
||||
|
||||
fn emit_enum_struct_variant_field<F>(&mut self, _: &str, idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_enum_variant_arg(idx, f)
|
||||
}
|
||||
|
||||
fn emit_struct<F>(&mut self, _: &str, _len: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_struct_field<F>(&mut self, _name: &str, _: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
f(self)
|
||||
}
|
||||
|
||||
fn emit_tuple<F>(&mut self, len: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_seq(len, f)
|
||||
}
|
||||
fn emit_tuple_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_seq_elt(idx, f)
|
||||
}
|
||||
|
||||
fn emit_tuple_struct<F>(&mut self, _: &str, len: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_seq(len, f)
|
||||
}
|
||||
fn emit_tuple_struct_arg<F>(&mut self, idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_seq_elt(idx, f)
|
||||
}
|
||||
|
||||
fn emit_option<F>(&mut self, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.emit_enum("Option", f)
|
||||
}
|
||||
|
|
@ -435,14 +435,14 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
self.emit_enum_variant("None", 0, 0, |_| Ok(()))
|
||||
}
|
||||
fn emit_option_some<F>(&mut self, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
|
||||
self.emit_enum_variant("Some", 1, 1, f)
|
||||
}
|
||||
|
||||
fn emit_seq<F>(&mut self, len: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
if len == 0 {
|
||||
// empty vector optimization
|
||||
|
|
@ -456,7 +456,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_seq_elt<F>(&mut self, _idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
|
||||
self.start_tag(EsVecElt as usize)?;
|
||||
|
|
@ -465,7 +465,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_map<F>(&mut self, len: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
if len == 0 {
|
||||
// empty map optimization
|
||||
|
|
@ -479,7 +479,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
|
||||
self.start_tag(EsMapKey as usize)?;
|
||||
|
|
@ -488,7 +488,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
|
|||
}
|
||||
|
||||
fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> EncodeResult
|
||||
where F: FnOnce(&mut Encoder<'a>) -> EncodeResult
|
||||
where F: FnOnce(&mut Self) -> EncodeResult
|
||||
{
|
||||
self.start_tag(EsMapVal as usize)?;
|
||||
f(self)?;
|
||||
|
|
|
|||
|
|
@ -27,13 +27,11 @@ use rustc::hir;
|
|||
|
||||
use syntax::abi::Abi;
|
||||
use syntax::ast;
|
||||
use errors::Handler;
|
||||
|
||||
use rbml::leb128;
|
||||
use encoder;
|
||||
|
||||
pub struct ctxt<'a, 'tcx: 'a> {
|
||||
pub diag: &'a Handler,
|
||||
// Def -> str Callback:
|
||||
pub ds: for<'b> fn(TyCtxt<'b, 'tcx, 'tcx>, DefId) -> String,
|
||||
// The type context.
|
||||
|
|
@ -42,12 +40,11 @@ pub struct ctxt<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> encoder::EncodeContext<'a, 'tcx> {
|
||||
pub fn ty_str_ctxt<'b>(&'b self) -> ctxt<'b, 'tcx> {
|
||||
pub fn ty_str_ctxt(&self) -> ctxt<'a, 'tcx> {
|
||||
ctxt {
|
||||
diag: self.tcx.sess.diagnostic(),
|
||||
ds: encoder::def_to_string,
|
||||
tcx: self.tcx,
|
||||
abbrevs: &self.type_abbrevs
|
||||
abbrevs: self.type_abbrevs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue