4
4
// FIXME dedup this logic between miri, cg_llvm and cg_clif
5
5
6
6
use crate :: prelude:: * ;
7
-
8
- const DROP_FN_INDEX : usize = 0 ;
9
- const SIZE_INDEX : usize = 1 ;
10
- const ALIGN_INDEX : usize = 2 ;
7
+ use ty:: VtblEntry ;
11
8
12
9
fn vtable_memflags ( ) -> MemFlags {
13
10
let mut flags = MemFlags :: trusted ( ) ; // A vtable access is always aligned and will never trap.
@@ -21,7 +18,7 @@ pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) ->
21
18
pointer_ty ( fx. tcx ) ,
22
19
vtable_memflags ( ) ,
23
20
vtable,
24
- ( DROP_FN_INDEX * usize_size) as i32 ,
21
+ ( ty :: COMMON_VTABLE_ENTRIES_DROPINPLACE * usize_size) as i32 ,
25
22
)
26
23
}
27
24
@@ -31,7 +28,7 @@ pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Val
31
28
pointer_ty ( fx. tcx ) ,
32
29
vtable_memflags ( ) ,
33
30
vtable,
34
- ( SIZE_INDEX * usize_size) as i32 ,
31
+ ( ty :: COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32 ,
35
32
)
36
33
}
37
34
@@ -41,7 +38,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
41
38
pointer_ty ( fx. tcx ) ,
42
39
vtable_memflags ( ) ,
43
40
vtable,
44
- ( ALIGN_INDEX * usize_size) as i32 ,
41
+ ( ty :: COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32 ,
45
42
)
46
43
}
47
44
@@ -62,7 +59,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
62
59
pointer_ty ( fx. tcx ) ,
63
60
vtable_memflags ( ) ,
64
61
vtable,
65
- ( ( idx + 3 ) * usize_size as usize ) as i32 ,
62
+ ( idx * usize_size as usize ) as i32 ,
66
63
) ;
67
64
( ptr, func_ref)
68
65
}
@@ -98,42 +95,49 @@ fn build_vtable<'tcx>(
98
95
Instance :: resolve_drop_in_place ( tcx, layout. ty ) . polymorphize ( fx. tcx ) ,
99
96
) ;
100
97
101
- let mut components: Vec < _ > = vec ! [ Some ( drop_in_place_fn) , None , None ] ;
102
-
103
- let methods_root;
104
- let methods = if let Some ( trait_ref) = trait_ref {
105
- methods_root = tcx. vtable_methods ( trait_ref. with_self_ty ( tcx, layout. ty ) ) ;
106
- methods_root. iter ( )
98
+ let vtable_entries = if let Some ( trait_ref) = trait_ref {
99
+ tcx. vtable_entries ( trait_ref. with_self_ty ( tcx, layout. ty ) )
107
100
} else {
108
- ( & [ ] ) . iter ( )
101
+ ty :: COMMON_VTABLE_ENTRIES
109
102
} ;
110
- let methods = methods. cloned ( ) . map ( |opt_mth| {
111
- opt_mth. map ( |( def_id, substs) | {
112
- import_function (
113
- tcx,
114
- fx. module ,
115
- Instance :: resolve_for_vtable ( tcx, ParamEnv :: reveal_all ( ) , def_id, substs)
116
- . unwrap ( )
117
- . polymorphize ( fx. tcx ) ,
118
- )
119
- } )
120
- } ) ;
121
- components. extend ( methods) ;
122
103
123
104
let mut data_ctx = DataContext :: new ( ) ;
124
105
let mut data = :: std:: iter:: repeat ( 0u8 )
125
- . take ( components . len ( ) * usize_size)
106
+ . take ( vtable_entries . len ( ) * usize_size)
126
107
. collect :: < Vec < u8 > > ( )
127
108
. into_boxed_slice ( ) ;
128
109
129
- write_usize ( fx. tcx , & mut data, SIZE_INDEX , layout. size . bytes ( ) ) ;
130
- write_usize ( fx. tcx , & mut data, ALIGN_INDEX , layout. align . abi . bytes ( ) ) ;
110
+ for ( idx, entry) in vtable_entries. iter ( ) . enumerate ( ) {
111
+ match entry {
112
+ VtblEntry :: MetadataSize => {
113
+ write_usize ( fx. tcx , & mut data, idx, layout. size . bytes ( ) ) ;
114
+ }
115
+ VtblEntry :: MetadataAlign => {
116
+ write_usize ( fx. tcx , & mut data, idx, layout. align . abi . bytes ( ) ) ;
117
+ }
118
+ VtblEntry :: MetadataDropInPlace | VtblEntry :: Vacant | VtblEntry :: Method ( _, _) => { }
119
+ }
120
+ }
131
121
data_ctx. define ( data) ;
132
122
133
- for ( i, component) in components. into_iter ( ) . enumerate ( ) {
134
- if let Some ( func_id) = component {
135
- let func_ref = fx. module . declare_func_in_data ( func_id, & mut data_ctx) ;
136
- data_ctx. write_function_addr ( ( i * usize_size) as u32 , func_ref) ;
123
+ for ( idx, entry) in vtable_entries. iter ( ) . enumerate ( ) {
124
+ match entry {
125
+ VtblEntry :: MetadataDropInPlace => {
126
+ let func_ref = fx. module . declare_func_in_data ( drop_in_place_fn, & mut data_ctx) ;
127
+ data_ctx. write_function_addr ( ( idx * usize_size) as u32 , func_ref) ;
128
+ }
129
+ VtblEntry :: Method ( def_id, substs) => {
130
+ let func_id = import_function (
131
+ tcx,
132
+ fx. module ,
133
+ Instance :: resolve_for_vtable ( tcx, ParamEnv :: reveal_all ( ) , * def_id, substs)
134
+ . unwrap ( )
135
+ . polymorphize ( fx. tcx ) ,
136
+ ) ;
137
+ let func_ref = fx. module . declare_func_in_data ( func_id, & mut data_ctx) ;
138
+ data_ctx. write_function_addr ( ( idx * usize_size) as u32 , func_ref) ;
139
+ }
140
+ VtblEntry :: MetadataSize | VtblEntry :: MetadataAlign | VtblEntry :: Vacant => { }
137
141
}
138
142
}
139
143
0 commit comments