1
1
use std:: convert:: TryFrom ;
2
2
use std:: convert:: TryInto ;
3
3
4
+ use gccjit:: LValue ;
4
5
use gccjit:: { Block , CType , RValue , Type , ToRValue } ;
5
6
use rustc_codegen_ssa:: mir:: place:: PlaceRef ;
6
7
use rustc_codegen_ssa:: traits:: {
@@ -10,7 +11,6 @@ use rustc_codegen_ssa::traits::{
10
11
MiscMethods ,
11
12
StaticMethods ,
12
13
} ;
13
- use rustc_middle:: bug;
14
14
use rustc_middle:: mir:: Mutability ;
15
15
use rustc_middle:: ty:: ScalarInt ;
16
16
use rustc_middle:: ty:: layout:: { TyAndLayout , LayoutOf } ;
@@ -27,28 +27,27 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
27
27
bytes_in_context ( self , bytes)
28
28
}
29
29
30
- fn const_cstr ( & self , symbol : Symbol , _null_terminated : bool ) -> RValue < ' gcc > {
30
+ fn const_cstr ( & self , symbol : Symbol , _null_terminated : bool ) -> LValue < ' gcc > {
31
31
// TODO(antoyo): handle null_terminated.
32
32
if let Some ( & value) = self . const_cstr_cache . borrow ( ) . get ( & symbol) {
33
- return value. to_rvalue ( ) ;
33
+ return value;
34
34
}
35
35
36
36
let global = self . global_string ( & * symbol. as_str ( ) ) ;
37
37
38
- self . const_cstr_cache . borrow_mut ( ) . insert ( symbol, global. dereference ( None ) ) ;
38
+ self . const_cstr_cache . borrow_mut ( ) . insert ( symbol, global) ;
39
39
global
40
40
}
41
41
42
- fn global_string ( & self , string : & str ) -> RValue < ' gcc > {
42
+ fn global_string ( & self , string : & str ) -> LValue < ' gcc > {
43
43
// TODO(antoyo): handle non-null-terminated strings.
44
44
let string = self . context . new_string_literal ( & * string) ;
45
45
let sym = self . generate_local_symbol_name ( "str" ) ;
46
46
// NOTE: TLS is always off for a string litteral.
47
47
// NOTE: string litterals do not have a link section.
48
- let global = self . define_global ( & sym, self . val_ty ( string) , false , None )
49
- . unwrap_or_else ( || bug ! ( "symbol `{}` is already defined" , sym) ) ;
50
- self . global_init_block . add_assignment ( None , global. dereference ( None ) , string) ;
51
- global. to_rvalue ( )
48
+ let global = self . declare_private_global ( & sym, self . val_ty ( string) ) ;
49
+ global. global_set_initializer_value ( string) ; // TODO: only set if not imported?
50
+ global
52
51
// TODO(antoyo): set linkage.
53
52
}
54
53
@@ -76,10 +75,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
76
75
77
76
pub fn bytes_in_context < ' gcc , ' tcx > ( cx : & CodegenCx < ' gcc , ' tcx > , bytes : & [ u8 ] ) -> RValue < ' gcc > {
78
77
let context = & cx. context ;
79
- let typ = context. new_array_type ( None , context. new_type :: < u8 > ( ) , bytes. len ( ) as i32 ) ;
80
- let global = cx. declare_unnamed_global ( typ) ;
81
- global. global_set_initializer ( bytes) ;
82
- global. to_rvalue ( )
78
+ let byte_type = context. new_type :: < u8 > ( ) ;
79
+ let typ = context. new_array_type ( None , byte_type, bytes. len ( ) as i32 ) ;
80
+ let elements: Vec < _ > =
81
+ bytes. iter ( )
82
+ . map ( |& byte| context. new_rvalue_from_int ( byte_type, byte as i32 ) )
83
+ . collect ( ) ;
84
+ context. new_rvalue_from_array ( None , typ, & elements)
83
85
}
84
86
85
87
pub fn type_is_pointer < ' gcc > ( typ : Type < ' gcc > ) -> bool {
@@ -180,7 +182,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
180
182
181
183
fn const_str ( & self , s : Symbol ) -> ( RValue < ' gcc > , RValue < ' gcc > ) {
182
184
let len = s. as_str ( ) . len ( ) ;
183
- let cs = self . const_ptrcast ( self . const_cstr ( s, false ) ,
185
+ let cs = self . const_ptrcast ( self . const_cstr ( s, false ) . get_address ( None ) ,
184
186
self . type_ptr_to ( self . layout_of ( self . tcx . types . str_ ) . gcc_type ( self , true ) ) ,
185
187
) ;
186
188
( cs, self . const_usize ( len as u64 ) )
@@ -191,16 +193,9 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
191
193
. map ( |value| value. get_type ( ) )
192
194
. collect ( ) ;
193
195
// TODO(antoyo): cache the type? It's anonymous, so probably not.
194
- let name = fields. iter ( ) . map ( |typ| format ! ( "{:?}" , typ) ) . collect :: < Vec < _ > > ( ) . join ( "_" ) ;
195
196
let typ = self . type_struct ( & fields, packed) ;
196
- let structure = self . global_init_func . new_local ( None , typ, & name) ;
197
197
let struct_type = typ. is_struct ( ) . expect ( "struct type" ) ;
198
- for ( index, value) in values. iter ( ) . enumerate ( ) {
199
- let field = struct_type. get_field ( index as i32 ) ;
200
- let field_lvalue = structure. access_field ( None , field) ;
201
- self . global_init_block . add_assignment ( None , field_lvalue, * value) ;
202
- }
203
- self . lvalue_to_rvalue ( structure)
198
+ self . context . new_rvalue_from_struct ( None , struct_type, values)
204
199
}
205
200
206
201
fn const_to_opt_uint ( & self , _v : RValue < ' gcc > ) -> Option < u64 > {
@@ -260,19 +255,18 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
260
255
} ,
261
256
GlobalAlloc :: Static ( def_id) => {
262
257
assert ! ( self . tcx. is_static( def_id) ) ;
263
- self . get_static ( def_id)
258
+ self . get_static ( def_id) . get_address ( None )
264
259
} ,
265
260
} ;
266
261
let ptr_type = base_addr. get_type ( ) ;
267
262
let base_addr = self . const_bitcast ( base_addr, self . usize_type ) ;
268
263
let offset = self . context . new_rvalue_from_long ( self . usize_type , offset. bytes ( ) as i64 ) ;
269
264
let ptr = self . const_bitcast ( base_addr + offset, ptr_type) ;
270
- let value = ptr. dereference ( None ) ;
271
265
if layout. value != Pointer {
272
- self . const_bitcast ( value . to_rvalue ( ) , ty)
266
+ self . const_bitcast ( ptr . dereference ( None ) . to_rvalue ( ) , ty)
273
267
}
274
268
else {
275
- self . const_bitcast ( value . get_address ( None ) , ty)
269
+ self . const_bitcast ( ptr , ty)
276
270
}
277
271
}
278
272
}
0 commit comments