8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use cast:: transmute;
11
+ # [ cfg ( not ( stage0 ) ) ] use cast:: transmute;
12
12
use container:: MutableSet ;
13
13
use hashmap:: HashSet ;
14
14
use libc:: c_char;
15
+ use option:: { Some , None } ;
16
+ use vec:: ImmutableVector ;
15
17
16
18
// Need to tell the linker on OS X to not barf on undefined symbols
17
19
// and instead look them up at runtime, which we need to resolve
@@ -24,36 +26,36 @@ extern {}
24
26
extern {
25
27
#[ weak_linkage]
26
28
#[ link_name = "_rust_crate_map_toplevel" ]
27
- static CRATE_MAP : CrateMap ;
29
+ static CRATE_MAP : CrateMap < ' static > ;
28
30
}
29
31
30
32
pub struct ModEntry {
31
33
name : * c_char ,
32
34
log_level : * mut u32
33
35
}
34
36
35
- struct CrateMapV0 {
36
- entries : & static [ ModEntry ] ,
37
- children : & ' static [ & ' static CrateMap ]
37
+ pub struct CrateMapV0 < ' self > {
38
+ entries : & ' self [ ModEntry ] ,
39
+ children : & ' self [ & ' self CrateMap < ' self > ]
38
40
}
39
41
40
- struct CrateMap {
42
+ pub struct CrateMap < ' self > {
41
43
version : i32 ,
42
- entries : & static [ ModEntry ] ,
44
+ entries : & ' self [ ModEntry ] ,
43
45
/// a dynamically sized struct, where all pointers to children are listed adjacent
44
46
/// to the struct, terminated with NULL
45
- children: [ * CrateMap , .. 1 ]
47
+ children : & ' self [ & ' self CrateMap < ' self > ]
46
48
}
47
49
48
50
#[ cfg( not( windows) ) ]
49
- pub fn get_crate_map ( ) -> * CrateMap {
50
- & ' static CRATE_MAP as * CrateMap
51
+ pub fn get_crate_map( ) -> & ' static CrateMap < ' static > {
52
+ & ' static CRATE_MAP
51
53
}
52
54
53
55
#[ cfg( windows) ]
54
56
#[ fixed_stack_segment]
55
57
#[ inline( never) ]
56
- pub fn get_crate_map ( ) -> * CrateMap {
58
+ pub fn get_crate_map ( ) -> & ' static CrateMap < ' static > {
57
59
use c_str:: ToCStr ;
58
60
use unstable:: dynamic_lib:: dl;
59
61
@@ -65,24 +67,24 @@ pub fn get_crate_map() -> *CrateMap {
65
67
dl:: close ( module) ;
66
68
sym
67
69
} ;
68
-
69
- sym as * CrateMap
70
+ sym
70
71
}
71
72
72
- fn version ( crate_map : & ' static CrateMap ) -> i32 {
73
+ fn version ( crate_map : & CrateMap ) -> i32 {
73
74
match crate_map. version {
74
75
1 => return 1 ,
75
76
_ => return 0
76
77
}
77
78
}
78
79
79
80
#[ cfg( not( stage0) ) ]
80
- fn entries ( crate_map : & ' static CrateMap ) -> * ModEntry {
81
+ fn get_entries_and_children < ' a > ( crate_map : & ' a CrateMap < ' a > ) ->
82
+ ( & ' a [ ModEntry ] , & ' a [ & ' a CrateMap < ' a > ] ) {
81
83
match version ( crate_map) {
82
84
0 => {
83
85
unsafe {
84
- let v0: & ' static CrateMapV0 = transmute ( crate_map) ;
85
- return v0. entries ;
86
+ let v0: & ' a CrateMapV0 < ' a > = transmute ( crate_map) ;
87
+ return ( v0. entries , v0 . children ) ;
86
88
}
87
89
}
88
90
1 => return ( * crate_map) . entries ,
@@ -91,100 +93,63 @@ fn entries(crate_map: &'static CrateMap) -> *ModEntry {
91
93
}
92
94
93
95
#[ cfg( not( stage0) ) ]
94
- fn iterator ( crate_map : & ' static CrateMap ) -> & ' static [ & ' static CrateMap ] {
95
- match version ( crate_map) {
96
- 0 => {
97
- unsafe {
98
- let v0: & ' static CrateMapV0 = transmute ( crate_map) ;
99
- return v0. children ;
100
- }
101
- }
102
- 1 => return vec:: raw:: to_ptr ( ( * crate_map) . children ) ,
103
- _ => fail2 ! ( "Unknown crate map version!" )
104
- }
105
- }
106
-
107
- fn iter_module_map ( mod_entries : * ModEntry , f : & fn ( & mut ModEntry ) ) {
108
- let mut curr = mod_entries;
109
-
110
- unsafe {
111
- while !( * curr) . name . is_null ( ) {
112
- f ( transmute ( curr) ) ;
113
- curr = curr. offset ( 1 ) ;
114
- }
96
+ fn iter_module_map ( mod_entries : & [ ModEntry ] , f : & fn ( & ModEntry ) ) {
97
+ for entry in mod_entries. iter ( ) {
98
+ f ( entry) ;
115
99
}
116
100
}
117
101
118
-
119
-
120
102
#[ cfg( not( stage0) ) ]
121
- fn do_iter_crate_map ( crate_map : & ' static CrateMap , f : & fn ( & mut ModEntry ) ,
122
- visited : & mut HashSet < * CrateMap > ) {
103
+ fn do_iter_crate_map < ' a > ( crate_map : & ' a CrateMap < ' a > , f : & fn ( & ModEntry ) ,
104
+ visited : & mut HashSet < * CrateMap < ' a > > ) {
123
105
if visited. insert ( crate_map as * CrateMap ) {
124
- iter_module_map ( crate_map. entries , |x| f ( x) ) ;
125
- let child_crates = iterator ( crate_map) ;
126
-
127
- let mut i = 0 ;
128
- while i < child_crates. len ( ) {
129
- do_iter_crate_map ( child_crates[ i] , |x| f ( x) , visited) ;
130
- i = i + 1 ;
106
+ let ( entries, children) = get_entries_and_children ( crate_map) ;
107
+ iter_module_map ( entries, |x| f ( x) ) ;
108
+ for child in children. iter ( ) {
109
+ do_iter_crate_map ( * child, |x| f ( x) , visited) ;
131
110
}
132
111
}
133
112
}
134
113
135
114
#[ cfg( stage0) ]
136
115
/// Iterates recursively over `crate_map` and all child crate maps
137
- pub fn iter_crate_map ( crate_map : * u8 , f : & fn ( & mut ModEntry ) ) {
116
+ pub fn iter_crate_map < ' a > ( crate_map : & ' a CrateMap < ' a > , f : & fn ( & ModEntry ) ) {
138
117
}
139
118
140
119
#[ cfg( not( stage0) ) ]
141
120
/// Iterates recursively over `crate_map` and all child crate maps
142
- pub fn iter_crate_map ( crate_map : & ' static CrateMap , f : & fn ( & mut ModEntry ) ) {
121
+ pub fn iter_crate_map < ' a > ( crate_map : & ' a CrateMap < ' a > , f : & fn ( & ModEntry ) ) {
143
122
// XXX: use random numbers as keys from the OS-level RNG when there is a nice
144
123
// way to do this
145
- let mut v: HashSet < * CrateMap > = HashSet :: with_capacity_and_keys ( 0 , 0 , 32 ) ;
146
- unsafe {
147
- do_iter_crate_map ( transmute ( crate_map) , f, & mut v) ;
148
- }
124
+ let mut v: HashSet < * CrateMap < ' a > > = HashSet :: with_capacity_and_keys ( 0 , 0 , 32 ) ;
125
+ do_iter_crate_map ( crate_map, f, & mut v) ;
149
126
}
150
127
151
128
#[ cfg( test) ]
152
129
mod tests {
153
130
use c_str:: ToCStr ;
154
131
use cast:: transmute;
155
- use ptr;
156
- use vec;
157
-
158
- use rt:: crate_map:: { ModEntry , iter_crate_map} ;
159
-
160
- struct CrateMap < ' self > {
161
- version : i32 ,
162
- entries : * ModEntry ,
163
- /// a dynamically sized struct, where all pointers to children are listed adjacent
164
- /// to the struct, terminated with NULL
165
- children : & ' self [ & ' self CrateMap < ' self > ]
166
- }
132
+ use rt:: crate_map:: { CrateMap , ModEntry , iter_crate_map} ;
167
133
168
134
#[ test]
169
135
fn iter_crate_map_duplicates( ) {
170
136
unsafe {
171
137
let mod_name1 = "c::m1" . to_c_str ( ) ;
172
138
let mut level3: u32 = 3 ;
173
139
174
- let entries: ~ [ ModEntry ] = ~ [
140
+ let entries = [
175
141
ModEntry { name : mod_name1. with_ref ( |buf| buf) , log_level : & mut level3} ,
176
- ModEntry { name : ptr:: null ( ) , log_level : ptr:: mut_null ( ) }
177
142
] ;
178
143
179
144
let child_crate = CrateMap {
180
145
version : 1 ,
181
- entries : vec :: raw :: to_ptr ( entries) ,
146
+ entries : entries,
182
147
children : [ ]
183
148
} ;
184
149
185
150
let root_crate = CrateMap {
186
151
version : 1 ,
187
- entries : vec :: raw :: to_ptr ( [ ModEntry { name : ptr :: null ( ) , log_level : ptr :: mut_null ( ) } ] ) ,
152
+ entries : [ ] ,
188
153
children : [ & child_crate, & child_crate]
189
154
} ;
190
155
@@ -206,29 +171,26 @@ mod tests {
206
171
let mut level3: u32 = 3 ;
207
172
let child_crate2 = CrateMap {
208
173
version : 1 ,
209
- entries : vec :: raw :: to_ptr ( [
174
+ entries : [
210
175
ModEntry { name : mod_name1. with_ref ( |buf| buf) , log_level : & mut level2} ,
211
176
ModEntry { name : mod_name2. with_ref ( |buf| buf) , log_level : & mut level3} ,
212
- ModEntry { name : ptr:: null ( ) , log_level : ptr:: mut_null ( ) }
213
- ] ) ,
177
+ ] ,
214
178
children : [ ]
215
179
} ;
216
180
217
181
let child_crate1 = CrateMap {
218
182
version : 1 ,
219
- entries : vec :: raw :: to_ptr ( [
183
+ entries : [
220
184
ModEntry { name : "t::f1" . to_c_str ( ) . with_ref ( |buf| buf) , log_level : & mut 1 } ,
221
- ModEntry { name : ptr:: null ( ) , log_level : ptr:: mut_null ( ) }
222
- ] ) ,
185
+ ] ,
223
186
children : [ & child_crate2]
224
187
} ;
225
188
226
189
let root_crate = CrateMap {
227
190
version : 1 ,
228
- entries : vec :: raw :: to_ptr ( [
191
+ entries : [
229
192
ModEntry { name : "t::f1" . to_c_str ( ) . with_ref ( |buf| buf) , log_level : & mut 0 } ,
230
- ModEntry { name : ptr:: null ( ) , log_level : ptr:: mut_null ( ) }
231
- ] ) ,
193
+ ] ,
232
194
children : [ & child_crate1]
233
195
} ;
234
196
0 commit comments