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