mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
auto merge of #8745 : brson/rust/metadata, r=cmr
This does two things: 1) stops compressing metadata, 2) stops copying the metadata section, instead holding a reference to the buffer returned by the LLVM section iterator. Not compressing metadata requires something like 7x the storage space, but makes running tests about 9% faster. This has been a time improvement on all platforms I've tested, including windows. I considered leaving compression as an option but it doesn't seem to be worth the complexity since we don't currently have any use cases where we need to save that space. In order to avoid copying the metadata section I had to hack up extra::ebml a bit to support unsafe buffers. We should probably move it into librustc so that it can evolve to support the compiler without worrying about having a crummy interface. r? @graydon
This commit is contained in:
commit
491bc3568c
3
configure
vendored
3
configure
vendored
@ -381,7 +381,8 @@ opt mingw-cross 0 "cross-compile for win32 using mingw"
|
||||
opt clang 0 "prefer clang to gcc for building the runtime"
|
||||
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
|
||||
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
|
||||
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)"
|
||||
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched
|
||||
kernels)"
|
||||
valopt prefix "/usr/local" "set installation prefix"
|
||||
valopt local-rust-root "/usr/local" "set prefix for local rust binary"
|
||||
valopt llvm-root "" "set LLVM root"
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
|
||||
use std::str;
|
||||
use std::cast;
|
||||
use std::vec;
|
||||
|
||||
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
|
||||
// cursor model. See the specification here:
|
||||
@ -29,9 +31,42 @@ struct EbmlState {
|
||||
data_pos: uint,
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub enum EbmlData {
|
||||
SafeData(@~[u8]),
|
||||
UnsafeData(*u8, uint)
|
||||
}
|
||||
|
||||
impl EbmlData {
|
||||
#[inline]
|
||||
pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [u8] {
|
||||
match *self {
|
||||
SafeData(@ref v) => v.slice(start, end),
|
||||
UnsafeData(buf, len) => unsafe {
|
||||
do vec::raw::buf_as_slice(buf, len) |s| {
|
||||
cast::transmute(s.slice(start, end))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
|
||||
self.slice(0, self.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> uint {
|
||||
match *self {
|
||||
SafeData(@ref v) => v.len(),
|
||||
UnsafeData(_, len) => len
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct Doc {
|
||||
data: @~[u8],
|
||||
data: EbmlData,
|
||||
start: uint,
|
||||
end: uint,
|
||||
}
|
||||
@ -185,24 +220,28 @@ pub mod reader {
|
||||
}
|
||||
|
||||
pub fn Doc(data: @~[u8]) -> Doc {
|
||||
Doc { data: data, start: 0u, end: data.len() }
|
||||
Doc { data: SafeData(data), start: 0u, end: data.len() }
|
||||
}
|
||||
|
||||
pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
|
||||
let elt_tag = vuint_at(*data, start);
|
||||
let elt_size = vuint_at(*data, elt_tag.next);
|
||||
pub fn unsafe_Doc(buf: *u8, len: uint) -> Doc {
|
||||
Doc { data: UnsafeData(buf, len), start: 0u, end: len }
|
||||
}
|
||||
|
||||
pub fn doc_at(data: &EbmlData, start: uint) -> TaggedDoc {
|
||||
let elt_tag = vuint_at(data.as_slice(), start);
|
||||
let elt_size = vuint_at(data.as_slice(), elt_tag.next);
|
||||
let end = elt_size.next + elt_size.val;
|
||||
TaggedDoc {
|
||||
tag: elt_tag.val,
|
||||
doc: Doc { data: data, start: elt_size.next, end: end }
|
||||
doc: Doc { data: data.clone(), start: elt_size.next, end: end }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
|
||||
let mut pos = d.start;
|
||||
while pos < d.end {
|
||||
let elt_tag = vuint_at(*d.data, pos);
|
||||
let elt_size = vuint_at(*d.data, elt_tag.next);
|
||||
let elt_tag = vuint_at(d.data.as_slice(), pos);
|
||||
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
|
||||
pos = elt_size.next + elt_size.val;
|
||||
if elt_tag.val == tg {
|
||||
return Some(Doc { data: d.data, start: elt_size.next,
|
||||
@ -225,8 +264,8 @@ pub mod reader {
|
||||
pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
|
||||
let mut pos = d.start;
|
||||
while pos < d.end {
|
||||
let elt_tag = vuint_at(*d.data, pos);
|
||||
let elt_size = vuint_at(*d.data, elt_tag.next);
|
||||
let elt_tag = vuint_at(d.data.as_slice(), pos);
|
||||
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
|
||||
pos = elt_size.next + elt_size.val;
|
||||
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
|
||||
if !it(elt_tag.val, doc) {
|
||||
@ -239,8 +278,8 @@ pub mod reader {
|
||||
pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
|
||||
let mut pos = d.start;
|
||||
while pos < d.end {
|
||||
let elt_tag = vuint_at(*d.data, pos);
|
||||
let elt_size = vuint_at(*d.data, elt_tag.next);
|
||||
let elt_tag = vuint_at(d.data.as_slice(), pos);
|
||||
let elt_size = vuint_at(d.data.as_slice(), elt_tag.next);
|
||||
pos = elt_size.next + elt_size.val;
|
||||
if elt_tag.val == tg {
|
||||
let doc = Doc { data: d.data, start: elt_size.next,
|
||||
@ -260,22 +299,22 @@ pub mod reader {
|
||||
|
||||
pub fn doc_as_u8(d: Doc) -> u8 {
|
||||
assert_eq!(d.end, d.start + 1u);
|
||||
(*d.data)[d.start]
|
||||
d.data.as_slice()[d.start]
|
||||
}
|
||||
|
||||
pub fn doc_as_u16(d: Doc) -> u16 {
|
||||
assert_eq!(d.end, d.start + 2u);
|
||||
io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
|
||||
io::u64_from_be_bytes(d.data.as_slice(), d.start, 2u) as u16
|
||||
}
|
||||
|
||||
pub fn doc_as_u32(d: Doc) -> u32 {
|
||||
assert_eq!(d.end, d.start + 4u);
|
||||
io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
|
||||
io::u64_from_be_bytes(d.data.as_slice(), d.start, 4u) as u32
|
||||
}
|
||||
|
||||
pub fn doc_as_u64(d: Doc) -> u64 {
|
||||
assert_eq!(d.end, d.start + 8u);
|
||||
io::u64_from_be_bytes(*d.data, d.start, 8u)
|
||||
io::u64_from_be_bytes(d.data.as_slice(), d.start, 8u)
|
||||
}
|
||||
|
||||
pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
|
||||
@ -298,8 +337,7 @@ pub mod reader {
|
||||
impl Decoder {
|
||||
fn _check_label(&mut self, lbl: &str) {
|
||||
if self.pos < self.parent.end {
|
||||
let TaggedDoc { tag: r_tag, doc: r_doc } =
|
||||
doc_at(self.parent.data, self.pos);
|
||||
let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(&self.parent.data, self.pos);
|
||||
|
||||
if r_tag == (EsLabel as uint) {
|
||||
self.pos = r_doc.end;
|
||||
@ -316,8 +354,7 @@ pub mod reader {
|
||||
if self.pos >= self.parent.end {
|
||||
fail!("no more documents in current node!");
|
||||
}
|
||||
let TaggedDoc { tag: r_tag, doc: r_doc } =
|
||||
doc_at(self.parent.data, self.pos);
|
||||
let TaggedDoc { tag: r_tag, doc: r_doc } = doc_at(&self.parent.data, self.pos);
|
||||
debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
|
||||
self.parent.start,
|
||||
self.parent.end,
|
||||
|
@ -763,7 +763,7 @@ pub fn build_session_options(binary: @str,
|
||||
parse_only: parse_only,
|
||||
no_trans: no_trans,
|
||||
debugging_opts: debugging_opts,
|
||||
android_cross_path: android_cross_path
|
||||
android_cross_path: android_cross_path,
|
||||
};
|
||||
return sopts;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata::filesearch::FileSearch;
|
||||
use metadata::loader;
|
||||
use metadata::loader::MetadataSection;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use syntax::ast;
|
||||
@ -308,7 +309,7 @@ fn resolve_crate(e: @mut Env,
|
||||
}
|
||||
|
||||
// Go through the crate metadata and load any crates that it references
|
||||
fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
|
||||
fn resolve_crate_deps(e: @mut Env, cdata: MetadataSection) -> cstore::cnum_map {
|
||||
debug!("resolving deps of external crate");
|
||||
// The map from crate numbers in the crate we're resolving to local crate
|
||||
// numbers
|
||||
|
@ -188,7 +188,7 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
|
||||
def: ast::def_id) -> ty::ty_param_bounds_and_ty {
|
||||
let cstore = tcx.cstore;
|
||||
let cdata = cstore::get_crate_data(cstore, class_id.crate);
|
||||
let all_items = reader::get_doc(reader::Doc(cdata.data), tag_items);
|
||||
let all_items = reader::get_doc(decoder::section_to_ebml_doc(cdata.data), tag_items);
|
||||
debug!("Looking up %?", class_id);
|
||||
let class_doc = expect(tcx.diag,
|
||||
decoder::maybe_find_item(class_id.node, all_items),
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata::loader::MetadataSection;
|
||||
|
||||
use std::hashmap::HashMap;
|
||||
use extra;
|
||||
@ -29,7 +30,7 @@ pub type cnum_map = @mut HashMap<ast::CrateNum, ast::CrateNum>;
|
||||
|
||||
pub struct crate_metadata {
|
||||
name: @str,
|
||||
data: @~[u8],
|
||||
data: MetadataSection,
|
||||
cnum_map: cnum_map,
|
||||
cnum: ast::CrateNum
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use metadata::decoder;
|
||||
use metadata::tydecode::{parse_ty_data, parse_def_id,
|
||||
parse_type_param_def_data,
|
||||
parse_bare_fn_ty_data, parse_trait_ref_data};
|
||||
use metadata::loader::{MetadataSection, UnsafeSection};
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::astencode::vtable_decoder_helpers;
|
||||
@ -56,16 +57,16 @@ fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: u64) ->
|
||||
let index = reader::get_doc(d, tag_index);
|
||||
let table = reader::get_doc(index, tag_index_table);
|
||||
let hash_pos = table.start + (hash % 256 * 4) as uint;
|
||||
let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4) as uint;
|
||||
let tagged_doc = reader::doc_at(d.data, pos);
|
||||
let pos = io::u64_from_be_bytes(d.data.as_slice(), hash_pos, 4) as uint;
|
||||
let tagged_doc = reader::doc_at(&d.data, pos);
|
||||
|
||||
let belt = tag_index_buckets_bucket_elt;
|
||||
|
||||
let mut ret = None;
|
||||
do reader::tagged_docs(tagged_doc.doc, belt) |elt| {
|
||||
let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4) as uint;
|
||||
let pos = io::u64_from_be_bytes(elt.data.as_slice(), elt.start, 4) as uint;
|
||||
if eq_fn(elt.data.slice(elt.start + 4, elt.end)) {
|
||||
ret = Some(reader::doc_at(d.data, pos).doc);
|
||||
ret = Some(reader::doc_at(&d.data, pos).doc);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
@ -96,8 +97,8 @@ fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
|
||||
|
||||
// Looks up an item in the given metadata and returns an ebml doc pointing
|
||||
// to the item data.
|
||||
fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
||||
let items = reader::get_doc(reader::Doc(data), tag_items);
|
||||
fn lookup_item(item_id: int, data: MetadataSection) -> ebml::Doc {
|
||||
let items = reader::get_doc(section_to_ebml_doc(data), tag_items);
|
||||
find_item(item_id, items)
|
||||
}
|
||||
|
||||
@ -215,13 +216,13 @@ fn variant_disr_val(d: ebml::Doc) -> Option<uint> {
|
||||
|
||||
fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
|
||||
let tp = reader::get_doc(doc, tag_items_data_item_type);
|
||||
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
||||
parse_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|
||||
|_, did| translate_def_id(cdata, did))
|
||||
}
|
||||
|
||||
fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
|
||||
let tp = reader::get_doc(doc, tag_item_method_fty);
|
||||
parse_bare_fn_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
||||
parse_bare_fn_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|
||||
|_, did| translate_def_id(cdata, did))
|
||||
}
|
||||
|
||||
@ -230,7 +231,7 @@ fn doc_transformed_self_ty(doc: ebml::Doc,
|
||||
cdata: cmd) -> Option<ty::t>
|
||||
{
|
||||
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
|
||||
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
||||
parse_ty_data(tp.data.as_slice(), cdata.cnum, tp.start, tcx,
|
||||
|_, did| translate_def_id(cdata, did))
|
||||
}
|
||||
}
|
||||
@ -241,7 +242,7 @@ pub fn item_type(_item_id: ast::def_id, item: ebml::Doc,
|
||||
}
|
||||
|
||||
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
|
||||
parse_trait_ref_data(*doc.data, cdata.cnum, doc.start, tcx,
|
||||
parse_trait_ref_data(doc.data.as_slice(), cdata.cnum, doc.start, tcx,
|
||||
|_, did| translate_def_id(cdata, did))
|
||||
}
|
||||
|
||||
@ -256,7 +257,7 @@ fn item_ty_param_defs(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
|
||||
let mut bounds = ~[];
|
||||
do reader::tagged_docs(item, tag) |p| {
|
||||
let bd = parse_type_param_def_data(
|
||||
*p.data, p.start, cdata.cnum, tcx,
|
||||
p.data.as_slice(), p.start, cdata.cnum, tcx,
|
||||
|_, did| translate_def_id(cdata, did));
|
||||
bounds.push(bd);
|
||||
true
|
||||
@ -359,7 +360,7 @@ fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::CrateNum)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_def(cnum: ast::CrateNum, data: @~[u8], did_: ast::def_id) ->
|
||||
pub fn lookup_def(cnum: ast::CrateNum, data: MetadataSection, did_: ast::def_id) ->
|
||||
ast::def {
|
||||
let item = lookup_item(did_.node, data);
|
||||
let did = ast::def_id { crate: cnum, node: did_.node };
|
||||
@ -418,7 +419,7 @@ pub fn get_region_param(cdata: cmd, id: ast::NodeId)
|
||||
return item_ty_region_param(item);
|
||||
}
|
||||
|
||||
pub fn get_type_param_count(data: @~[u8], id: ast::NodeId) -> uint {
|
||||
pub fn get_type_param_count(data: MetadataSection, id: ast::NodeId) -> uint {
|
||||
item_ty_param_count(lookup_item(id, data))
|
||||
}
|
||||
|
||||
@ -449,7 +450,7 @@ pub fn get_impl_vtables(cdata: cmd,
|
||||
|
||||
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
|
||||
name: ast::ident) -> Option<ast::def_id> {
|
||||
let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
|
||||
let items = reader::get_doc(section_to_ebml_doc(cdata.data), tag_items);
|
||||
let mut found = None;
|
||||
do reader::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| {
|
||||
let m_did = reader::with_doc_data(mid, parse_def_id);
|
||||
@ -461,7 +462,7 @@ pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
|
||||
found
|
||||
}
|
||||
|
||||
pub fn get_symbol(data: @~[u8], id: ast::NodeId) -> ~str {
|
||||
pub fn get_symbol(data: MetadataSection, id: ast::NodeId) -> ~str {
|
||||
return item_symbol(lookup_item(id, data));
|
||||
}
|
||||
|
||||
@ -482,7 +483,7 @@ fn def_like_to_def(def_like: def_like) -> ast::def {
|
||||
|
||||
/// Iterates over the language items in the given crate.
|
||||
pub fn each_lang_item(cdata: cmd, f: &fn(ast::NodeId, uint) -> bool) -> bool {
|
||||
let root = reader::Doc(cdata.data);
|
||||
let root = section_to_ebml_doc(cdata.data);
|
||||
let lang_items = reader::get_doc(root, tag_lang_items);
|
||||
do reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| {
|
||||
let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
|
||||
@ -577,10 +578,10 @@ impl<'self> EachItemContext<'self> {
|
||||
fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool {
|
||||
// This item might not be in this crate. If it's not, look it up.
|
||||
let items = if def_id.crate == self.cdata.cnum {
|
||||
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
||||
reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
|
||||
} else {
|
||||
let crate_data = (self.get_crate_data)(def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
let root = section_to_ebml_doc(crate_data.data);
|
||||
reader::get_doc(root, tag_items)
|
||||
};
|
||||
|
||||
@ -606,10 +607,10 @@ impl<'self> EachItemContext<'self> {
|
||||
// a reexport.
|
||||
let other_crates_items = if child_def_id.crate ==
|
||||
self.cdata.cnum {
|
||||
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
||||
reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
|
||||
} else {
|
||||
let crate_data = (self.get_crate_data)(child_def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
let root = section_to_ebml_doc(crate_data.data);
|
||||
reader::get_doc(root, tag_items)
|
||||
};
|
||||
|
||||
@ -673,10 +674,10 @@ impl<'self> EachItemContext<'self> {
|
||||
|
||||
// This reexport may be in yet another crate.
|
||||
let other_crates_items = if def_id.crate == self.cdata.cnum {
|
||||
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
||||
reader::get_doc(section_to_ebml_doc(self.cdata.data), tag_items)
|
||||
} else {
|
||||
let crate_data = (self.get_crate_data)(def_id.crate);
|
||||
let root = reader::Doc(crate_data.data);
|
||||
let root = section_to_ebml_doc(crate_data.data);
|
||||
reader::get_doc(root, tag_items)
|
||||
};
|
||||
|
||||
@ -708,7 +709,7 @@ pub fn each_path(intr: @ident_interner,
|
||||
// make fast. It's the source of most of the performance problems when
|
||||
// compiling small crates.
|
||||
|
||||
let root_doc = reader::Doc(cdata.data);
|
||||
let root_doc = section_to_ebml_doc(cdata.data);
|
||||
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
||||
let crate_items_doc = reader::get_doc(misc_info_doc,
|
||||
tag_misc_info_crate_items);
|
||||
@ -768,7 +769,7 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
|
||||
pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::NodeId,
|
||||
tcx: ty::ctxt) -> ~[@ty::VariantInfo] {
|
||||
let data = cdata.data;
|
||||
let items = reader::get_doc(reader::Doc(data), tag_items);
|
||||
let items = reader::get_doc(section_to_ebml_doc(data), tag_items);
|
||||
let item = find_item(id, items);
|
||||
let mut infos: ~[@ty::VariantInfo] = ~[];
|
||||
let variant_ids = enum_variant_ids(item, cdata);
|
||||
@ -1206,8 +1207,14 @@ fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str,
|
||||
out.write_str("\n\n");
|
||||
}
|
||||
|
||||
pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::Attribute] {
|
||||
return get_attributes(reader::Doc(data));
|
||||
pub fn get_crate_attributes(data: MetadataSection) -> ~[ast::Attribute] {
|
||||
return get_attributes(section_to_ebml_doc(data));
|
||||
}
|
||||
|
||||
pub fn section_to_ebml_doc(data: MetadataSection) -> ebml::Doc {
|
||||
match data {
|
||||
UnsafeSection(_, buf, len) => reader::unsafe_Doc(buf, len)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
@ -1218,9 +1225,9 @@ pub struct crate_dep {
|
||||
hash: @str
|
||||
}
|
||||
|
||||
pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
|
||||
pub fn get_crate_deps(data: MetadataSection) -> ~[crate_dep] {
|
||||
let mut deps: ~[crate_dep] = ~[];
|
||||
let cratedoc = reader::Doc(data);
|
||||
let cratedoc = section_to_ebml_doc(data);
|
||||
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
|
||||
let mut crate_num = 1;
|
||||
fn docstr(doc: ebml::Doc, tag_: uint) -> @str {
|
||||
@ -1238,7 +1245,7 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
|
||||
return deps;
|
||||
}
|
||||
|
||||
fn list_crate_deps(data: @~[u8], out: @io::Writer) {
|
||||
fn list_crate_deps(data: MetadataSection, out: @io::Writer) {
|
||||
out.write_str("=External Dependencies=\n");
|
||||
|
||||
let r = get_crate_deps(data);
|
||||
@ -1251,13 +1258,13 @@ fn list_crate_deps(data: @~[u8], out: @io::Writer) {
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
pub fn get_crate_hash(data: @~[u8]) -> @str {
|
||||
let cratedoc = reader::Doc(data);
|
||||
pub fn get_crate_hash(data: MetadataSection) -> @str {
|
||||
let cratedoc = section_to_ebml_doc(data);
|
||||
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
|
||||
hashdoc.as_str_slice().to_managed()
|
||||
}
|
||||
|
||||
pub fn get_crate_vers(data: @~[u8]) -> @str {
|
||||
pub fn get_crate_vers(data: MetadataSection) -> @str {
|
||||
let attrs = decoder::get_crate_attributes(data);
|
||||
let linkage_attrs = attr::find_linkage_metas(attrs);
|
||||
|
||||
@ -1282,10 +1289,10 @@ fn iter_crate_items(intr: @ident_interner, cdata: cmd,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
|
||||
pub fn list_crate_metadata(intr: @ident_interner, bytes: MetadataSection,
|
||||
out: @io::Writer) {
|
||||
let hash = get_crate_hash(bytes);
|
||||
let md = reader::Doc(bytes);
|
||||
let md = section_to_ebml_doc(bytes);
|
||||
list_crate_attributes(intr, md, hash, out);
|
||||
list_crate_deps(bytes, out);
|
||||
}
|
||||
@ -1307,7 +1314,7 @@ pub fn translate_def_id(cdata: cmd, did: ast::def_id) -> ast::def_id {
|
||||
}
|
||||
|
||||
pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
|
||||
let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args);
|
||||
let link_args = reader::get_doc(section_to_ebml_doc(cdata.data), tag_link_args);
|
||||
let mut result = ~[];
|
||||
do reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| {
|
||||
result.push(arg_doc.as_str());
|
||||
|
@ -26,7 +26,6 @@ use std::hashmap::{HashMap, HashSet};
|
||||
use std::io;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use extra::flate;
|
||||
use extra::serialize::Encodable;
|
||||
use extra;
|
||||
use syntax::abi::AbiSet;
|
||||
@ -1570,7 +1569,7 @@ pub static metadata_encoding_version : &'static [u8] =
|
||||
0x75, //'u' as u8,
|
||||
0x73, //'s' as u8,
|
||||
0x74, //'t' as u8,
|
||||
0, 0, 0, 1 ];
|
||||
0, 0, 0, 2 ];
|
||||
|
||||
pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
||||
let wr = @io::BytesWriter::new();
|
||||
@ -1683,8 +1682,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
||||
|
||||
let writer_bytes: &mut ~[u8] = wr.bytes;
|
||||
|
||||
metadata_encoding_version.to_owned() +
|
||||
flate::deflate_bytes(*writer_bytes)
|
||||
return metadata_encoding_version.to_owned() + *writer_bytes;
|
||||
}
|
||||
|
||||
// Get the encoded string for a type
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Finds crate binaries and loads their metadata
|
||||
|
||||
|
||||
use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
|
||||
use lib::llvm::{False, llvm, mk_object_file, mk_section_iter, ObjectFile};
|
||||
use metadata::decoder;
|
||||
use metadata::encoder;
|
||||
use metadata::filesearch::FileSearch;
|
||||
@ -32,7 +32,6 @@ use std::os::consts::{macos, freebsd, linux, android, win32};
|
||||
use std::ptr;
|
||||
use std::str;
|
||||
use std::vec;
|
||||
use extra::flate;
|
||||
|
||||
pub enum os {
|
||||
os_macos,
|
||||
@ -54,7 +53,14 @@ pub struct Context {
|
||||
intr: @ident_interner
|
||||
}
|
||||
|
||||
pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
|
||||
#[deriving(Clone)]
|
||||
pub enum MetadataSection {
|
||||
// A pointer to the object file metadata section, along with
|
||||
// the ObjectFile handle that keeps it from being destructed
|
||||
UnsafeSection(@ObjectFile, *u8, uint)
|
||||
}
|
||||
|
||||
pub fn load_library_crate(cx: &Context) -> (~str, MetadataSection) {
|
||||
match find_library_crate(cx) {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
@ -65,7 +71,7 @@ pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_library_crate(cx: &Context) -> Option<(~str, @~[u8])> {
|
||||
fn find_library_crate(cx: &Context) -> Option<(~str, MetadataSection)> {
|
||||
attr::require_unique_names(cx.diag, cx.metas);
|
||||
find_library_crate_aux(cx, libname(cx), cx.filesearch)
|
||||
}
|
||||
@ -87,7 +93,7 @@ fn find_library_crate_aux(
|
||||
cx: &Context,
|
||||
(prefix, suffix): (~str, ~str),
|
||||
filesearch: @filesearch::FileSearch
|
||||
) -> Option<(~str, @~[u8])> {
|
||||
) -> Option<(~str, MetadataSection)> {
|
||||
let crate_name = crate_name_from_metas(cx.metas);
|
||||
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||
let prefix = fmt!("%s%s-", prefix, crate_name);
|
||||
@ -171,7 +177,7 @@ pub fn note_linkage_attrs(intr: @ident_interner,
|
||||
}
|
||||
}
|
||||
|
||||
fn crate_matches(crate_data: @~[u8],
|
||||
fn crate_matches(crate_data: MetadataSection,
|
||||
metas: &[@ast::MetaItem],
|
||||
hash: @str) -> bool {
|
||||
let attrs = decoder::get_crate_attributes(crate_data);
|
||||
@ -197,17 +203,17 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
|
||||
}
|
||||
|
||||
fn get_metadata_section(os: os,
|
||||
filename: &Path) -> Option<@~[u8]> {
|
||||
filename: &Path) -> Option<MetadataSection> {
|
||||
unsafe {
|
||||
let mb = do filename.with_c_str |buf| {
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
};
|
||||
if mb as int == 0 { return option::None::<@~[u8]>; }
|
||||
let of = match mk_object_file(mb) {
|
||||
if mb as int == 0 { return None; }
|
||||
let of = @match mk_object_file(mb) {
|
||||
option::Some(of) => of,
|
||||
_ => return option::None::<@~[u8]>
|
||||
_ => return None
|
||||
};
|
||||
let si = mk_section_iter(of.llof);
|
||||
let si = mk_section_iter((*of).llof);
|
||||
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
|
||||
let name_buf = llvm::LLVMGetSectionName(si.llsi);
|
||||
let name = str::raw::from_c_str(name_buf);
|
||||
@ -215,7 +221,6 @@ fn get_metadata_section(os: os,
|
||||
if name == read_meta_section_name(os) {
|
||||
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
||||
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
|
||||
let mut found = None;
|
||||
let cvbuf: *u8 = cast::transmute(cbuf);
|
||||
let vlen = encoder::metadata_encoding_version.len();
|
||||
debug!("checking %u bytes of metadata-version stamp",
|
||||
@ -229,19 +234,12 @@ fn get_metadata_section(os: os,
|
||||
if !version_ok { return None; }
|
||||
|
||||
let cvbuf1 = ptr::offset(cvbuf, vlen as int);
|
||||
debug!("inflating %u bytes of compressed metadata",
|
||||
csz - vlen);
|
||||
do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| {
|
||||
let inflated = flate::inflate_bytes(bytes);
|
||||
found = Some(@(inflated));
|
||||
}
|
||||
if found != None {
|
||||
return found;
|
||||
}
|
||||
|
||||
return Some(UnsafeSection(of, cvbuf1, csz-vlen))
|
||||
}
|
||||
llvm::LLVMMoveToNextSection(si.llsi);
|
||||
}
|
||||
return option::None::<@~[u8]>;
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1022,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t {
|
||||
do self.read_opaque |_, doc| {
|
||||
tydecode::parse_ty_data(
|
||||
*doc.data,
|
||||
doc.data.as_slice(),
|
||||
cdata.cnum,
|
||||
doc.start,
|
||||
tcx,
|
||||
@ -1044,7 +1044,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
|
||||
|
||||
return do self.read_opaque |this, doc| {
|
||||
let ty = tydecode::parse_ty_data(
|
||||
*doc.data,
|
||||
doc.data.as_slice(),
|
||||
xcx.dcx.cdata.cnum,
|
||||
doc.start,
|
||||
xcx.dcx.tcx,
|
||||
@ -1060,7 +1060,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
|
||||
fn type_string(doc: ebml::Doc) -> ~str {
|
||||
let mut str = ~"";
|
||||
for i in range(doc.start, doc.end) {
|
||||
str.push_char(doc.data[i] as char);
|
||||
str.push_char(doc.data.as_slice()[i] as char);
|
||||
}
|
||||
str
|
||||
}
|
||||
@ -1074,7 +1074,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder {
|
||||
-> ty::TypeParameterDef {
|
||||
do self.read_opaque |this, doc| {
|
||||
tydecode::parse_type_param_def_data(
|
||||
*doc.data,
|
||||
doc.data.as_slice(),
|
||||
doc.start,
|
||||
xcx.dcx.cdata.cnum,
|
||||
xcx.dcx.tcx,
|
||||
|
Loading…
Reference in New Issue
Block a user