forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove support for older CrateMap versions
- Loading branch information
Showing
1 changed file
with
10 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 {} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
alexcrichton
|
||
|
||
#[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 | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
||
|
@@ -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") | ||
} | ||
} | ||
|
@@ -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); | ||
} | ||
} | ||
} |
1 comment
on commit f3b1f79
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r+
You could probably also add this to the non-windows path if we're grouping everything else together anyways.