Skip to content

Commit 0f40e81

Browse files
committed
Memcpy a poitner to a struct through ErasedPtr
1 parent 238d847 commit 0f40e81

2 files changed

Lines changed: 23 additions & 83 deletions

File tree

‎libcc2rs/src/fn_ptr.rs‎

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::marker::PhantomData;
66
use std::ops::Deref;
77
use std::rc::Rc;
88

9-
use crate::rc::{AnyPtr, ErasedPtr};
9+
use crate::rc::{AnyPtr, ErasedPtr, Ptr};
1010
use crate::reinterpret::ByteRepr;
1111

1212
pub trait FnAddr {
@@ -146,20 +146,14 @@ impl<T> Eq for FnPtr<T> {}
146146
impl<T: 'static> ByteRepr for FnPtr<T> {}
147147

148148
impl<T: 'static> ErasedPtr for FnPtr<T> {
149-
fn pointee_type_id(&self) -> TypeId {
150-
TypeId::of::<T>()
151-
}
152-
fn memcpy(&self, _src: &dyn ErasedPtr, _len: usize) {
153-
panic!("memcpy not supported on fn pointer");
149+
fn as_bytes(&self) -> Ptr<u8> {
150+
panic!("byte view not supported on fn pointer");
154151
}
155152
fn as_any(&self) -> &dyn Any {
156153
self
157154
}
158-
fn equals(&self, other: &dyn ErasedPtr) -> Option<bool> {
159-
if self.pointee_type_id() != other.pointee_type_id() {
160-
return None;
161-
}
162-
other.as_any().downcast_ref::<FnPtr<T>>().map(|o| self == o)
155+
fn equals(&self, other: &dyn ErasedPtr) -> bool {
156+
other.as_any().downcast_ref::<FnPtr<T>>() == Some(self)
163157
}
164158
fn is_null(&self) -> bool {
165159
FnPtr::is_null(self)

‎libcc2rs/src/rc.rs‎

Lines changed: 18 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,49 +1042,33 @@ impl Ptr<u8> {
10421042
}
10431043

10441044
pub(crate) trait ErasedPtr: std::any::Any {
1045-
fn pointee_type_id(&self) -> std::any::TypeId;
1046-
fn memcpy(&self, src: &dyn ErasedPtr, len: usize);
1045+
fn as_bytes(&self) -> Ptr<u8>;
10471046
fn as_any(&self) -> &dyn std::any::Any;
1048-
fn equals(&self, other: &dyn ErasedPtr) -> Option<bool>;
1047+
fn equals(&self, other: &dyn ErasedPtr) -> bool;
10491048
fn is_null(&self) -> bool;
10501049
}
10511050

1051+
impl PartialEq for dyn ErasedPtr {
1052+
fn eq(&self, other: &Self) -> bool {
1053+
self.equals(other)
1054+
}
1055+
}
1056+
10521057
impl<T> ErasedPtr for Ptr<T>
10531058
where
10541059
T: ByteRepr + 'static,
10551060
Ptr<T>: PartialEq,
10561061
{
1057-
fn pointee_type_id(&self) -> std::any::TypeId {
1058-
std::any::TypeId::of::<T>()
1059-
}
1060-
1061-
fn memcpy(&self, src: &dyn ErasedPtr, len: usize) {
1062-
if self.pointee_type_id() != src.pointee_type_id() {
1063-
panic!("memcpy: type mismatch");
1064-
}
1065-
let src_ptr = src
1066-
.as_any()
1067-
.downcast_ref::<Ptr<T>>()
1068-
.expect("memcpy: downcast to Ptr<T> failed");
1069-
let dst_bytes: Ptr<u8> = self.reinterpret_cast();
1070-
let src_bytes: Ptr<u8> = src_ptr.reinterpret_cast();
1071-
dst_bytes.memcpy(&src_bytes, len);
1062+
fn as_bytes(&self) -> Ptr<u8> {
1063+
self.reinterpret_cast::<u8>()
10721064
}
10731065

10741066
fn as_any(&self) -> &dyn std::any::Any {
10751067
self
10761068
}
10771069

1078-
fn equals(&self, other: &dyn ErasedPtr) -> Option<bool> {
1079-
if self.pointee_type_id() != other.pointee_type_id() {
1080-
return None;
1081-
}
1082-
1083-
if let Some(other_ptr) = other.as_any().downcast_ref::<Ptr<T>>() {
1084-
return Some(self == other_ptr);
1085-
}
1086-
1087-
None
1070+
fn equals(&self, other: &dyn ErasedPtr) -> bool {
1071+
other.as_any().downcast_ref::<Ptr<T>>() == Some(self)
10881072
}
10891073

10901074
fn is_null(&self) -> bool {
@@ -1118,66 +1102,28 @@ impl AnyPtr {
11181102
}
11191103
self.ptr.as_any().downcast_ref::<Ptr<T>>().cloned()
11201104
}
1121-
1122-
pub fn reinterpret_cast<T: ByteRepr>(&self) -> Ptr<T> {
1123-
macro_rules! try_src {
1124-
($ty:ty) => {{
1125-
if let Some(p) = self.cast::<$ty>() {
1126-
return p.reinterpret_cast::<T>();
1127-
}
1128-
if let Some(pv) = self.cast::<Vec<$ty>>() {
1129-
return pv.reinterpret_cast::<T>();
1130-
}
1131-
}};
1132-
}
1133-
1134-
try_src!(u8);
1135-
try_src!(i8);
1136-
try_src!(u16);
1137-
try_src!(i16);
1138-
try_src!(u32);
1139-
try_src!(i32);
1140-
try_src!(u64);
1141-
try_src!(i64);
1142-
try_src!(usize);
1143-
try_src!(isize);
1144-
1145-
panic!("reinterpret_cast: unsupported AnyPtr source");
1146-
}
11471105
}
11481106

11491107
impl PartialEq for AnyPtr {
11501108
fn eq(&self, other: &Self) -> bool {
1151-
let lhs: &dyn ErasedPtr = self.ptr.as_ref();
1152-
let rhs: &dyn ErasedPtr = other.ptr.as_ref();
1153-
1154-
lhs.equals(rhs).unwrap_or_default()
1109+
*self.ptr == *other.ptr
11551110
}
11561111
}
11571112

11581113
impl AnyPtr {
11591114
pub fn memcpy(&self, src: &AnyPtr, len: usize) {
1160-
let dst_erased = &*self.ptr;
1161-
let src_erased = &*src.ptr;
1162-
1163-
if dst_erased.pointee_type_id() == src_erased.pointee_type_id() {
1164-
dst_erased.memcpy(src_erased, len);
1165-
return;
1166-
}
1167-
1168-
let dst_u8: Ptr<u8> = self.reinterpret_cast();
1169-
let src_u8: Ptr<u8> = src.reinterpret_cast();
1115+
let dst_u8 = self.ptr.as_bytes();
1116+
let src_u8 = src.ptr.as_bytes();
11701117
dst_u8.memcpy(&src_u8, len);
11711118
}
11721119

11731120
pub fn memset(&self, value: u8, num: usize) {
1174-
let dst_u8: Ptr<u8> = self.reinterpret_cast();
1175-
dst_u8.memset(value, num);
1121+
self.ptr.as_bytes().memset(value, num);
11761122
}
11771123

11781124
pub fn memcmp(&self, other: &AnyPtr, len: usize) -> i32 {
1179-
let a: Ptr<u8> = self.reinterpret_cast();
1180-
let b: Ptr<u8> = other.reinterpret_cast();
1125+
let a = self.ptr.as_bytes();
1126+
let b = other.ptr.as_bytes();
11811127
a.memcmp(&b, len)
11821128
}
11831129
}

0 commit comments

Comments
 (0)