Skip to content

Commit

Permalink
Use version and hash in crate_map name
Browse files Browse the repository at this point in the history
Related issue #2137
  • Loading branch information
lht committed Apr 7, 2012
1 parent 13686b6 commit 2f42b14
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 6 deletions.
16 changes: 15 additions & 1 deletion src/rustc/metadata/cstore.rs
Expand Up @@ -3,7 +3,7 @@

import std::map;
import std::map::hashmap;
import syntax::ast;
import syntax::{ast, attr};
import util::common::*;

export cstore::{};
Expand All @@ -12,6 +12,8 @@ export crate_metadata;
export mk_cstore;
export get_crate_data;
export set_crate_data;
export get_crate_hash;
export get_crate_vers;
export have_crate_data;
export iter_crate_data;
export add_used_crate_file;
Expand Down Expand Up @@ -79,6 +81,18 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
ret p(cstore).metas.get(cnum);
}

fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> str {
let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_hash(cdata.data);
}

fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> str {
let cdata = get_crate_data(cstore, cnum);
let attrs = decoder::get_crate_attributes(cdata.data);
ret option::get(attr::meta_item_value_from_list(
attr::find_linkage_metas(attrs), "vers"));
}

fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
data: crate_metadata) {
p(cstore).metas.insert(cnum, data);
Expand Down
14 changes: 9 additions & 5 deletions src/rustc/middle/trans/base.rs
Expand Up @@ -4748,14 +4748,16 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
}


fn decl_crate_map(sess: session::session, mapname: str,
fn decl_crate_map(sess: session::session, mapmeta: link::link_meta,
llmod: ModuleRef) -> ValueRef {
let targ_cfg = sess.targ_cfg;
let int_type = T_int(targ_cfg);
let mut n_subcrates = 1;
let cstore = sess.cstore;
while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
let mapname = if sess.building_library { mapname } else { "toplevel" };
let mapname = if sess.building_library {
mapmeta.name + "_" + mapmeta.vers + "_" + mapmeta.extras_hash
} else { "toplevel" };
let sym_name = "_rust_crate_map_" + mapname;
let arrtype = T_array(int_type, n_subcrates as uint);
let maptype = T_struct([int_type, arrtype]);
Expand All @@ -4766,13 +4768,15 @@ fn decl_crate_map(sess: session::session, mapname: str,
ret map;
}

// FIXME use hashed metadata instead of crate names once we have that
fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
let mut subcrates: [ValueRef] = [];
let mut i = 1;
let cstore = ccx.sess.cstore;
while cstore::have_crate_data(cstore, i) {
let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name;
let cdata = cstore::get_crate_data(cstore, i);
let nm = "_rust_crate_map_" + cdata.name +
"_" + cstore::get_crate_vers(cstore, i) +
"_" + cstore::get_crate_hash(cstore, i);
let cr = str::as_c_str(nm, {|buf|
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
});
Expand Down Expand Up @@ -4857,7 +4861,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
lib::llvm::associate_type(tn, "taskptr", taskptr_type);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, "tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta.name, llmod);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
option::some(debuginfo::mk_ctxt(llmod_id))
} else {
Expand Down
6 changes: 6 additions & 0 deletions src/test/auxiliary/crateresolve3-1.rs
@@ -0,0 +1,6 @@
#[link(name = "crateresolve3",
vers = "0.1")];

#[crate_type = "lib"];

fn f() -> int { 10 }
6 changes: 6 additions & 0 deletions src/test/auxiliary/crateresolve3-2.rs
@@ -0,0 +1,6 @@
#[link(name = "crateresolve3",
vers = "0.2")];

#[crate_type = "lib"];

fn g() -> int { 20 }
21 changes: 21 additions & 0 deletions src/test/run-pass/crateresolve3.rs
@@ -0,0 +1,21 @@
// xfail-fast
// aux-build:crateresolve3-1.rs
// aux-build:crateresolve3-2.rs

// verify able to link with crates with same name but different versions
// as long as no name collision on invoked functions.

mod a {
use crateresolve3(vers = "0.1");
fn f() { assert crateresolve3::f() == 10; }
}

mod b {
use crateresolve3(vers = "0.2");
fn f() { assert crateresolve3::g() == 20; }
}

fn main() {
a::f();
b::f();
}

1 comment on commit 2f42b14

@brson
Copy link
Contributor

@brson brson commented on 2f42b14 Apr 7, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

Please sign in to comment.