@@ -88,16 +88,57 @@ pub unsafe trait InstanceStructExt: InstanceStruct {
88
88
fn class ( & self ) -> & <Self :: Type as ObjectSubclass >:: Class ;
89
89
}
90
90
91
+ // rustdoc-stripper-ignore-next
92
+ /// Offset `ptr` by `offset` *bytes* and cast the result to `*const U`.
93
+ ///
94
+ /// The result must be a correctly aligned pointer to a valid value of type `U`.
95
+ ///
96
+ /// # Panics:
97
+ ///
98
+ /// This function panics if debug assertions are enabled if adding `offset` causes `ptr` to
99
+ /// overflow or if the resulting pointer is not correctly aligned.
100
+ #[ inline]
101
+ fn offset_ptr_by_bytes < T , U > ( ptr : * const T , offset : isize ) -> * const U {
102
+ // FIXME: Use `ptr::expose_addr()` once stable
103
+ let ptr = ptr as usize ;
104
+ let ptr = if offset < 0 {
105
+ ptr - ( -offset) as usize
106
+ } else {
107
+ ptr + offset as usize
108
+ } ;
109
+ debug_assert_eq ! ( ptr & ( mem:: align_of:: <U >( ) - 1 ) , 0 ) ;
110
+ ptr as * const U
111
+ }
112
+
113
+ // rustdoc-stripper-ignore-next
114
+ /// Offset `ptr` by `offset` *bytes* and cast the result to `*mut U`.
115
+ ///
116
+ /// The result must be a correctly aligned pointer to a valid value of type `U`.
117
+ ///
118
+ /// # Panics:
119
+ ///
120
+ /// This function panics if debug assertions are enabled if adding `offset` causes `ptr` to
121
+ /// overflow or if the resulting pointer is not correctly aligned.
122
+ #[ inline]
123
+ fn offset_ptr_by_bytes_mut < T , U > ( ptr : * mut T , offset : isize ) -> * mut U {
124
+ // FIXME: Use `ptr::expose_addr()` once stable
125
+ let ptr = ptr as usize ;
126
+ let ptr = if offset < 0 {
127
+ ptr - ( -offset) as usize
128
+ } else {
129
+ ptr + offset as usize
130
+ } ;
131
+ debug_assert_eq ! ( ptr & ( mem:: align_of:: <U >( ) - 1 ) , 0 ) ;
132
+ ptr as * mut U
133
+ }
134
+
91
135
unsafe impl < T : InstanceStruct > InstanceStructExt for T {
92
136
#[ inline]
93
137
fn imp ( & self ) -> & Self :: Type {
94
138
unsafe {
95
139
let data = Self :: Type :: type_data ( ) ;
96
140
let private_offset = data. as_ref ( ) . impl_offset ( ) ;
97
- let ptr: * const u8 = self as * const _ as * const u8 ;
98
- let imp_ptr = ptr. offset ( private_offset) ;
99
- let imp = imp_ptr as * const Self :: Type ;
100
-
141
+ let imp = offset_ptr_by_bytes :: < T , Self :: Type > ( self , private_offset) ;
101
142
& * imp
102
143
}
103
144
}
@@ -717,17 +758,15 @@ impl<T: ObjectSubclass> ObjectSubclassExt for T {
717
758
debug_assert ! ( type_. is_valid( ) ) ;
718
759
719
760
let offset = -data. as_ref ( ) . impl_offset ( ) ;
720
-
721
- let ptr = self as * const Self as * const u8 ;
722
- let ptr = ptr. offset ( offset) ;
723
- let ptr = ptr as * mut u8 as * mut <Self :: Type as ObjectType >:: GlibType ;
761
+ let ptr =
762
+ offset_ptr_by_bytes :: < Self , <Self :: Type as ObjectType >:: GlibType > ( self , offset) ;
724
763
725
764
// The object might just be finalized, and in that case it's unsafe to access
726
765
// it and use any API on it. This can only happen from inside the Drop impl
727
766
// of Self.
728
- debug_assert_ne ! ( ( * ( ptr as * mut gobject_ffi:: GObject ) ) . ref_count, 0 ) ;
767
+ debug_assert_ne ! ( ( * ( ptr as * const gobject_ffi:: GObject ) ) . ref_count, 0 ) ;
729
768
730
- crate :: BorrowedObject :: new ( ptr)
769
+ crate :: BorrowedObject :: new ( mut_override ( ptr) )
731
770
}
732
771
}
733
772
@@ -752,10 +791,7 @@ impl<T: ObjectSubclass> ObjectSubclassExt for T {
752
791
debug_assert ! ( self_type_. is_valid( ) ) ;
753
792
754
793
let offset = -type_data. as_ref ( ) . private_imp_offset ;
755
-
756
- let ptr = self as * const Self as * const u8 ;
757
- let ptr = ptr. offset ( offset) ;
758
- let ptr = ptr as * const PrivateStruct < Self > ;
794
+ let ptr = offset_ptr_by_bytes :: < Self , PrivateStruct < Self > > ( self , offset) ;
759
795
let priv_ = & * ptr;
760
796
761
797
match priv_. instance_data {
@@ -821,9 +857,10 @@ impl<T: ObjectSubclass> InitializingObject<T> {
821
857
822
858
let offset = type_data. as_ref ( ) . private_offset ;
823
859
824
- let ptr = self . 0 . as_ptr ( ) as * mut u8 ;
825
- let ptr = ptr. offset ( offset) ;
826
- let ptr = ptr as * mut PrivateStruct < T > ;
860
+ let ptr = offset_ptr_by_bytes_mut :: <
861
+ <<T as ObjectSubclass >:: Type as ObjectType >:: GlibType ,
862
+ PrivateStruct < T > ,
863
+ > ( self . 0 . as_ptr ( ) , offset) ;
827
864
let priv_ = & mut * ptr;
828
865
829
866
if priv_. instance_data . is_none ( ) {
@@ -885,8 +922,10 @@ unsafe extern "C" fn instance_init<T: ObjectSubclass>(
885
922
// and actually store it in that place.
886
923
let mut data = T :: type_data ( ) ;
887
924
let private_offset = data. as_mut ( ) . private_offset ;
888
- let ptr = obj as * mut u8 ;
889
- let priv_ptr = ptr. offset ( private_offset) ;
925
+ let priv_ptr = offset_ptr_by_bytes_mut :: < gobject_ffi:: GTypeInstance , PrivateStruct < T > > (
926
+ obj,
927
+ private_offset,
928
+ ) ;
890
929
891
930
assert ! (
892
931
priv_ptr as usize & ( mem:: align_of:: <PrivateStruct <T >>( ) - 1 ) == 0 ,
@@ -897,13 +936,11 @@ unsafe extern "C" fn instance_init<T: ObjectSubclass>(
897
936
2 * mem:: size_of:: <usize >( ) ,
898
937
) ;
899
938
900
- let priv_storage = priv_ptr as * mut PrivateStruct < T > ;
901
-
902
939
let klass = & * ( klass as * const T :: Class ) ;
903
940
904
941
let imp = T :: with_class ( klass) ;
905
942
ptr:: write (
906
- priv_storage ,
943
+ priv_ptr ,
907
944
PrivateStruct {
908
945
imp,
909
946
instance_data : None ,
@@ -925,11 +962,10 @@ unsafe extern "C" fn finalize<T: ObjectSubclass>(obj: *mut gobject_ffi::GObject)
925
962
// Retrieve the private struct and drop it for freeing all associated memory.
926
963
let mut data = T :: type_data ( ) ;
927
964
let private_offset = data. as_mut ( ) . private_offset ;
928
- let ptr = obj as * mut u8 ;
929
- let priv_ptr = ptr. offset ( private_offset) ;
930
- let priv_storage = & mut * ( priv_ptr as * mut PrivateStruct < T > ) ;
931
- ptr:: drop_in_place ( & mut priv_storage. imp ) ;
932
- ptr:: drop_in_place ( & mut priv_storage. instance_data ) ;
965
+ let priv_ptr =
966
+ offset_ptr_by_bytes_mut :: < gobject_ffi:: GObject , PrivateStruct < T > > ( obj, private_offset) ;
967
+ ptr:: drop_in_place ( ptr:: addr_of_mut!( ( * priv_ptr) . imp) ) ;
968
+ ptr:: drop_in_place ( ptr:: addr_of_mut!( ( * priv_ptr) . instance_data) ) ;
933
969
934
970
// Chain up to the parent class' finalize implementation, if any.
935
971
let parent_class = & * ( data. as_ref ( ) . parent_class ( ) as * const gobject_ffi:: GObjectClass ) ;
@@ -996,11 +1032,10 @@ pub fn register_type<T: ObjectSubclass>() -> Type {
996
1032
// some hoops because Rust doesn't have an offsetof operator yet.
997
1033
data. as_mut ( ) . private_imp_offset = {
998
1034
// Must not be a dangling pointer so let's create some uninitialized memory
999
- let priv_ = std :: mem:: MaybeUninit :: < PrivateStruct < T > > :: uninit ( ) ;
1035
+ let priv_ = mem:: MaybeUninit :: < PrivateStruct < T > > :: uninit ( ) ;
1000
1036
let ptr = priv_. as_ptr ( ) ;
1001
- let imp_ptr = std:: ptr:: addr_of!( ( * ptr) . imp) as * const u8 ;
1002
- let ptr = ptr as * const u8 ;
1003
- imp_ptr. offset_from ( ptr)
1037
+ let imp_ptr = ptr:: addr_of!( ( * ptr) . imp) ;
1038
+ ( imp_ptr as isize ) - ( ptr as isize )
1004
1039
} ;
1005
1040
1006
1041
let iface_types = T :: Interfaces :: iface_infos ( ) ;
0 commit comments