Skip to content

Commit 84f4cd8

Browse files
committed
Use reinterpret_sized for array translation in unions
1 parent 297f2bc commit 84f4cd8

3 files changed

Lines changed: 43 additions & 15 deletions

File tree

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,18 @@ void ConverterRefCount::EmitRustUnion(clang::RecordDecl *decl) {
506506
PushConversionKind push(*this, ConversionKind::FullRefCount);
507507
std::string storage_ty = ToString(field->getType());
508508
Unwrap(storage_ty, "Value<", ">");
509-
StrCat(std::format(
510-
"pub fn {}(&self) -> Ptr<{}> {{ (self.__bytes.as_pointer() "
511-
"as Ptr<u8>).reinterpret_cast() }}",
512-
GetNamedDeclAsString(field), storage_ty));
509+
if (field->getType()->isArrayType()) {
510+
auto byte_size = ctx_.getTypeSize(field->getType()) / 8;
511+
StrCat(std::format(
512+
"pub fn {}(&self) -> Ptr<{}> {{ (self.__bytes.as_pointer() "
513+
"as Ptr<u8>).reinterpret_sized({}) }}",
514+
GetNamedDeclAsString(field), storage_ty, byte_size));
515+
} else {
516+
StrCat(std::format(
517+
"pub fn {}(&self) -> Ptr<{}> {{ (self.__bytes.as_pointer() "
518+
"as Ptr<u8>).reinterpret_cast() }}",
519+
GetNamedDeclAsString(field), storage_ty));
520+
}
513521
}
514522
}
515523

