diff options
Diffstat (limited to 'src/librustc/metadata/encoder.rs')
| -rw-r--r-- | src/librustc/metadata/encoder.rs | 382 |
1 files changed, 251 insertions, 131 deletions
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5d5d7582b5f..77a8d1792db 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -10,25 +10,23 @@ // Metadata encoding -use core::prelude::*; use metadata::common::*; use metadata::cstore; use metadata::decoder; use metadata::tyencode; -use middle::trans::reachable; use middle::ty::node_id_to_type; use middle::ty; use middle; use util::ppaux::ty_to_str; -use core::hash::HashUtil; -use core::hashmap::HashMap; -use core::int; -use core::io; -use core::str; -use core::uint; -use core::vec; +use std::hash::HashUtil; +use std::hashmap::{HashMap, HashSet}; +use std::int; +use std::io; +use std::str; +use std::uint; +use std::vec; use extra::flate; use extra::serialize::Encodable; use extra; @@ -47,7 +45,7 @@ use syntax::parse::token; use syntax; use writer = extra::ebml::writer; -use core::cast; +use std::cast; // used by astencode: type abbrev_map = @mut HashMap<ty::t, tyencode::ty_abbrev>; @@ -60,13 +58,13 @@ pub type encode_inlined_item<'self> = &'self fn(ecx: &EncodeContext, pub struct EncodeParams<'self> { diag: @span_handler, tcx: ty::ctxt, - reachable: reachable::map, reexports2: middle::resolve::ExportMap2, item_symbols: &'self HashMap<ast::node_id, ~str>, discrim_symbols: &'self HashMap<ast::node_id, @str>, link_meta: &'self LinkMeta, cstore: @mut cstore::CStore, - encode_inlined_item: encode_inlined_item<'self> + encode_inlined_item: encode_inlined_item<'self>, + reachable: @mut HashSet<ast::node_id>, } struct Stats { @@ -75,6 +73,7 @@ struct Stats { dep_bytes: uint, lang_item_bytes: uint, link_args_bytes: uint, + misc_bytes: uint, item_bytes: uint, index_bytes: uint, zero_bytes: uint, @@ -87,14 +86,14 @@ pub struct EncodeContext<'self> { diag: @span_handler, tcx: ty::ctxt, stats: @mut Stats, - reachable: reachable::map, reexports2: middle::resolve::ExportMap2, item_symbols: &'self HashMap<ast::node_id, ~str>, discrim_symbols: &'self HashMap<ast::node_id, @str>, link_meta: &'self LinkMeta, cstore: &'self cstore::CStore, encode_inlined_item: encode_inlined_item<'self>, - type_abbrevs: abbrev_map + type_abbrevs: abbrev_map, + reachable: @mut HashSet<ast::node_id>, } pub fn reachable(ecx: &EncodeContext, id: node_id) -> bool { @@ -152,13 +151,12 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder, ecx: &EncodeContext, trait_ref: &ty::TraitRef, tag: uint) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; ebml_w.start_tag(tag); tyencode::enc_trait_ref(ebml_w.writer, ty_str_ctxt, trait_ref); @@ -180,14 +178,13 @@ fn encode_ty_type_param_defs(ebml_w: &mut writer::Encoder, ecx: &EncodeContext, params: @~[ty::TypeParameterDef], tag: uint) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; - for params.each |param| { + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; + for params.iter().advance |param| { ebml_w.start_tag(tag); tyencode::enc_type_param_def(ebml_w.writer, ty_str_ctxt, param); ebml_w.end_tag(); @@ -213,26 +210,24 @@ fn encode_variant_id(ebml_w: &mut writer::Encoder, vid: def_id) { pub fn write_type(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, typ: ty::t) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ); } pub fn write_vstore(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, vstore: ty::vstore) { - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore); } @@ -259,13 +254,12 @@ fn encode_method_fty(ecx: &EncodeContext, typ: &ty::BareFnTy) { ebml_w.start_tag(tag_item_method_fty); - let r = ecx.reachable; let ty_str_ctxt = @tyencode::ctxt { diag: ecx.diag, ds: def_to_str, tcx: ecx.tcx, - reachable: |a| r.contains(&a), - abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)}; + abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs) + }; tyencode::enc_bare_fn_ty(ebml_w.writer, ty_str_ctxt, typ); ebml_w.end_tag(); @@ -325,7 +319,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext, let mut i = 0; let vi = ty::enum_variants(ecx.tcx, ast::def_id { crate: local_crate, node: id }); - for variants.each |variant| { + for variants.iter().advance |variant| { index.push(entry {val: variant.node.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); @@ -373,7 +367,7 @@ fn encode_path(ecx: &EncodeContext, ebml_w.start_tag(tag_path); ebml_w.wr_tagged_u32(tag_path_len, (path.len() + 1) as u32); - for path.each |pe| { + for path.iter().advance |pe| { encode_path_elt(ecx, ebml_w, *pe); } encode_path_elt(ecx, ebml_w, name); @@ -403,8 +397,8 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext, -> bool { match ecx.tcx.base_impls.find(&exp.def_id) { Some(implementations) => { - for implementations.each |&base_impl| { - for base_impl.methods.each |&m| { + for implementations.iter().advance |&base_impl| { + for base_impl.methods.iter().advance |&m| { if m.explicit_self == ast::sty_static { encode_reexported_static_method(ecx, ebml_w, exp, m.did, m.ident); @@ -424,7 +418,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext, -> bool { match ecx.tcx.trait_methods_cache.find(&exp.def_id) { Some(methods) => { - for methods.each |&m| { + for methods.iter().advance |&m| { if m.explicit_self == ast::sty_static { encode_reexported_static_method(ecx, ebml_w, exp, m.def_id, m.ident); @@ -473,12 +467,77 @@ fn encode_reexported_static_methods(ecx: &EncodeContext, } } +/// Iterates through "auxiliary node IDs", which are node IDs that describe +/// top-level items that are sub-items of the given item. Specifically: +/// +/// * For enums, iterates through the node IDs of the variants. +/// +/// * For newtype structs, iterates through the node ID of the constructor. +fn each_auxiliary_node_id(item: @item, callback: &fn(node_id) -> bool) + -> bool { + let mut continue = true; + match item.node { + item_enum(ref enum_def, _) => { + for enum_def.variants.iter().advance |variant| { + continue = callback(variant.node.id); + if !continue { + break + } + } + } + item_struct(struct_def, _) => { + // If this is a newtype struct, return the constructor. + match struct_def.ctor_id { + Some(ctor_id) if struct_def.fields.len() > 0 && + struct_def.fields[0].node.kind == + ast::unnamed_field => { + continue = callback(ctor_id); + } + _ => {} + } + } + _ => {} + } + + continue +} + +fn encode_reexports(ecx: &EncodeContext, + ebml_w: &mut writer::Encoder, + id: node_id, + path: &[ast_map::path_elt]) { + debug!("(encoding info for module) encoding reexports for %d", id); + match ecx.reexports2.find(&id) { + Some(ref exports) => { + debug!("(encoding info for module) found reexports for %d", id); + for exports.iter().advance |exp| { + debug!("(encoding info for module) reexport '%s' for %d", + exp.name, id); + ebml_w.start_tag(tag_items_data_item_reexport); + ebml_w.start_tag(tag_items_data_item_reexport_def_id); + ebml_w.wr_str(def_to_str(exp.def_id)); + ebml_w.end_tag(); + ebml_w.start_tag(tag_items_data_item_reexport_name); + ebml_w.wr_str(exp.name); + ebml_w.end_tag(); + ebml_w.end_tag(); + encode_reexported_static_methods(ecx, ebml_w, path, exp); + } + } + None => { + debug!("(encoding info for module) found no reexports for %d", + id); + } + } +} + fn encode_info_for_mod(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, md: &_mod, id: node_id, path: &[ast_map::path_elt], - name: ident) { + name: ident, + vis: visibility) { ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(id)); encode_family(ebml_w, 'm'); @@ -486,7 +545,17 @@ fn encode_info_for_mod(ecx: &EncodeContext, debug!("(encoding info for module) encoding info for module ID %d", id); // Encode info about all the module children. - for md.items.each |item| { + for md.items.iter().advance |item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(item.id))); + ebml_w.end_tag(); + + for each_auxiliary_node_id(*item) |auxiliary_node_id| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id))); + ebml_w.end_tag(); + } + match item.node { item_impl(*) => { let (ident, did) = (item.ident, item.id); @@ -500,35 +569,16 @@ fn encode_info_for_mod(ecx: &EncodeContext, ebml_w.wr_str(def_to_str(local_def(did))); ebml_w.end_tag(); } - _ => {} // FIXME #4573: Encode these too. + _ => {} } } encode_path(ecx, ebml_w, path, ast_map::path_mod(name)); - // Encode the reexports of this module. - debug!("(encoding info for module) encoding reexports for %d", id); - match ecx.reexports2.find(&id) { - Some(ref exports) => { - debug!("(encoding info for module) found reexports for %d", id); - for exports.each |exp| { - debug!("(encoding info for module) reexport '%s' for %d", - exp.name, id); - ebml_w.start_tag(tag_items_data_item_reexport); - ebml_w.start_tag(tag_items_data_item_reexport_def_id); - ebml_w.wr_str(def_to_str(exp.def_id)); - ebml_w.end_tag(); - ebml_w.start_tag(tag_items_data_item_reexport_name); - ebml_w.wr_str(exp.name); - ebml_w.end_tag(); - ebml_w.end_tag(); - encode_reexported_static_methods(ecx, ebml_w, path, exp); - } - } - None => { - debug!("(encoding info for module) found no reexports for %d", - id); - } + // Encode the reexports of this module, if this module is public. + if vis == public { + debug!("(encoding info for module) encoding reexports for %d", id); + encode_reexports(ecx, ebml_w, id, path); } ebml_w.end_tag(); @@ -574,9 +624,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic ebml_w.writer.write(&[ '@' as u8 ]); encode_mutability(ebml_w, m); } - sty_uniq(m) => { + sty_uniq => { ebml_w.writer.write(&[ '~' as u8 ]); - encode_mutability(ebml_w, m); } } @@ -617,7 +666,7 @@ fn encode_info_for_struct(ecx: &EncodeContext, let tcx = ecx.tcx; /* We encode both private and public fields -- need to include private fields to get the offsets right */ - for fields.each |field| { + for fields.iter().advance |field| { let (nm, vis) = match field.node.kind { named_field(nm, vis) => (nm, vis), unnamed_field => (special_idents::unnamed_field, inherited) @@ -731,8 +780,8 @@ fn encode_info_for_method(ecx: &EncodeContext, } let mut combined_ty_params = opt_vec::Empty; - combined_ty_params.push_all(&owner_generics.ty_params); - combined_ty_params.push_all(&method_generics.ty_params); + for owner_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } + for method_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } let len = combined_ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &combined_ty_params); @@ -753,7 +802,6 @@ fn encode_info_for_method(ecx: &EncodeContext, fn purity_fn_family(p: purity) -> char { match p { unsafe_fn => 'u', - pure_fn => 'p', impure_fn => 'f', extern_fn => 'e' } @@ -762,7 +810,6 @@ fn purity_fn_family(p: purity) -> char { fn purity_static_method_family(p: purity) -> char { match p { unsafe_fn => 'U', - pure_fn => 'P', impure_fn => 'F', _ => fail!("extern fn can't be static") } @@ -782,13 +829,6 @@ fn encode_info_for_item(ecx: &EncodeContext, index: @mut ~[entry<int>], path: &[ast_map::path_elt]) { let tcx = ecx.tcx; - let must_write = - match item.node { - item_enum(_, _) | item_impl(*) | item_trait(*) | item_struct(*) | - item_mod(*) | item_foreign_mod(*) | item_const(*) => true, - _ => false - }; - if !must_write && !reachable(ecx, item.id) { return; } fn add_to_index_(item: @item, ebml_w: &writer::Encoder, index: @mut ~[entry<int>]) { @@ -800,13 +840,18 @@ fn encode_info_for_item(ecx: &EncodeContext, ecx.tcx.sess.codemap.span_to_str(item.span)); match item.node { - item_const(_, _) => { + item_static(_, m, _) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_family(ebml_w, 'c'); + if m == ast::m_mutbl { + encode_family(ebml_w, 'b'); + } else { + encode_family(ebml_w, 'c'); + } encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); + encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); ebml_w.end_tag(); @@ -819,6 +864,7 @@ fn encode_info_for_item(ecx: &EncodeContext, let tps_len = generics.ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); + encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); encode_attributes(ebml_w, item.attrs); if tps_len > 0u || should_inline(item.attrs) { @@ -830,15 +876,29 @@ fn encode_info_for_item(ecx: &EncodeContext, } item_mod(ref m) => { add_to_index(); - encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident); + encode_info_for_mod(ecx, + ebml_w, + m, + item.id, + path, + item.ident, + item.vis); } - item_foreign_mod(_) => { + item_foreign_mod(ref fm) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); encode_family(ebml_w, 'n'); encode_name(ecx, ebml_w, item.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); + + // Encode all the items in this module. + for fm.items.iter().advance |foreign_item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(foreign_item.id))); + ebml_w.end_tag(); + } + ebml_w.end_tag(); } item_ty(_, ref generics) => { @@ -862,7 +922,7 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_name(ecx, ebml_w, item.ident); - for (*enum_definition).variants.each |v| { + for (*enum_definition).variants.iter().advance |v| { encode_variant_id(ebml_w, local_def(v.node.id)); } (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item)); @@ -896,23 +956,6 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); - // If this is a tuple- or enum-like struct, encode the type of the - // constructor. - if struct_def.fields.len() > 0 && - struct_def.fields[0].node.kind == ast::unnamed_field { - let ctor_id = match struct_def.ctor_id { - Some(ctor_id) => ctor_id, - None => ecx.tcx.sess.bug("struct def didn't have ctor id"), - }; - - encode_info_for_struct_ctor(ecx, - ebml_w, - path, - item.ident, - ctor_id, - index); - } - encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); @@ -921,7 +964,7 @@ fn encode_info_for_item(ecx: &EncodeContext, /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - for struct_def.fields.each |f| { + for struct_def.fields.iter().advance |f| { match f.node.kind { named_field(ident, vis) => { ebml_w.start_tag(tag_item_field); @@ -942,6 +985,23 @@ fn encode_info_for_item(ecx: &EncodeContext, let bkts = create_index(idx); encode_index(ebml_w, bkts, write_int); ebml_w.end_tag(); + + // If this is a tuple- or enum-like struct, encode the type of the + // constructor. + if struct_def.fields.len() > 0 && + struct_def.fields[0].node.kind == ast::unnamed_field { + let ctor_id = match struct_def.ctor_id { + Some(ctor_id) => ctor_id, + None => ecx.tcx.sess.bug("struct def didn't have ctor id"), + }; + + encode_info_for_struct_ctor(ecx, + ebml_w, + path, + item.ident, + ctor_id, + index); + } } item_impl(ref generics, opt_trait, ty, ref methods) => { add_to_index(); @@ -954,13 +1014,14 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); match ty.node { - ast::ty_path(path, _) if path.idents.len() == 1 => { + ast::ty_path(path, bounds, _) if path.idents.len() == 1 => { + assert!(bounds.is_none()); encode_impl_type_basename(ecx, ebml_w, ast_util::path_to_ident(path)); } _ => {} } - for methods.each |m| { + for methods.iter().advance |m| { ebml_w.start_tag(tag_item_impl_method); let method_def_id = local_def(m.id); let s = def_to_str(method_def_id); @@ -976,9 +1037,9 @@ fn encode_info_for_item(ecx: &EncodeContext, // >:-< let mut impl_path = vec::append(~[], path); - impl_path += [ast_map::path_name(item.ident)]; + impl_path.push(ast_map::path_name(item.ident)); - for methods.each |m| { + for methods.iter().advance |m| { index.push(entry {val: m.id, pos: ebml_w.writer.tell()}); encode_info_for_method(ecx, ebml_w, @@ -1001,20 +1062,25 @@ fn encode_info_for_item(ecx: &EncodeContext, encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref); encode_name(ecx, ebml_w, item.ident); encode_attributes(ebml_w, item.attrs); - for ty::trait_method_def_ids(tcx, local_def(item.id)).each |&method_def_id| { + for ty::trait_method_def_ids(tcx, local_def(item.id)).iter().advance |&method_def_id| { ebml_w.start_tag(tag_item_trait_method); encode_def_id(ebml_w, method_def_id); ebml_w.end_tag(); + + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(method_def_id)); + ebml_w.end_tag(); } encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); - for super_traits.each |ast_trait_ref| { + for super_traits.iter().advance |ast_trait_ref| { let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id); encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref); } ebml_w.end_tag(); // Now output the method info for each method. - for ty::trait_method_def_ids(tcx, local_def(item.id)).eachi |i, &method_def_id| { + let r = ty::trait_method_def_ids(tcx, local_def(item.id)); + for r.iter().enumerate().advance |(i, &method_def_id)| { assert_eq!(method_def_id.crate, ast::local_crate); let method_ty = ty::method(tcx, method_def_id); @@ -1088,7 +1154,6 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, index: @mut ~[entry<int>], path: ast_map::path, abi: AbiSet) { - if !reachable(ecx, nitem.id) { return; } index.push(entry { val: nitem.id, pos: ebml_w.writer.tell() }); ebml_w.start_tag(tag_items_data_item); @@ -1098,6 +1163,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, encode_family(ebml_w, purity_fn_family(purity)); encode_type_param_bounds(ebml_w, ecx, &generics.ty_params); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); + encode_name(ecx, ebml_w, nitem.ident); if abi.is_intrinsic() { (ecx.encode_inlined_item)(ecx, ebml_w, path, ii_foreign(nitem)); } else { @@ -1105,11 +1171,16 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext, } encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident)); } - foreign_item_const(*) => { + foreign_item_static(_, mutbl) => { encode_def_id(ebml_w, local_def(nitem.id)); - encode_family(ebml_w, 'c'); + if mutbl { + encode_family(ebml_w, 'b'); + } else { + encode_family(ebml_w, 'c'); + } encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); + encode_name(ecx, ebml_w, nitem.ident); encode_path(ecx, ebml_w, path, ast_map::path_name(nitem.ident)); } } @@ -1123,9 +1194,13 @@ fn encode_info_for_items(ecx: &EncodeContext, let index = @mut ~[]; ebml_w.start_tag(tag_items_data); index.push(entry { val: crate_node_id, pos: ebml_w.writer.tell() }); - encode_info_for_mod(ecx, ebml_w, &crate.node.module, - crate_node_id, [], - syntax::parse::token::special_idents::invalid); + encode_info_for_mod(ecx, + ebml_w, + &crate.node.module, + crate_node_id, + [], + syntax::parse::token::special_idents::invalid, + public); let items = ecx.tcx.items; // See comment in `encode_side_tables_for_ii` in astencode @@ -1154,6 +1229,12 @@ fn encode_info_for_items(ecx: &EncodeContext, visit::visit_foreign_item(ni, (cx, v)); match items.get_copy(&ni.id) { ast_map::node_foreign_item(_, abi, _, pt) => { + debug!("writing foreign item %s::%s", + ast_map::path_to_str( + *pt, + token::get_ident_interner()), + token::ident_to_str(&ni.ident)); + let mut ebml_w = copy ebml_w; // See above let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) }; @@ -1182,13 +1263,13 @@ fn create_index<T:Copy + Hash + IterBytes>(index: ~[entry<T>]) -> ~[@~[entry<T>]] { let mut buckets: ~[@mut ~[entry<T>]] = ~[]; for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; - for index.each |elt| { + for index.iter().advance |elt| { let h = elt.val.hash() as uint; buckets[h % 256].push(copy *elt); } let mut buckets_frozen = ~[]; - for buckets.each |bucket| { + for buckets.iter().advance |bucket| { buckets_frozen.push(@/*bad*/copy **bucket); } return buckets_frozen; @@ -1201,10 +1282,10 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder, ebml_w.start_tag(tag_index); let mut bucket_locs: ~[uint] = ~[]; ebml_w.start_tag(tag_index_buckets); - for buckets.each |bucket| { + for buckets.iter().advance |bucket| { bucket_locs.push(ebml_w.writer.tell()); ebml_w.start_tag(tag_index_buckets_bucket); - for (**bucket).each |elt| { + for (**bucket).iter().advance |elt| { ebml_w.start_tag(tag_index_buckets_bucket_elt); assert!(elt.pos < 0xffff_ffff); writer.write_be_u32(elt.pos as u32); @@ -1215,7 +1296,7 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder, } ebml_w.end_tag(); ebml_w.start_tag(tag_index_table); - for bucket_locs.each |pos| { + for bucket_locs.iter().advance |pos| { assert!(*pos < 0xffff_ffff); writer.write_be_u32(*pos as u32); } @@ -1261,7 +1342,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { ebml_w.start_tag(tag_meta_item_name); ebml_w.writer.write(name.as_bytes()); ebml_w.end_tag(); - for items.each |inner_item| { + for items.iter().advance |inner_item| { encode_meta_item(ebml_w, *inner_item); } ebml_w.end_tag(); @@ -1271,7 +1352,7 @@ fn encode_meta_item(ebml_w: &mut writer::Encoder, mi: @meta_item) { fn encode_attributes(ebml_w: &mut writer::Encoder, attrs: &[attribute]) { ebml_w.start_tag(tag_attributes); - for attrs.each |attr| { + for attrs.iter().advance |attr| { ebml_w.start_tag(tag_attribute); encode_meta_item(ebml_w, attr.node.value); ebml_w.end_tag(); @@ -1313,7 +1394,7 @@ fn synthesize_crate_attrs(ecx: &EncodeContext, let mut attrs: ~[attribute] = ~[]; let mut found_link_attr = false; - for crate.node.attrs.each |attr| { + for crate.node.attrs.iter().advance |attr| { attrs.push( if "link" != attr::get_attr_name(attr) { copy *attr @@ -1355,13 +1436,12 @@ fn encode_crate_deps(ecx: &EncodeContext, // Sanity-check the crate numbers let mut expected_cnum = 1; - for deps.each |n| { + for deps.iter().advance |n| { assert_eq!(n.cnum, expected_cnum); expected_cnum += 1; } - // mut -> immutable hack for vec::map - deps.slice(0, deps.len()).to_owned() + deps } // We're just going to write a list of crate 'name-hash-version's, with @@ -1369,7 +1449,8 @@ fn encode_crate_deps(ecx: &EncodeContext, // FIXME (#2166): This is not nearly enough to support correct versioning // but is enough to get transitive crate dependencies working. ebml_w.start_tag(tag_crate_deps); - for get_ordered_deps(ecx, cstore).each |dep| { + let r = get_ordered_deps(ecx, cstore); + for r.iter().advance |dep| { encode_crate_dep(ecx, ebml_w, *dep); } ebml_w.end_tag(); @@ -1403,7 +1484,7 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.start_tag(tag_link_args); let link_args = cstore::get_used_link_args(ecx.cstore); - for link_args.each |link_arg| { + for link_args.iter().advance |link_arg| { ebml_w.start_tag(tag_link_args_arg); ebml_w.writer.write_str(link_arg.to_str()); ebml_w.end_tag(); @@ -1412,6 +1493,30 @@ fn encode_link_args(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) { ebml_w.end_tag(); } +fn encode_misc_info(ecx: &EncodeContext, + crate: &crate, + ebml_w: &mut writer::Encoder) { + ebml_w.start_tag(tag_misc_info); + ebml_w.start_tag(tag_misc_info_crate_items); + for crate.node.module.items.iter().advance |&item| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(item.id))); + ebml_w.end_tag(); + + for each_auxiliary_node_id(item) |auxiliary_node_id| { + ebml_w.start_tag(tag_mod_child); + ebml_w.wr_str(def_to_str(local_def(auxiliary_node_id))); + ebml_w.end_tag(); + } + } + + // Encode reexports for the root module. + encode_reexports(ecx, ebml_w, 0, []); + + ebml_w.end_tag(); + ebml_w.end_tag(); +} + fn encode_crate_dep(ecx: &EncodeContext, ebml_w: &mut writer::Encoder, dep: decoder::crate_dep) { @@ -1451,29 +1556,39 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { dep_bytes: 0, lang_item_bytes: 0, link_args_bytes: 0, + misc_bytes: 0, item_bytes: 0, index_bytes: 0, zero_bytes: 0, total_bytes: 0, n_inlines: 0 }; - let EncodeParams{item_symbols, diag, tcx, reachable, reexports2, - discrim_symbols, cstore, encode_inlined_item, - link_meta, _} = parms; + let EncodeParams { + item_symbols, + diag, + tcx, + reexports2, + discrim_symbols, + cstore, + encode_inlined_item, + link_meta, + reachable, + _ + } = parms; let type_abbrevs = @mut HashMap::new(); let stats = @mut stats; let ecx = EncodeContext { diag: diag, tcx: tcx, stats: stats, - reachable: reachable, reexports2: reexports2, item_symbols: item_symbols, discrim_symbols: discrim_symbols, link_meta: link_meta, cstore: cstore, encode_inlined_item: encode_inlined_item, - type_abbrevs: type_abbrevs + type_abbrevs: type_abbrevs, + reachable: reachable, }; let mut ebml_w = writer::Encoder(wr as @io::Writer); @@ -1499,6 +1614,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { encode_link_args(&ecx, &mut ebml_w); ecx.stats.link_args_bytes = *wr.pos - i; + // Encode miscellaneous info. + i = *wr.pos; + encode_misc_info(&ecx, crate, &mut ebml_w); + ecx.stats.misc_bytes = *wr.pos - i; + // Encode and index the items. ebml_w.start_tag(tag_items); i = *wr.pos; @@ -1514,7 +1634,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { ecx.stats.total_bytes = *wr.pos; if (tcx.sess.meta_stats()) { - for wr.bytes.each |e| { + for wr.bytes.iter().advance |e| { if *e == 0 { ecx.stats.zero_bytes += 1; } @@ -1526,6 +1646,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { io::println(fmt!(" dep bytes: %u", ecx.stats.dep_bytes)); io::println(fmt!(" lang item bytes: %u", ecx.stats.lang_item_bytes)); io::println(fmt!(" link args bytes: %u", ecx.stats.link_args_bytes)); + io::println(fmt!(" misc bytes: %u", ecx.stats.misc_bytes)); io::println(fmt!(" item bytes: %u", ecx.stats.item_bytes)); io::println(fmt!(" index bytes: %u", ecx.stats.index_bytes)); io::println(fmt!(" zero bytes: %u", ecx.stats.zero_bytes)); @@ -1548,7 +1669,6 @@ pub fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> ~str { diag: tcx.diag, ds: def_to_str, tcx: tcx, - reachable: |_id| false, abbrevs: tyencode::ac_no_abbrevs}; do io::with_str_writer |wr| { tyencode::enc_ty(wr, cx, t); |
