Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support for older CrateMap versions #9809

Merged
merged 1 commit into from
Oct 11, 2013
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 10 additions & 170 deletions src/libstd/rt/crate_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,13 @@ use hashmap::HashSet;
use option::{Some, None, Option};
use vec::ImmutableVector;

/// Imports for old crate map versions
use cast::transmute;
use libc::c_char;
use ptr;
use str::raw::from_c_str;
use vec;

// Need to tell the linker on OS X to not barf on undefined symbols
// and instead look them up at runtime, which we need to resolve
// the crate_map properly.
#[cfg(target_os = "macos")]
#[link_args = "-undefined dynamic_lookup"]
extern {}

#[cfg(not(windows))]
extern {
#[weak_linkage]
#[link_name = "_rust_crate_map_toplevel"]
static CRATE_MAP: CrateMap<'static>;
}

/// structs for old crate map versions
pub struct ModEntryV0 {
name: *c_char,
log_level: *mut u32
}
pub struct CrateMapV0 {
entries: *ModEntryV0,
children: [*CrateMapV0, ..1]
}

pub struct CrateMapV1 {
version: i32,
entries: *ModEntryV0,
/// a dynamically sized struct, where all pointers to children are listed adjacent
/// to the struct, terminated with NULL
children: [*CrateMapV1, ..1]
}

pub struct ModEntry<'self> {
name: &'self str,
log_level: *mut u32
Expand All @@ -65,6 +33,12 @@ pub struct CrateMap<'self> {

#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
extern {
#[weak_linkage]
#[link_name = "_rust_crate_map_toplevel"]
static CRATE_MAP: CrateMap<'static>;
}

let ptr: (*CrateMap) = &'static CRATE_MAP;
if ptr.is_null() {
return None;
Expand All @@ -77,6 +51,7 @@ pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
#[fixed_stack_segment]
#[inline(never)]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
use cast::transmute;
use c_str::ToCStr;
use unstable::dynamic_lib::dl;

Expand All @@ -101,54 +76,23 @@ pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
fn version(crate_map: &CrateMap) -> i32 {
match crate_map.version {
2 => return 2,
1 => return 1,
_ => return 0
}
}

fn iter_module_map(mod_entries: &[ModEntry], f: &fn(&ModEntry)) {
for entry in mod_entries.iter() {
f(entry);
}
}

unsafe fn iter_module_map_v0(entries: *ModEntryV0, f: &fn(&ModEntry)) {
let mut curr = entries;
while !(*curr).name.is_null() {
let mod_entry = ModEntry { name: from_c_str((*curr).name), log_level: (*curr).log_level };
f(&mod_entry);
curr = curr.offset(1);
}
}

fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
visited: &mut HashSet<*CrateMap<'a>>) {
if visited.insert(crate_map as *CrateMap) {
match version(crate_map) {
2 => {
let (entries, children) = (crate_map.entries, crate_map.children);
iter_module_map(entries, |x| f(x));
for entry in entries.iter() {
f(entry);
}
for child in children.iter() {
do_iter_crate_map(*child, |x| f(x), visited);
}
},
// code for old crate map versions
1 => unsafe {
let v1: *CrateMapV1 = transmute(crate_map);
iter_module_map_v0((*v1).entries, |x| f(x));
let children = vec::raw::to_ptr((*v1).children);
do ptr::array_each(children) |child| {
do_iter_crate_map(transmute(child), |x| f(x), visited);
}
},
0 => unsafe {
let v0: *CrateMapV0 = transmute(crate_map);
iter_module_map_v0((*v0).entries, |x| f(x));
let children = vec::raw::to_ptr((*v0).children);
do ptr::array_each(children) |child| {
do_iter_crate_map(transmute(child), |x| f(x), visited);
}
},
_ => fail2!("invalid crate map version")
}
}
Expand Down Expand Up @@ -234,108 +178,4 @@ mod tests {
assert!(cnt == 4);
}
}


/// Tests for old crate map versions
#[test]
fn iter_crate_map_duplicates_v1() {
use c_str::ToCStr;
use cast::transmute;
use ptr;
use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
use vec;

struct CrateMapT3 {
version: i32,
entries: *ModEntryV0,
children: [*CrateMapV1, ..3]
}

unsafe {
let mod_name1 = "c::m1".to_c_str();
let mut level3: u32 = 3;

let entries: ~[ModEntryV0] = ~[
ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
];
let child_crate = CrateMapV1 {
version: 1,
entries: vec::raw::to_ptr(entries),
children: [ptr::null()]
};

let root_crate = CrateMapT3 {
version: 1,
entries: vec::raw::to_ptr([
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
]),
children: [&child_crate as *CrateMapV1, &child_crate as *CrateMapV1, ptr::null()]
};

let mut cnt = 0;
do iter_crate_map(transmute(&root_crate)) |entry| {
assert!(*(*entry).log_level == 3);
cnt += 1;
}
assert!(cnt == 1);
}
}

#[test]
fn iter_crate_map_follow_children_v1() {
use c_str::ToCStr;
use cast::transmute;
use ptr;
use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
use vec;

struct CrateMapT2 {
version: i32,
entries: *ModEntryV0,
children: [*CrateMapV1, ..2]
}

unsafe {
let mod_name1 = "c::m1".to_c_str();
let mod_name2 = "c::m2".to_c_str();
let mut level2: u32 = 2;
let mut level3: u32 = 3;
let child_crate2 = CrateMapV1 {
version: 1,
entries: vec::raw::to_ptr([
ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
ModEntryV0 { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
]),
children: [ptr::null()]
};

let child_crate1 = CrateMapT2 {
version: 1,
entries: vec::raw::to_ptr([
ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
]),
children: [&child_crate2 as *CrateMapV1, ptr::null()]
};

let child_crate1_ptr: *CrateMapV1 = transmute(&child_crate1);
let root_crate = CrateMapT2 {
version: 1,
entries: vec::raw::to_ptr([
ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
]),
children: [child_crate1_ptr, ptr::null()]
};

let mut cnt = 0;
do iter_crate_map(transmute(&root_crate)) |entry| {
assert!(*(*entry).log_level == cnt);
cnt += 1;
}
assert!(cnt == 4);
}
}
}