libcc2rs/src/rc.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub enum StrongPtr<T> {
4848
Reinterpreted {
4949
alloc: Rc<dyn OriginalAlloc>,
5050
byte_offset: usize,
51+
elem_byte_size: usize,
5152
// Local buffer for deref(). None until first access.
5253
// Read-through: refreshed from alloc on every deref() call.
5354
cell: RefCell<Option<T>>,
@@ -63,10 +64,11 @@ impl<T: ByteRepr> StrongPtr<T> {
6364
StrongPtr::Reinterpreted {
6465
alloc,
6566
byte_offset,
67+
elem_byte_size,
6668
cell,
6769
} => {
6870
// Read-through: always re-read from the original allocation.
69-
let mut buf = vec![0u8; T::byte_size()];
71+
let mut buf = vec![0u8; *elem_byte_size];
7072
alloc.read_bytes(*byte_offset, &mut buf);
7173
*cell.borrow_mut() = Some(T::from_bytes(&buf));
7274
Ref::map(cell.borrow(), |opt| opt.as_ref().unwrap())
@@ -353,6 +355,7 @@ impl<T> Ptr<T> {
353355
PtrKind::Reinterpreted(data) => StrongPtr::Reinterpreted {
354356
alloc: Rc::clone(&data.alloc),
355357
byte_offset: self.offset,
358+
elem_byte_size: data.elem_byte_size,
356359
cell: RefCell::new(None),
357360
},
358361
}
@@ -377,7 +380,7 @@ impl<T> Ptr<T> {
377380
rc.borrow_mut()[self.offset] = value;
378381
}
379382
PtrKind::Reinterpreted(data) => {
380-
let mut buf = vec![0u8; T::byte_size()];
383+
let mut buf = vec![0u8; data.elem_byte_size];
381384
value.to_bytes(&mut buf);
382385
data.alloc.write_bytes(self.offset, &buf);
383386
}
@@ -406,20 +409,26 @@ impl<T> Ptr<T> {
406409
panic!("cannot reinterpret_cast to zero-sized type");
407410
}
408411

409-
let src_byte_off = self.offset.wrapping_mul(T::byte_size());
412+
self.reinterpret_sized::<U>(U::byte_size())
413+
}
414+
415+
pub fn reinterpret_sized<U>(&self, elem_byte_size: usize) -> Ptr<U>
416+
where
417+
T: ByteRepr,
418+
{
410419
let (alloc, abs_byte_off): (Rc<dyn OriginalAlloc>, usize) = match &self.kind {
411420
PtrKind::Null => return Ptr::null(),
412421
PtrKind::StackSingle(weak) | PtrKind::HeapSingle(weak) => (
413422
Rc::new(SingleOriginalAlloc { weak: weak.clone() }),
414-
src_byte_off,
423+
self.offset.wrapping_mul(T::byte_size()),
415424
),
416425
PtrKind::Vec(weak) => (
417426
Rc::new(SliceOriginalAlloc { weak: weak.clone() }),
418-
src_byte_off,
427+
self.offset.wrapping_mul(T::byte_size()),
419428
),
420429
PtrKind::StackArray(weak) | PtrKind::HeapArray(weak) => (
421430
Rc::new(SliceOriginalAlloc { weak: weak.clone() }),
422-
src_byte_off,
431+
self.offset.wrapping_mul(T::byte_size()),
423432
),
424433
PtrKind::Reinterpreted(data) => (Rc::clone(&data.alloc), self.offset),
425434
};
@@ -428,7 +437,7 @@ impl<T> Ptr<T> {
428437
offset: abs_byte_off,
429438
kind: PtrKind::Reinterpreted(Rc::new(ReinterpretedView {
430439
alloc,
431-
elem_byte_size: U::byte_size(),
440+
elem_byte_size,
432441
})),
433442
}
434443
}
@@ -457,7 +466,7 @@ impl<T> Ptr<T> {
457466
f(&mut borrow[self.offset])
458467
}
459468
PtrKind::Reinterpreted(data) => {
460-
let mut buf = vec![0u8; T::byte_size()];
469+
let mut buf = vec![0u8; data.elem_byte_size];
461470
data.alloc.read_bytes(self.offset, &mut buf);
462471
let mut val = T::from_bytes(&buf);
463472
let ret = f(&mut val);
@@ -490,7 +499,7 @@ impl<T> Ptr<T> {
490499
f(&borrow[self.offset])
491500
}
492501
PtrKind::Reinterpreted(data) => {
493-
let mut buf = vec![0u8; T::byte_size()];
502+
let mut buf = vec![0u8; data.elem_byte_size];
494503
data.alloc.read_bytes(self.offset, &mut buf);
495504
let val = T::from_bytes(&buf);
496505
f(&val)
@@ -517,7 +526,7 @@ impl<T: Clone + ByteRepr> Ptr<T> {
517526
weak.upgrade().expect("ub: dangling pointer").borrow()[self.offset].clone()
518527
}
519528
PtrKind::Reinterpreted(ref data) => {
520-
let mut buf = vec![0u8; T::byte_size()];
529+
let mut buf = vec![0u8; data.elem_byte_size];
521530
data.alloc.read_bytes(self.offset, &mut buf);
522531
T::from_bytes(&buf)
523532
}

libcc2rs/src/reinterpret.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,18 @@ impl<T: ByteRepr> ByteRepr for Vec<T> {}
8585
impl<T: ByteRepr> ByteRepr for Option<T> {}
8686
impl<T: ByteRepr> ByteRepr for std::rc::Rc<T> {}
8787
impl<T: ByteRepr> ByteRepr for std::cell::RefCell<T> {}
88-
impl<T: ByteRepr> ByteRepr for Box<[T]> {}
88+
impl<T: ByteRepr> ByteRepr for Box<[T]> {
89+
fn to_bytes(&self, buf: &mut [u8]) {
90+
let size = T::byte_size();
91+
for (i, elem) in self.iter().enumerate() {
92+
elem.to_bytes(&mut buf[i * size..(i + 1) * size]);
93+
}
94+
}
95+
fn from_bytes(buf: &[u8]) -> Self {
96+
let size = T::byte_size();
97+
buf.chunks(size).map(|c| T::from_bytes(c)).collect()
98+
}
99+
}
89100
impl<T: ByteRepr> ByteRepr for Box<T> {}
90101
impl<T: 'static> ByteRepr for *const T {}
91102
impl<T: 'static> ByteRepr for *mut T {}

0 commit comments

Comments
 (0)