From 5aa5220f8a3fc3ec0c58dede9f4c14be4a3752af Mon Sep 17 00:00:00 2001 From: Haitao Li Date: Sun, 8 Apr 2012 01:59:37 +0800 Subject: [PATCH] Encode crate dependencies' hash and version data --- src/rustc/metadata/common.rs | 4 +++ src/rustc/metadata/cstore.rs | 4 +-- src/rustc/metadata/decoder.rs | 25 +++++++++++++++--- src/rustc/metadata/encoder.rs | 50 ++++++++++++++++++++++------------- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs index 4d534efea35..b74d1149d76 100644 --- a/src/rustc/metadata/common.rs +++ b/src/rustc/metadata/common.rs @@ -64,6 +64,10 @@ const tag_parent_item: uint = 0x29u; +const tag_crate_dep_name: uint = 0x2au; +const tag_crate_dep_hash: uint = 0x2bu; +const tag_crate_dep_vers: uint = 0x2cu; + const tag_mod_impl: uint = 0x30u; const tag_item_method: uint = 0x31u; diff --git a/src/rustc/metadata/cstore.rs b/src/rustc/metadata/cstore.rs index fd7f82a7bc7..370d09e0017 100644 --- a/src/rustc/metadata/cstore.rs +++ b/src/rustc/metadata/cstore.rs @@ -88,9 +88,7 @@ fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> str { 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")); + ret decoder::get_crate_vers(cdata.data); } fn set_crate_data(cstore: cstore, cnum: ast::crate_num, diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index c40e8d8f609..015f9d27258 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -33,6 +33,7 @@ export crate_dep; export get_crate_deps; export get_crate_hash; +export get_crate_vers; export get_impls_for_mod; export get_iface_methods; export get_crate_module_paths; @@ -579,16 +580,22 @@ fn get_crate_attributes(data: @[u8]) -> [ast::attribute] { ret get_attributes(ebml::doc(data)); } -type crate_dep = {cnum: ast::crate_num, ident: str}; +type crate_dep = {cnum: ast::crate_num, name: ast::ident, + vers: str, hash: str}; fn get_crate_deps(data: @[u8]) -> [crate_dep] { let mut deps: [crate_dep] = []; let cratedoc = ebml::doc(data); let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps); let mut crate_num = 1; + fn docstr(doc: ebml::doc, tag_: uint) -> str { + str::from_bytes(ebml::doc_data(ebml::get_doc(doc, tag_))) + } ebml::tagged_docs(depsdoc, tag_crate_dep) {|depdoc| - let depname = str::from_bytes(ebml::doc_data(depdoc)); - deps += [{cnum: crate_num, ident: depname}]; + deps += [{cnum: crate_num, + name: docstr(depdoc, tag_crate_dep_name), + vers: docstr(depdoc, tag_crate_dep_vers), + hash: docstr(depdoc, tag_crate_dep_hash)}]; crate_num += 1; }; ret deps; @@ -598,7 +605,8 @@ fn list_crate_deps(data: @[u8], out: io::writer) { out.write_str("=External Dependencies=\n"); for get_crate_deps(data).each {|dep| - out.write_str(#fmt["%d %s\n", dep.cnum, dep.ident]); + out.write_str(#fmt["%d %s-%s-%s\n", + dep.cnum, dep.name, dep.hash, dep.vers]); } out.write_str("\n"); @@ -610,6 +618,15 @@ fn get_crate_hash(data: @[u8]) -> str { ret str::from_bytes(ebml::doc_data(hashdoc)); } +fn get_crate_vers(data: @[u8]) -> str { + let attrs = decoder::get_crate_attributes(data); + ret alt attr::meta_item_value_from_list( + attr::find_linkage_metas(attrs), "vers") { + some(ver) { ver } + none { "0.0" } + }; +} + fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) { out.write_str("=Items=\n"); let items = ebml::get_doc(md, tag_items); diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 5a8f26c6d8d..197f8be6f02 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -907,47 +907,59 @@ fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) -> fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) { - fn get_ordered_names(cstore: cstore::cstore) -> [str] { + fn get_ordered_deps(cstore: cstore::cstore) -> [decoder::crate_dep] { type hashkv = @{key: crate_num, val: cstore::crate_metadata}; - type numname = {crate: crate_num, ident: str}; + type numdep = decoder::crate_dep; - // Pull the cnums and names out of cstore - let mut pairs: [mut numname] = [mut]; + // Pull the cnums and name,vers,hash out of cstore + let mut deps: [mut numdep] = [mut]; cstore::iter_crate_data(cstore) {|key, val| - pairs += [mut {crate: key, ident: val.name}]; + let dep = {cnum: key, name: val.name, + vers: decoder::get_crate_vers(val.data), + hash: decoder::get_crate_hash(val.data)}; + deps += [mut dep]; }; // Sort by cnum - fn lteq(kv1: numname, kv2: numname) -> bool { kv1.crate <= kv2.crate } - std::sort::quick_sort(lteq, pairs); + fn lteq(kv1: numdep, kv2: numdep) -> bool { kv1.cnum <= kv2.cnum } + std::sort::quick_sort(lteq, deps); // Sanity-check the crate numbers let mut expected_cnum = 1; - for pairs.each {|n| - assert (n.crate == expected_cnum); + for deps.each {|n| + assert (n.cnum == expected_cnum); expected_cnum += 1; } - // Return just the names - fn name(kv: numname) -> str { kv.ident } // mut -> immutable hack for vec::map - let immpairs = vec::slice(pairs, 0u, vec::len(pairs)); - ret vec::map(immpairs, name); + ret vec::slice(deps, 0u, vec::len(deps)); } - // We're just going to write a list of crate names, with the assumption - // that they are numbered 1 to n. + // We're just going to write a list of crate 'name-hash-version's, with + // the assumption that they are numbered 1 to n. // FIXME: 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_names(cstore).each {|cname| - ebml_w.start_tag(tag_crate_dep); - ebml_w.writer.write(str::bytes(cname)); - ebml_w.end_tag(); + for get_ordered_deps(cstore).each {|dep| + encode_crate_dep(ebml_w, dep); } ebml_w.end_tag(); } +fn encode_crate_dep(ebml_w: ebml::writer, dep: decoder::crate_dep) { + ebml_w.start_tag(tag_crate_dep); + ebml_w.start_tag(tag_crate_dep_name); + ebml_w.writer.write(str::bytes(dep.name)); + ebml_w.end_tag(); + ebml_w.start_tag(tag_crate_dep_vers); + ebml_w.writer.write(str::bytes(dep.vers)); + ebml_w.end_tag(); + ebml_w.start_tag(tag_crate_dep_hash); + ebml_w.writer.write(str::bytes(dep.hash)); + ebml_w.end_tag(); + ebml_w.end_tag(); +} + fn encode_hash(ebml_w: ebml::writer, hash: str) { ebml_w.start_tag(tag_crate_hash); ebml_w.writer.write(str::bytes(hash)); -- GitLab