rustc: Eliminate metadata's dependency on trans

This commit is contained in:
Brian Anderson 2012-05-13 17:01:52 -07:00
parent ecf290d448
commit a2572fe77e
10 changed files with 123 additions and 68 deletions

View File

@ -1,3 +1,16 @@
export maps;
// Auxiliary maps of things to be encoded
type maps = {
mutbl_map: middle::borrowck::mutbl_map,
copy_map: middle::alias::copy_map,
last_uses: middle::last_use::last_uses,
impl_map: middle::resolve::impl_map,
method_map: middle::typeck::method_map,
vtable_map: middle::typeck::vtable_map,
spill_map: middle::last_use::spill_map
};
// Define the rustc API's that the metadata module has access to
// Over time we will reduce these dependencies and, once metadata has
// no dependencies on rustc it can move into its own crate.
@ -7,8 +20,6 @@ mod middle {
export ast_map;
import ty = middle_::ty;
export ty;
import trans = middle_::trans;
export trans;
import typeck = middle_::typeck;
export typeck;
import last_use = middle_::last_use;
@ -17,12 +28,18 @@ mod middle {
export freevars;
import resolve = middle_::resolve;
export resolve;
import borrowck = middle_::borrowck;
export borrowck;
import alias = middle_::alias;
export alias;
}
mod front {
}
mod back {
import link = back_::link;
export link;
}
mod driver {

View File

@ -17,7 +17,6 @@ import std::serialization::serializer_helpers;
import std::serialization::deserializer_helpers;
import std::prettyprint::serializer;
import std::smallintmap::map;
import middle::trans::common::maps;
import middle::{ty, typeck, last_use, ast_map};
import middle::typeck::{method_origin,
serialize_method_origin,
@ -657,7 +656,7 @@ impl helpers for ebml::ebml_deserializer {
impl helpers for @e::encode_ctxt {
fn ty_str_ctxt() -> @tyencode::ctxt {
@{ds: e::def_to_str,
tcx: self.ccx.tcx,
tcx: self.tcx,
reachable: encoder::reachable(self, _),
abbrevs: tyencode::ac_use_abbrevs(self.type_abbrevs)}
}
@ -721,8 +720,7 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt,
fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
ebml_w: ebml::writer,
id: ast::node_id) {
let ccx = ecx.ccx;
let tcx = ccx.tcx;
let tcx = ecx.tcx;
#debug["Encoding side tables for id %d", id];
@ -796,25 +794,25 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
// }
//}
option::iter(ccx.maps.mutbl_map.find(id)) {|_m|
option::iter(ecx.maps.mutbl_map.find(id)) {|_m|
ebml_w.tag(c::tag_table_mutbl) {||
ebml_w.id(id);
}
}
option::iter(ccx.maps.copy_map.find(id)) {|_m|
option::iter(ecx.maps.copy_map.find(id)) {|_m|
ebml_w.tag(c::tag_table_copy) {||
ebml_w.id(id);
}
}
option::iter(ccx.maps.spill_map.find(id)) {|_m|
option::iter(ecx.maps.spill_map.find(id)) {|_m|
ebml_w.tag(c::tag_table_spill) {||
ebml_w.id(id);
}
}
option::iter(ccx.maps.last_uses.find(id)) {|m|
option::iter(ecx.maps.last_uses.find(id)) {|m|
ebml_w.tag(c::tag_table_last_use) {||
ebml_w.id(id);
ebml_w.tag(c::tag_table_val) {||
@ -826,7 +824,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
// impl_map is not used except when emitting metadata,
// don't need to keep it.
option::iter(ccx.maps.method_map.find(id)) {|mo|
option::iter(ecx.maps.method_map.find(id)) {|mo|
ebml_w.tag(c::tag_table_method_map) {||
ebml_w.id(id);
ebml_w.tag(c::tag_table_val) {||
@ -835,7 +833,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
}
}
option::iter(ccx.maps.vtable_map.find(id)) {|dr|
option::iter(ecx.maps.vtable_map.find(id)) {|dr|
ebml_w.tag(c::tag_table_vtable_map) {||
ebml_w.id(id);
ebml_w.tag(c::tag_table_val) {||

View File

@ -131,4 +131,3 @@ fn hash_path(&&s: str) -> uint {
for str::each(s) {|ch| h = (h << 5u) + h ^ (ch as uint); }
ret h;
}

View File

@ -7,7 +7,6 @@ import middle::{ty, ast_map};
import option::{some, none};
import driver::session;
import driver::session::expect;
import middle::trans::common::maps;
import common::*;
import std::map::hashmap;

View File

@ -13,7 +13,6 @@ import tydecode::{parse_ty_data, parse_def_id, parse_bounds_data,
parse_ident};
import syntax::print::pprust;
import cmd=cstore::crate_metadata;
import middle::trans::common::maps;
import util::ppaux::ty_to_str;
import ebml::deserializer;

View File

@ -11,15 +11,17 @@ import syntax::print::pprust;
import syntax::{ast_util, visit};
import syntax::ast_util::local_def;
import common::*;
import middle::trans::common::crate_ctxt;
import middle::ty;
import middle::ty::node_id_to_type;
import middle::ast_map;
import syntax::attr;
import driver::session::session;
import std::serialization::serializer;
import std::ebml::serializer;
import middle::resolve;
import syntax::ast;
import driver::session::session;
export encode_parms;
export encode_metadata;
export encoded_ty;
export reachable;
@ -32,11 +34,31 @@ export encode_def_id;
type abbrev_map = map::hashmap<ty::t, tyencode::ty_abbrev>;
type encode_ctxt = {ccx: @crate_ctxt,
type_abbrevs: abbrev_map};
type encode_parms = {
tcx: ty::ctxt,
reachable: hashmap<ast::node_id, ()>,
exp_map: resolve::exp_map,
item_symbols: hashmap<ast::node_id, str>,
discrim_symbols: hashmap<ast::node_id, str>,
link_meta: back::link::link_meta,
cstore: cstore::cstore,
maps: maps
};
type encode_ctxt = {
tcx: ty::ctxt,
reachable: hashmap<ast::node_id, ()>,
exp_map: resolve::exp_map,
item_symbols: hashmap<ast::node_id, str>,
discrim_symbols: hashmap<ast::node_id, str>,
link_meta: back::link::link_meta,
cstore: cstore::cstore,
maps: maps,
type_abbrevs: abbrev_map
};
fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
ecx.ccx.reachable.contains_key(id)
ecx.reachable.contains_key(id)
}
// Path table encoding
@ -201,7 +223,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
fn encode_iface_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @iface_ref) {
ebml_w.start_tag(tag_impl_iface);
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, t.id));
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.id));
ebml_w.end_tag();
}
@ -218,8 +240,8 @@ fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
fn encode_reexport_paths(ebml_w: ebml::writer,
ecx: @encode_ctxt, &index: [entry<str>]) {
let tcx = ecx.ccx.tcx;
for ecx.ccx.exp_map.each {|exp_id, defs|
let tcx = ecx.tcx;
for ecx.exp_map.each {|exp_id, defs|
for defs.each {|def|
if !def.reexp { cont; }
let path = alt check tcx.items.get(exp_id) {
@ -247,12 +269,12 @@ fn def_to_str(did: def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
params: [ty_param]) {
let ty_str_ctxt = @{ds: def_to_str,
tcx: ecx.ccx.tcx,
tcx: ecx.tcx,
reachable: reachable(ecx, _),
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
for params.each {|param|
ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
let bs = ecx.ccx.tcx.ty_param_bounds.get(param.id);
let bs = ecx.tcx.ty_param_bounds.get(param.id);
tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
ebml_w.end_tag();
}
@ -267,7 +289,7 @@ fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
let ty_str_ctxt =
@{ds: def_to_str,
tcx: ecx.ccx.tcx,
tcx: ecx.tcx,
reachable: reachable(ecx, _),
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
@ -281,9 +303,9 @@ fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
ebml_w.start_tag(tag_items_data_item_symbol);
let sym = alt ecx.ccx.item_symbols.find(id) {
let sym = alt ecx.item_symbols.find(id) {
some(x) { x }
none { ecx.ccx.tcx.sess.bug(#fmt("encode_symbol: \
none { ecx.tcx.sess.bug(#fmt("encode_symbol: \
id not found %d", id)); }
};
ebml_w.writer.write(str::bytes(sym));
@ -292,7 +314,7 @@ fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
ebml_w.start_tag(tag_items_data_item_symbol);
ebml_w.writer.write(str::bytes(ecx.ccx.discrim_symbols.get(id)));
ebml_w.writer.write(str::bytes(ecx.discrim_symbols.get(id)));
ebml_w.end_tag();
}
@ -314,7 +336,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
ty_params: [ty_param]) {
let mut disr_val = 0;
let mut i = 0;
let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id});
let vi = ty::enum_variants(ecx.tcx, {crate: local_crate, node: id});
for variants.each {|variant|
*index += [{val: variant.node.id, pos: ebml_w.writer.tell()}];
ebml_w.start_tag(tag_items_data_item);
@ -323,7 +345,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_name(ebml_w, variant.node.name);
encode_parent_item(ebml_w, local_def(id));
encode_type(ecx, ebml_w,
node_id_to_type(ecx.ccx.tcx, variant.node.id));
node_id_to_type(ecx.tcx, variant.node.id));
if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
encode_symbol(ecx, ebml_w, variant.node.id);
}
@ -365,22 +387,22 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
encode_def_id(ebml_w, local_def(id));
encode_family(ebml_w, 'm');
encode_name(ebml_w, name);
alt ecx.ccx.maps.impl_map.get(id) {
alt ecx.maps.impl_map.get(id) {
list::cons(impls, @list::nil) {
for vec::each(*impls) {|i|
if ast_util::is_exported(i.ident, md) {
ebml_w.start_tag(tag_mod_impl);
/* If did stands for an iface
ref, we need to map it to its parent class */
alt ecx.ccx.tcx.items.get(i.did.node) {
alt ecx.tcx.items.get(i.did.node) {
ast_map::node_item(it@@{node: cl@item_class(*),_},_) {
ebml_w.wr_str(def_to_str(local_def(it.id)));
some(ty::lookup_item_type(ecx.ccx.tcx, i.did).ty)
some(ty::lookup_item_type(ecx.tcx, i.did).ty)
}
ast_map::node_item(@{node: item_impl(_,_,
some(ifce),_,_),_},_) {
ebml_w.wr_str(def_to_str(i.did));
some(ty::node_id_to_type(ecx.ccx.tcx, ifce.id))
some(ty::node_id_to_type(ecx.tcx, ifce.id))
}
_ {
ebml_w.wr_str(def_to_str(i.did)); none
@ -391,7 +413,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
} // for
} // list::cons alt
_ {
ecx.ccx.tcx.sess.bug(#fmt("encode_info_for_mod: empty impl_map \
ecx.tcx.sess.bug(#fmt("encode_info_for_mod: empty impl_map \
entry for %?", path));
}
}
@ -413,7 +435,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer,
global_index: @mut[entry<int>])
-> [entry<int>] {
let index = @mut [];
let tcx = ecx.ccx.tcx;
let tcx = ecx.tcx;
for items.each {|ci|
/* We encode both private and public fields -- need to include
private fields to get the offsets right */
@ -460,9 +482,9 @@ fn encode_info_for_fn(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_def_id(ebml_w, local_def(id));
encode_family(ebml_w, purity_fn_family(decl.purity));
encode_type_param_bounds(ebml_w, ecx, tps);
let its_ty = node_id_to_type(ecx.ccx.tcx, id);
let its_ty = node_id_to_type(ecx.tcx, id);
#debug("fn name = %s ty = %s", ident,
util::ppaux::ty_to_str(ecx.ccx.tcx, its_ty));
util::ppaux::ty_to_str(ecx.tcx, its_ty));
encode_type(ecx, ebml_w, its_ty);
encode_path(ebml_w, path, ast_map::path_name(ident));
alt item {
@ -485,7 +507,7 @@ fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_def_id(ebml_w, local_def(m.id));
encode_family(ebml_w, purity_fn_family(m.decl.purity));
encode_type_param_bounds(ebml_w, ecx, all_tps);
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, m.id));
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
encode_name(ebml_w, m.ident);
encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
if all_tps.len() > 0u || should_inline {
@ -519,7 +541,7 @@ fn should_inline(attrs: [attribute]) -> bool {
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
index: @mut [entry<int>], path: ast_map::path) {
let tcx = ecx.ccx.tcx;
let tcx = ecx.tcx;
let must_write =
alt item.node { item_enum(_, _, _) { true } _ { false } };
if !must_write && !reachable(ecx, item.id) { ret; }
@ -750,7 +772,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_def_id(ebml_w, local_def(nitem.id));
encode_family(ebml_w, purity_fn_family(fn_decl.purity));
encode_type_param_bounds(ebml_w, ecx, tps);
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
if abi == native_abi_rust_intrinsic {
astencode::encode_inlined_item(ecx, ebml_w, path,
ii_native(nitem));
@ -774,7 +796,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
visit_expr: {|_e, _cx, _v|},
visit_item: {|i, cx, v|
visit::visit_item(i, cx, v);
alt check ecx.ccx.tcx.items.get(i.id) {
alt check ecx.tcx.items.get(i.id) {
ast_map::node_item(_, pt) {
encode_info_for_item(ecx, ebml_w, i, index, *pt);
/* encode ctor, then encode items */
@ -798,7 +820,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
},
visit_native_item: {|ni, cx, v|
visit::visit_native_item(ni, cx, v);
alt check ecx.ccx.tcx.items.get(ni.id) {
alt check ecx.tcx.items.get(ni.id) {
ast_map::node_native_item(_, abi, pt) {
encode_info_for_native_item(ecx, ebml_w, ni, index, *pt, abi);
}
@ -915,13 +937,13 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> [attribute] {
fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) ->
attribute {
assert (ecx.ccx.link_meta.name != "");
assert (ecx.ccx.link_meta.vers != "");
assert (ecx.link_meta.name != "");
assert (ecx.link_meta.vers != "");
let name_item =
attr::mk_name_value_item_str("name", ecx.ccx.link_meta.name);
attr::mk_name_value_item_str("name", ecx.link_meta.name);
let vers_item =
attr::mk_name_value_item_str("vers", ecx.ccx.link_meta.vers);
attr::mk_name_value_item_str("vers", ecx.link_meta.vers);
let other_items =
{
@ -1018,19 +1040,29 @@ fn encode_hash(ebml_w: ebml::writer, hash: str) {
ebml_w.end_tag();
}
fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> [u8] {
let ecx = @{ccx: cx, type_abbrevs: ty::new_ty_hash()};
fn encode_metadata(parms: encode_parms, crate: @crate) -> [u8] {
let ecx: @encode_ctxt = @{
tcx: parms.tcx,
reachable: parms.reachable,
exp_map: parms.exp_map,
item_symbols: parms.item_symbols,
discrim_symbols: parms.discrim_symbols,
link_meta: parms.link_meta,
cstore: parms.cstore,
maps: parms.maps,
type_abbrevs: ty::new_ty_hash()
};
let buf = io::mem_buffer();
let buf_w = io::mem_buffer_writer(buf);
let ebml_w = ebml::writer(buf_w);
encode_hash(ebml_w, cx.link_meta.extras_hash);
encode_hash(ebml_w, ecx.link_meta.extras_hash);
let crate_attrs = synthesize_crate_attrs(ecx, crate);
encode_attributes(ebml_w, crate_attrs);
encode_crate_deps(ebml_w, cx.sess.cstore);
encode_crate_deps(ebml_w, ecx.cstore);
// Encode and index the paths.
ebml_w.start_tag(tag_paths);

View File

@ -38,7 +38,7 @@ import link::{mangle_internal_name_by_type_only,
mangle_internal_name_by_path,
mangle_internal_name_by_path_and_seq,
mangle_exported_name};
import metadata::{csearch, cstore};
import metadata::{csearch, cstore, encoder};
import util::ppaux::{ty_to_str, ty_to_short_str};
import common::*;
@ -4932,9 +4932,26 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
C_array(ccx.int_type, subcrates)]));
}
fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
-> encoder::encode_parms {
{
tcx: cx.tcx,
reachable: cx.reachable,
exp_map: cx.exp_map,
item_symbols: cx.item_symbols,
discrim_symbols: cx.discrim_symbols,
link_meta: cx.link_meta,
cstore: cx.sess.cstore,
maps: cx.maps,
}
}
fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
if !cx.sess.building_library { ret; }
let llmeta = C_bytes(metadata::encoder::encode_metadata(cx, crate));
let encode_parms = crate_ctxt_to_encode_parms(cx);
let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
let llconst = C_struct([llmeta]);
let mut llglobal = str::as_c_str("rust_metadata", {|buf|
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)
@ -4961,7 +4978,8 @@ fn write_abi_version(ccx: @crate_ctxt) {
}
fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
output: str, emap: resolve::exp_map, maps: maps)
output: str, emap: resolve::exp_map,
maps: metadata::maps)
-> (ModuleRef, link::link_meta) {
let sha = std::sha1::sha1();
let link_meta = link::build_link_meta(sess, *crate, output, sha);

View File

@ -17,7 +17,7 @@ import lib::llvm::{llvm, target_data, type_names, associate_type,
name_has_type};
import lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef};
import lib::llvm::{True, False, Bool};
import metadata::csearch;
import metadata::{csearch, encoder};
import ast_map::path;
type namegen = fn@(str) -> str;
@ -62,17 +62,6 @@ type stats =
resource BuilderRef_res(B: BuilderRef) { llvm::LLVMDisposeBuilder(B); }
// Misc. auxiliary maps used in the crate_ctxt
type maps = {
mutbl_map: middle::borrowck::mutbl_map,
copy_map: middle::alias::copy_map,
last_uses: middle::last_use::last_uses,
impl_map: middle::resolve::impl_map,
method_map: middle::typeck::method_map,
vtable_map: middle::typeck::vtable_map,
spill_map: last_use::spill_map
};
// Crate context. Every crate we compile has one of these.
type crate_ctxt = {
sess: session::session,
@ -110,7 +99,7 @@ type crate_ctxt = {
type_short_names: hashmap<ty::t, str>,
all_llvm_symbols: set<str>,
tcx: ty::ctxt,
maps: maps,
maps: metadata::maps,
stats: stats,
upcalls: @upcall::upcalls,
tydesc_type: TypeRef,

View File

@ -28,6 +28,7 @@ import util_ = util;
import lib_ = lib;
import driver_ = driver;
import middle_ = middle;
import back_ = back;
mod middle {
mod trans {

View File

@ -28,3 +28,6 @@ export attr;
import rustsyntax::ext;
export ext;
import rustsyntax::diagnostic;
export diagnostic;