@@ -6,17 +6,23 @@ use rustc_mir::interpret::{CompileTimeEvaluator, Memory};
6
6
7
7
#[ derive( Default ) ]
8
8
pub struct ConstantCx {
9
- todo_allocs : HashSet < AllocId > ,
9
+ todo : HashSet < TodoItem > ,
10
10
done : HashSet < DataId > ,
11
11
}
12
12
13
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
14
+ enum TodoItem {
15
+ Alloc ( AllocId ) ,
16
+ Static ( DefId ) ,
17
+ }
18
+
13
19
impl ConstantCx {
14
20
pub fn finalize < ' a , ' tcx : ' a , B : Backend > (
15
21
mut self ,
16
22
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
17
23
module : & mut Module < B > ,
18
24
) {
19
- println ! ( "todo allocs: {:?}" , self . todo_allocs ) ;
25
+ println ! ( "todo {:?}" , self . todo ) ;
20
26
define_all_allocs ( tcx, module, & mut self ) ;
21
27
println ! ( "done {:?}" , self . done) ;
22
28
for data_id in self . done . drain ( ) {
@@ -26,14 +32,15 @@ impl ConstantCx {
26
32
}
27
33
28
34
pub fn codegen_static < ' a , ' tcx : ' a , B : Backend > ( cx : & mut CodegenCx < ' a , ' tcx , B > , def_id : DefId ) {
29
- unimpl ! ( "static mono item {:?}" , def_id) ;
35
+ cx . constants . todo . insert ( TodoItem :: Static ( def_id) ) ;
30
36
}
31
37
32
38
pub fn codegen_static_ref < ' a , ' tcx : ' a > (
33
39
fx : & mut FunctionCx < ' a , ' tcx > ,
34
40
static_ : & Static < ' tcx > ,
35
41
) -> CPlace < ' tcx > {
36
- unimpl ! ( "static place {:?} ty {:?}" , static_. def_id, static_. ty) ;
42
+ let data_id = data_id_for_static ( fx. tcx , fx. module , static_. def_id ) ;
43
+ cplace_for_dataid ( fx, static_. ty , data_id)
37
44
}
38
45
39
46
pub fn trans_promoted < ' a , ' tcx : ' a > (
@@ -109,38 +116,36 @@ fn trans_const_place<'a, 'tcx: 'a>(
109
116
fx : & mut FunctionCx < ' a , ' tcx > ,
110
117
const_ : & ' tcx Const < ' tcx > ,
111
118
) -> CPlace < ' tcx > {
112
- let ty = fx. monomorphize ( & const_. ty ) ;
113
- let layout = fx. layout_of ( ty) ;
114
-
115
119
let alloc = fx. tcx . const_value_to_allocation ( const_) ;
116
120
//println!("const value: {:?} allocation: {:?}", value, alloc);
117
121
let alloc_id = fx. tcx . alloc_map . lock ( ) . allocate ( alloc) ;
118
- let data_id = get_global_for_alloc_id ( fx. module , fx. constants , alloc_id) ;
119
- let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
120
- // TODO: does global_value return a ptr of a val?
121
- let global_ptr = fx. bcx . ins ( ) . global_value ( types:: I64 , local_data_id) ;
122
- CPlace :: Addr ( global_ptr, layout)
122
+ fx. constants . todo . insert ( TodoItem :: Alloc ( alloc_id) ) ;
123
+ let data_id = data_id_for_alloc_id ( fx. module , alloc_id) ;
124
+ cplace_for_dataid ( fx, const_. ty , data_id)
123
125
}
124
126
125
- // If ret.1 is true, then the global didn't exist before
126
- fn define_global_for_alloc_id < ' a , ' tcx : ' a , B : Backend > (
127
- module : & mut Module < B > ,
128
- cx : & mut ConstantCx ,
129
- alloc_id : AllocId ,
130
- ) -> DataId {
127
+ fn data_id_for_alloc_id < B : Backend > ( module : & mut Module < B > , alloc_id : AllocId ) -> DataId {
131
128
module
132
129
. declare_data ( & alloc_id. 0 . to_string ( ) , Linkage :: Local , false )
133
130
. unwrap ( )
134
131
}
135
132
136
- fn get_global_for_alloc_id < ' a , ' tcx : ' a , B : Backend + ' a > (
137
- module : & mut Module < B > ,
138
- cx : & mut ConstantCx ,
139
- alloc_id : AllocId ,
140
- ) -> DataId {
141
- cx. todo_allocs . insert ( alloc_id) ;
142
- let data_id = define_global_for_alloc_id ( module, cx, alloc_id) ;
143
- data_id
133
+ fn data_id_for_static < B : Backend > ( tcx : TyCtxt , module : & mut Module < B > , def_id : DefId ) -> DataId {
134
+ let symbol_name = tcx. symbol_name ( Instance :: mono ( tcx, def_id) ) . as_str ( ) ;
135
+ module
136
+ . declare_data ( & * symbol_name, Linkage :: Export , false )
137
+ . unwrap ( )
138
+ }
139
+
140
+ fn cplace_for_dataid < ' a , ' tcx : ' a > (
141
+ fx : & mut FunctionCx < ' a , ' tcx > ,
142
+ ty : Ty < ' tcx > ,
143
+ data_id : DataId ,
144
+ ) -> CPlace < ' tcx > {
145
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
146
+ let global_ptr = fx. bcx . ins ( ) . global_value ( types:: I64 , local_data_id) ;
147
+ let layout = fx. layout_of ( fx. monomorphize ( & ty) ) ;
148
+ CPlace :: Addr ( global_ptr, layout)
144
149
}
145
150
146
151
fn define_all_allocs < ' a , ' tcx : ' a , B : Backend + ' a > (
@@ -150,15 +155,38 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
150
155
) {
151
156
let memory = Memory :: < CompileTimeEvaluator > :: new ( tcx. at ( DUMMY_SP ) , ( ) ) ;
152
157
153
- while let Some ( alloc_id) = pop_set ( & mut cx. todo_allocs ) {
154
- let data_id = define_global_for_alloc_id ( module, cx, alloc_id) ;
155
- println ! ( "alloc_id {} data_id {}" , alloc_id, data_id) ;
158
+ while let Some ( todo_item) = pop_set ( & mut cx. todo ) {
159
+ let ( data_id, alloc) = match todo_item {
160
+ TodoItem :: Alloc ( alloc_id) => {
161
+ println ! ( "alloc_id {}" , alloc_id) ;
162
+ let data_id = data_id_for_alloc_id ( module, alloc_id) ;
163
+ let alloc = memory. get ( alloc_id) . unwrap ( ) ;
164
+ ( data_id, alloc)
165
+ }
166
+ TodoItem :: Static ( def_id) => {
167
+ println ! ( "static {:?}" , def_id) ;
168
+ let instance = ty:: Instance :: mono ( tcx, def_id) ;
169
+ let cid = GlobalId {
170
+ instance,
171
+ promoted : None ,
172
+ } ;
173
+ let const_ = tcx. const_eval ( ParamEnv :: reveal_all ( ) . and ( cid) ) . unwrap ( ) ;
174
+
175
+ let alloc = match const_. val {
176
+ ConstValue :: ByRef ( alloc, n) if n. bytes ( ) == 0 => alloc,
177
+ _ => bug ! ( "static const eval returned {:#?}" , const_) ,
178
+ } ;
179
+
180
+ let data_id = data_id_for_static ( tcx, module, def_id) ;
181
+ ( data_id, alloc)
182
+ }
183
+ } ;
184
+
185
+ println ! ( "data_id {}" , data_id) ;
156
186
if cx. done . contains ( & data_id) {
157
187
continue ;
158
188
}
159
189
160
- let alloc = memory. get ( alloc_id) . unwrap ( ) ;
161
- //let alloc = tcx.alloc_map.lock().get(alloc_id).unwrap();
162
190
let mut data_ctx = DataContext :: new ( ) ;
163
191
164
192
data_ctx. define (
@@ -167,8 +195,8 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
167
195
) ;
168
196
169
197
for & ( offset, reloc) in alloc. relocations . iter ( ) {
170
- cx. todo_allocs . insert ( reloc) ;
171
- let data_id = define_global_for_alloc_id ( module, cx , reloc) ;
198
+ cx. todo . insert ( TodoItem :: Alloc ( reloc) ) ;
199
+ let data_id = data_id_for_alloc_id ( module, reloc) ;
172
200
173
201
let reloc_offset = {
174
202
let endianness = memory. endianness ( ) ;
@@ -186,7 +214,7 @@ fn define_all_allocs<'a, 'tcx: 'a, B: Backend + 'a>(
186
214
cx. done . insert ( data_id) ;
187
215
}
188
216
189
- assert ! ( cx. todo_allocs . is_empty( ) , "{:?}" , cx. todo_allocs ) ;
217
+ assert ! ( cx. todo . is_empty( ) , "{:?}" , cx. todo ) ;
190
218
}
191
219
192
220
fn pop_set < T : Copy + Eq + :: std:: hash:: Hash > ( set : & mut HashSet < T > ) -> Option < T > {
0 commit comments