Skip to content

Commit b7b4f7a

Browse files
committed
Add code for older crate map versions, bumped crate map version number
1 parent 5dd1145 commit b7b4f7a

File tree

2 files changed

+172
-39
lines changed

2 files changed

+172
-39
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3008,7 +3008,7 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
30083008
let (mod_map, mod_count, mod_struct_size) = create_module_map(ccx);
30093009

30103010
llvm::LLVMSetInitializer(map, C_struct(
3011-
[C_i32(1),
3011+
[C_i32(2),
30123012
C_struct([
30133013
p2i(ccx, mod_map),
30143014
// byte size of the module map array, an entry consists of two integers

src/libstd/rt/crate_map.rs

Lines changed: 171 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[cfg(not(stage0))] use cast::transmute;
11+
//#[cfg(not(stage0))] use cast::transmute;
1212
use container::MutableSet;
1313
use hashmap::HashSet;
1414
use option::{Some, None};
1515
use vec::ImmutableVector;
1616

17+
/// Imports for old crate map versions
18+
use cast::transmute;
19+
use libc::c_char;
20+
use ptr;
21+
use str::raw::from_c_str;
22+
use vec;
23+
1724
// Need to tell the linker on OS X to not barf on undefined symbols
1825
// and instead look them up at runtime, which we need to resolve
1926
// the crate_map properly.
@@ -28,14 +35,27 @@ extern {
2835
static CRATE_MAP: CrateMap<'static>;
2936
}
3037

31-
pub struct ModEntry<'self> {
32-
name: &'self str,
38+
/// structs for old crate map versions
39+
pub struct ModEntryV0 {
40+
name: *c_char,
3341
log_level: *mut u32
3442
}
43+
pub struct CrateMapV0 {
44+
entries: *ModEntryV0,
45+
children: [*CrateMapV0, ..1]
46+
}
3547

36-
pub struct CrateMapV0<'self> {
37-
entries: &'self [ModEntry<'self>],
38-
children: &'self [&'self CrateMap<'self>]
48+
pub struct CrateMapV1 {
49+
version: i32,
50+
entries: *ModEntryV0,
51+
/// a dynamically sized struct, where all pointers to children are listed adjacent
52+
/// to the struct, terminated with NULL
53+
children: [*CrateMapV1, ..1]
54+
}
55+
56+
pub struct ModEntry<'self> {
57+
name: &'self str,
58+
log_level: *mut u32
3959
}
4060

4161
pub struct CrateMap<'self> {
@@ -46,6 +66,8 @@ pub struct CrateMap<'self> {
4666
children: &'self [&'self CrateMap<'self>]
4767
}
4868

69+
70+
4971
#[cfg(not(windows))]
5072
pub fn get_crate_map() -> &'static CrateMap<'static> {
5173
&'static CRATE_MAP
@@ -71,51 +93,60 @@ pub fn get_crate_map() -> &'static CrateMap<'static> {
7193

7294
fn version(crate_map: &CrateMap) -> i32 {
7395
match crate_map.version {
96+
2 => return 2,
7497
1 => return 1,
7598
_ => return 0
7699
}
77100
}
78101

79-
#[cfg(not(stage0))]
80-
fn get_entries_and_children<'a>(crate_map: &'a CrateMap<'a>) ->
81-
(&'a [ModEntry<'a>], &'a [&'a CrateMap<'a>]) {
82-
match version(crate_map) {
83-
0 => {
84-
unsafe {
85-
let v0: &'a CrateMapV0<'a> = transmute(crate_map);
86-
return (v0.entries, v0.children);
87-
}
88-
}
89-
1 => return (*crate_map).entries,
90-
_ => fail2!("Unknown crate map version!")
91-
}
92-
}
93-
94-
#[cfg(not(stage0))]
95102
fn iter_module_map(mod_entries: &[ModEntry], f: &fn(&ModEntry)) {
96103
for entry in mod_entries.iter() {
97104
f(entry);
98105
}
99106
}
100107

101-
#[cfg(not(stage0))]
108+
unsafe fn iter_module_map_v0(entries: *ModEntryV0, f: &fn(&ModEntry)) {
109+
let mut curr = entries;
110+
while !(*curr).name.is_null() {
111+
let mod_entry = ModEntry { name: from_c_str((*curr).name), log_level: (*curr).log_level };
112+
f(&mod_entry);
113+
curr = curr.offset(1);
114+
}
115+
}
116+
102117
fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
103118
visited: &mut HashSet<*CrateMap<'a>>) {
104119
if visited.insert(crate_map as *CrateMap) {
105-
let (entries, children) = get_entries_and_children(crate_map);
106-
iter_module_map(entries, |x| f(x));
107-
for child in children.iter() {
108-
do_iter_crate_map(*child, |x| f(x), visited);
120+
match version(crate_map) {
121+
2 => {
122+
let (entries, children) = (crate_map.entries, crate_map.children);
123+
iter_module_map(entries, |x| f(x));
124+
for child in children.iter() {
125+
do_iter_crate_map(*child, |x| f(x), visited);
126+
}
127+
},
128+
/// code for old crate map versions
129+
1 => unsafe {
130+
let v1: *CrateMapV1 = transmute(crate_map);
131+
iter_module_map_v0((*v1).entries, |x| f(x));
132+
let children = vec::raw::to_ptr((*v1).children);
133+
do ptr::array_each(children) |child| {
134+
do_iter_crate_map(transmute(child), |x| f(x), visited);
135+
}
136+
},
137+
0 => unsafe {
138+
let v0: *CrateMapV0 = transmute(crate_map);
139+
iter_module_map_v0((*v0).entries, |x| f(x));
140+
let children = vec::raw::to_ptr((*v0).children);
141+
do ptr::array_each(children) |child| {
142+
do_iter_crate_map(transmute(child), |x| f(x), visited);
143+
}
144+
},
145+
_ => fail2!("invalid crate map version")
109146
}
110147
}
111148
}
112149

113-
#[cfg(stage0)]
114-
/// Iterates recursively over `crate_map` and all child crate maps
115-
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
116-
}
117-
118-
#[cfg(not(stage0))]
119150
/// Iterates recursively over `crate_map` and all child crate maps
120151
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
121152
// XXX: use random numbers as keys from the OS-level RNG when there is a nice
@@ -137,13 +168,13 @@ mod tests {
137168
];
138169

139170
let child_crate = CrateMap {
140-
version: 1,
171+
version: 2,
141172
entries: entries,
142173
children: []
143174
};
144175

145176
let root_crate = CrateMap {
146-
version: 1,
177+
version: 2,
147178
entries: [],
148179
children: [&child_crate, &child_crate]
149180
};
@@ -163,7 +194,7 @@ mod tests {
163194
let mut level2: u32 = 2;
164195
let mut level3: u32 = 3;
165196
let child_crate2 = CrateMap {
166-
version: 1,
197+
version: 2,
167198
entries: [
168199
ModEntry { name: "c::m1", log_level: &mut level2},
169200
ModEntry { name: "c::m2", log_level: &mut level3},
@@ -172,15 +203,15 @@ mod tests {
172203
};
173204

174205
let child_crate1 = CrateMap {
175-
version: 1,
206+
version: 2,
176207
entries: [
177208
ModEntry { name: "t::f1", log_level: &mut 1},
178209
],
179210
children: [&child_crate2]
180211
};
181212

182213
let root_crate = CrateMap {
183-
version: 1,
214+
version: 2,
184215
entries: [
185216
ModEntry { name: "t::f2", log_level: &mut 0},
186217
],
@@ -196,4 +227,106 @@ mod tests {
196227
assert!(cnt == 4);
197228
}
198229
}
230+
231+
232+
/// Tests for old crate map versions
233+
#[test]
234+
fn iter_crate_map_duplicates_v1() {
235+
use c_str::ToCStr;
236+
use cast::transmute;
237+
use ptr;
238+
use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
239+
use vec;
240+
241+
struct CrateMapT3 {
242+
version: i32,
243+
entries: *ModEntryV0,
244+
children: [*CrateMapV1, ..3]
245+
}
246+
247+
unsafe {
248+
let mod_name1 = "c::m1".to_c_str();
249+
let mut level3: u32 = 3;
250+
251+
let entries: ~[ModEntryV0] = ~[
252+
ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
253+
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
254+
];
255+
let child_crate = CrateMapV1 {
256+
version: 1,
257+
entries: vec::raw::to_ptr(entries),
258+
children: [ptr::null()]
259+
};
260+
261+
let root_crate = CrateMapT3 {
262+
version: 1,
263+
entries: vec::raw::to_ptr([ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}]),
264+
children: [&child_crate as *CrateMapV1, &child_crate as *CrateMapV1, ptr::null()]
265+
};
266+
267+
let mut cnt = 0;
268+
do iter_crate_map(transmute(&root_crate)) |entry| {
269+
assert!(*(*entry).log_level == 3);
270+
cnt += 1;
271+
}
272+
assert!(cnt == 1);
273+
}
274+
}
275+
276+
#[test]
277+
fn iter_crate_map_follow_children_v1() {
278+
use c_str::ToCStr;
279+
use cast::transmute;
280+
use ptr;
281+
use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
282+
use vec;
283+
284+
struct CrateMapT2 {
285+
version: i32,
286+
entries: *ModEntryV0,
287+
children: [*CrateMapV1, ..2]
288+
}
289+
290+
unsafe {
291+
let mod_name1 = "c::m1".to_c_str();
292+
let mod_name2 = "c::m2".to_c_str();
293+
let mut level2: u32 = 2;
294+
let mut level3: u32 = 3;
295+
let child_crate2 = CrateMapV1 {
296+
version: 1,
297+
entries: vec::raw::to_ptr([
298+
ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
299+
ModEntryV0 { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
300+
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
301+
]),
302+
children: [ptr::null()]
303+
};
304+
305+
let child_crate1 = CrateMapT2 {
306+
version: 1,
307+
entries: vec::raw::to_ptr([
308+
ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
309+
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
310+
]),
311+
children: [&child_crate2 as *CrateMapV1, ptr::null()]
312+
};
313+
314+
let child_crate1_ptr: *CrateMapV1 = transmute(&child_crate1);
315+
let root_crate = CrateMapT2 {
316+
version: 1,
317+
entries: vec::raw::to_ptr([
318+
ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
319+
ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
320+
]),
321+
children: [child_crate1_ptr, ptr::null()]
322+
};
323+
324+
let mut cnt = 0;
325+
do iter_crate_map(transmute(&root_crate)) |entry| {
326+
assert!(*(*entry).log_level == cnt);
327+
cnt += 1;
328+
}
329+
assert!(cnt == 4);
330+
}
331+
}
199332
}

0 commit comments

Comments
 (0)