44// FIXME dedup this logic between miri, cg_llvm and cg_clif
55
66use 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 ;
118
129fn vtable_memflags ( ) -> MemFlags {
1310 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) ->
2118 pointer_ty ( fx. tcx ) ,
2219 vtable_memflags ( ) ,
2320 vtable,
24- ( DROP_FN_INDEX * usize_size) as i32 ,
21+ ( ty :: COMMON_VTABLE_ENTRIES_DROPINPLACE * usize_size) as i32 ,
2522 )
2623}
2724
@@ -31,7 +28,7 @@ pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Val
3128 pointer_ty ( fx. tcx ) ,
3229 vtable_memflags ( ) ,
3330 vtable,
34- ( SIZE_INDEX * usize_size) as i32 ,
31+ ( ty :: COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32 ,
3532 )
3633}
3734
@@ -41,7 +38,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
4138 pointer_ty ( fx. tcx ) ,
4239 vtable_memflags ( ) ,
4340 vtable,
44- ( ALIGN_INDEX * usize_size) as i32 ,
41+ ( ty :: COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32 ,
4542 )
4643}
4744
@@ -62,7 +59,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
6259 pointer_ty ( fx. tcx ) ,
6360 vtable_memflags ( ) ,
6461 vtable,
65- ( ( idx + 3 ) * usize_size as usize ) as i32 ,
62+ ( idx * usize_size as usize ) as i32 ,
6663 ) ;
6764 ( ptr, func_ref)
6865}
@@ -98,42 +95,49 @@ fn build_vtable<'tcx>(
9895 Instance :: resolve_drop_in_place ( tcx, layout. ty ) . polymorphize ( fx. tcx ) ,
9996 ) ;
10097
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 ) )
107100 } else {
108- ( & [ ] ) . iter ( )
101+ ty :: COMMON_VTABLE_ENTRIES
109102 } ;
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) ;
122103
123104 let mut data_ctx = DataContext :: new ( ) ;
124105 let mut data = :: std:: iter:: repeat ( 0u8 )
125- . take ( components . len ( ) * usize_size)
106+ . take ( vtable_entries . len ( ) * usize_size)
126107 . collect :: < Vec < u8 > > ( )
127108 . into_boxed_slice ( ) ;
128109
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+ }
131121 data_ctx. define ( data) ;
132122
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 => { }
137141 }
138142 }
139143
0 commit comments