diff --git a/src/rt/rust_crate_map.cpp b/src/rt/rust_crate_map.cpp index 633361bb932..9f6c18d9207 100644 --- a/src/rt/rust_crate_map.cpp +++ b/src/rt/rust_crate_map.cpp @@ -12,13 +12,13 @@ void iter_crate_map(const cratemap* map, void (*fn)(const mod_entry* map, void *cookie), void *cookie) { // First iterate this crate - iter_module_map(map->entries, fn, cookie); + iter_module_map(map->entries(), fn, cookie); // Then recurse on linked crates // FIXME (#2673) this does double work in diamond-shaped deps. could // keep a set of visited addresses, if it turns out to be actually // slow - for (size_t i = 0; map->children[i]; i++) { - iter_crate_map(map->children[i], fn, cookie); + for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) { + iter_crate_map(*i, fn, cookie); } } diff --git a/src/rt/rust_crate_map.h b/src/rt/rust_crate_map.h index 453feb36e57..bdb0630a1af 100644 --- a/src/rt/rust_crate_map.h +++ b/src/rt/rust_crate_map.h @@ -2,15 +2,71 @@ #define RUST_CRATE_MAP_H #include "rust_log.h" +#include struct mod_entry { const char* name; uint32_t* state; }; -struct cratemap { - const mod_entry* entries; - const cratemap* children[1]; +class cratemap; + +class cratemap_v0 { + friend class cratemap; + const mod_entry *m_entries; + const cratemap* m_children[1]; +}; + +class cratemap { +private: + int32_t m_version; + const void *m_annihilate_fn; + const mod_entry* m_entries; + const cratemap* m_children[1]; + + inline int32_t version() const { + switch (m_version) { + case 1: return 1; + default: return 0; + } + } + +public: + typedef const cratemap *const *iterator; + + inline const void *annihilate_fn() const { + switch (version()) { + case 0: return NULL; + case 1: return m_annihilate_fn; + default: assert(false && "Unknown crate map version!"); + } + } + + inline const mod_entry *entries() const { + switch (version()) { + case 0: return reinterpret_cast(this)->m_entries; + case 1: return m_entries; + default: assert(false && "Unknown crate map version!"); + } + } + + inline const iterator begin() const { + switch (version()) { + case 0: + return &reinterpret_cast(this)-> + m_children[0]; + case 1: + return &m_children[1]; + default: assert(false && "Unknown crate map version!"); + } + } + + inline const iterator end() const { + iterator i = begin(); + while (*i) + i++; + return i; + } }; void iter_module_map(const mod_entry* map, diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index 666183fcdd3..11671cf0326 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -236,11 +236,11 @@ void update_crate_map(const cratemap* map, log_directive* dirs, } void print_crate_log_map(const cratemap* map) { - for (const mod_entry* cur = map->entries; cur->name; cur++) { + for (const mod_entry* cur = map->entries(); cur->name; cur++) { printf(" %s\n", cur->name); } - for (size_t i = 0; map->children[i]; i++) { - print_crate_log_map(map->children[i]); + for (cratemap::iterator i = map->begin(), e = map->end(); i != e; ++i) { + print_crate_log_map(*i); } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 3cd80a6e572..aaed7d35343 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2478,7 +2478,7 @@ fn decl_crate_map(sess: session::session, mapmeta: link_meta, } 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]); + let maptype = T_struct(~[T_i32(), T_ptr(T_i8()), int_type, arrtype]); let map = str::as_c_str(sym_name, |buf| { llvm::LLVMAddGlobal(llmod, maptype, buf) }); @@ -2502,9 +2502,25 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { i += 1; } vec::push(subcrates, C_int(ccx, 0)); + + let llannihilatefn; + let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn.get(); + if annihilate_def_id.crate == ast::local_crate { + llannihilatefn = get_item_val(ccx, annihilate_def_id.node); + } else { + let annihilate_fn_type = csearch::get_type(ccx.tcx, + annihilate_def_id).ty; + llannihilatefn = trans_external_path(ccx, + annihilate_def_id, + annihilate_fn_type); + } + llvm::LLVMSetInitializer(map, C_struct( - ~[p2i(ccx, create_module_map(ccx)), - C_array(ccx.int_type, subcrates)])); + ~[C_i32(1), + lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, + T_ptr(T_i8())), + p2i(ccx, create_module_map(ccx)), + C_array(ccx.int_type, subcrates)])); } fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)