@@ -8,22 +8,47 @@ use crate::value::Value;
8
8
use cstr:: cstr;
9
9
use libc:: c_uint;
10
10
use rustc_codegen_ssa:: traits:: * ;
11
+ use rustc_data_structures:: captures:: Captures ;
11
12
use rustc_hir:: def_id:: DefId ;
12
13
use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
13
14
use rustc_middle:: mir:: interpret:: {
14
- read_target_uint, Allocation , ErrorHandled , GlobalAlloc , Pointer ,
15
+ read_target_uint, Allocation , ErrorHandled , GlobalAlloc , InitChunk , Pointer ,
15
16
} ;
16
17
use rustc_middle:: mir:: mono:: MonoItem ;
17
18
use rustc_middle:: ty:: { self , Instance , Ty } ;
18
19
use rustc_middle:: { bug, span_bug} ;
19
20
use rustc_target:: abi:: { AddressSpace , Align , HasDataLayout , LayoutOf , Primitive , Scalar , Size } ;
21
+ use std:: ops:: Range ;
20
22
use tracing:: debug;
21
23
22
24
pub fn const_alloc_to_llvm ( cx : & CodegenCx < ' ll , ' _ > , alloc : & Allocation ) -> & ' ll Value {
23
25
let mut llvals = Vec :: with_capacity ( alloc. relocations ( ) . len ( ) + 1 ) ;
24
26
let dl = cx. data_layout ( ) ;
25
27
let pointer_size = dl. pointer_size . bytes ( ) as usize ;
26
28
29
+ // Note: this function may call `inspect_with_uninit_and_ptr_outside_interpreter`,
30
+ // so `range` must be within the bounds of `alloc` and not within a relocation.
31
+ fn chunks_of_init_and_uninit_bytes < ' ll , ' a , ' b > (
32
+ cx : & ' a CodegenCx < ' ll , ' b > ,
33
+ alloc : & ' a Allocation ,
34
+ range : Range < usize > ,
35
+ ) -> impl Iterator < Item = & ' ll Value > + Captures < ' a > + Captures < ' b > {
36
+ alloc
37
+ . init_mask ( )
38
+ . range_as_init_chunks ( Size :: from_bytes ( range. start ) , Size :: from_bytes ( range. end ) )
39
+ . map ( move |chunk| match chunk {
40
+ InitChunk :: Init ( range) => {
41
+ let range = ( range. start . bytes ( ) as usize ) ..( range. end . bytes ( ) as usize ) ;
42
+ let bytes = alloc. inspect_with_uninit_and_ptr_outside_interpreter ( range) ;
43
+ cx. const_bytes ( bytes)
44
+ }
45
+ InitChunk :: Uninit ( range) => {
46
+ let len = range. end . bytes ( ) - range. start . bytes ( ) ;
47
+ cx. const_undef ( cx. type_array ( cx. type_i8 ( ) , len) )
48
+ }
49
+ } )
50
+ }
51
+
27
52
let mut next_offset = 0 ;
28
53
for & ( offset, ( ( ) , alloc_id) ) in alloc. relocations ( ) . iter ( ) {
29
54
let offset = offset. bytes ( ) ;
@@ -32,12 +57,8 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
32
57
if offset > next_offset {
33
58
// This `inspect` is okay since we have checked that it is not within a relocation, it
34
59
// is within the bounds of the allocation, and it doesn't affect interpreter execution
35
- // (we inspect the result after interpreter execution). Any undef byte is replaced with
36
- // some arbitrary byte value.
37
- //
38
- // FIXME: relay undef bytes to codegen as undef const bytes
39
- let bytes = alloc. inspect_with_uninit_and_ptr_outside_interpreter ( next_offset..offset) ;
40
- llvals. push ( cx. const_bytes ( bytes) ) ;
60
+ // (we inspect the result after interpreter execution).
61
+ llvals. extend ( chunks_of_init_and_uninit_bytes ( cx, alloc, next_offset..offset) ) ;
41
62
}
42
63
let ptr_offset = read_target_uint (
43
64
dl. endian ,
@@ -65,12 +86,8 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
65
86
let range = next_offset..alloc. len ( ) ;
66
87
// This `inspect` is okay since we have check that it is after all relocations, it is
67
88
// within the bounds of the allocation, and it doesn't affect interpreter execution (we
68
- // inspect the result after interpreter execution). Any undef byte is replaced with some
69
- // arbitrary byte value.
70
- //
71
- // FIXME: relay undef bytes to codegen as undef const bytes
72
- let bytes = alloc. inspect_with_uninit_and_ptr_outside_interpreter ( range) ;
73
- llvals. push ( cx. const_bytes ( bytes) ) ;
89
+ // inspect the result after interpreter execution).
90
+ llvals. extend ( chunks_of_init_and_uninit_bytes ( cx, alloc, range) ) ;
74
91
}
75
92
76
93
cx. const_struct ( & llvals, true )
0 commit comments